Browse Source

Merge remote-tracking branch 'origin/dev' into optimize-buffer-geometry-indices

Garrett Johnson 7 years ago
parent
commit
73dba53db6
100 changed files with 7338 additions and 4770 deletions
  1. 1 1
      .github/ISSUE_TEMPLATE.md
  2. 11 1
      build/three.js
  3. 382 381
      build/three.min.js
  4. 11 1
      build/three.module.js
  5. 3 3
      docs/api/core/Object3D.html
  6. 1 1
      docs/api/loaders/JSONLoader.html
  7. 1 1
      docs/api/objects/Line.html
  8. 1 1
      docs/api/objects/Mesh.html
  9. 1 1
      docs/api/objects/Points.html
  10. 1 1
      docs/api/objects/Sprite.html
  11. 1 0
      docs/api/textures/DataTexture.html
  12. 1 1
      docs/examples/exporters/GLTFExporter.html
  13. 62 0
      docs/examples/exporters/PLYExporter.html
  14. 1 0
      docs/examples/renderers/CSS2DRenderer.html
  15. 3 1
      docs/list.js
  16. 5 5
      docs/manual/introduction/Animation-system.html
  17. 1 1
      docs/manual/introduction/Creating-a-scene.html
  18. 3 3
      docs/manual/introduction/FAQ.html
  19. 3 3
      docs/manual/introduction/Import-via-modules.html
  20. 129 0
      docs/manual/introduction/Loading-3D-models.html
  21. 7 0
      docs/manual/introduction/Useful-links.html
  22. 11 27
      docs/scenes/geometry-browser.html
  23. 150 0
      examples/css2d_label.html
  24. 6 2
      examples/files.js
  25. 9 8
      examples/js/MorphBlendMesh.js
  26. 1 1
      examples/js/animation/CCDIKSolver.js
  27. 8 5
      examples/js/animation/MMDAnimationHelper.js
  28. 14 6
      examples/js/cameras/CinematicCamera.js
  29. 0 149
      examples/js/controls/VRControls.js
  30. 1 1
      examples/js/effects/OutlineEffect.js
  31. 0 533
      examples/js/effects/VREffect.js
  32. 4 0
      examples/js/exporters/GLTFExporter.js
  33. 1 1
      examples/js/exporters/PLYExporter.js
  34. 0 94
      examples/js/exporters/STLBinaryExporter.js
  35. 110 25
      examples/js/exporters/STLExporter.js
  36. 5 0
      examples/js/loaders/DRACOLoader.js
  37. 1 7
      examples/js/loaders/EquiangularToCubeGenerator.js
  38. 25 24
      examples/js/loaders/GLTFLoader.js
  39. 199 131
      examples/js/loaders/MD2Loader.js
  40. 8 7
      examples/js/loaders/MMDLoader.js
  41. 21 69
      examples/js/loaders/TDSLoader.js
  42. 22 48
      examples/js/loaders/VTKLoader.js
  43. 7 2
      examples/js/loaders/XLoader.js
  44. 96 63
      examples/js/modifiers/SimplifyModifier.js
  45. 2 2
      examples/js/objects/Reflector.js
  46. 0 2
      examples/js/objects/ReflectorRTT.js
  47. 1 7
      examples/js/pmrem/PMREMCubeUVPacker.js
  48. 1 7
      examples/js/pmrem/PMREMGenerator.js
  49. 62 0
      examples/js/renderers/CSS2DRenderer.js
  50. 91 26
      examples/js/shaders/BokehShader2.js
  51. 5 2
      examples/js/vr/WebVR.js
  52. 193 0
      examples/misc_exporter_stl.html
  53. 0 1
      examples/webgl_buffergeometry_instancing_lambert.html
  54. 2 2
      examples/webgl_geometry_colors_json.html
  55. 29 23
      examples/webgl_interactive_voxelpainter.html
  56. 1 1
      examples/webgl_loader_json.html
  57. 12 8
      examples/webgl_loader_mmd.html
  58. 8 4
      examples/webgl_loader_mmd_audio.html
  59. 23 18
      examples/webgl_loader_mmd_pose.html
  60. 16 18
      examples/webgl_loader_x.html
  61. 44 88
      examples/webgl_modifier_simplifier.html
  62. 71 13
      examples/webgl_postprocessing_dof2.html
  63. 0 1
      examples/webgl_shaders_tonemapping.html
  64. 2 2
      examples/webvr_cubes.html
  65. 1 1
      examples/webvr_daydream.html
  66. 1 1
      examples/webvr_gearvr.html
  67. 5 8
      examples/webvr_panorama.html
  68. 2 2
      examples/webvr_rollercoaster.html
  69. 2 2
      examples/webvr_sandbox.html
  70. 1 1
      examples/webvr_video.html
  71. 1 1
      examples/webvr_vive.html
  72. 1 1
      examples/webvr_vive_dragging.html
  73. 1 1
      examples/webvr_vive_paint.html
  74. 1 1
      examples/webvr_vive_sculpt.html
  75. 5250 0
      package-lock.json
  76. 13 13
      package.json
  77. 1 1
      src/constants.js
  78. 54 0
      src/geometries/ExtrudeGeometry.js
  79. 30 0
      src/loaders/ObjectLoader.js
  80. 10 0
      src/math/Matrix4.js
  81. 12 2
      src/renderers/WebGLRenderer.js
  82. 0 1
      src/renderers/shaders/ShaderLib/meshlambert_frag.glsl
  83. 0 1
      src/renderers/shaders/ShaderLib/meshlambert_vert.glsl
  84. 0 1
      src/renderers/shaders/ShaderLib/meshphong_frag.glsl
  85. 1 1
      src/renderers/webgl/WebGLAnimation.js
  86. 2 0
      src/renderers/webgl/WebGLUniforms.js
  87. 0 8
      src/renderers/webvr/WebVRManager.js
  88. 57 19
      src/renderers/webvr/WebXRManager.js
  89. 0 3
      utils/exporters/blender/.gitignore
  90. 1 66
      utils/exporters/blender/README.md
  91. 0 1059
      utils/exporters/blender/addons/io_three/__init__.py
  92. 0 398
      utils/exporters/blender/addons/io_three/constants.py
  93. 0 112
      utils/exporters/blender/addons/io_three/dialogs.py
  94. 0 9
      utils/exporters/blender/addons/io_three/exceptions.py
  95. 0 96
      utils/exporters/blender/addons/io_three/exporter/__init__.py
  96. 0 208
      utils/exporters/blender/addons/io_three/exporter/_json.py
  97. 0 77
      utils/exporters/blender/addons/io_three/exporter/api/__init__.py
  98. 0 683
      utils/exporters/blender/addons/io_three/exporter/api/animation.py
  99. 0 130
      utils/exporters/blender/addons/io_three/exporter/api/camera.py
  100. 0 29
      utils/exporters/blender/addons/io_three/exporter/api/constants.py

+ 1 - 1
.github/ISSUE_TEMPLATE.md

@@ -19,7 +19,7 @@ Please also include a live example if possible. You can start from these templat
 ##### Three.js version
 ##### Three.js version
 
 
 - [ ] Dev
 - [ ] Dev
-- [ ] r92
+- [ ] r93
 - [ ] ...
 - [ ] ...
 
 
 ##### Browser
 ##### Browser

File diff suppressed because it is too large
+ 11 - 1
build/three.js


File diff suppressed because it is too large
+ 382 - 381
build/three.min.js


File diff suppressed because it is too large
+ 11 - 1
build/three.module.js


+ 3 - 3
docs/api/core/Object3D.html

@@ -387,13 +387,13 @@
 		</p>
 		</p>
 
 
 		<h3>[method:this translateX]( [param:Float distance] )</h3>
 		<h3>[method:this translateX]( [param:Float distance] )</h3>
-		<p>Translates object along x axis by *distance* units.</p>
+		<p>Translates object along x axis in object space by *distance* units.</p>
 
 
 		<h3>[method:this translateY]( [param:Float distance] )</h3>
 		<h3>[method:this translateY]( [param:Float distance] )</h3>
-		<p>Translates object along y axis by *distance* units.</p>
+		<p>Translates object along y axis in object space by *distance* units.</p>
 
 
 		<h3>[method:this translateZ]( [param:Float distance] )</h3>
 		<h3>[method:this translateZ]( [param:Float distance] )</h3>
-		<p>Translates object along z axis by *distance* units.</p>
+		<p>Translates object along z axis in object space by *distance* units.</p>
 
 
 		<h3>[method:null traverse]( [param:Function callback] )</h3>
 		<h3>[method:null traverse]( [param:Function callback] )</h3>
 		<p>
 		<p>

+ 1 - 1
docs/api/loaders/JSONLoader.html

@@ -18,7 +18,7 @@
 		<h2>Example</h2>
 		<h2>Example</h2>
 
 
 		<p>
 		<p>
-		[example:webgl_loader_json_blender WebGL / loader / json / blender]<br />
+		[example:webgl_loader_json WebGL / loader / json]<br />
 		[example:webgl_loader_json_objconverter WebGL / loader / json / objconverter]
 		[example:webgl_loader_json_objconverter WebGL / loader / json / objconverter]
 		</p>
 		</p>
 
 

+ 1 - 1
docs/api/objects/Line.html

@@ -79,7 +79,7 @@
 		Computes an array of distance values which are necessary for [page:LineDashedMaterial]. For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line.
 		Computes an array of distance values which are necessary for [page:LineDashedMaterial]. For each vertex in the geometry, the method calculates the cumulative length from the current point to the very beginning of the line.
 		</p>
 		</p>
 
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		<p>
 		Get intersections between a casted [page:Ray] and this Line.
 		Get intersections between a casted [page:Ray] and this Line.
 		[page:Raycaster.intersectObject] will call this method.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Mesh.html

@@ -92,7 +92,7 @@
 		<h3>[method:Mesh clone]()</h3>
 		<h3>[method:Mesh clone]()</h3>
 		<p>Returns a clone of this [name] object and its descendants.</p>
 		<p>Returns a clone of this [name] object and its descendants.</p>
 
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		<p>
 		Get intersections between a casted ray and this mesh.
 		Get intersections between a casted ray and this mesh.
 		[page:Raycaster.intersectObject] will call this method.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Points.html

@@ -58,7 +58,7 @@
 		<h2>Methods</h2>
 		<h2>Methods</h2>
 		<p>See the base [page:Object3D] class for common methods.</p>
 		<p>See the base [page:Object3D] class for common methods.</p>
 
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		<p>
 		Get intersections between a casted ray and this Points.
 		Get intersections between a casted ray and this Points.
 		[page:Raycaster.intersectObject] will call this method.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 1
docs/api/objects/Sprite.html

@@ -76,7 +76,7 @@ scene.add( sprite );
 		Copies the properties of the passed sprite to this one.
 		Copies the properties of the passed sprite to this one.
 		</p>
 		</p>
 
 
-		<h3>[method:Array raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
+		<h3>[method:null raycast]( [param:Raycaster raycaster], [param:Array intersects] )</h3>
 		<p>
 		<p>
 		Get intersections between a casted ray and this sprite.
 		Get intersections between a casted ray and this sprite.
 		[page:Raycaster.intersectObject] will call this method.
 		[page:Raycaster.intersectObject] will call this method.

+ 1 - 0
docs/api/textures/DataTexture.html

@@ -57,6 +57,7 @@
 		// used the buffer to create a [name]
 		// used the buffer to create a [name]
 
 
 		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
 		var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
+		texture.needsUpdate = true
 		</code>
 		</code>
 
 
 		<h2>Properties</h2>
 		<h2>Properties</h2>

+ 1 - 1
docs/examples/exporters/GLTFExporter.html

@@ -25,7 +25,7 @@
 
 
 		<code>
 		<code>
 		// Instantiate a exporter
 		// Instantiate a exporter
-		var exporter = new THREE.GLTFExporter( defaultOptions );
+		var exporter = new THREE.GLTFExporter();
 
 
 		// Parse the input and generate the glTF output
 		// Parse the input and generate the glTF output
 		exporter.parse( scene, function ( gltf ) {
 		exporter.parse( scene, function ( gltf ) {

+ 62 - 0
docs/examples/exporters/PLYExporter.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<p class="desc">
+		An exporter for *PLY*.
+		<br /><br />
+		<a href="https://www.khronos.org/gltf">PLY</a> (Polygon or Stanford Triangle Format) is a
+		file format for efficient delivery and loading of simple, static 3D content in a dense format.
+		Both binary and ascii formats are supported. PLY can store vertex positions, colors, normals and
+		uv coordinates. No textures or texture references are saved.
+		</p>
+
+		<h2>Example</h2>
+
+		<code>
+		// Instantiate an exporter
+		var exporter = new THREE.PLYExporter();
+
+		// Parse the input and generate the ply output
+		var data = exporter.parse( scene, options );
+		downloadFile(data);
+		</code>
+
+		<h2>Constructor</h2>
+
+		<h3>[name]()</h3>
+		<p>
+		</p>
+		<p>
+		Creates a new [name].
+		</p>
+
+		<h2>Methods</h2>
+
+		<h3>[method:null parse]( [param:Object3D input], [param:Object options] )</h3>
+		<p>
+		[page:Object input] — Object3D<br />
+		[page:Options options] — Export options<br />
+		<ul>
+			<li>excludeAttributes - array. Which properties to explicitly exclude from the exported PLY file. Valid values are 'color', 'normal', 'uv', and 'index'. If triangle indices are excluded, then a point cloud is exported. Default is an empty array.</li>
+			<li>binary - bool. Export in binary format, returning an ArrayBuffer. Default is false.</li>
+		</ul>
+		</p>
+		<p>
+		Generates ply file data as string or ArrayBuffer (ascii or binary) output from the input object.
+		If the object is composed of multiple children and geometry, they are merged into a single mesh in the file.
+		</p>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/examples/js/exporters/PLYExporter.js examples/js/exporters/PLYExporter.js]
+	</body>
+</html>

+ 1 - 0
docs/examples/renderers/CSS2DRenderer.html

@@ -33,6 +33,7 @@
 		<h2>Examples</h2>
 		<h2>Examples</h2>
 
 
 		<p>
 		<p>
+			[example:css2d_label]<br>
 			[example:webgl_loader_pdb molecules]
 			[example:webgl_loader_pdb molecules]
 		</p>
 		</p>
 
 

+ 3 - 1
docs/list.js

@@ -10,6 +10,7 @@ var list = {
 			"How to run things locally": "manual/introduction/How-to-run-things-locally",
 			"How to run things locally": "manual/introduction/How-to-run-things-locally",
 			"Drawing Lines": "manual/introduction/Drawing-lines",
 			"Drawing Lines": "manual/introduction/Drawing-lines",
 			"Creating Text": "manual/introduction/Creating-text",
 			"Creating Text": "manual/introduction/Creating-text",
+			"Loading 3D Models": "manual/introduction/Loading-3D-models",
 			"Migration Guide": "manual/introduction/Migration-guide",
 			"Migration Guide": "manual/introduction/Migration-guide",
 			"Code Style Guide": "manual/introduction/Code-style-guide",
 			"Code Style Guide": "manual/introduction/Code-style-guide",
 			"FAQ": "manual/introduction/FAQ",
 			"FAQ": "manual/introduction/FAQ",
@@ -373,7 +374,8 @@ var list = {
 		},
 		},
 
 
 		"Exporters": {
 		"Exporters": {
-			"GLTFExporter": "examples/exporters/GLTFExporter"
+			"GLTFExporter": "examples/exporters/GLTFExporter",
+			"PLYExporter": "examples/exporters/PLYExporter"
 		},
 		},
 
 
 		"Plugins": {
 		"Plugins": {

+ 5 - 5
docs/manual/introduction/Animation-system.html

@@ -35,11 +35,11 @@
 		<p class="desc">
 		<p class="desc">
 
 
 			If you have successfully imported an animated 3D object (it doesn't matter if it has
 			If you have successfully imported an animated 3D object (it doesn't matter if it has
-			bones or morph targets or both) - for example exporting it from Blender with the
-			[link:https://github.com/mrdoob/three.js/tree/master/utils/exporters/blender/addons/io_three Blender exporter] and
-			loading it into a three.js scene using [page:JSONLoader] -, one of the geometry's
-			properties of the loaded mesh should be an array named "animations", containing the
-			[page:AnimationClip AnimationClips] for this model (see a list of possible loaders below).<br /><br />
+			bones or morph targets or both)  for example exporting it from Blender with the
+			[link:https://github.com/KhronosGroup/glTF-Blender-Exporter glTF Blender exporter] and
+			loading it into a three.js scene using [page:GLTFLoader] — one of the response fields
+			should be an array named "animations", containing the [page:AnimationClip AnimationClips]
+			for this model (see a list of possible loaders below).<br /><br />
 
 
 			Each *AnimationClip* usually holds the data for a certain activity of the object. If the
 			Each *AnimationClip* usually holds the data for a certain activity of the object. If the
 			mesh is a character, for example, there may be one AnimationClip for a walkcycle, a second
 			mesh is a character, for example, there may be one AnimationClip for a walkcycle, a second

+ 1 - 1
docs/manual/introduction/Creating-a-scene.html

@@ -14,7 +14,7 @@
 
 
 		<h2>Before we start</h2>
 		<h2>Before we start</h2>
 
 
-		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of <a href="http://threejs.org/build/three.js">three.js</a> in the js/ directory, and open it in your browser.</p>
+		<p>Before you can use three.js, you need somewhere to display it. Save the following HTML to a file on your computer, along with a copy of [link:https://threejs.org/build/three.js three.js] in the js/ directory, and open it in your browser.</p>
 
 
 		<code>
 		<code>
 		&lt;!DOCTYPE html&gt;
 		&lt;!DOCTYPE html&gt;

+ 3 - 3
docs/manual/introduction/FAQ.html

@@ -16,7 +16,7 @@
 				The recommended format for importing and exporting assets is glTF (GL Transmission Format). Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.
 				The recommended format for importing and exporting assets is glTF (GL Transmission Format). Because glTF is focused on runtime asset delivery, it is compact to transmit and fast to load.
 			</p>
 			</p>
 			<p>
 			<p>
-				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first.
+				three.js provides loaders for many other popular formats like FBX, Collada or OBJ as well. Nevertheless, you should always try to establish a glTF based workflow in your projects first. For more information, see [link:#manual/introduction/Loading-3D-models loading 3D models].
 			</p>
 			</p>
 		</div>
 		</div>
 
 
@@ -26,9 +26,9 @@
 
 
 				<p>These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).</p>
 				<p>These tags control viewport size and scale for mobile browsers (where page content may be rendered at different size than visible viewport).</p>
 
 
-				<p><a href="https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html">Safari: Using the Viewport</a></p>
+				<p>[link:https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html Safari: Using the Viewport]</p>
 
 
-				<p><a href="https://developer.mozilla.org/en/Mobile/Viewport_meta_tag">MDN: Using the viewport meta tag</a></p>
+				<p>[link:https://developer.mozilla.org/en/Mobile/Viewport_meta_tag MDN: Using the viewport meta tag]</p>
 		</div>
 		</div>
 
 
 		<h2>How can scene scale be preserved on resize?</h2>
 		<h2>How can scene scale be preserved on resize?</h2>

+ 3 - 3
docs/manual/introduction/Import-via-modules.html

@@ -23,11 +23,11 @@
 
 
 		<h2>Installation via npm</h2>
 		<h2>Installation via npm</h2>
 
 
-		<p>Three.js is published as an npm module, see: <a href="https://www.npmjs.com/package/three" target="_blank">npm</a>. This means all you need to do to include three.js into your project is run "npm install three"</p>
+		<p>Three.js is published as an npm module, see: [link:https://www.npmjs.com/package/three npm]. This means all you need to do to include three.js into your project is run "npm install three"</p>
 
 
 		<h2>Importing the module</h2>
 		<h2>Importing the module</h2>
 
 
-		<p>Assuming that you're bundling your files with a tool such as <a href="https://webpack.github.io/" target="_blank">Webpack</a> or <a href="https://github.com/substack/node-browserify" target="_blank">Browserify</a>, which allow you to "require('modules') in the browser by bundling up all of your dependencies."</p>
+		<p>Assuming that you're bundling your files with a tool such as [link:https://webpack.github.io/ Webpack] or [link:https://github.com/substack/node-browserify Browserify], which allow you to "require('modules') in the browser by bundling up all of your dependencies."</p>
 
 
 		<p>
 		<p>
 			You should now be able to import the module into your source files and continue to use it as per normal.
 			You should now be able to import the module into your source files and continue to use it as per normal.
@@ -41,7 +41,7 @@
 		</code>
 		</code>
 
 
 		<p>
 		<p>
-			You're also able to leverage <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import" target="_blank">ES6 import syntax</a>:
+			You're also able to leverage [link:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import ES6 import syntax]:
 		</p>
 		</p>
 
 
 		<code>
 		<code>

+ 129 - 0
docs/manual/introduction/Loading-3D-models.html

@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="utf-8">
+  <base href="../../" />
+  <script src="list.js"></script>
+  <script src="page.js"></script>
+  <link type="text/css" rel="stylesheet" href="page.css" />
+</head>
+
+<body>
+  <h1>[name]</h1>
+  <br />
+
+  <p>
+    3D models are available in hundreds of file formats, each with different
+    purposes, assorted features, and varying complexity. Although
+    <a href="https://github.com/mrdoob/three.js/tree/dev/examples/js/loaders">
+    three.js provides many loaders</a>, choosing the right format and
+    workflow will save time and frustration later on. Some formats are
+    difficult to work with, inefficient for realtime experiences, or simply not
+    fully supported at this time.
+  </p>
+
+  <p>
+    This guide provides a workflow recommended for most users, and suggestions
+    for what to try if things don't go as expected.
+  </p>
+
+  <h2>Before we start</h2>
+
+  <p>
+    If you're new to running a local server, begin with
+    [link:#manual/introduction/How-to-run-things-locally how to run things locally]
+    first. Many common errors viewing 3D models can be avoided by hosting files
+    correctly.
+  </p>
+
+  <h2>Recommended workflow</h2>
+
+  <p>
+    Where possible, we recommend using glTF (GL Transmission Format). Both
+    <small>.GLB</small> and <small>.GLTF</small> versions of the format are
+    well supported. Because glTF is focused on runtime asset delivery, it is
+    compact to transmit and fast to load. Features include meshes, materials,
+    textures, skins, skeletons, morph targets, animations, lights, and
+    cameras.
+  </p>
+
+  <p>
+    Public-domain glTF files are available on sites like
+    <a href="https://sketchfab.com/models?features=downloadable&sort_by=-likeCount&type=models">
+    Sketchfab</a>, or various tools include glTF export:
+  </p>
+
+  <ul>
+    <li><a href="https://github.com/KhronosGroup/glTF-Blender-Exporter">glTF-Blender-Exporter</a> by the Khronos Group</li>
+    <li><a href="https://github.com/KhronosGroup/COLLADA2GLTF">COLLADA2GLTF</a> by the Khronos Group</li>
+    <li><a href="https://github.com/facebookincubator/FBX2glTF">FBX2GLTF</a> by Facebook</li>
+    <li><a href="https://github.com/AnalyticalGraphicsInc/obj2gltf">OBJ2GLTF</a> by Analytical Graphics Inc</li>
+    <li><a href="https://www.allegorithmic.com/products/substance-painter">Substance Painter</a> by Allegorithmic</li>
+    <li><a href="https://www.foundry.com/products/modo">Modo</a> by Foundry</li>
+    <li><a href="https://www.marmoset.co/toolbag/">Toolbag</a> by Marmoset</li>
+    <li>&hellip;and <a href="https://github.com/khronosgroup/gltf#gltf-tools">many more</a></li>
+  </ul>
+
+  <p>
+    If your preferred tools do not support glTF, consider requesting glTF
+    export from the authors, or posting on
+    <a href="https://github.com/KhronosGroup/glTF/issues/1051">the glTF roadmap thread</a>.
+  </p>
+
+  <p>
+    When glTF is not an option, popular formats such as FBX, OBJ, or COLLADA
+    are also available and regularly maintained.
+  </p>
+
+  <h2>Troubleshooting</h2>
+
+  <p>
+    You've spent hours modeling an artisanal masterpiece, you load it into
+    the webpage, and — oh no! 😭 It's distorted, miscolored, or missing entirely.
+    Start with these troubleshooting steps:
+  </p>
+
+  <ol>
+    <li>
+      Check the JavaScript console for errors, and make sure you've used an
+      <em>onError</em> callback when calling <em>.load()</em> to log the result.
+    </li>
+    <li>
+      View the model in another application. For glTF, drag-and-drop viewers
+      are available for
+      <a href="https://gltf-viewer.donmccurdy.com/">three.js</a> and
+      <a href="http://sandbox.babylonjs.com/">babylon.js</a>. If the model
+      appears correctly in one or more applications,
+      <a href="https://github.com/mrdoob/three.js/issues/new">file a bug against three.js</a>.
+      If the model cannot be shown in any application, we strongly encourage
+      filing a bug with the application used to create the model.
+    </li>
+    <li>
+      Try scaling the model up or down by a factor of 1000. Many models are
+      scaled differently, and large models may not appear if the camera is
+      inside the model.
+    </li>
+    <li>
+      Look for failed texture requests in the network tab, like
+      <em>C:\\Path\To\Model\texture.jpg</em>. Use paths relative to your
+      model instead, such as <em>images/texture.jpg</em> — this may require
+      editing the model file in a text editor.
+    </li>
+  </ol>
+
+  <h2>Asking for help</h2>
+
+  <p>
+    If you've gone through the troubleshooting process above and your model
+    still isn't working, the right approach to asking for help will get you to
+    a solution faster. Post a question on the
+    <a href="https://discourse.threejs.org/">three.js forum</a> and, whenever possible,
+    include your model (or a simpler model with the same problem) in any formats
+    you have available. Include enough information for someone else to reproduce
+    the issue quickly — ideally, a live demo.
+  </p>
+
+</body>
+
+</html>

+ 7 - 0
docs/manual/introduction/Useful-links.html

@@ -126,6 +126,13 @@
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 			[link:http://idflood.github.io/ThreeNodes.js/ ThreeNodes.js].
 		</li>
 		</li>
 	 </ul>
 	 </ul>
+		
+	<h2>WebGL References</h2>
+	 <ul>
+		 <li>
+			[link:https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf] - Reference of all WebGL and GLSL keywords, terminology, syntex and definations.
+		 </li>
+	 </ul>
 
 
 	 <h2>Old Links</h2>
 	 <h2>Old Links</h2>
 	 <p>
 	 <p>

+ 11 - 27
docs/scenes/geometry-browser.html

@@ -72,36 +72,20 @@
 			scene.add( lights[ 1 ] );
 			scene.add( lights[ 1 ] );
 			scene.add( lights[ 2 ] );
 			scene.add( lights[ 2 ] );
 
 
-			var mesh = new THREE.Object3D();
+			var group = new THREE.Group();
 
 
-			mesh.add( new THREE.LineSegments(
+			var geometry = new THREE.BufferGeometry();
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( [], 3 ) );
 
 
-				new THREE.Geometry(),
+			var lineMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, transparent: true, opacity: 0.5 } );
+			var meshMaterial = new THREE.MeshPhongMaterial( { color: 0x156289, emissive: 0x072534, side: THREE.DoubleSide, flatShading: true } );
 
 
-				new THREE.LineBasicMaterial( {
-					color: 0xffffff,
-					transparent: true,
-					opacity: 0.5
-				} )
+			group.add( new THREE.LineSegments( geometry, lineMaterial ) );
+			group.add( new THREE.Mesh( geometry, meshMaterial ) );
 
 
-			) );
+			var options = chooseFromHash( group );
 
 
-			mesh.add( new THREE.Mesh(
-
-				new THREE.Geometry(),
-
-				new THREE.MeshPhongMaterial( {
-					color: 0x156289,
-					emissive: 0x072534,
-					side: THREE.DoubleSide,
-					flatShading: true
-				} )
-
-			) );
-
-			var options = chooseFromHash( mesh );
-
-			scene.add( mesh );
+			scene.add( group );
 
 
 			var prevFog = false;
 			var prevFog = false;
 
 
@@ -111,8 +95,8 @@
 
 
 				if ( ! options.fixed ) {
 				if ( ! options.fixed ) {
 
 
-					mesh.rotation.x += 0.005;
-					mesh.rotation.y += 0.005;
+					group.rotation.x += 0.005;
+					group.rotation.y += 0.005;
 
 
 				}
 				}
 
 

+ 150 - 0
examples/css2d_label.html

@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<title>three.js css2d - label</title>
+		<style>
+			body {
+				background-color: #000;
+				margin: 0;
+				overflow: hidden;
+			}
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				color: #FFF;
+				padding: 5px;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
+				z-index: 1;
+			}
+
+			.label{
+				color: #FFF;
+				font-family: sans-serif;
+				padding: 2px;
+				background: rgba( 0, 0, 0, .6 );
+			}
+
+			a {
+				color: #000000;
+			}
+
+		</style>
+	</head>
+	<body>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - three.js css2d - label</div>
+
+		<script src="../build/three.js"></script>
+
+		<script src="js/controls/OrbitControls.js"></script>
+
+		<script src="js/renderers/CSS2DRenderer.js"></script>
+
+		<script>
+
+			var camera, scene, renderer, labelRenderer;
+			var controls;
+			var clock = new THREE.Clock();
+			var textureLoader = new THREE.TextureLoader();
+
+			var earth, moon;
+
+			init();
+			animate();
+
+			function init() {
+
+				var EARTH_RADIUS = 1;
+				var MOON_RADIUS = 0.27;
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 10, 5, 20 );
+
+				controls = new THREE.OrbitControls( camera );
+
+				scene = new THREE.Scene();
+
+				scene2 = new THREE.Scene();
+
+				dirLight = new THREE.DirectionalLight( 0xffffff );
+				dirLight.position.set( 0, 0, 1 );
+				scene.add( dirLight );
+
+				var axesHelper = new THREE.AxesHelper( 5 );
+				scene.add( axesHelper );
+
+				//
+
+				var earthGeometry = new THREE.SphereBufferGeometry( EARTH_RADIUS, 16, 16 );
+				var earthMaterial = new THREE.MeshPhongMaterial( {
+					specular: 0x333333,
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/earth_atmos_2048.jpg' ),
+					specularMap: textureLoader.load( 'textures/planets/earth_specular_2048.jpg' ),
+					normalMap: textureLoader.load( 'textures/planets/earth_normal_2048.jpg' ),
+					normalScale: new THREE.Vector2( 0.85, 0.85 )
+				} );
+				earth = new THREE.Mesh( earthGeometry, earthMaterial );
+				scene.add( earth );
+
+				var moonGeometry = new THREE.SphereBufferGeometry( MOON_RADIUS, 16, 16 );
+				var moonMaterial = new THREE.MeshPhongMaterial( {
+					shininess: 5,
+					map: textureLoader.load( 'textures/planets/moon_1024.jpg' )
+				} );
+				moon = new THREE.Mesh( moonGeometry, moonMaterial );
+				scene.add( moon );
+
+				//
+
+				var earthDiv = document.createElement( 'div' );
+				earthDiv.className = 'label';
+				earthDiv.textContent = 'Earth';
+				earthDiv.style.marginTop = '-1em';
+				var earthLabel = new THREE.CSS2DObject( earthDiv );
+				earthLabel.position.set( 0, EARTH_RADIUS, 0 );
+				earth.add( earthLabel );
+
+				var moonDiv = document.createElement( 'div' );
+				moonDiv.className = 'label';
+				moonDiv.textContent = 'Moon';
+				moonDiv.style.marginTop = '-1em';
+				var moonLabel = new THREE.CSS2DObject( moonDiv );
+				moonLabel.position.set( 0, MOON_RADIUS, 0 );
+				moon.add( moonLabel );
+
+				//
+
+				renderer = new THREE.WebGLRenderer();
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
+
+				labelRenderer = new THREE.CSS2DRenderer();
+				labelRenderer.setSize( window.innerWidth, window.innerHeight );
+				labelRenderer.domElement.style.position = 'absolute';
+				labelRenderer.domElement.style.top = 0;
+				document.body.appendChild( labelRenderer.domElement );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+
+				var elapsed = clock.getElapsedTime();
+
+				moon.position.set( Math.sin( elapsed ) * 5, 0, Math.cos( elapsed ) * 5 );
+
+				renderer.render( scene, camera );
+				labelRenderer.render( scene, camera );
+
+			}
+
+		</script>
+	</body>
+</html>

+ 6 - 2
examples/files.js

@@ -22,7 +22,7 @@ var files = {
 		"webgl_geometries",
 		"webgl_geometries",
 		"webgl_geometries_parametric",
 		"webgl_geometries_parametric",
 		"webgl_geometry_colors",
 		"webgl_geometry_colors",
-		"webgl_geometry_colors_blender",
+		"webgl_geometry_colors_json",
 		"webgl_geometry_colors_lookuptable",
 		"webgl_geometry_colors_lookuptable",
 		"webgl_geometry_convex",
 		"webgl_geometry_convex",
 		"webgl_geometry_cube",
 		"webgl_geometry_cube",
@@ -93,7 +93,7 @@ var files = {
 		"webgl_loader_gltf",
 		"webgl_loader_gltf",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_gltf_extensions",
 		"webgl_loader_imagebitmap",
 		"webgl_loader_imagebitmap",
-		"webgl_loader_json_blender",
+		"webgl_loader_json",
 		"webgl_loader_json_claraio",
 		"webgl_loader_json_claraio",
 		"webgl_loader_json_objconverter",
 		"webgl_loader_json_objconverter",
 		"webgl_loader_kmz",
 		"webgl_loader_kmz",
@@ -342,6 +342,7 @@ var files = {
 		"misc_controls_transform",
 		"misc_controls_transform",
 		"misc_exporter_gltf",
 		"misc_exporter_gltf",
 		"misc_exporter_obj",
 		"misc_exporter_obj",
+		"misc_exporter_stl",
 		"misc_fps",
 		"misc_fps",
 		"misc_lights_test",
 		"misc_lights_test",
 		"misc_lookat",
 		"misc_lookat",
@@ -359,6 +360,9 @@ var files = {
 		"css3d_sprites",
 		"css3d_sprites",
 		"css3d_youtube"
 		"css3d_youtube"
 	],
 	],
+	"css2d": [
+		"css2d_label"
+	],
 	"canvas": [
 	"canvas": [
 		"canvas_ascii_effect",
 		"canvas_ascii_effect",
 		"canvas_camera_orthographic",
 		"canvas_camera_orthographic",

+ 9 - 8
examples/js/MorphBlendMesh.js

@@ -12,9 +12,9 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	// prepare default animation
 	// prepare default animation
 	// (all frames played together in 1 second)
 	// (all frames played together in 1 second)
 
 
-	var numFrames = this.geometry.morphTargets.length;
+	var numFrames = Object.keys( this.morphTargetDictionary ).length;
 
 
-	var name = "__default";
+	var name = '__default';
 
 
 	var startFrame = 0;
 	var startFrame = 0;
 	var endFrame = numFrames - 1;
 	var endFrame = numFrames - 1;
@@ -24,7 +24,7 @@ THREE.MorphBlendMesh = function ( geometry, material ) {
 	this.createAnimation( name, startFrame, endFrame, fps );
 	this.createAnimation( name, startFrame, endFrame, fps );
 	this.setAnimationWeight( name, 1 );
 	this.setAnimationWeight( name, 1 );
 
 
-}
+};
 
 
 THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
 THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.prototype ), {
 
 
@@ -61,18 +61,17 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 
 	},
 	},
 
 
-		autoCreateAnimations: function ( fps ) {
+	autoCreateAnimations: function ( fps ) {
 
 
 		var pattern = /([a-z]+)_?(\d+)/i;
 		var pattern = /([a-z]+)_?(\d+)/i;
 
 
 		var firstAnimation, frameRanges = {};
 		var firstAnimation, frameRanges = {};
 
 
-		var geometry = this.geometry;
+		var i = 0;
 
 
-		for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
+		for ( var key in this.morphTargetDictionary ) {
 
 
-			var morph = geometry.morphTargets[ i ];
-			var chunks = morph.name.match( pattern );
+			var chunks = key.match( pattern );
 
 
 			if ( chunks && chunks.length > 1 ) {
 			if ( chunks && chunks.length > 1 ) {
 
 
@@ -89,6 +88,8 @@ THREE.MorphBlendMesh.prototype = Object.assign( Object.create( THREE.Mesh.protot
 
 
 			}
 			}
 
 
+			i ++;
+
 		}
 		}
 
 
 		for ( var name in frameRanges ) {
 		for ( var name in frameRanges ) {

+ 1 - 1
examples/js/animation/CCDIKSolver.js

@@ -203,7 +203,7 @@ THREE.CCDIKSolver = ( function () {
 		 */
 		 */
 		createHelper: function () {
 		createHelper: function () {
 
 
-			return new CCDIKHelper( this.mesh, this.mesh.geometry.iks );
+			return new CCDIKHelper( this.mesh, this.mesh.geometry.userData.MMD.iks );
 
 
 		},
 		},
 
 

+ 8 - 5
examples/js/animation/MMDAnimationHelper.js

@@ -275,7 +275,7 @@ THREE.MMDAnimationHelper = ( function () {
 		 */
 		 */
 		createGrantSolver: function ( mesh ) {
 		createGrantSolver: function ( mesh ) {
 
 
-			return new GrantSolver( mesh, mesh.geometry.grants );
+			return new GrantSolver( mesh, mesh.geometry.userData.MMD.grants );
 
 
 		},
 		},
 
 
@@ -581,8 +581,8 @@ THREE.MMDAnimationHelper = ( function () {
 
 
 		_optimizeIK: function ( mesh, physicsEnabled ) {
 		_optimizeIK: function ( mesh, physicsEnabled ) {
 
 
-			var iks = mesh.geometry.iks;
-			var bones = mesh.geometry.bones;
+			var iks = mesh.geometry.userData.MMD.iks;
+			var bones = mesh.geometry.userData.MMD.bones;
 
 
 			for ( var i = 0, il = iks.length; i < il; i ++ ) {
 			for ( var i = 0, il = iks.length; i < il; i ++ ) {
 
 
@@ -619,7 +619,7 @@ THREE.MMDAnimationHelper = ( function () {
 
 
 			}
 			}
 
 
-			return new THREE.CCDIKSolver( mesh, mesh.geometry.iks );
+			return new THREE.CCDIKSolver( mesh, mesh.geometry.userData.MMD.iks );
 
 
 		},
 		},
 
 
@@ -632,7 +632,10 @@ THREE.MMDAnimationHelper = ( function () {
 			}
 			}
 
 
 			return new THREE.MMDPhysics(
 			return new THREE.MMDPhysics(
-				mesh, mesh.geometry.rigidBodies, mesh.geometry.constraints, params );
+				mesh,
+				mesh.geometry.userData.MMD.rigidBodies,
+				mesh.geometry.userData.MMD.constraints,
+				params );
 
 
 		},
 		},
 
 

+ 14 - 6
examples/js/cameras/CinematicCamera.js

@@ -5,20 +5,28 @@
  * @author kaypiKun
  * @author kaypiKun
  */
  */
 
 
-THREE.CinematicCamera = function( fov, aspect, near, far ) {
+THREE.CinematicCamera = function ( fov, aspect, near, far ) {
 
 
 	THREE.PerspectiveCamera.call( this, fov, aspect, near, far );
 	THREE.PerspectiveCamera.call( this, fov, aspect, near, far );
 
 
-	this.type = "CinematicCamera";
+	this.type = 'CinematicCamera';
 
 
-	this.postprocessing = { enabled	: true };
+	this.postprocessing = { enabled: true };
 	this.shaderSettings = {
 	this.shaderSettings = {
 		rings: 3,
 		rings: 3,
 		samples: 4
 		samples: 4
 	};
 	};
 
 
-	this.material_depth = new THREE.MeshDepthMaterial();
-	this.material_depth.depthPacking = THREE.RGBADepthPacking;
+	var depthShader = THREE.BokehDepthShader;
+
+	this.materialDepth = new THREE.ShaderMaterial( {
+		uniforms: depthShader.uniforms,
+		vertexShader: depthShader.vertexShader,
+		fragmentShader: depthShader.fragmentShader
+	} );
+
+	this.materialDepth.uniforms[ 'mNear' ].value = near;
+	this.materialDepth.uniforms[ 'mFar' ].value = far;
 
 
 	// In case of cinematicCamera, having a default lens set is important
 	// In case of cinematicCamera, having a default lens set is important
 	this.setLens();
 	this.setLens();
@@ -178,7 +186,7 @@ THREE.CinematicCamera.prototype.renderCinematic = function ( scene, renderer ) {
 
 
 		// Render depth into texture
 		// Render depth into texture
 
 
-		scene.overrideMaterial = this.material_depth;
+		scene.overrideMaterial = this.materialDepth;
 		renderer.render( scene, camera, this.postprocessing.rtTextureDepth, true );
 		renderer.render( scene, camera, this.postprocessing.rtTextureDepth, true );
 
 
 		// Render bokeh composite
 		// Render bokeh composite

+ 0 - 149
examples/js/controls/VRControls.js

@@ -1,149 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- */
-
-THREE.VRControls = function ( object, onError ) {
-
-	var scope = this;
-
-	var vrDisplay, vrDisplays;
-
-	var standingMatrix = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'VR input not available.' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VRControls: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	// the Rift SDK returns the position in meters
-	// this scale factor allows the user to define how meters
-	// are converted to scene units.
-
-	this.scale = 1;
-
-	// If true will use "standing space" coordinate system where y=0 is the
-	// floor and x=0, z=0 is the center of the room.
-	this.standing = false;
-
-	// Distance from the users eyes to the floor in meters. Used when
-	// standing=true but the VRDisplay doesn't provide stageParameters.
-	this.userHeight = 1.6;
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VRControls: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.getStandingMatrix = function () {
-
-		return standingMatrix;
-
-	};
-
-	this.update = function () {
-
-		if ( vrDisplay ) {
-
-			var pose;
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.getFrameData( frameData );
-				pose = frameData.pose;
-
-			} else if ( vrDisplay.getPose ) {
-
-				pose = vrDisplay.getPose();
-
-			}
-
-			if ( pose.orientation !== null ) {
-
-				object.quaternion.fromArray( pose.orientation );
-
-			}
-
-			if ( pose.position !== null ) {
-
-				object.position.fromArray( pose.position );
-
-			} else {
-
-				object.position.set( 0, 0, 0 );
-
-			}
-
-			if ( this.standing ) {
-
-				if ( vrDisplay.stageParameters ) {
-
-					object.updateMatrix();
-
-					standingMatrix.fromArray( vrDisplay.stageParameters.sittingToStandingTransform );
-					object.applyMatrix( standingMatrix );
-
-				} else {
-
-					object.position.setY( object.position.y + this.userHeight );
-
-				}
-
-			}
-
-			object.position.multiplyScalar( scope.scale );
-
-		}
-
-	};
-
-	this.dispose = function () {
-
-		vrDisplay = null;
-
-	};
-
-};

+ 1 - 1
examples/js/effects/OutlineEffect.js

@@ -448,7 +448,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) {
 	 * The following property copies and wrapper methods enable
 	 * The following property copies and wrapper methods enable
 	 * THREE.OutlineEffect to be called from other *Effect, like
 	 * THREE.OutlineEffect to be called from other *Effect, like
 	 *
 	 *
-	 * effect = new THREE.VREffect( new THREE.OutlineEffect( renderer ) );
+	 * effect = new THREE.StereoEffect( new THREE.OutlineEffect( renderer ) );
 	 *
 	 *
 	 * function render () {
 	 * function render () {
 	 *
 	 *

+ 0 - 533
examples/js/effects/VREffect.js

@@ -1,533 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- * @author mrdoob / http://mrdoob.com
- *
- * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
- *
- * Firefox: http://mozvr.com/downloads/
- * Chromium: https://webvr.info/get-chrome
- */
-
-THREE.VREffect = function ( renderer, onError ) {
-
-	var vrDisplay, vrDisplays;
-	var eyeTranslationL = new THREE.Vector3();
-	var eyeTranslationR = new THREE.Vector3();
-	var renderRectL, renderRectR;
-	var headMatrix = new THREE.Matrix4();
-	var eyeMatrixL = new THREE.Matrix4();
-	var eyeMatrixR = new THREE.Matrix4();
-
-	var frameData = null;
-
-	if ( 'VRFrameData' in window ) {
-
-		frameData = new window.VRFrameData();
-
-	}
-
-	function gotVRDisplays( displays ) {
-
-		vrDisplays = displays;
-
-		if ( displays.length > 0 ) {
-
-			vrDisplay = displays[ 0 ];
-
-		} else {
-
-			if ( onError ) onError( 'HMD not available' );
-
-		}
-
-	}
-
-	if ( navigator.getVRDisplays ) {
-
-		navigator.getVRDisplays().then( gotVRDisplays ).catch( function () {
-
-			console.warn( 'THREE.VREffect: Unable to get VR Displays' );
-
-		} );
-
-	}
-
-	//
-
-	this.isPresenting = false;
-
-	var scope = this;
-
-	var rendererSize = renderer.getSize();
-	var rendererUpdateStyle = false;
-	var rendererPixelRatio = renderer.getPixelRatio();
-
-	this.getVRDisplay = function () {
-
-		return vrDisplay;
-
-	};
-
-	this.setVRDisplay = function ( value ) {
-
-		vrDisplay = value;
-
-	};
-
-	this.getVRDisplays = function () {
-
-		console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
-		return vrDisplays;
-
-	};
-
-	this.setSize = function ( width, height, updateStyle ) {
-
-		rendererSize = { width: width, height: height };
-		rendererUpdateStyle = updateStyle;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			renderer.setPixelRatio( 1 );
-			renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
-
-		} else {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( width, height, updateStyle );
-
-		}
-
-	};
-
-	// VR presentation
-
-	var canvas = renderer.domElement;
-	var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
-	var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
-
-	function onVRDisplayPresentChange() {
-
-		var wasPresenting = scope.isPresenting;
-		scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
-
-		if ( scope.isPresenting ) {
-
-			var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-			var eyeWidth = eyeParamsL.renderWidth;
-			var eyeHeight = eyeParamsL.renderHeight;
-
-			if ( ! wasPresenting ) {
-
-				rendererPixelRatio = renderer.getPixelRatio();
-				rendererSize = renderer.getSize();
-
-				renderer.setPixelRatio( 1 );
-				renderer.setSize( eyeWidth * 2, eyeHeight, false );
-
-			}
-
-		} else if ( wasPresenting ) {
-
-			renderer.setPixelRatio( rendererPixelRatio );
-			renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
-
-		}
-
-	}
-
-	window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	this.setFullScreen = function ( boolean ) {
-
-		return new Promise( function ( resolve, reject ) {
-
-			if ( vrDisplay === undefined ) {
-
-				reject( new Error( 'No VR hardware found.' ) );
-				return;
-
-			}
-
-			if ( scope.isPresenting === boolean ) {
-
-				resolve();
-				return;
-
-			}
-
-			if ( boolean ) {
-
-				resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
-
-			} else {
-
-				resolve( vrDisplay.exitPresent() );
-
-			}
-
-		} );
-
-	};
-
-	this.requestPresent = function () {
-
-		return this.setFullScreen( true );
-
-	};
-
-	this.exitPresent = function () {
-
-		return this.setFullScreen( false );
-
-	};
-
-	this.requestAnimationFrame = function ( f ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			return vrDisplay.requestAnimationFrame( f );
-
-		} else {
-
-			return window.requestAnimationFrame( f );
-
-		}
-
-	};
-
-	this.cancelAnimationFrame = function ( h ) {
-
-		if ( vrDisplay !== undefined ) {
-
-			vrDisplay.cancelAnimationFrame( h );
-
-		} else {
-
-			window.cancelAnimationFrame( h );
-
-		}
-
-	};
-
-	this.submitFrame = function () {
-
-		if ( vrDisplay !== undefined && scope.isPresenting ) {
-
-			vrDisplay.submitFrame();
-
-		}
-
-	};
-
-	this.autoSubmitFrame = true;
-
-	// render
-
-	var cameraL = new THREE.PerspectiveCamera();
-	cameraL.layers.enable( 1 );
-
-	var cameraR = new THREE.PerspectiveCamera();
-	cameraR.layers.enable( 2 );
-
-	this.render = function ( scene, camera, renderTarget, forceClear ) {
-
-		if ( vrDisplay && scope.isPresenting ) {
-
-			var autoUpdate = scene.autoUpdate;
-
-			if ( autoUpdate ) {
-
-				scene.updateMatrixWorld();
-				scene.autoUpdate = false;
-
-			}
-
-			if ( Array.isArray( scene ) ) {
-
-				console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
-				scene = scene[ 0 ];
-
-			}
-
-			// When rendering we don't care what the recommended size is, only what the actual size
-			// of the backbuffer is.
-			var size = renderer.getSize();
-			var layers = vrDisplay.getLayers();
-			var leftBounds;
-			var rightBounds;
-
-			if ( layers.length ) {
-
-				var layer = layers[ 0 ];
-
-				leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
-				rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
-
-			} else {
-
-				leftBounds = defaultLeftBounds;
-				rightBounds = defaultRightBounds;
-
-			}
-
-			renderRectL = {
-				x: Math.round( size.width * leftBounds[ 0 ] ),
-				y: Math.round( size.height * leftBounds[ 1 ] ),
-				width: Math.round( size.width * leftBounds[ 2 ] ),
-				height: Math.round( size.height * leftBounds[ 3 ] )
-			};
-			renderRectR = {
-				x: Math.round( size.width * rightBounds[ 0 ] ),
-				y: Math.round( size.height * rightBounds[ 1 ] ),
-				width: Math.round( size.width * rightBounds[ 2 ] ),
-				height: Math.round( size.height * rightBounds[ 3 ] )
-			};
-
-			if ( renderTarget ) {
-
-				renderer.setRenderTarget( renderTarget );
-				renderTarget.scissorTest = true;
-
-			} else {
-
-				renderer.setRenderTarget( null );
-				renderer.setScissorTest( true );
-
-			}
-
-			if ( renderer.autoClear || forceClear ) renderer.clear();
-
-			if ( camera.parent === null ) camera.updateMatrixWorld();
-
-			camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-			cameraR.position.copy( cameraL.position );
-			cameraR.quaternion.copy( cameraL.quaternion );
-			cameraR.scale.copy( cameraL.scale );
-
-			if ( vrDisplay.getFrameData ) {
-
-				vrDisplay.depthNear = camera.near;
-				vrDisplay.depthFar = camera.far;
-
-				vrDisplay.getFrameData( frameData );
-
-				cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
-				cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
-
-				getEyeMatrices( frameData );
-
-				cameraL.updateMatrix();
-				cameraL.matrix.multiply( eyeMatrixL );
-				cameraL.matrix.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
-
-				cameraR.updateMatrix();
-				cameraR.matrix.multiply( eyeMatrixR );
-				cameraR.matrix.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
-
-			} else {
-
-				var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
-				var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
-
-				cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
-				cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
-
-				eyeTranslationL.fromArray( eyeParamsL.offset );
-				eyeTranslationR.fromArray( eyeParamsR.offset );
-
-				cameraL.translateOnAxis( eyeTranslationL, cameraL.scale.x );
-				cameraR.translateOnAxis( eyeTranslationR, cameraR.scale.x );
-
-			}
-
-			// render left eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			} else {
-
-				renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-				renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
-
-			}
-			renderer.render( scene, cameraL, renderTarget, forceClear );
-
-			// render right eye
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			} else {
-
-				renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-				renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
-
-			}
-			renderer.render( scene, cameraR, renderTarget, forceClear );
-
-			if ( renderTarget ) {
-
-				renderTarget.viewport.set( 0, 0, size.width, size.height );
-				renderTarget.scissor.set( 0, 0, size.width, size.height );
-				renderTarget.scissorTest = false;
-				renderer.setRenderTarget( null );
-
-			} else {
-
-				renderer.setViewport( 0, 0, size.width, size.height );
-				renderer.setScissorTest( false );
-
-			}
-
-			if ( autoUpdate ) {
-
-				scene.autoUpdate = true;
-
-			}
-
-			if ( scope.autoSubmitFrame ) {
-
-				scope.submitFrame();
-
-			}
-
-			return;
-
-		}
-
-		// Regular render mode if not HMD
-
-		renderer.render( scene, camera, renderTarget, forceClear );
-
-	};
-
-	this.dispose = function () {
-
-		window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
-
-	};
-
-	//
-
-	var poseOrientation = new THREE.Quaternion();
-	var posePosition = new THREE.Vector3();
-
-	// Compute model matrices of the eyes with respect to the head.
-	function getEyeMatrices( frameData ) {
-
-		// Compute the matrix for the position of the head based on the pose
-		if ( frameData.pose.orientation ) {
-
-			poseOrientation.fromArray( frameData.pose.orientation );
-			headMatrix.makeRotationFromQuaternion( poseOrientation );
-
-		}	else {
-
-			headMatrix.identity();
-
-		}
-
-		if ( frameData.pose.position ) {
-
-			posePosition.fromArray( frameData.pose.position );
-			headMatrix.setPosition( posePosition );
-
-		}
-
-		// The view matrix transforms vertices from sitting space to eye space. As such, the view matrix can be thought of as a product of two matrices:
-		// headToEyeMatrix * sittingToHeadMatrix
-
-		// The headMatrix that we've calculated above is the model matrix of the head in sitting space, which is the inverse of sittingToHeadMatrix.
-		// So when we multiply the view matrix with headMatrix, we're left with headToEyeMatrix:
-		// viewMatrix * headMatrix = headToEyeMatrix * sittingToHeadMatrix * headMatrix = headToEyeMatrix
-
-		eyeMatrixL.fromArray( frameData.leftViewMatrix );
-		eyeMatrixL.multiply( headMatrix );
-		eyeMatrixR.fromArray( frameData.rightViewMatrix );
-		eyeMatrixR.multiply( headMatrix );
-
-		// The eye's model matrix in head space is the inverse of headToEyeMatrix we calculated above.
-
-		eyeMatrixL.getInverse( eyeMatrixL );
-		eyeMatrixR.getInverse( eyeMatrixR );
-
-	}
-
-	function fovToNDCScaleOffset( fov ) {
-
-		var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
-		var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5;
-		var pyscale = 2.0 / ( fov.upTan + fov.downTan );
-		var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5;
-		return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
-
-	}
-
-	function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
-
-		rightHanded = rightHanded === undefined ? true : rightHanded;
-		zNear = zNear === undefined ? 0.01 : zNear;
-		zFar = zFar === undefined ? 10000.0 : zFar;
-
-		var handednessScale = rightHanded ? - 1.0 : 1.0;
-
-		// start with an identity matrix
-		var mobj = new THREE.Matrix4();
-		var m = mobj.elements;
-
-		// and with scale/offset info for normalized device coords
-		var scaleAndOffset = fovToNDCScaleOffset( fov );
-
-		// X result, map clip edges to [-w,+w]
-		m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
-		m[ 0 * 4 + 1 ] = 0.0;
-		m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
-		m[ 0 * 4 + 3 ] = 0.0;
-
-		// Y result, map clip edges to [-w,+w]
-		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
-		// but the NDC scaling has Y=down (thanks D3D?)
-		m[ 1 * 4 + 0 ] = 0.0;
-		m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
-		m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
-		m[ 1 * 4 + 3 ] = 0.0;
-
-		// Z result (up to the app)
-		m[ 2 * 4 + 0 ] = 0.0;
-		m[ 2 * 4 + 1 ] = 0.0;
-		m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
-		m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
-
-		// W result (= Z in)
-		m[ 3 * 4 + 0 ] = 0.0;
-		m[ 3 * 4 + 1 ] = 0.0;
-		m[ 3 * 4 + 2 ] = handednessScale;
-		m[ 3 * 4 + 3 ] = 0.0;
-
-		mobj.transpose();
-		return mobj;
-
-	}
-
-	function fovToProjection( fov, rightHanded, zNear, zFar ) {
-
-		var DEG2RAD = Math.PI / 180.0;
-
-		var fovPort = {
-			upTan: Math.tan( fov.upDegrees * DEG2RAD ),
-			downTan: Math.tan( fov.downDegrees * DEG2RAD ),
-			leftTan: Math.tan( fov.leftDegrees * DEG2RAD ),
-			rightTan: Math.tan( fov.rightDegrees * DEG2RAD )
-		};
-
-		return fovPortToProjection( fovPort, rightHanded, zNear, zFar );
-
-	}
-
-};

+ 4 - 0
examples/js/exporters/GLTFExporter.js

@@ -1182,6 +1182,8 @@ THREE.GLTFExporter.prototype = {
 
 
 			}
 			}
 
 
+			var extras = ( Object.keys( geometry.userData ).length > 0 ) ? serializeUserData( geometry ) : undefined;
+
 			var forceIndices = options.forceIndices;
 			var forceIndices = options.forceIndices;
 			var isMultiMaterial = Array.isArray( mesh.material );
 			var isMultiMaterial = Array.isArray( mesh.material );
 
 
@@ -1223,6 +1225,8 @@ THREE.GLTFExporter.prototype = {
 					attributes: attributes,
 					attributes: attributes,
 				};
 				};
 
 
+				if ( extras ) primitive.extras = extras;
+
 				if ( targets.length > 0 ) primitive.targets = targets;
 				if ( targets.length > 0 ) primitive.targets = targets;
 
 
 				if ( geometry.index !== null ) {
 				if ( geometry.index !== null ) {

+ 1 - 1
examples/js/exporters/PLYExporter.js

@@ -6,7 +6,7 @@
  *  var exporter = new THREE.PLYExporter();
  *  var exporter = new THREE.PLYExporter();
  *
  *
  *  // second argument is a list of options
  *  // second argument is a list of options
- *  var data = exporter.parse(mesh, { binar: true, excludeAttributes: [ 'color' ] });
+ *  var data = exporter.parse( mesh, { binary: true, excludeAttributes: [ 'color' ] } );
  *
  *
  * Format Definition:
  * Format Definition:
  *  http://paulbourke.net/dataformats/ply/
  *  http://paulbourke.net/dataformats/ply/

+ 0 - 94
examples/js/exporters/STLBinaryExporter.js

@@ -1,94 +0,0 @@
-/**
- * @author kovacsv / http://kovacsv.hu/
- * @author mrdoob / http://mrdoob.com/
- * @author mudcube / http://mudcu.be/
- */
-
-THREE.STLBinaryExporter = function () {};
-
-THREE.STLBinaryExporter.prototype = {
-
-	constructor: THREE.STLBinaryExporter,
-
-	parse: ( function () {
-
-		var vector = new THREE.Vector3();
-		var normalMatrixWorld = new THREE.Matrix3();
-
-		return function parse( scene ) {
-
-			// We collect objects first, as we may need to convert from BufferGeometry to Geometry
-			var objects = [];
-			var triangles = 0;
-			scene.traverse( function ( object ) {
-
-				if ( ! ( object instanceof THREE.Mesh ) ) return;
-
-				var geometry = object.geometry;
-				if ( geometry instanceof THREE.BufferGeometry ) {
-
-					geometry = new THREE.Geometry().fromBufferGeometry( geometry );
-
-				}
-
-				if ( ! ( geometry instanceof THREE.Geometry ) ) return;
-				triangles += geometry.faces.length;
-
-				objects.push( {
-
-					geometry: geometry,
-					matrix: object.matrixWorld
-
-				} );
-
-			} );
-
-			var offset = 80; // skip header
-			var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
-			var arrayBuffer = new ArrayBuffer( bufferLength );
-			var output = new DataView( arrayBuffer );
-			output.setUint32( offset, triangles, true ); offset += 4;
-
-			// Traversing our collected objects
-			objects.forEach( function ( object ) {
-
-				var vertices = object.geometry.vertices;
-				var faces = object.geometry.faces;
-
-				normalMatrixWorld.getNormalMatrix( object.matrix );
-
-				for ( var i = 0, l = faces.length; i < l; i ++ ) {
-
-					var face = faces[ i ];
-
-					vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
-
-					output.setFloat32( offset, vector.x, true ); offset += 4; // normal
-					output.setFloat32( offset, vector.y, true ); offset += 4;
-					output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					var indices = [ face.a, face.b, face.c ];
-
-					for ( var j = 0; j < 3; j ++ ) {
-
-						vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( object.matrix );
-
-						output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
-						output.setFloat32( offset, vector.y, true ); offset += 4;
-						output.setFloat32( offset, vector.z, true ); offset += 4;
-
-					}
-
-					output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
-
-				}
-
-			} );
-
-			return output;
-
-		};
-
-	}() )
-
-};

+ 110 - 25
examples/js/exporters/STLExporter.js

@@ -1,6 +1,15 @@
 /**
 /**
  * @author kovacsv / http://kovacsv.hu/
  * @author kovacsv / http://kovacsv.hu/
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
+ * @author mudcube / http://mudcu.be/
+ * @author Mugen87 / https://github.com/Mugen87
+ *
+ * Usage:
+ *  var exporter = new THREE.STLExporter();
+ *
+ *  // second argument is a list of options
+ *  var data = exporter.parse( mesh, { binary: true } );
+ *
  */
  */
 
 
 THREE.STLExporter = function () {};
 THREE.STLExporter = function () {};
@@ -14,65 +23,141 @@ THREE.STLExporter.prototype = {
 		var vector = new THREE.Vector3();
 		var vector = new THREE.Vector3();
 		var normalMatrixWorld = new THREE.Matrix3();
 		var normalMatrixWorld = new THREE.Matrix3();
 
 
-		return function parse( scene ) {
+		return function parse( scene, options ) {
 
 
-			var output = '';
+			if ( options === undefined ) options = {};
 
 
-			output += 'solid exported\n';
+			var binary = options.binary !== undefined ? options.binary : false;
+
+			//
+
+			var objects = [];
+			var triangles = 0;
 
 
 			scene.traverse( function ( object ) {
 			scene.traverse( function ( object ) {
 
 
-				if ( object instanceof THREE.Mesh ) {
+				if ( object.isMesh ) {
 
 
 					var geometry = object.geometry;
 					var geometry = object.geometry;
-					var matrixWorld = object.matrixWorld;
 
 
-					if ( geometry instanceof THREE.BufferGeometry ) {
+					if ( geometry.isBufferGeometry ) {
 
 
 						geometry = new THREE.Geometry().fromBufferGeometry( geometry );
 						geometry = new THREE.Geometry().fromBufferGeometry( geometry );
 
 
 					}
 					}
 
 
-					if ( geometry instanceof THREE.Geometry ) {
+					if ( geometry.isGeometry ) {
 
 
-						var vertices = geometry.vertices;
-						var faces = geometry.faces;
+						triangles += geometry.faces.length;
 
 
-						normalMatrixWorld.getNormalMatrix( matrixWorld );
+						objects.push( {
 
 
-						for ( var i = 0, l = faces.length; i < l; i ++ ) {
+							geometry: geometry,
+							matrixWorld: object.matrixWorld
 
 
-							var face = faces[ i ];
+						} );
 
 
-							vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+					}
 
 
-							output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
-							output += '\t\touter loop\n';
+				}
 
 
-							var indices = [ face.a, face.b, face.c ];
+			} );
 
 
-							for ( var j = 0; j < 3; j ++ ) {
+			if ( binary ) {
+
+				var offset = 80; // skip header
+				var bufferLength = triangles * 2 + triangles * 3 * 4 * 4 + 80 + 4;
+				var arrayBuffer = new ArrayBuffer( bufferLength );
+				var output = new DataView( arrayBuffer );
+				output.setUint32( offset, triangles, true ); offset += 4;
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					var object = objects[ i ];
+
+					var vertices = object.geometry.vertices;
+					var faces = object.geometry.faces;
+					var matrixWorld = object.matrixWorld;
 
 
-								vector.copy( vertices[ indices[ j ] ] ).applyMatrix4( matrixWorld );
+					normalMatrixWorld.getNormalMatrix( matrixWorld );
 
 
-								output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
 
 
-							}
+						var face = faces[ j ];
 
 
-							output += '\t\tendloop\n';
-							output += '\tendfacet\n';
+						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+
+						output.setFloat32( offset, vector.x, true ); offset += 4; // normal
+						output.setFloat32( offset, vector.y, true ); offset += 4;
+						output.setFloat32( offset, vector.z, true ); offset += 4;
+
+						var indices = [ face.a, face.b, face.c ];
+
+						for ( var k = 0; k < 3; k ++ ) {
+
+							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+
+							output.setFloat32( offset, vector.x, true ); offset += 4; // vertices
+							output.setFloat32( offset, vector.y, true ); offset += 4;
+							output.setFloat32( offset, vector.z, true ); offset += 4;
 
 
 						}
 						}
 
 
+						output.setUint16( offset, 0, true ); offset += 2; // attribute byte count
+
 					}
 					}
 
 
 				}
 				}
 
 
-			} );
+				return output;
+
+			} else {
+
+				var output = '';
+
+				output += 'solid exported\n';
+
+				for ( var i = 0, il = objects.length; i < il; i ++ ) {
+
+					var object = objects[ i ];
+
+					var vertices = object.geometry.vertices;
+					var faces = object.geometry.faces;
+					var matrixWorld = object.matrixWorld;
+
+					normalMatrixWorld.getNormalMatrix( matrixWorld );
+
+					for ( var j = 0, jl = faces.length; j < jl; j ++ ) {
+
+						var face = faces[ j ];
+
+						vector.copy( face.normal ).applyMatrix3( normalMatrixWorld ).normalize();
+
+						output += '\tfacet normal ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+						output += '\t\touter loop\n';
+
+						var indices = [ face.a, face.b, face.c ];
+
+						for ( var k = 0; k < 3; k ++ ) {
+
+							vector.copy( vertices[ indices[ k ] ] ).applyMatrix4( matrixWorld );
+
+							output += '\t\t\tvertex ' + vector.x + ' ' + vector.y + ' ' + vector.z + '\n';
+
+						}
+
+						output += '\t\tendloop\n';
+						output += '\tendfacet\n';
+
+					}
+
+				}
+
+				output += 'endsolid exported\n';
 
 
-			output += 'endsolid exported\n';
+				return output;
 
 
-			return output;
+			}
 
 
 		};
 		};
 
 

+ 5 - 0
examples/js/loaders/DRACOLoader.js

@@ -52,14 +52,17 @@ THREE.DRACOLoader.prototype = {
 
 
     setPath: function(value) {
     setPath: function(value) {
         this.path = value;
         this.path = value;
+        return this;
     },
     },
 
 
     setCrossOrigin: function(value) {
     setCrossOrigin: function(value) {
         this.crossOrigin = value;
         this.crossOrigin = value;
+        return this;
     },
     },
 
 
     setVerbosity: function(level) {
     setVerbosity: function(level) {
         this.verbosity = level;
         this.verbosity = level;
+        return this;
     },
     },
 
 
     /**
     /**
@@ -70,6 +73,7 @@ THREE.DRACOLoader.prototype = {
      */
      */
     setDrawMode: function(drawMode) {
     setDrawMode: function(drawMode) {
         this.drawMode = drawMode;
         this.drawMode = drawMode;
+        return this;
     },
     },
 
 
     /**
     /**
@@ -84,6 +88,7 @@ THREE.DRACOLoader.prototype = {
           skipDequantization = skip;
           skipDequantization = skip;
         this.getAttributeOptions(attributeName).skipDequantization =
         this.getAttributeOptions(attributeName).skipDequantization =
             skipDequantization;
             skipDequantization;
+        return this;
     },
     },
 
 
     /**
     /**

+ 1 - 7
examples/js/loaders/EquiangularToCubeGenerator.js

@@ -95,13 +95,7 @@ THREE.EquiangularToCubeGenerator.prototype = {
 					gl_FragColor = vec4( color, 1.0 );\n\
 					gl_FragColor = vec4( color, 1.0 );\n\
 				}",
 				}",
 
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 
 		} );
 		} );
 
 

+ 25 - 24
examples/js/loaders/GLTFLoader.js

@@ -246,9 +246,9 @@ THREE.GLTFLoader = ( function () {
 	/**
 	/**
 	 * DDS Texture Extension
 	 * DDS Texture Extension
 	 *
 	 *
-	 * Specification: 
+	 * Specification:
 	 * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds
 	 * https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/MSFT_texture_dds
-	 * 
+	 *
 	 */
 	 */
 	function GLTFTextureDDSExtension() {
 	function GLTFTextureDDSExtension() {
 
 
@@ -455,7 +455,7 @@ THREE.GLTFLoader = ( function () {
 	 *
 	 *
 	 * Specification: https://github.com/KhronosGroup/glTF/pull/874
 	 * Specification: https://github.com/KhronosGroup/glTF/pull/874
 	 */
 	 */
-	function GLTFDracoMeshCompressionExtension ( json, dracoLoader ) {
+	function GLTFDracoMeshCompressionExtension( json, dracoLoader ) {
 
 
 		if ( ! dracoLoader ) {
 		if ( ! dracoLoader ) {
 
 
@@ -481,7 +481,7 @@ THREE.GLTFLoader = ( function () {
 
 
 		for ( var attributeName in gltfAttributeMap ) {
 		for ( var attributeName in gltfAttributeMap ) {
 
 
-			if ( !( attributeName in ATTRIBUTES ) ) continue;
+			if ( ! ( attributeName in ATTRIBUTES ) ) continue;
 
 
 			threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
 			threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
 
 
@@ -494,7 +494,7 @@ THREE.GLTFLoader = ( function () {
 				var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
 				var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
 				var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
 				var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
 
 
-				attributeTypeMap[ ATTRIBUTES[ attributeName ] ]  = componentType;
+				attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType;
 				attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
 				attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
 
 
 			}
 			}
@@ -934,7 +934,7 @@ THREE.GLTFLoader = ( function () {
 
 
 		THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
 		THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
 
 
-	};
+	}
 
 
 	GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype );
 	GLTFCubicSplineInterpolant.prototype = Object.create( THREE.Interpolant.prototype );
 	GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant;
 	GLTFCubicSplineInterpolant.prototype.constructor = GLTFCubicSplineInterpolant;
@@ -966,10 +966,10 @@ THREE.GLTFLoader = ( function () {
 		//   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
 		//   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
 		for ( var i = 0; i !== stride; i ++ ) {
 		for ( var i = 0; i !== stride; i ++ ) {
 
 
-			var p0 = values[ offset0 + i + stride ];        // splineVertex_k
-			var m0 = values[ offset0 + i + stride2 ] * td;  // outTangent_k * (t_k+1 - t_k)
-			var p1 = values[ offset1 + i + stride ];        // splineVertex_k+1
-			var m1 = values[ offset1 + i ] * td;            // inTangent_k+1 * (t_k+1 - t_k)
+			var p0 = values[ offset0 + i + stride ]; // splineVertex_k
+			var m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)
+			var p1 = values[ offset1 + i + stride ]; // splineVertex_k+1
+			var m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)
 
 
 			result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
 			result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
 
 
@@ -1123,7 +1123,7 @@ THREE.GLTFLoader = ( function () {
 		WEIGHT: 'skinWeight', // deprecated
 		WEIGHT: 'skinWeight', // deprecated
 		JOINTS_0: 'skinIndex',
 		JOINTS_0: 'skinIndex',
 		JOINT: 'skinIndex' // deprecated
 		JOINT: 'skinIndex' // deprecated
-	}
+	};
 
 
 	var PATH_PROPERTIES = {
 	var PATH_PROPERTIES = {
 		scale: 'scale',
 		scale: 'scale',
@@ -1214,7 +1214,7 @@ THREE.GLTFLoader = ( function () {
 	/**
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
 	 *
 	 *
-	 * @param {THREE.Geometry} geometry
+	 * @param {THREE.BufferGeometry} geometry
 	 * @param {Array<GLTF.Target>} targets
 	 * @param {Array<GLTF.Target>} targets
 	 * @param {Array<THREE.BufferAttribute>} accessors
 	 * @param {Array<THREE.BufferAttribute>} accessors
 	 */
 	 */
@@ -1533,7 +1533,7 @@ THREE.GLTFLoader = ( function () {
 		// BufferGeometry caching
 		// BufferGeometry caching
 		this.primitiveCache = [];
 		this.primitiveCache = [];
 		this.multiplePrimitivesCache = [];
 		this.multiplePrimitivesCache = [];
-		this.multiPassGeometryCache = []
+		this.multiPassGeometryCache = [];
 
 
 		this.textureLoader = new THREE.TextureLoader( this.options.manager );
 		this.textureLoader = new THREE.TextureLoader( this.options.manager );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
@@ -2178,7 +2178,7 @@ THREE.GLTFLoader = ( function () {
 
 
 		}
 		}
 
 
-		if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 
 			pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) );
 			pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture.index ) );
 
 
@@ -2192,7 +2192,7 @@ THREE.GLTFLoader = ( function () {
 
 
 		}
 		}
 
 
-		if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 
 			pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) );
 			pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture.index ) );
 
 
@@ -2204,13 +2204,13 @@ THREE.GLTFLoader = ( function () {
 
 
 		}
 		}
 
 
-		if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 
 			materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
 			materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
 
 
 		}
 		}
 
 
-		if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
+		if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
 
 
 			pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) );
 			pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture.index ) );
 
 
@@ -2240,9 +2240,10 @@ THREE.GLTFLoader = ( function () {
 
 
 			}
 			}
 
 
-			// emissiveTexture and baseColorTexture use sRGB encoding.
+			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
 			if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
 			if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
+			if ( material.specularMap ) material.specularMap.encoding = THREE.sRGBEncoding;
 
 
 			if ( materialDef.extras ) material.userData = materialDef.extras;
 			if ( materialDef.extras ) material.userData = materialDef.extras;
 
 
@@ -2269,7 +2270,7 @@ THREE.GLTFLoader = ( function () {
 			var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ];
 			var bufferAttribute = accessors[ attributes[ gltfAttributeName ] ];
 
 
 			// Skip attributes already provided by e.g. Draco extension.
 			// Skip attributes already provided by e.g. Draco extension.
-			if ( !threeAttributeName ) continue;
+			if ( ! threeAttributeName ) continue;
 			if ( threeAttributeName in geometry.attributes ) continue;
 			if ( threeAttributeName in geometry.attributes ) continue;
 
 
 			geometry.addAttribute( threeAttributeName, bufferAttribute );
 			geometry.addAttribute( threeAttributeName, bufferAttribute );
@@ -2507,7 +2508,7 @@ THREE.GLTFLoader = ( function () {
 
 
 					var mesh;
 					var mesh;
 
 
-					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ]
+					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ];
 
 
 					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
 					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
 						primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
 						primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
@@ -2591,7 +2592,7 @@ THREE.GLTFLoader = ( function () {
 								THREE.Material.prototype.copy.call( pointsMaterial, material );
 								THREE.Material.prototype.copy.call( pointsMaterial, material );
 								pointsMaterial.color.copy( material.color );
 								pointsMaterial.color.copy( material.color );
 								pointsMaterial.map = material.map;
 								pointsMaterial.map = material.map;
-								pointsMaterial.lights = false;  // PointsMaterial doesn't support lights yet
+								pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
 
 
 								scope.cache.add( cacheKey, pointsMaterial );
 								scope.cache.add( cacheKey, pointsMaterial );
 
 
@@ -2610,7 +2611,7 @@ THREE.GLTFLoader = ( function () {
 								lineMaterial = new THREE.LineBasicMaterial();
 								lineMaterial = new THREE.LineBasicMaterial();
 								THREE.Material.prototype.copy.call( lineMaterial, material );
 								THREE.Material.prototype.copy.call( lineMaterial, material );
 								lineMaterial.color.copy( material.color );
 								lineMaterial.color.copy( material.color );
-								lineMaterial.lights = false;  // LineBasicMaterial doesn't support lights yet
+								lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
 
 
 								scope.cache.add( cacheKey, lineMaterial );
 								scope.cache.add( cacheKey, lineMaterial );
 
 
@@ -2637,8 +2638,8 @@ THREE.GLTFLoader = ( function () {
 							if ( ! cachedMaterial ) {
 							if ( ! cachedMaterial ) {
 
 
 								cachedMaterial = material.isGLTFSpecularGlossinessMaterial
 								cachedMaterial = material.isGLTFSpecularGlossinessMaterial
-										? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
-										: material.clone();
+									? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
+									: material.clone();
 
 
 								if ( useSkinning ) cachedMaterial.skinning = true;
 								if ( useSkinning ) cachedMaterial.skinning = true;
 								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;
 								if ( useVertexColors ) cachedMaterial.vertexColors = THREE.VertexColors;

+ 199 - 131
examples/js/loaders/MD2Loader.js

@@ -28,88 +28,88 @@ THREE.MD2Loader.prototype = {
 
 
 	parse: ( function () {
 	parse: ( function () {
 
 
-		var normals = [
-			[ -0.525731,  0.000000,  0.850651 ], [ -0.442863,  0.238856,  0.864188 ],
-			[ -0.295242,  0.000000,  0.955423 ], [ -0.309017,  0.500000,  0.809017 ],
-			[ -0.162460,  0.262866,  0.951056 ], [  0.000000,  0.000000,  1.000000 ],
-			[  0.000000,  0.850651,  0.525731 ], [ -0.147621,  0.716567,  0.681718 ],
-			[  0.147621,  0.716567,  0.681718 ], [  0.000000,  0.525731,  0.850651 ],
-			[  0.309017,  0.500000,  0.809017 ], [  0.525731,  0.000000,  0.850651 ],
-			[  0.295242,  0.000000,  0.955423 ], [  0.442863,  0.238856,  0.864188 ],
-			[  0.162460,  0.262866,  0.951056 ], [ -0.681718,  0.147621,  0.716567 ],
-			[ -0.809017,  0.309017,  0.500000 ], [ -0.587785,  0.425325,  0.688191 ],
-			[ -0.850651,  0.525731,  0.000000 ], [ -0.864188,  0.442863,  0.238856 ],
-			[ -0.716567,  0.681718,  0.147621 ], [ -0.688191,  0.587785,  0.425325 ],
-			[ -0.500000,  0.809017,  0.309017 ], [ -0.238856,  0.864188,  0.442863 ],
-			[ -0.425325,  0.688191,  0.587785 ], [ -0.716567,  0.681718, -0.147621 ],
-			[ -0.500000,  0.809017, -0.309017 ], [ -0.525731,  0.850651,  0.000000 ],
-			[  0.000000,  0.850651, -0.525731 ], [ -0.238856,  0.864188, -0.442863 ],
-			[  0.000000,  0.955423, -0.295242 ], [ -0.262866,  0.951056, -0.162460 ],
-			[  0.000000,  1.000000,  0.000000 ], [  0.000000,  0.955423,  0.295242 ],
-			[ -0.262866,  0.951056,  0.162460 ], [  0.238856,  0.864188,  0.442863 ],
-			[  0.262866,  0.951056,  0.162460 ], [  0.500000,  0.809017,  0.309017 ],
-			[  0.238856,  0.864188, -0.442863 ], [  0.262866,  0.951056, -0.162460 ],
-			[  0.500000,  0.809017, -0.309017 ], [  0.850651,  0.525731,  0.000000 ],
-			[  0.716567,  0.681718,  0.147621 ], [  0.716567,  0.681718, -0.147621 ],
-			[  0.525731,  0.850651,  0.000000 ], [  0.425325,  0.688191,  0.587785 ],
-			[  0.864188,  0.442863,  0.238856 ], [  0.688191,  0.587785,  0.425325 ],
-			[  0.809017,  0.309017,  0.500000 ], [  0.681718,  0.147621,  0.716567 ],
-			[  0.587785,  0.425325,  0.688191 ], [  0.955423,  0.295242,  0.000000 ],
-			[  1.000000,  0.000000,  0.000000 ], [  0.951056,  0.162460,  0.262866 ],
-			[  0.850651, -0.525731,  0.000000 ], [  0.955423, -0.295242,  0.000000 ],
-			[  0.864188, -0.442863,  0.238856 ], [  0.951056, -0.162460,  0.262866 ],
-			[  0.809017, -0.309017,  0.500000 ], [  0.681718, -0.147621,  0.716567 ],
-			[  0.850651,  0.000000,  0.525731 ], [  0.864188,  0.442863, -0.238856 ],
-			[  0.809017,  0.309017, -0.500000 ], [  0.951056,  0.162460, -0.262866 ],
-			[  0.525731,  0.000000, -0.850651 ], [  0.681718,  0.147621, -0.716567 ],
-			[  0.681718, -0.147621, -0.716567 ], [  0.850651,  0.000000, -0.525731 ],
-			[  0.809017, -0.309017, -0.500000 ], [  0.864188, -0.442863, -0.238856 ],
-			[  0.951056, -0.162460, -0.262866 ], [  0.147621,  0.716567, -0.681718 ],
-			[  0.309017,  0.500000, -0.809017 ], [  0.425325,  0.688191, -0.587785 ],
-			[  0.442863,  0.238856, -0.864188 ], [  0.587785,  0.425325, -0.688191 ],
-			[  0.688191,  0.587785, -0.425325 ], [ -0.147621,  0.716567, -0.681718 ],
-			[ -0.309017,  0.500000, -0.809017 ], [  0.000000,  0.525731, -0.850651 ],
-			[ -0.525731,  0.000000, -0.850651 ], [ -0.442863,  0.238856, -0.864188 ],
-			[ -0.295242,  0.000000, -0.955423 ], [ -0.162460,  0.262866, -0.951056 ],
-			[  0.000000,  0.000000, -1.000000 ], [  0.295242,  0.000000, -0.955423 ],
-			[  0.162460,  0.262866, -0.951056 ], [ -0.442863, -0.238856, -0.864188 ],
-			[ -0.309017, -0.500000, -0.809017 ], [ -0.162460, -0.262866, -0.951056 ],
-			[  0.000000, -0.850651, -0.525731 ], [ -0.147621, -0.716567, -0.681718 ],
-			[  0.147621, -0.716567, -0.681718 ], [  0.000000, -0.525731, -0.850651 ],
-			[  0.309017, -0.500000, -0.809017 ], [  0.442863, -0.238856, -0.864188 ],
-			[  0.162460, -0.262866, -0.951056 ], [  0.238856, -0.864188, -0.442863 ],
-			[  0.500000, -0.809017, -0.309017 ], [  0.425325, -0.688191, -0.587785 ],
-			[  0.716567, -0.681718, -0.147621 ], [  0.688191, -0.587785, -0.425325 ],
-			[  0.587785, -0.425325, -0.688191 ], [  0.000000, -0.955423, -0.295242 ],
-			[  0.000000, -1.000000,  0.000000 ], [  0.262866, -0.951056, -0.162460 ],
-			[  0.000000, -0.850651,  0.525731 ], [  0.000000, -0.955423,  0.295242 ],
-			[  0.238856, -0.864188,  0.442863 ], [  0.262866, -0.951056,  0.162460 ],
-			[  0.500000, -0.809017,  0.309017 ], [  0.716567, -0.681718,  0.147621 ],
-			[  0.525731, -0.850651,  0.000000 ], [ -0.238856, -0.864188, -0.442863 ],
-			[ -0.500000, -0.809017, -0.309017 ], [ -0.262866, -0.951056, -0.162460 ],
-			[ -0.850651, -0.525731,  0.000000 ], [ -0.716567, -0.681718, -0.147621 ],
-			[ -0.716567, -0.681718,  0.147621 ], [ -0.525731, -0.850651,  0.000000 ],
-			[ -0.500000, -0.809017,  0.309017 ], [ -0.238856, -0.864188,  0.442863 ],
-			[ -0.262866, -0.951056,  0.162460 ], [ -0.864188, -0.442863,  0.238856 ],
-			[ -0.809017, -0.309017,  0.500000 ], [ -0.688191, -0.587785,  0.425325 ],
-			[ -0.681718, -0.147621,  0.716567 ], [ -0.442863, -0.238856,  0.864188 ],
-			[ -0.587785, -0.425325,  0.688191 ], [ -0.309017, -0.500000,  0.809017 ],
-			[ -0.147621, -0.716567,  0.681718 ], [ -0.425325, -0.688191,  0.587785 ],
-			[ -0.162460, -0.262866,  0.951056 ], [  0.442863, -0.238856,  0.864188 ],
-			[  0.162460, -0.262866,  0.951056 ], [  0.309017, -0.500000,  0.809017 ],
-			[  0.147621, -0.716567,  0.681718 ], [  0.000000, -0.525731,  0.850651 ],
-			[  0.425325, -0.688191,  0.587785 ], [  0.587785, -0.425325,  0.688191 ],
-			[  0.688191, -0.587785,  0.425325 ], [ -0.955423,  0.295242,  0.000000 ],
-			[ -0.951056,  0.162460,  0.262866 ], [ -1.000000,  0.000000,  0.000000 ],
-			[ -0.850651,  0.000000,  0.525731 ], [ -0.955423, -0.295242,  0.000000 ],
-			[ -0.951056, -0.162460,  0.262866 ], [ -0.864188,  0.442863, -0.238856 ],
-			[ -0.951056,  0.162460, -0.262866 ], [ -0.809017,  0.309017, -0.500000 ],
-			[ -0.864188, -0.442863, -0.238856 ], [ -0.951056, -0.162460, -0.262866 ],
-			[ -0.809017, -0.309017, -0.500000 ], [ -0.681718,  0.147621, -0.716567 ],
-			[ -0.681718, -0.147621, -0.716567 ], [ -0.850651,  0.000000, -0.525731 ],
-			[ -0.688191,  0.587785, -0.425325 ], [ -0.587785,  0.425325, -0.688191 ],
-			[ -0.425325,  0.688191, -0.587785 ], [ -0.425325, -0.688191, -0.587785 ],
-			[ -0.587785, -0.425325, -0.688191 ], [ -0.688191, -0.587785, -0.425325 ]
+		var normalData = [
+			[ - 0.525731, 0.000000, 0.850651 ], [ - 0.442863, 0.238856, 0.864188 ],
+			[ - 0.295242, 0.000000, 0.955423 ], [ - 0.309017, 0.500000, 0.809017 ],
+			[ - 0.162460, 0.262866, 0.951056 ], [ 0.000000, 0.000000, 1.000000 ],
+			[ 0.000000, 0.850651, 0.525731 ], [ - 0.147621, 0.716567, 0.681718 ],
+			[ 0.147621, 0.716567, 0.681718 ], [ 0.000000, 0.525731, 0.850651 ],
+			[ 0.309017, 0.500000, 0.809017 ], [ 0.525731, 0.000000, 0.850651 ],
+			[ 0.295242, 0.000000, 0.955423 ], [ 0.442863, 0.238856, 0.864188 ],
+			[ 0.162460, 0.262866, 0.951056 ], [ - 0.681718, 0.147621, 0.716567 ],
+			[ - 0.809017, 0.309017, 0.500000 ], [ - 0.587785, 0.425325, 0.688191 ],
+			[ - 0.850651, 0.525731, 0.000000 ], [ - 0.864188, 0.442863, 0.238856 ],
+			[ - 0.716567, 0.681718, 0.147621 ], [ - 0.688191, 0.587785, 0.425325 ],
+			[ - 0.500000, 0.809017, 0.309017 ], [ - 0.238856, 0.864188, 0.442863 ],
+			[ - 0.425325, 0.688191, 0.587785 ], [ - 0.716567, 0.681718, - 0.147621 ],
+			[ - 0.500000, 0.809017, - 0.309017 ], [ - 0.525731, 0.850651, 0.000000 ],
+			[ 0.000000, 0.850651, - 0.525731 ], [ - 0.238856, 0.864188, - 0.442863 ],
+			[ 0.000000, 0.955423, - 0.295242 ], [ - 0.262866, 0.951056, - 0.162460 ],
+			[ 0.000000, 1.000000, 0.000000 ], [ 0.000000, 0.955423, 0.295242 ],
+			[ - 0.262866, 0.951056, 0.162460 ], [ 0.238856, 0.864188, 0.442863 ],
+			[ 0.262866, 0.951056, 0.162460 ], [ 0.500000, 0.809017, 0.309017 ],
+			[ 0.238856, 0.864188, - 0.442863 ], [ 0.262866, 0.951056, - 0.162460 ],
+			[ 0.500000, 0.809017, - 0.309017 ], [ 0.850651, 0.525731, 0.000000 ],
+			[ 0.716567, 0.681718, 0.147621 ], [ 0.716567, 0.681718, - 0.147621 ],
+			[ 0.525731, 0.850651, 0.000000 ], [ 0.425325, 0.688191, 0.587785 ],
+			[ 0.864188, 0.442863, 0.238856 ], [ 0.688191, 0.587785, 0.425325 ],
+			[ 0.809017, 0.309017, 0.500000 ], [ 0.681718, 0.147621, 0.716567 ],
+			[ 0.587785, 0.425325, 0.688191 ], [ 0.955423, 0.295242, 0.000000 ],
+			[ 1.000000, 0.000000, 0.000000 ], [ 0.951056, 0.162460, 0.262866 ],
+			[ 0.850651, - 0.525731, 0.000000 ], [ 0.955423, - 0.295242, 0.000000 ],
+			[ 0.864188, - 0.442863, 0.238856 ], [ 0.951056, - 0.162460, 0.262866 ],
+			[ 0.809017, - 0.309017, 0.500000 ], [ 0.681718, - 0.147621, 0.716567 ],
+			[ 0.850651, 0.000000, 0.525731 ], [ 0.864188, 0.442863, - 0.238856 ],
+			[ 0.809017, 0.309017, - 0.500000 ], [ 0.951056, 0.162460, - 0.262866 ],
+			[ 0.525731, 0.000000, - 0.850651 ], [ 0.681718, 0.147621, - 0.716567 ],
+			[ 0.681718, - 0.147621, - 0.716567 ], [ 0.850651, 0.000000, - 0.525731 ],
+			[ 0.809017, - 0.309017, - 0.500000 ], [ 0.864188, - 0.442863, - 0.238856 ],
+			[ 0.951056, - 0.162460, - 0.262866 ], [ 0.147621, 0.716567, - 0.681718 ],
+			[ 0.309017, 0.500000, - 0.809017 ], [ 0.425325, 0.688191, - 0.587785 ],
+			[ 0.442863, 0.238856, - 0.864188 ], [ 0.587785, 0.425325, - 0.688191 ],
+			[ 0.688191, 0.587785, - 0.425325 ], [ - 0.147621, 0.716567, - 0.681718 ],
+			[ - 0.309017, 0.500000, - 0.809017 ], [ 0.000000, 0.525731, - 0.850651 ],
+			[ - 0.525731, 0.000000, - 0.850651 ], [ - 0.442863, 0.238856, - 0.864188 ],
+			[ - 0.295242, 0.000000, - 0.955423 ], [ - 0.162460, 0.262866, - 0.951056 ],
+			[ 0.000000, 0.000000, - 1.000000 ], [ 0.295242, 0.000000, - 0.955423 ],
+			[ 0.162460, 0.262866, - 0.951056 ], [ - 0.442863, - 0.238856, - 0.864188 ],
+			[ - 0.309017, - 0.500000, - 0.809017 ], [ - 0.162460, - 0.262866, - 0.951056 ],
+			[ 0.000000, - 0.850651, - 0.525731 ], [ - 0.147621, - 0.716567, - 0.681718 ],
+			[ 0.147621, - 0.716567, - 0.681718 ], [ 0.000000, - 0.525731, - 0.850651 ],
+			[ 0.309017, - 0.500000, - 0.809017 ], [ 0.442863, - 0.238856, - 0.864188 ],
+			[ 0.162460, - 0.262866, - 0.951056 ], [ 0.238856, - 0.864188, - 0.442863 ],
+			[ 0.500000, - 0.809017, - 0.309017 ], [ 0.425325, - 0.688191, - 0.587785 ],
+			[ 0.716567, - 0.681718, - 0.147621 ], [ 0.688191, - 0.587785, - 0.425325 ],
+			[ 0.587785, - 0.425325, - 0.688191 ], [ 0.000000, - 0.955423, - 0.295242 ],
+			[ 0.000000, - 1.000000, 0.000000 ], [ 0.262866, - 0.951056, - 0.162460 ],
+			[ 0.000000, - 0.850651, 0.525731 ], [ 0.000000, - 0.955423, 0.295242 ],
+			[ 0.238856, - 0.864188, 0.442863 ], [ 0.262866, - 0.951056, 0.162460 ],
+			[ 0.500000, - 0.809017, 0.309017 ], [ 0.716567, - 0.681718, 0.147621 ],
+			[ 0.525731, - 0.850651, 0.000000 ], [ - 0.238856, - 0.864188, - 0.442863 ],
+			[ - 0.500000, - 0.809017, - 0.309017 ], [ - 0.262866, - 0.951056, - 0.162460 ],
+			[ - 0.850651, - 0.525731, 0.000000 ], [ - 0.716567, - 0.681718, - 0.147621 ],
+			[ - 0.716567, - 0.681718, 0.147621 ], [ - 0.525731, - 0.850651, 0.000000 ],
+			[ - 0.500000, - 0.809017, 0.309017 ], [ - 0.238856, - 0.864188, 0.442863 ],
+			[ - 0.262866, - 0.951056, 0.162460 ], [ - 0.864188, - 0.442863, 0.238856 ],
+			[ - 0.809017, - 0.309017, 0.500000 ], [ - 0.688191, - 0.587785, 0.425325 ],
+			[ - 0.681718, - 0.147621, 0.716567 ], [ - 0.442863, - 0.238856, 0.864188 ],
+			[ - 0.587785, - 0.425325, 0.688191 ], [ - 0.309017, - 0.500000, 0.809017 ],
+			[ - 0.147621, - 0.716567, 0.681718 ], [ - 0.425325, - 0.688191, 0.587785 ],
+			[ - 0.162460, - 0.262866, 0.951056 ], [ 0.442863, - 0.238856, 0.864188 ],
+			[ 0.162460, - 0.262866, 0.951056 ], [ 0.309017, - 0.500000, 0.809017 ],
+			[ 0.147621, - 0.716567, 0.681718 ], [ 0.000000, - 0.525731, 0.850651 ],
+			[ 0.425325, - 0.688191, 0.587785 ], [ 0.587785, - 0.425325, 0.688191 ],
+			[ 0.688191, - 0.587785, 0.425325 ], [ - 0.955423, 0.295242, 0.000000 ],
+			[ - 0.951056, 0.162460, 0.262866 ], [ - 1.000000, 0.000000, 0.000000 ],
+			[ - 0.850651, 0.000000, 0.525731 ], [ - 0.955423, - 0.295242, 0.000000 ],
+			[ - 0.951056, - 0.162460, 0.262866 ], [ - 0.864188, 0.442863, - 0.238856 ],
+			[ - 0.951056, 0.162460, - 0.262866 ], [ - 0.809017, 0.309017, - 0.500000 ],
+			[ - 0.864188, - 0.442863, - 0.238856 ], [ - 0.951056, - 0.162460, - 0.262866 ],
+			[ - 0.809017, - 0.309017, - 0.500000 ], [ - 0.681718, 0.147621, - 0.716567 ],
+			[ - 0.681718, - 0.147621, - 0.716567 ], [ - 0.850651, 0.000000, - 0.525731 ],
+			[ - 0.688191, 0.587785, - 0.425325 ], [ - 0.587785, 0.425325, - 0.688191 ],
+			[ - 0.425325, 0.688191, - 0.587785 ], [ - 0.425325, - 0.688191, - 0.587785 ],
+			[ - 0.587785, - 0.425325, - 0.688191 ], [ - 0.688191, - 0.587785, - 0.425325 ]
 		];
 		];
 
 
 		return function ( buffer ) {
 		return function ( buffer ) {
@@ -151,11 +151,11 @@ THREE.MD2Loader.prototype = {
 
 
 			//
 			//
 
 
-			var geometry = new THREE.Geometry();
+			var geometry = new THREE.BufferGeometry();
 
 
 			// uvs
 			// uvs
 
 
-			var uvs = [];
+			var uvsTemp = [];
 			var offset = header.offset_st;
 			var offset = header.offset_st;
 
 
 			for ( var i = 0, l = header.num_st; i < l; i ++ ) {
 			for ( var i = 0, l = header.num_st; i < l; i ++ ) {
@@ -163,7 +163,7 @@ THREE.MD2Loader.prototype = {
 				var u = data.getInt16( offset + 0, true );
 				var u = data.getInt16( offset + 0, true );
 				var v = data.getInt16( offset + 2, true );
 				var v = data.getInt16( offset + 2, true );
 
 
-				uvs.push( new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) ) );
+				uvsTemp.push( u / header.skinwidth, 1 - ( v / header.skinheight ) );
 
 
 				offset += 4;
 				offset += 4;
 
 
@@ -171,21 +171,24 @@ THREE.MD2Loader.prototype = {
 
 
 			// triangles
 			// triangles
 
 
-			var offset = header.offset_tris;
+			offset = header.offset_tris;
 
 
-			for ( var i = 0, l = header.num_tris; i < l; i ++ ) {
+			var vertexIndices = [];
+			var uvIndices = [];
 
 
-				var a = data.getUint16( offset + 0, true );
-				var b = data.getUint16( offset + 2, true );
-				var c = data.getUint16( offset + 4, true );
+			for ( var i = 0, l = header.num_tris; i < l; i ++ ) {
 
 
-				geometry.faces.push( new THREE.Face3( a, b, c ) );
+				vertexIndices.push(
+					data.getUint16( offset + 0, true ),
+					data.getUint16( offset + 2, true ),
+					data.getUint16( offset + 4, true )
+				);
 
 
-				geometry.faceVertexUvs[ 0 ].push( [
-					uvs[ data.getUint16( offset + 6, true ) ],
-					uvs[ data.getUint16( offset + 8, true ) ],
-					uvs[ data.getUint16( offset + 10, true ) ]
-				] );
+				uvIndices.push(
+					data.getUint16( offset + 6, true ),
+					data.getUint16( offset + 8, true ),
+					data.getUint16( offset + 10, true )
+				);
 
 
 				offset += 12;
 				offset += 12;
 
 
@@ -197,7 +200,9 @@ THREE.MD2Loader.prototype = {
 			var scale = new THREE.Vector3();
 			var scale = new THREE.Vector3();
 			var string = [];
 			var string = [];
 
 
-			var offset = header.offset_frames;
+			var frames = [];
+
+			offset = header.offset_frames;
 
 
 			for ( var i = 0, l = header.num_frames; i < l; i ++ ) {
 			for ( var i = 0, l = header.num_frames; i < l; i ++ ) {
 
 
@@ -237,68 +242,131 @@ THREE.MD2Loader.prototype = {
 					var x = data.getUint8( offset ++, true );
 					var x = data.getUint8( offset ++, true );
 					var y = data.getUint8( offset ++, true );
 					var y = data.getUint8( offset ++, true );
 					var z = data.getUint8( offset ++, true );
 					var z = data.getUint8( offset ++, true );
-					var n = normals[ data.getUint8( offset ++, true ) ];
-
-					var vertex = new THREE.Vector3(
-						x * scale.x + translation.x,
-						z * scale.z + translation.z,
-						y * scale.y + translation.y
-					);
+					var n = normalData[ data.getUint8( offset ++, true ) ];
 
 
-					var normal = new THREE.Vector3( n[ 0 ], n[ 2 ], n[ 1 ] );
+					x = x * scale.x + translation.x;
+					y = y * scale.y + translation.y;
+					z = z * scale.z + translation.z;
 
 
-					frame.vertices.push( vertex );
-					frame.normals.push( normal );
+					frame.vertices.push( x, z, y ); // convert to Y-up
+					frame.normals.push( n[ 0 ], n[ 2 ], n[ 1 ] ); // convert to Y-up
 
 
 				}
 				}
 
 
-				geometry.morphTargets.push( frame );
+				frames.push( frame );
 
 
 			}
 			}
 
 
-			// Static
+			// static
+
+			var positions = [];
+			var normals = [];
+			var uvs = [];
+
+			var verticesTemp = frames[ 0 ].vertices;
+			var normalsTemp = frames[ 0 ].normals;
+
+			for ( var i = 0, l = vertexIndices.length; i < l; i ++ ) {
+
+				var vertexIndex = vertexIndices[ i ];
+				var stride = vertexIndex * 3;
+
+				//
+
+				var x = verticesTemp[ stride ];
+				var y = verticesTemp[ stride + 1 ];
+				var z = verticesTemp[ stride + 2 ];
 
 
-			geometry.vertices = geometry.morphTargets[ 0 ].vertices;
+				positions.push( x, y, z );
 
 
-			var morphTarget = geometry.morphTargets[ 0 ];
+				//
 
 
-			for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
+				var nx = normalsTemp[ stride ];
+				var ny = normalsTemp[ stride + 1 ];
+				var nz = normalsTemp[ stride + 2 ];
 
 
-				var face = geometry.faces[ j ];
+				normals.push( nx, ny, nz );
 
 
-				face.vertexNormals = [
-					morphTarget.normals[ face.a ],
-					morphTarget.normals[ face.b ],
-					morphTarget.normals[ face.c ]
-				];
+				//
+
+				var uvIndex = uvIndices[ i ];
+				stride = uvIndex * 2;
+
+				var u = uvsTemp[ stride ];
+				var v = uvsTemp[ stride + 1 ];
+
+				uvs.push( u, v );
 
 
 			}
 			}
 
 
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
+			geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
+			geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
+
+			// animation
 
 
-			// Convert to geometry.morphNormals
+			var morphPositions = [];
+			var morphNormals = [];
 
 
-			for ( var i = 0, l = geometry.morphTargets.length; i < l; i ++ ) {
+			for ( var i = 0, l = frames.length; i < l; i ++ ) {
 
 
-				var morphTarget = geometry.morphTargets[ i ];
-				var vertexNormals = [];
+				var frame = frames[ i ];
+				var attributeName = frame.name;
 
 
-				for ( var j = 0, jl = geometry.faces.length; j < jl; j ++ ) {
+				if ( frame.vertices.length > 0 ) {
 
 
-					var face = geometry.faces[ j ];
+					var positions = [];
 
 
-					vertexNormals.push( {
-						a: morphTarget.normals[ face.a ],
-						b: morphTarget.normals[ face.b ],
-						c: morphTarget.normals[ face.c ]
-					} );
+					for ( var j = 0, jl = vertexIndices.length; j < jl; j ++ ) {
+
+						var vertexIndex = vertexIndices[ j ];
+						var stride = vertexIndex * 3;
+
+						var x = frame.vertices[ stride ];
+						var y = frame.vertices[ stride + 1 ];
+						var z = frame.vertices[ stride + 2 ];
+
+						positions.push( x, y, z );
+
+					}
+
+					var positionAttribute = new THREE.Float32BufferAttribute( positions, 3 );
+					positionAttribute.name = attributeName;
+
+					morphPositions.push( positionAttribute );
 
 
 				}
 				}
 
 
-				geometry.morphNormals.push( { vertexNormals: vertexNormals } );
+				if ( frame.normals.length > 0 ) {
+
+					var normals = [];
+
+					for ( var j = 0, jl = vertexIndices.length; j < jl; j ++ ) {
+
+						var vertexIndex = vertexIndices[ j ];
+						var stride = vertexIndex * 3;
+
+						var nx = frame.normals[ stride ];
+						var ny = frame.normals[ stride + 1 ];
+						var nz = frame.normals[ stride + 2 ];
+
+						normals.push( nx, ny, nz );
+
+					}
+
+					var normalAttribute = new THREE.Float32BufferAttribute( normals, 3 );
+					normalAttribute.name = attributeName;
+
+					morphNormals.push( normalAttribute );
+
+				}
 
 
 			}
 			}
 
 
-			geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( geometry.morphTargets, 10 );
+			geometry.morphAttributes.position = morphPositions;
+			geometry.morphAttributes.normal = morphNormals;
+
+			geometry.animations = THREE.AnimationClip.CreateClipsFromMorphTargetSequences( frames, 10 );
 
 
 			console.timeEnd( 'MD2Loader' );
 			console.timeEnd( 'MD2Loader' );
 
 

+ 8 - 7
examples/js/loaders/MMDLoader.js

@@ -841,13 +841,14 @@ THREE.MMDLoader = ( function () {
 			geometry.morphTargets = morphTargets;
 			geometry.morphTargets = morphTargets;
 			geometry.morphAttributes.position = morphPositions;
 			geometry.morphAttributes.position = morphPositions;
 
 
-			geometry.iks = iks;
-			geometry.grants = grants;
-
-			geometry.rigidBodies = rigidBodies;
-			geometry.constraints = constraints;
-
-			geometry.mmdFormat = data.metadata.format;
+			geometry.userData.MMD = {
+				bones: bones,
+				iks: iks,
+				grants: grants,
+				rigidBodies: rigidBodies,
+				constraints: constraints,
+				format: data.metadata.format
+			};
 
 
 			geometry.computeBoundingSphere();
 			geometry.computeBoundingSphere();
 
 

+ 21 - 69
examples/js/loaders/TDSLoader.js

@@ -1,5 +1,5 @@
 /*
 /*
- * Autodesk 3DS threee.js file loader, based on lib3ds.
+ * Autodesk 3DS three.js file loader, based on lib3ds.
  *
  *
  * Loads geometry with uv and materials basic properties with texture support.
  * Loads geometry with uv and materials basic properties with texture support.
  *
  *
@@ -321,20 +321,9 @@ THREE.TDSLoader.prototype = {
 		var chunk = this.readChunk( data );
 		var chunk = this.readChunk( data );
 		var next = this.nextChunk( data, chunk );
 		var next = this.nextChunk( data, chunk );
 
 
-		var useBufferGeometry = false;
-		var geometry = null;
+		var geometry = new THREE.BufferGeometry();
 		var uvs = [];
 		var uvs = [];
 
 
-		if ( useBufferGeometry ) {
-
-			geometry = new THREE.BufferGeometry();
-
-		}	else {
-
-			geometry = new THREE.Geometry();
-
-		}
-
 		var material = new THREE.MeshPhongMaterial();
 		var material = new THREE.MeshPhongMaterial();
 		var mesh = new THREE.Mesh( geometry, material );
 		var mesh = new THREE.Mesh( geometry, material );
 		mesh.name = 'mesh';
 		mesh.name = 'mesh';
@@ -349,29 +338,18 @@ THREE.TDSLoader.prototype = {
 
 
 				//BufferGeometry
 				//BufferGeometry
 
 
-				if ( useBufferGeometry )	{
-
-					var vertices = [];
-					for ( var i = 0; i < points; i ++ )		{
-
-						vertices.push( this.readFloat( data ) );
-						vertices.push( this.readFloat( data ) );
-						vertices.push( this.readFloat( data ) );
-
-					}
-
-					geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
-
-				} else	{ //Geometry
+				var vertices = [];
 
 
-					for ( var i = 0; i < points; i ++ )		{
+				for ( var i = 0; i < points; i ++ )		{
 
 
-						geometry.vertices.push( new THREE.Vector3( this.readFloat( data ), this.readFloat( data ), this.readFloat( data ) ) );
-
-					}
+					vertices.push( this.readFloat( data ) );
+					vertices.push( this.readFloat( data ) );
+					vertices.push( this.readFloat( data ) );
 
 
 				}
 				}
 
 
+				geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+
 			} else if ( next === FACE_ARRAY ) {
 			} else if ( next === FACE_ARRAY ) {
 
 
 				this.resetPosition( data );
 				this.resetPosition( data );
@@ -385,27 +363,17 @@ THREE.TDSLoader.prototype = {
 
 
 				//BufferGeometry
 				//BufferGeometry
 
 
-				if ( useBufferGeometry )	{
-
-					var uvs = [];
-					for ( var i = 0; i < texels; i ++ )		{
-
-						uvs.push( this.readFloat( data ) );
-						uvs.push( this.readFloat( data ) );
-
-					}
-					geometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( uvs ), 2 ) );
+				var uvs = [];
 
 
-				} else { //Geometry
+				for ( var i = 0; i < texels; i ++ )		{
 
 
-					uvs = [];
-					for ( var i = 0; i < texels; i ++ )		{
+					uvs.push( this.readFloat( data ) );
+					uvs.push( this.readFloat( data ) );
 
 
-						uvs.push( new THREE.Vector2( this.readFloat( data ), this.readFloat( data ) ) );
+				}
 
 
-					}
+				geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
 
 
-				}
 
 
 			} else if ( next === MESH_MATRIX ) {
 			} else if ( next === MESH_MATRIX ) {
 
 
@@ -464,27 +432,7 @@ THREE.TDSLoader.prototype = {
 
 
 		this.endChunk( chunk );
 		this.endChunk( chunk );
 
 
-		if ( ! useBufferGeometry ) {
-
-			//geometry.faceVertexUvs[0][faceIndex][vertexIndex]
-
-			if ( uvs.length > 0 ) {
-
-				var faceUV = [];
-
-				for ( var i = 0; i < geometry.faces.length; i ++ ) {
-
-					faceUV.push( [ uvs[ geometry.faces[ i ].a ], uvs[ geometry.faces[ i ].b ], uvs[ geometry.faces[ i ].c ] ] );
-
-				}
-
-				geometry.faceVertexUvs[ 0 ] = faceUV;
-
-			}
-
-			geometry.computeVertexNormals();
-
-		}
+		geometry.computeVertexNormals();
 
 
 		return mesh;
 		return mesh;
 
 
@@ -504,14 +452,18 @@ THREE.TDSLoader.prototype = {
 
 
 		this.debugMessage( '   Faces: ' + faces );
 		this.debugMessage( '   Faces: ' + faces );
 
 
+		var index = [];
+
 		for ( var i = 0; i < faces; ++ i ) {
 		for ( var i = 0; i < faces; ++ i ) {
 
 
-			mesh.geometry.faces.push( new THREE.Face3( this.readWord( data ), this.readWord( data ), this.readWord( data ) ) );
+			index.push( this.readWord( data ), this.readWord( data ), this.readWord( data ) );
 
 
 			var visibility = this.readWord( data );
 			var visibility = this.readWord( data );
 
 
 		}
 		}
 
 
+		mesh.geometry.setIndex( index );
+
 		//The rest of the FACE_ARRAY chunk is subchunks
 		//The rest of the FACE_ARRAY chunk is subchunks
 
 
 		while ( this.position < chunk.end ) {
 		while ( this.position < chunk.end ) {

+ 22 - 48
examples/js/loaders/VTKLoader.js

@@ -250,77 +250,51 @@ Object.assign( THREE.VTKLoader.prototype, THREE.EventDispatcher.prototype, {
 
 
 			}
 			}
 
 
-			var geometry;
-			var stagger = 'point';
+			var geometry = new THREE.BufferGeometry();
+			geometry.setIndex( indices );
+			geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
 
 
-			if ( colors.length === indices.length ) {
+			if ( normals.length === positions.length ) {
 
 
-				stagger = 'cell';
+				geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
 
 
 			}
 			}
 
 
-			if ( stagger === 'point' ) {
+			if ( colors.length !== indices.length ) {
 
 
-				// Nodal. Use BufferGeometry
-				geometry = new THREE.BufferGeometry();
-				geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
-				geometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) );
+				// stagger
 
 
 				if ( colors.length === positions.length ) {
 				if ( colors.length === positions.length ) {
 
 
-					geometry.addAttribute( 'color', new THREE.BufferAttribute( new Float32Array( colors ), 3 ) );
-
-				}
-
-				if ( normals.length === positions.length ) {
-
-					geometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
+					geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
 
 
 				}
 				}
 
 
 			} else {
 			} else {
 
 
-				// Cell centered colors. The only way to attach a solid color to each triangle
-				// is to use Geometry, which is less efficient than BufferGeometry
-				geometry = new THREE.Geometry();
-
-				var numTriangles = indices.length / 3;
-				var numPoints = positions.length / 3;
-				var face;
-				var ia, ib, ic;
-				var x, y, z;
-				var r, g, b;
+				// cell
 
 
-				for ( var j = 0; j < numPoints; ++ j ) {
+				geometry = geometry.toNonIndexed();
+				var numTriangles = geometry.attributes.position.count / 3;
 
 
-					x = positions[ 3 * j + 0 ];
-					y = positions[ 3 * j + 1 ];
-					z = positions[ 3 * j + 2 ];
-					geometry.vertices.push( new THREE.Vector3( x, y, z ) );
+				if ( colors.length === ( numTriangles * 3 ) ) {
 
 
-				}
-
-				for ( var i = 0; i < numTriangles; ++ i ) {
-
-					ia = indices[ 3 * i + 0 ];
-					ib = indices[ 3 * i + 1 ];
-					ic = indices[ 3 * i + 2 ];
-					geometry.faces.push( new THREE.Face3( ia, ib, ic ) );
+					var newColors = [];
 
 
-				}
-
-				if ( colors.length === numTriangles * 3 ) {
+					for ( var i = 0; i < numTriangles; i ++ ) {
 
 
-					for ( var i = 0; i < numTriangles; ++ i ) {
+						var r = colors[ 3 * i + 0 ];
+						var g = colors[ 3 * i + 1 ];
+						var b = colors[ 3 * i + 2 ];
 
 
-						face = geometry.faces[ i ];
-						r = colors[ 3 * i + 0 ];
-						g = colors[ 3 * i + 1 ];
-						b = colors[ 3 * i + 2 ];
-						face.color = new THREE.Color().setRGB( r, g, b );
+						newColors.push( r, g, b );
+						newColors.push( r, g, b );
+						newColors.push( r, g, b );
 
 
 					}
 					}
 
 
+					geometry.addAttribute( 'color', new THREE.Float32BufferAttribute( newColors, 3 ) );
+
 				}
 				}
 
 
 			}
 			}

+ 7 - 2
examples/js/loaders/XLoader.js

@@ -1,3 +1,8 @@
+/**
+ * @author adrs2002 / https://github.com/adrs2002
+ */
+
+
 ( function ( global, factory ) {
 ( function ( global, factory ) {
 
 
 	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
 	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
@@ -203,13 +208,13 @@
 
 
 	var XLoader = function () {
 	var XLoader = function () {
 
 
-		function XLoader( manager, texloader ) {
+		function XLoader( manager ) {
 
 
 			classCallCheck( this, XLoader );
 			classCallCheck( this, XLoader );
 
 
 			this.debug = false;
 			this.debug = false;
 			this.manager = manager !== undefined ? manager : new THREE.DefaultLoadingManager();
 			this.manager = manager !== undefined ? manager : new THREE.DefaultLoadingManager();
-			this.texloader = texloader !== undefined ? texloader : new THREE.TextureLoader();
+			this.texloader = new THREE.TextureLoader( this.manager );
 			this.url = "";
 			this.url = "";
 			this.baseDir = "";
 			this.baseDir = "";
 			this._putMatLength = 0;
 			this._putMatLength = 0;

+ 96 - 63
examples/js/modifiers/SimplifyModifier.js

@@ -8,24 +8,22 @@
  *    - http://www.melax.com/polychop/
  *    - http://www.melax.com/polychop/
  */
  */
 
 
-THREE.SimplifyModifier = function() {
+THREE.SimplifyModifier = function () {};
 
 
-};
-
-(function() {
+( function () {
 
 
 	var cb = new THREE.Vector3(), ab = new THREE.Vector3();
 	var cb = new THREE.Vector3(), ab = new THREE.Vector3();
 
 
 	function pushIfUnique( array, object ) {
 	function pushIfUnique( array, object ) {
 
 
-		if ( array.indexOf( object ) === -1 ) array.push( object );
+		if ( array.indexOf( object ) === - 1 ) array.push( object );
 
 
 	}
 	}
 
 
 	function removeFromArray( array, object ) {
 	function removeFromArray( array, object ) {
 
 
 		var k = array.indexOf( object );
 		var k = array.indexOf( object );
-		if ( k > -1 ) array.splice( k, 1 );
+		if ( k > - 1 ) array.splice( k, 1 );
 
 
 	}
 	}
 
 
@@ -38,14 +36,14 @@ THREE.SimplifyModifier = function() {
 		var curvature = 0;
 		var curvature = 0;
 
 
 		var sideFaces = [];
 		var sideFaces = [];
-		var i, uFaces = u.faces, il = u.faces.length, face, sideFace;
+		var i, il = u.faces.length, face, sideFace;
 
 
 		// find the "sides" triangles that are on the edge uv
 		// find the "sides" triangles that are on the edge uv
-		for ( i = 0 ; i < il; i ++ ) {
+		for ( i = 0; i < il; i ++ ) {
 
 
 			face = u.faces[ i ];
 			face = u.faces[ i ];
 
 
-			if ( face.hasVertex(v) ) {
+			if ( face.hasVertex( v ) ) {
 
 
 				sideFaces.push( face );
 				sideFaces.push( face );
 
 
@@ -55,20 +53,22 @@ THREE.SimplifyModifier = function() {
 
 
 		// use the triangle facing most away from the sides
 		// use the triangle facing most away from the sides
 		// to determine our curvature term
 		// to determine our curvature term
-		for ( i = 0 ; i < il; i ++ ) {
+		for ( i = 0; i < il; i ++ ) {
 
 
 			var minCurvature = 1;
 			var minCurvature = 1;
 			face = u.faces[ i ];
 			face = u.faces[ i ];
 
 
-			for( var j = 0; j < sideFaces.length; j ++ ) {
+			for ( var j = 0; j < sideFaces.length; j ++ ) {
 
 
 				sideFace = sideFaces[ j ];
 				sideFace = sideFaces[ j ];
 				// use dot product of face normals.
 				// use dot product of face normals.
 				var dotProd = face.normal.dot( sideFace.normal );
 				var dotProd = face.normal.dot( sideFace.normal );
-				minCurvature = Math.min( minCurvature, ( 1.001 - dotProd ) / 2);
+				minCurvature = Math.min( minCurvature, ( 1.001 - dotProd ) / 2 );
+
 			}
 			}
 
 
 			curvature = Math.max( curvature, minCurvature );
 			curvature = Math.max( curvature, minCurvature );
+
 		}
 		}
 
 
 		// crude approach in attempt to preserve borders
 		// crude approach in attempt to preserve borders
@@ -79,6 +79,7 @@ THREE.SimplifyModifier = function() {
 			// we add some arbitrary cost for borders,
 			// we add some arbitrary cost for borders,
 			// borders += 10;
 			// borders += 10;
 			curvature = 1;
 			curvature = 1;
+
 		}
 		}
 
 
 		var amt = edgelength * curvature + borders;
 		var amt = edgelength * curvature + borders;
@@ -88,6 +89,7 @@ THREE.SimplifyModifier = function() {
 	}
 	}
 
 
 	function computeEdgeCostAtVertex( v ) {
 	function computeEdgeCostAtVertex( v ) {
+
 		// compute the edge collapse cost for all edges that start
 		// compute the edge collapse cost for all edges that start
 		// from vertex v.  Since we are only interested in reducing
 		// from vertex v.  Since we are only interested in reducing
 		// the object by selecting the min cost edge at each step, we
 		// the object by selecting the min cost edge at each step, we
@@ -113,12 +115,14 @@ THREE.SimplifyModifier = function() {
 
 
 			var collapseCost = computeEdgeCollapseCost( v, v.neighbors[ i ] );
 			var collapseCost = computeEdgeCollapseCost( v, v.neighbors[ i ] );
 
 
-			if ( !v.collapseNeighbor ) {
+			if ( ! v.collapseNeighbor ) {
+
 				v.collapseNeighbor = v.neighbors[ i ];
 				v.collapseNeighbor = v.neighbors[ i ];
 				v.collapseCost = collapseCost;
 				v.collapseCost = collapseCost;
 				v.minCost = collapseCost;
 				v.minCost = collapseCost;
 				v.totalCost = 0;
 				v.totalCost = 0;
 				v.costCount = 0;
 				v.costCount = 0;
+
 			}
 			}
 
 
 			v.costCount ++;
 			v.costCount ++;
@@ -166,13 +170,16 @@ THREE.SimplifyModifier = function() {
 		var vs = [ this.v1, this.v2, this.v3 ];
 		var vs = [ this.v1, this.v2, this.v3 ];
 		var v1, v2;
 		var v1, v2;
 
 
-		for( var i = 0 ; i < 3 ; i ++ ) {
+		for ( var i = 0; i < 3; i ++ ) {
+
 			v1 = vs[ i ];
 			v1 = vs[ i ];
-			v2 = vs[( i+1) % 3 ];
+			v2 = vs[ ( i + 1 ) % 3 ];
+
+			if ( ! v1 || ! v2 ) continue;
 
 
-			if( !v1 || !v2 ) continue;
 			v1.removeIfNonNeighbor( v2 );
 			v1.removeIfNonNeighbor( v2 );
 			v2.removeIfNonNeighbor( v1 );
 			v2.removeIfNonNeighbor( v1 );
+
 		}
 		}
 
 
 	}
 	}
@@ -181,7 +188,7 @@ THREE.SimplifyModifier = function() {
 
 
 		// Collapse the edge uv by moving vertex u onto v
 		// Collapse the edge uv by moving vertex u onto v
 
 
-		if ( !v ) {
+		if ( ! v ) {
 
 
 			// u is a vertex all by itself so just delete it..
 			// u is a vertex all by itself so just delete it..
 			removeVertex( u, vertices );
 			removeVertex( u, vertices );
@@ -192,7 +199,7 @@ THREE.SimplifyModifier = function() {
 		var i;
 		var i;
 		var tmpVertices = [];
 		var tmpVertices = [];
 
 
-		for( i = 0 ; i < u.neighbors.length; i ++ ) {
+		for ( i = 0; i < u.neighbors.length; i ++ ) {
 
 
 			tmpVertices.push( u.neighbors[ i ] );
 			tmpVertices.push( u.neighbors[ i ] );
 
 
@@ -200,7 +207,7 @@ THREE.SimplifyModifier = function() {
 
 
 
 
 		// delete triangles on edge uv:
 		// delete triangles on edge uv:
-		for( i = u.faces.length - 1; i >= 0; i -- ) {
+		for ( i = u.faces.length - 1; i >= 0; i -- ) {
 
 
 			if ( u.faces[ i ].hasVertex( v ) ) {
 			if ( u.faces[ i ].hasVertex( v ) ) {
 
 
@@ -211,9 +218,9 @@ THREE.SimplifyModifier = function() {
 		}
 		}
 
 
 		// update remaining triangles to have v instead of u
 		// update remaining triangles to have v instead of u
-		for( i = u.faces.length -1 ; i >= 0; i -- ) {
+		for ( i = u.faces.length - 1; i >= 0; i -- ) {
 
 
-			u.faces[i].replaceVertex( u, v );
+			u.faces[ i ].replaceVertex( u, v );
 
 
 		}
 		}
 
 
@@ -221,7 +228,7 @@ THREE.SimplifyModifier = function() {
 		removeVertex( u, vertices );
 		removeVertex( u, vertices );
 
 
 		// recompute the edge collapse costs in neighborhood
 		// recompute the edge collapse costs in neighborhood
-		for( i = 0; i < tmpVertices.length; i ++ ) {
+		for ( i = 0; i < tmpVertices.length; i ++ ) {
 
 
 			computeEdgeCostAtVertex( tmpVertices[ i ] );
 			computeEdgeCostAtVertex( tmpVertices[ i ] );
 
 
@@ -237,13 +244,14 @@ THREE.SimplifyModifier = function() {
 
 
 		var least = vertices[ 0 ];
 		var least = vertices[ 0 ];
 
 
-		for (var i = 0; i < vertices.length; i ++ ) {
+		for ( var i = 0; i < vertices.length; i ++ ) {
 
 
 			if ( vertices[ i ].collapseCost < least.collapseCost ) {
 			if ( vertices[ i ].collapseCost < least.collapseCost ) {
 
 
 				least = vertices[ i ];
 				least = vertices[ i ];
 
 
 			}
 			}
+
 		}
 		}
 
 
 		return least;
 		return least;
@@ -253,6 +261,7 @@ THREE.SimplifyModifier = function() {
 	// we use a triangle class to represent structure of face slightly differently
 	// we use a triangle class to represent structure of face slightly differently
 
 
 	function Triangle( v1, v2, v3, a, b, c ) {
 	function Triangle( v1, v2, v3, a, b, c ) {
+
 		this.a = a;
 		this.a = a;
 		this.b = b;
 		this.b = b;
 		this.c = c;
 		this.c = c;
@@ -280,7 +289,7 @@ THREE.SimplifyModifier = function() {
 
 
 	}
 	}
 
 
-	Triangle.prototype.computeNormal = function() {
+	Triangle.prototype.computeNormal = function () {
 
 
 		var vA = this.v1.position;
 		var vA = this.v1.position;
 		var vB = this.v2.position;
 		var vB = this.v2.position;
@@ -294,13 +303,13 @@ THREE.SimplifyModifier = function() {
 
 
 	};
 	};
 
 
-	Triangle.prototype.hasVertex = function( v ) {
+	Triangle.prototype.hasVertex = function ( v ) {
 
 
 		return v === this.v1 || v === this.v2 || v === this.v3;
 		return v === this.v1 || v === this.v2 || v === this.v3;
 
 
 	};
 	};
 
 
-	Triangle.prototype.replaceVertex = function( oldv, newv ) {
+	Triangle.prototype.replaceVertex = function ( oldv, newv ) {
 
 
 		if ( oldv === this.v1 ) this.v1 = newv;
 		if ( oldv === this.v1 ) this.v1 = newv;
 		else if ( oldv === this.v2 ) this.v2 = newv;
 		else if ( oldv === this.v2 ) this.v2 = newv;
@@ -347,17 +356,19 @@ THREE.SimplifyModifier = function() {
 
 
 	}
 	}
 
 
-	Vertex.prototype.addUniqueNeighbor = function( vertex ) {
-		pushIfUnique(this.neighbors, vertex);
+	Vertex.prototype.addUniqueNeighbor = function ( vertex ) {
+
+		pushIfUnique( this.neighbors, vertex );
+
 	};
 	};
 
 
-	Vertex.prototype.removeIfNonNeighbor = function( n ) {
+	Vertex.prototype.removeIfNonNeighbor = function ( n ) {
 
 
 		var neighbors = this.neighbors;
 		var neighbors = this.neighbors;
 		var faces = this.faces;
 		var faces = this.faces;
 
 
 		var offset = neighbors.indexOf( n );
 		var offset = neighbors.indexOf( n );
-		if ( offset === -1 ) return;
+		if ( offset === - 1 ) return;
 		for ( var i = 0; i < faces.length; i ++ ) {
 		for ( var i = 0; i < faces.length; i ++ ) {
 
 
 			if ( faces[ i ].hasVertex( n ) ) return;
 			if ( faces[ i ].hasVertex( n ) ) return;
@@ -365,13 +376,15 @@ THREE.SimplifyModifier = function() {
 		}
 		}
 
 
 		neighbors.splice( offset, 1 );
 		neighbors.splice( offset, 1 );
+
 	};
 	};
 
 
-	THREE.SimplifyModifier.prototype.modify = function( geometry, count ) {
+	THREE.SimplifyModifier.prototype.modify = function ( geometry, count ) {
+
+		if ( geometry.isBufferGeometry ) {
 
 
-		if ( geometry instanceof THREE.BufferGeometry && !geometry.vertices && !geometry.faces ) {
-			console.log('converting BufferGeometry to Geometry');
 			geometry = new THREE.Geometry().fromBufferGeometry( geometry );
 			geometry = new THREE.Geometry().fromBufferGeometry( geometry );
+
 		}
 		}
 
 
 		geometry.mergeVertices();
 		geometry.mergeVertices();
@@ -379,83 +392,103 @@ THREE.SimplifyModifier = function() {
 		var oldVertices = geometry.vertices; // Three Position
 		var oldVertices = geometry.vertices; // Three Position
 		var oldFaces = geometry.faces; // Three Face
 		var oldFaces = geometry.faces; // Three Face
 
 
-		var newGeometry = new THREE.Geometry();
-
 		// conversion
 		// conversion
-		var vertices = new Array( oldVertices.length ); // Simplify Custom Vertex Struct
-		var faces = new Array( oldFaces.length ); // Simplify Custom Traignle Struct
+		var vertices = [];
+		var faces = [];
 
 
-		var i, il, face;
+		var i, il;
 
 
 		//
 		//
 		// put data of original geometry in different data structures
 		// put data of original geometry in different data structures
 		//
 		//
 
 
 		// add vertices
 		// add vertices
+
 		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
 		for ( i = 0, il = oldVertices.length; i < il; i ++ ) {
 
 
-			vertices[ i ] = new Vertex( oldVertices[ i ], i );
+			var vertex = new Vertex( oldVertices[ i ], i );
+			vertices.push( vertex );
 
 
 		}
 		}
 
 
 		// add faces
 		// add faces
+
 		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
 		for ( i = 0, il = oldFaces.length; i < il; i ++ ) {
 
 
-			face = oldFaces[ i ];
-			faces[ i ] = new Triangle( vertices[ face.a ], vertices[ face.b ], vertices[ face.c ], face.a, face.b, face.c );
+			var face = oldFaces[ i ];
+
+			var a = face.a;
+			var b = face.b;
+			var c = face.c;
+
+			var triangle = new Triangle( vertices[ a ], vertices[ b ], vertices[ c ], a, b, c );
+			faces.push( triangle );
 
 
 		}
 		}
 
 
 		// compute all edge collapse costs
 		// compute all edge collapse costs
+
 		for ( i = 0, il = vertices.length; i < il; i ++ ) {
 		for ( i = 0, il = vertices.length; i < il; i ++ ) {
 
 
 			computeEdgeCostAtVertex( vertices[ i ] );
 			computeEdgeCostAtVertex( vertices[ i ] );
 
 
 		}
 		}
 
 
-		var permutation = new Array( vertices.length );
-		var map = new Array( vertices.length );
-
 		var nextVertex;
 		var nextVertex;
 
 
 		var z = count;
 		var z = count;
 
 
-		// console.time('z')
-		// console.profile('zz');
+		while ( z -- ) {
 
 
-		while( z-- ) {
 			nextVertex = minimumCostEdge( vertices );
 			nextVertex = minimumCostEdge( vertices );
-			if (!nextVertex) {
-				console.log('no next vertex');
+
+			if ( ! nextVertex ) {
+
+				console.log( 'THREE.SimplifyModifier: No next vertex' );
 				break;
 				break;
+
 			}
 			}
+
 			collapse( vertices, faces, nextVertex, nextVertex.collapseNeighbor );
 			collapse( vertices, faces, nextVertex, nextVertex.collapseNeighbor );
+
 		}
 		}
 
 
-		// console.profileEnd('zz');
-		// console.timeEnd('z')
+		//
+
+		var simplifiedGeometry = new THREE.BufferGeometry();
+		var position = [];
+		var index = [];
 
 
-		// TODO convert to buffer geometry.
-		var newGeo = new THREE.Geometry();
+		//
 
 
 		for ( i = 0; i < vertices.length; i ++ ) {
 		for ( i = 0; i < vertices.length; i ++ ) {
 
 
-			var v = vertices[ i ];
-			newGeo.vertices.push( v.position )
+			var vertex = vertices[ i ].position;
+			position.push( vertex.x, vertex.y, vertex.z );
 
 
 		}
 		}
 
 
+		//
+
 		for ( i = 0; i < faces.length; i ++ ) {
 		for ( i = 0; i < faces.length; i ++ ) {
 
 
-			var tri = faces[ i ];
-			newGeo.faces.push( new THREE.Face3(
-				vertices.indexOf(tri.v1),
-				vertices.indexOf(tri.v2),
-				vertices.indexOf(tri.v3)
-			) )
+			var face = faces[ i ];
+
+			var a = vertices.indexOf( face.v1 );
+			var b = vertices.indexOf( face.v2 );
+			var c = vertices.indexOf( face.v3 );
+
+			index.push( a, b, c );
 
 
 		}
 		}
 
 
-		return newGeo;
+		//
+
+		simplifiedGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( position, 3 ) );
+		simplifiedGeometry.setIndex( index );
+
+		return simplifiedGeometry;
+
 	};
 	};
-})();
+
+} )();

+ 2 - 2
examples/js/objects/Reflector.js

@@ -55,8 +55,7 @@ THREE.Reflector = function ( geometry, options ) {
 	var material = new THREE.ShaderMaterial( {
 	var material = new THREE.ShaderMaterial( {
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 		fragmentShader: shader.fragmentShader,
 		fragmentShader: shader.fragmentShader,
-		vertexShader: shader.vertexShader,
-
+		vertexShader: shader.vertexShader
 	} );
 	} );
 
 
 	material.uniforms.tDiffuse.value = renderTarget.texture;
 	material.uniforms.tDiffuse.value = renderTarget.texture;
@@ -64,6 +63,7 @@ THREE.Reflector = function ( geometry, options ) {
 	material.uniforms.textureMatrix.value = textureMatrix;
 	material.uniforms.textureMatrix.value = textureMatrix;
 
 
 	this.material = material;
 	this.material = material;
+	this.renderOrder = - Infinity; // render first
 
 
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 	this.onBeforeRender = function ( renderer, scene, camera ) {
 
 

+ 0 - 2
examples/js/objects/ReflectorRTT.js

@@ -4,8 +4,6 @@ THREE.ReflectorRTT = function ( geometry, options ) {
 
 
 	this.geometry.setDrawRange( 0, 0 ); // avoid rendering geometry
 	this.geometry.setDrawRange( 0, 0 ); // avoid rendering geometry
 
 
-	this.renderOrder = -Infinity; // render RTT first
-
 };
 };
 
 
 THREE.ReflectorRTT.prototype = Object.create( THREE.Reflector.prototype );
 THREE.ReflectorRTT.prototype = Object.create( THREE.Reflector.prototype );

+ 1 - 7
examples/js/pmrem/PMREMCubeUVPacker.js

@@ -178,13 +178,7 @@ THREE.PMREMCubeUVPacker.prototype = {
 					gl_FragColor = linearToOutputTexel( color );\
 					gl_FragColor = linearToOutputTexel( color );\
 				}",
 				}",
 
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 
 		} );
 		} );
 
 

+ 1 - 7
examples/js/pmrem/PMREMGenerator.js

@@ -259,13 +259,7 @@ THREE.PMREMGenerator.prototype = {
 					gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\
 					gl_FragColor = linearToOutputTexel( vec4( rgbColor, 1.0 ) );\n\
 				}",
 				}",
 
 
-			blending: THREE.CustomBlending,
-			premultipliedAlpha: false,
-			blendSrc: THREE.OneFactor,
-			blendDst: THREE.ZeroFactor,
-			blendSrcAlpha: THREE.OneFactor,
-			blendDstAlpha: THREE.ZeroFactor,
-			blendEquation: THREE.AddEquation
+			blending: THREE.NoBlending
 
 
 		} );
 		} );
 
 

+ 62 - 0
examples/js/renderers/CSS2DRenderer.js

@@ -37,6 +37,10 @@ THREE.CSS2DRenderer = function () {
 	var viewMatrix = new THREE.Matrix4();
 	var viewMatrix = new THREE.Matrix4();
 	var viewProjectionMatrix = new THREE.Matrix4();
 	var viewProjectionMatrix = new THREE.Matrix4();
 
 
+	var cache = {
+		objects: new WeakMap()
+	};
+
 	var domElement = document.createElement( 'div' );
 	var domElement = document.createElement( 'div' );
 	domElement.style.overflow = 'hidden';
 	domElement.style.overflow = 'hidden';
 
 
@@ -79,6 +83,12 @@ THREE.CSS2DRenderer = function () {
 			element.style.oTransform = style;
 			element.style.oTransform = style;
 			element.style.transform = style;
 			element.style.transform = style;
 
 
+			var objectData = {
+				distanceToCameraSquared: getDistanceToSquared( camera, object )
+			};
+
+			cache.objects.set( object, objectData );
+
 			if ( element.parentNode !== domElement ) {
 			if ( element.parentNode !== domElement ) {
 
 
 				domElement.appendChild( element );
 				domElement.appendChild( element );
@@ -95,6 +105,57 @@ THREE.CSS2DRenderer = function () {
 
 
 	};
 	};
 
 
+	var getDistanceToSquared = function () {
+
+		var a = new THREE.Vector3();
+		var b = new THREE.Vector3();
+
+		return function ( object1, object2 ) {
+
+			a.setFromMatrixPosition( object1.matrixWorld );
+			b.setFromMatrixPosition( object2.matrixWorld );
+
+			return a.distanceToSquared( b );
+
+		};
+
+	}();
+
+	var filterAndFlatten = function ( scene ) {
+
+		var result = [];
+
+		scene.traverse( function ( object ) {
+
+			if ( object instanceof THREE.CSS2DObject ) result.push( object );
+
+		} );
+
+		return result;
+
+	};
+
+	var zOrder = function ( scene ) {
+
+		var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
+
+			var distanceA = cache.objects.get( a ).distanceToCameraSquared;
+			var distanceB = cache.objects.get( b ).distanceToCameraSquared;
+
+			return distanceA - distanceB;
+
+		} );
+
+		var zMax = sorted.length;
+
+		for ( var i = 0, l = sorted.length; i < l; i ++ ) {
+
+			sorted[ i ].element.style.zIndex = zMax - i;
+
+		}
+
+	};
+
 	this.render = function ( scene, camera ) {
 	this.render = function ( scene, camera ) {
 
 
 		scene.updateMatrixWorld();
 		scene.updateMatrixWorld();
@@ -105,6 +166,7 @@ THREE.CSS2DRenderer = function () {
 		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
 		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
 
 
 		renderObject( scene, camera );
 		renderObject( scene, camera );
+		zOrder( scene );
 
 
 	};
 	};
 
 

+ 91 - 26
examples/js/shaders/BokehShader2.js

@@ -26,7 +26,9 @@ THREE.BokehShader = {
 
 
 		"maxblur":  { value: 1.0 },
 		"maxblur":  { value: 1.0 },
 
 
+		"showFocus":   { value: 0 },
 		"manualdof":   { value: 0 },
 		"manualdof":   { value: 0 },
+		"vignetting":   { value: 0 },
 		"depthblur":   { value: 0 },
 		"depthblur":   { value: 0 },
 
 
 		"threshold":  { value: 0.5 },
 		"threshold":  { value: 0.5 },
@@ -75,6 +77,7 @@ THREE.BokehShader = {
 		"uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below",
 		"uniform float focalDepth;  //focal distance value in meters, but you may use autofocus option below",
 		"uniform float focalLength; //focal length in mm",
 		"uniform float focalLength; //focal length in mm",
 		"uniform float fstop; //f-stop value",
 		"uniform float fstop; //f-stop value",
+		"uniform bool showFocus; //show debug focus point and focal range (red = focal point, green = focal range)",
 
 
 		"/*",
 		"/*",
 		"make sure that these two values are the same for your camera, otherwise distances will be wrong.",
 		"make sure that these two values are the same for your camera, otherwise distances will be wrong.",
@@ -99,6 +102,12 @@ THREE.BokehShader = {
 
 
 		"float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)",
 		"float CoC = 0.03; //circle of confusion size in mm (35mm film = 0.03mm)",
 
 
+		"uniform bool vignetting; // use optical lens vignetting",
+
+		"float vignout = 1.3; // vignetting outer border",
+		"float vignin = 0.0; // vignetting inner border",
+		"float vignfade = 22.0; // f-stops till vignete fades",
+
 		"uniform bool shaderFocus;",
 		"uniform bool shaderFocus;",
 		"// disable if you use external focalDepth value",
 		"// disable if you use external focalDepth value",
 
 
@@ -133,22 +142,6 @@ THREE.BokehShader = {
 
 
 		"//------------------------------------------",
 		"//------------------------------------------",
 
 
-		"float getDepth( const in vec2 screenPosition ) {",
-		"	#if DEPTH_PACKING == 1",
-		"	return unpackRGBAToDepth( texture2D( tDepth, screenPosition ) );",
-		"	#else",
-		"	return texture2D( tDepth, screenPosition ).x;",
-		"	#endif",
-		"}",
-
-		"float getViewZ( const in float depth ) {",
-		"	#if PERSPECTIVE_CAMERA == 1",
-		"	return perspectiveDepthToViewZ( depth, znear, zfar );",
-		"	#else",
-		"	return orthographicDepthToViewZ( depth, znear, zfar );",
-		"	#endif",
-		"}",
-
 		"float penta(vec2 coords) {",
 		"float penta(vec2 coords) {",
 			"//pentagonal shape",
 			"//pentagonal shape",
 			"float scale = float(rings) - 1.3;",
 			"float scale = float(rings) - 1.3;",
@@ -210,7 +203,7 @@ THREE.BokehShader = {
 
 
 
 
 			"for( int i=0; i<9; i++ ) {",
 			"for( int i=0; i<9; i++ ) {",
-				"float tmp = getDepth( coords + offset[ i ] );",
+				"float tmp = texture2D(tDepth, coords + offset[i]).r;",
 				"d += tmp * kernel[i];",
 				"d += tmp * kernel[i];",
 			"}",
 			"}",
 
 
@@ -234,6 +227,28 @@ THREE.BokehShader = {
 			"return col+mix(vec3(0.0),col,thresh*blur);",
 			"return col+mix(vec3(0.0),col,thresh*blur);",
 		"}",
 		"}",
 
 
+		"vec3 debugFocus(vec3 col, float blur, float depth) {",
+			"float edge = 0.002*depth; //distance based edge smoothing",
+			"float m = clamp(smoothstep(0.0,edge,blur),0.0,1.0);",
+			"float e = clamp(smoothstep(1.0-edge,1.0,blur),0.0,1.0);",
+
+			"col = mix(col,vec3(1.0,0.5,0.0),(1.0-m)*0.6);",
+			"col = mix(col,vec3(0.0,0.5,1.0),((1.0-e)-(1.0-m))*0.2);",
+
+			"return col;",
+		"}",
+
+		"float linearize(float depth) {",
+			"return -zfar * znear / (depth * (zfar - znear) - zfar);",
+		"}",
+
+
+		"float vignette() {",
+			"float dist = distance(vUv.xy, vec2(0.5,0.5));",
+			"dist = smoothstep(vignout+(fstop/vignfade), vignin+(fstop/vignfade), dist);",
+			"return clamp(dist,0.0,1.0);",
+		"}",
+
 		"float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {",
 		"float gather(float i, float j, int ringsamples, inout vec3 col, float w, float h, float blur) {",
 			"float rings2 = float(rings);",
 			"float rings2 = float(rings);",
 			"float step = PI*2.0 / float(ringsamples);",
 			"float step = PI*2.0 / float(ringsamples);",
@@ -250,20 +265,20 @@ THREE.BokehShader = {
 		"void main() {",
 		"void main() {",
 			"//scene depth calculation",
 			"//scene depth calculation",
 
 
-			"float depth = getViewZ( getDepth( vUv.xy ) );",
+			"float depth = linearize(texture2D(tDepth,vUv.xy).x);",
 
 
 			"// Blur depth?",
 			"// Blur depth?",
-			"if (depthblur) {",
-				"depth = getViewZ(bdepth(vUv.xy));",
+			"if ( depthblur ) {",
+				"depth = linearize(bdepth(vUv.xy));",
 			"}",
 			"}",
 
 
 			"//focal plane calculation",
 			"//focal plane calculation",
 
 
-			"float fDepth = - focalDepth;", // viewZ is negative
+			"float fDepth = focalDepth;",
 
 
 			"if (shaderFocus) {",
 			"if (shaderFocus) {",
 
 
-				"fDepth = getViewZ( getDepth( focusCoords ) );",
+				"fDepth = linearize(texture2D(tDepth,focusCoords).x);",
 
 
 			"}",
 			"}",
 
 
@@ -272,14 +287,14 @@ THREE.BokehShader = {
 			"float blur = 0.0;",
 			"float blur = 0.0;",
 
 
 			"if (manualdof) {",
 			"if (manualdof) {",
-				"float a = depth - fDepth; // Focal plane",
+				"float a = depth-fDepth; // Focal plane",
 				"float b = (a-fdofstart)/fdofdist; // Far DoF",
 				"float b = (a-fdofstart)/fdofdist; // Far DoF",
 				"float c = (-a-ndofstart)/ndofdist; // Near Dof",
 				"float c = (-a-ndofstart)/ndofdist; // Near Dof",
 				"blur = (a>0.0) ? b : c;",
 				"blur = (a>0.0) ? b : c;",
 			"} else {",
 			"} else {",
-				"float f = focalLength;",
-				"float d = fDepth;",
-				"float o = depth;",
+				"float f = focalLength; // focal length in mm",
+				"float d = fDepth*1000.0; // focal plane in mm",
+				"float o = depth*1000.0; // depth in mm",
 
 
 				"float a = (o*f)/(o-f);",
 				"float a = (o*f)/(o-f);",
 				"float b = (d*f)/(d-f);",
 				"float b = (d*f)/(d-f);",
@@ -325,6 +340,14 @@ THREE.BokehShader = {
 				"col /= s; //divide by sample count",
 				"col /= s; //divide by sample count",
 			"}",
 			"}",
 
 
+			"if (showFocus) {",
+				"col = debugFocus(col, blur, depth);",
+			"}",
+
+			"if (vignetting) {",
+				"col *= vignette();",
+			"}",
+
 			"gl_FragColor.rgb = col;",
 			"gl_FragColor.rgb = col;",
 			"gl_FragColor.a = 1.0;",
 			"gl_FragColor.a = 1.0;",
 		"} "
 		"} "
@@ -332,3 +355,45 @@ THREE.BokehShader = {
 	].join( "\n" )
 	].join( "\n" )
 
 
 };
 };
+
+THREE.BokehDepthShader = {
+
+	uniforms: {
+
+		"mNear": { value: 1.0 },
+		"mFar": { value: 1000.0 },
+
+	},
+
+	vertexShader: [
+
+		"varying float vViewZDepth;",
+
+		"void main() {",
+
+		"	#include <begin_vertex>",
+		"	#include <project_vertex>",
+
+		"	vViewZDepth = - mvPosition.z;",
+
+		"}"
+
+	].join( "\n" ),
+
+	fragmentShader: [
+
+		"uniform float mNear;",
+		"uniform float mFar;",
+
+		"varying float vViewZDepth;",
+
+		"void main() {",
+
+		"	float color = 1.0 - smoothstep( mNear, mFar, vViewZDepth );",
+		"	gl_FragColor = vec4( vec3( color ), 1.0 );",
+
+		"} "
+
+	].join( "\n" )
+
+};

+ 5 - 2
examples/js/vr/WebVR.js

@@ -7,7 +7,7 @@
 
 
 var WEBVR = {
 var WEBVR = {
 
 
-	createButton: function ( renderer ) {
+	createButton: function ( renderer, options ) {
 
 
 		function showEnterVR( device ) {
 		function showEnterVR( device ) {
 
 
@@ -38,9 +38,12 @@ var WEBVR = {
 
 
 			function onSessionStarted( session ) {
 			function onSessionStarted( session ) {
 
 
+				if ( options === undefined ) options = {};
+				if ( options.frameOfReferenceType === undefined ) options.frameOfReferenceType = 'stage';
+
 				session.addEventListener( 'end', onSessionEnded );
 				session.addEventListener( 'end', onSessionEnded );
 
 
-				renderer.vr.setSession( session );
+				renderer.vr.setSession( session, options );
 				button.textContent = 'EXIT XR';
 				button.textContent = 'EXIT XR';
 
 
 				currentSession = session;
 				currentSession = session;

+ 193 - 0
examples/misc_exporter_stl.html

@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - exporter - stl</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<style>
+			body {
+				font-family: Monospace;
+				background-color: #000;
+				color: #fff;
+				margin: 0px;
+				overflow: hidden;
+			}
+			#info {
+				color: #fff;
+				position: absolute;
+				top: 10px;
+				width: 100%;
+				text-align: center;
+				display:block;
+			}
+			#info a {
+				color: #046;
+				font-weight: bold;
+			}
+		</style>
+	</head>
+	<body>
+		<div id="info">
+			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - exporter - stl
+		</div>
+
+		<script src="../build/three.js"></script>
+		<script src="js/controls/OrbitControls.js"></script>
+		<script src="js/exporters/STLExporter.js"></script>
+
+		<script src="js/Detector.js"></script>
+		<script src="js/libs/dat.gui.min.js"></script>
+
+		<script>
+
+			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
+
+			var scene, camera, renderer, exporter;
+
+			init();
+			animate();
+
+			function init() {
+
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.set( 200, 100, 200 );
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0xa0a0a0 );
+				scene.fog = new THREE.Fog( 0xa0a0a0, 200, 1000 );
+
+				exporter = new THREE.STLExporter();
+
+				//
+
+				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
+				hemiLight.position.set( 0, 200, 0 );
+				scene.add( hemiLight );
+
+				var directionalLight = new THREE.DirectionalLight( 0xffffff );
+				directionalLight.position.set( 0, 200, 100 );
+				directionalLight.castShadow = true;
+				directionalLight.shadow.camera.top = 180;
+				directionalLight.shadow.camera.bottom = - 100;
+				directionalLight.shadow.camera.left = - 120;
+				directionalLight.shadow.camera.right = 120;
+				scene.add( directionalLight );
+
+				// ground
+
+				var ground = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2000, 2000 ), new THREE.MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
+				ground.rotation.x = - Math.PI / 2;
+				ground.receiveShadow = true;
+				scene.add( ground );
+
+				var grid = new THREE.GridHelper( 2000, 20, 0x000000, 0x000000 );
+				grid.material.opacity = 0.2;
+				grid.material.transparent = true;
+				scene.add( grid );
+
+				// export mesh
+
+				var geometry = new THREE.BoxBufferGeometry( 50, 50, 50 );
+				var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
+
+				mesh = new THREE.Mesh( geometry, material );
+				mesh.castShadow = true;
+				mesh.position.y = 25;
+				scene.add( mesh );
+
+				//
+
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.shadowMap.enabled = true;
+				document.body.appendChild( renderer.domElement );
+
+				//
+
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.target.set( 0, 25, 0 );
+				controls.update();
+
+				//
+
+				var params = {
+					ASCII: function() {
+						exportASCII();
+					},
+					Binary: function() {
+						exportBinary();
+					}
+				}
+
+				var gui = new dat.GUI();
+				var folder = gui.addFolder( 'Export' );
+
+				folder.add( params, 'ASCII' );
+				folder.add( params, 'Binary' );
+				folder.open();
+
+				//
+
+				window.addEventListener( 'resize', onWindowResize, false );
+
+			}
+
+			function onWindowResize() {
+
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+			}
+
+			function animate() {
+
+				requestAnimationFrame( animate );
+				renderer.render( scene, camera );
+
+			}
+
+			function exportASCII() {
+
+				var result = exporter.parse( mesh );
+				saveString( result, 'box.stl' );
+
+			}
+
+			function exportBinary() {
+
+				var result = exporter.parse( mesh, { binary: true } );
+				saveArrayBuffer( result, 'box.stl' );
+
+			}
+
+			var link = document.createElement( 'a' );
+			link.style.display = 'none';
+			document.body.appendChild( link );
+
+			function save( blob, filename ) {
+
+				link.href = URL.createObjectURL( blob );
+				link.download = filename;
+				link.click();
+
+			}
+
+			function saveString( text, filename ) {
+
+				save( new Blob( [ text ], { type: 'text/plain' } ), filename );
+
+			}
+
+			function saveArrayBuffer( buffer, filename ) {
+
+				save( new Blob( [ buffer ], { type: 'application/octet-stream' } ), filename );
+
+			}
+
+		</script>
+
+	</body>
+</html>

+ 0 - 1
examples/webgl_buffergeometry_instancing_lambert.html

@@ -144,7 +144,6 @@
 				#include <envmap_pars_vertex>
 				#include <envmap_pars_vertex>
 				#include <bsdfs>
 				#include <bsdfs>
 				#include <lights_pars_begin>
 				#include <lights_pars_begin>
-				#include <lights_pars_maps>
 				#include <color_pars_vertex>
 				#include <color_pars_vertex>
 				#include <fog_pars_vertex>
 				#include <fog_pars_vertex>
 				#include <morphtarget_pars_vertex>
 				#include <morphtarget_pars_vertex>

+ 2 - 2
examples/webgl_geometry_colors_blender.html → examples/webgl_geometry_colors_json.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
-		<title>three.js webgl - io blender - vertex colors</title>
+		<title>three.js webgl - json - vertex colors</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		<style>
@@ -32,7 +32,7 @@
 	<body>
 	<body>
 
 
 		<div id="container"></div>
 		<div id="container"></div>
-		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - io blender - vertex colors</div>
+		<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - json - vertex colors</div>
 
 
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 

+ 29 - 23
examples/webgl_interactive_voxelpainter.html

@@ -6,17 +6,35 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		<style>
 			body {
 			body {
-				font-family: Monospace;
-				background-color: #f0f0f0;
-				margin: 0px;
-				overflow: hidden;
+				background:#777;
+				padding:0;
+				margin:0;
+				font-weight: bold;
+				overflow:hidden;
 			}
 			}
 
 
-			#oldie { background-color: #ddd !important }
+			#info {
+				position: absolute;
+				top: 0px;
+				width: 100%;
+				padding: 5px;
+				font-family:Monospace;
+				font-size:13px;
+				text-align:center;
+			}
+
+			a {
+				color: #ff0000;
+			}
 		</style>
 		</style>
 	</head>
 	</head>
 	<body>
 	<body>
 
 
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - voxel painter - webgl<br>
+			<strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel
+		</div>
+
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 
 
 		<script src="js/Detector.js"></script>
 		<script src="js/Detector.js"></script>
@@ -25,7 +43,6 @@
 
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
 
-			var container;
 			var camera, scene, renderer;
 			var camera, scene, renderer;
 			var plane, cube;
 			var plane, cube;
 			var mouse, raycaster, isShiftDown = false;
 			var mouse, raycaster, isShiftDown = false;
@@ -40,17 +57,6 @@
 
 
 			function init() {
 			function init() {
 
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
-				var info = document.createElement( 'div' );
-				info.style.position = 'absolute';
-				info.style.top = '10px';
-				info.style.width = '100%';
-				info.style.textAlign = 'center';
-				info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - voxel painter - webgl<br><strong>click</strong>: add voxel, <strong>shift + click</strong>: remove voxel';
-				container.appendChild( info );
-
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
 				camera.position.set( 500, 800, 1300 );
 				camera.position.set( 500, 800, 1300 );
 				camera.lookAt( new THREE.Vector3() );
 				camera.lookAt( new THREE.Vector3() );
@@ -60,15 +66,15 @@
 
 
 				// roll-over helpers
 				// roll-over helpers
 
 
-				var rollOverGeo = new THREE.BoxGeometry( 50, 50, 50 );
+				var rollOverGeo = new THREE.BoxBufferGeometry( 50, 50, 50 );
 				rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
 				rollOverMaterial = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.5, transparent: true } );
 				rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
 				rollOverMesh = new THREE.Mesh( rollOverGeo, rollOverMaterial );
 				scene.add( rollOverMesh );
 				scene.add( rollOverMesh );
 
 
 				// cubes
 				// cubes
 
 
-				cubeGeo = new THREE.BoxGeometry( 50, 50, 50 );
-				cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( "textures/square-outline-textured.png" ) } );
+				cubeGeo = new THREE.BoxBufferGeometry( 50, 50, 50 );
+				cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xfeb74c, map: new THREE.TextureLoader().load( 'textures/square-outline-textured.png' ) } );
 
 
 				// grid
 				// grid
 
 
@@ -88,7 +94,7 @@
 
 
 				objects.push( plane );
 				objects.push( plane );
 
 
-				// Lights
+				// lights
 
 
 				var ambientLight = new THREE.AmbientLight( 0x606060 );
 				var ambientLight = new THREE.AmbientLight( 0x606060 );
 				scene.add( ambientLight );
 				scene.add( ambientLight );
@@ -100,7 +106,7 @@
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				document.body.appendChild( renderer.domElement );
 
 
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
 				document.addEventListener( 'mousedown', onDocumentMouseDown, false );
@@ -163,7 +169,7 @@
 
 
 					if ( isShiftDown ) {
 					if ( isShiftDown ) {
 
 
-						if ( intersect.object != plane ) {
+						if ( intersect.object !== plane ) {
 
 
 							scene.remove( intersect.object );
 							scene.remove( intersect.object );
 
 

+ 1 - 1
examples/webgl_loader_json_blender.html → examples/webgl_loader_json.html

@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html lang="en">
 <html lang="en">
 	<head>
 	<head>
-		<title>three.js webgl - blender -json</title>
+		<title>three.js webgl - loader -json</title>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 		<style>

+ 12 - 8
examples/webgl_loader_mmd.html

@@ -82,14 +82,14 @@
 				scene.background = new THREE.Color( 0xffffff );
 				scene.background = new THREE.Color( 0xffffff );
 
 
 				var gridHelper = new THREE.PolarGridHelper( 30, 10 );
 				var gridHelper = new THREE.PolarGridHelper( 30, 10 );
-				gridHelper.position.y = -10;
+				gridHelper.position.y = - 10;
 				scene.add( gridHelper );
 				scene.add( gridHelper );
 
 
 				var ambient = new THREE.AmbientLight( 0x666666 );
 				var ambient = new THREE.AmbientLight( 0x666666 );
 				scene.add( ambient );
 				scene.add( ambient );
 
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 				scene.add( directionalLight );
 
 
 				//
 				//
@@ -108,14 +108,18 @@
 
 
 				// model
 				// model
 
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
 					}
+
 				};
 				};
 
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 				};
 
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
@@ -130,7 +134,7 @@
 				loader.loadWithAnimation( modelFile, vmdFiles, function ( mmd ) {
 				loader.loadWithAnimation( modelFile, vmdFiles, function ( mmd ) {
 
 
 					mesh = mmd.mesh;
 					mesh = mmd.mesh;
-					mesh.position.y = -10;
+					mesh.position.y = - 10;
 					scene.add( mesh );
 					scene.add( mesh );
 
 
 					helper.add( mesh, {
 					helper.add( mesh, {
@@ -157,7 +161,7 @@
 				var phongMaterials;
 				var phongMaterials;
 				var originalMaterials;
 				var originalMaterials;
 
 
-				function makePhongMaterials ( materials ) {
+				function makePhongMaterials( materials ) {
 
 
 					var array = [];
 					var array = [];
 
 
@@ -175,7 +179,7 @@
 
 
 				}
 				}
 
 
-				function initGui () {
+				function initGui() {
 
 
 					var api = {
 					var api = {
 						'animation': true,
 						'animation': true,

+ 8 - 4
examples/webgl_loader_mmd_audio.html

@@ -87,7 +87,7 @@
 				scene.add( ambient );
 				scene.add( ambient );
 
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 				scene.add( directionalLight );
 
 
 				//
 				//
@@ -101,14 +101,18 @@
 
 
 				// model
 				// model
 
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
 					}
+
 				};
 				};
 
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 				};
 
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';

+ 23 - 18
examples/webgl_loader_mmd_pose.html

@@ -80,7 +80,7 @@
 				scene.add( ambient );
 				scene.add( ambient );
 
 
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
 				var directionalLight = new THREE.DirectionalLight( 0x887766 );
-				directionalLight.position.set( -1, 1, 1 ).normalize();
+				directionalLight.position.set( - 1, 1, 1 ).normalize();
 				scene.add( directionalLight );
 				scene.add( directionalLight );
 
 
 				//
 				//
@@ -94,14 +94,18 @@
 
 
 				// model
 				// model
 
 
-				var onProgress = function ( xhr ) {
+				function onProgress( xhr ) {
+
 					if ( xhr.lengthComputable ) {
 					if ( xhr.lengthComputable ) {
+
 						var percentComplete = xhr.loaded / xhr.total * 100;
 						var percentComplete = xhr.loaded / xhr.total * 100;
-						console.log( Math.round(percentComplete, 2) + '% downloaded' );
+						console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
+
 					}
 					}
+
 				};
 				};
 
 
-				var onError = function ( xhr ) {
+				function onError( xhr ) {
 				};
 				};
 
 
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
 				var modelFile = 'models/mmd/miku/miku_v2.pmd';
@@ -126,13 +130,13 @@
 				loader.load( modelFile, function ( object ) {
 				loader.load( modelFile, function ( object ) {
 
 
 					mesh = object;
 					mesh = object;
-					mesh.position.y = -10;
+					mesh.position.y = - 10;
 
 
 					scene.add( mesh );
 					scene.add( mesh );
 
 
 					var vpdIndex = 0;
 					var vpdIndex = 0;
 
 
-					function loadVpd () {
+					function loadVpd() {
 
 
 						var vpdFile = vpdFiles[ vpdIndex ];
 						var vpdFile = vpdFiles[ vpdIndex ];
 
 
@@ -140,7 +144,7 @@
 
 
 							vpds.push( vpd );
 							vpds.push( vpd );
 
 
-							vpdIndex++;
+							vpdIndex ++;
 
 
 							if ( vpdIndex < vpdFiles.length ) {
 							if ( vpdIndex < vpdFiles.length ) {
 
 
@@ -155,6 +159,7 @@
 						}, onProgress, onError );
 						}, onProgress, onError );
 
 
 					}
 					}
+
 					loadVpd();
 					loadVpd();
 
 
 				}, onProgress, onError );
 				}, onProgress, onError );
@@ -163,7 +168,7 @@
 
 
 				window.addEventListener( 'resize', onWindowResize, false );
 				window.addEventListener( 'resize', onWindowResize, false );
 
 
-				function initGui () {
+				function initGui() {
 
 
 					var gui = new dat.GUI();
 					var gui = new dat.GUI();
 
 
@@ -175,13 +180,13 @@
 					var poses = gui.addFolder( 'Poses' );
 					var poses = gui.addFolder( 'Poses' );
 					var morphs = gui.addFolder( 'Morphs' );
 					var morphs = gui.addFolder( 'Morphs' );
 
 
-					function getBaseName ( s ) {
+					function getBaseName( s ) {
 
 
 						return s.slice( s.lastIndexOf( '/' ) + 1 );
 						return s.slice( s.lastIndexOf( '/' ) + 1 );
 
 
 					}
 					}
 
 
-					function initControls () {
+					function initControls() {
 
 
 						for ( var key in dictionary ) {
 						for ( var key in dictionary ) {
 
 
@@ -189,7 +194,7 @@
 
 
 						}
 						}
 
 
-						controls.pose = -1;
+						controls.pose = - 1;
 
 
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 
 
@@ -199,7 +204,7 @@
 
 
 					}
 					}
 
 
-					function initKeys () {
+					function initKeys() {
 
 
 						for ( var key in dictionary ) {
 						for ( var key in dictionary ) {
 
 
@@ -209,9 +214,9 @@
 
 
 					}
 					}
 
 
-					function initPoses () {
+					function initPoses() {
 
 
-						var files = { default: -1 };
+						var files = { default: - 1 };
 
 
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 						for ( var i = 0; i < vpdFiles.length; i++ ) {
 
 
@@ -223,7 +228,7 @@
 
 
 					}
 					}
 
 
-					function initMorphs () {
+					function initMorphs() {
 
 
 						for ( var key in dictionary ) {
 						for ( var key in dictionary ) {
 
 
@@ -233,7 +238,7 @@
 
 
 					}
 					}
 
 
-					function onChangeMorph () {
+					function onChangeMorph() {
 
 
 						for ( var i = 0; i < keys.length; i++ ) {
 						for ( var i = 0; i < keys.length; i++ ) {
 
 
@@ -245,11 +250,11 @@
 
 
 					}
 					}
 
 
-					function onChangePose () {
+					function onChangePose() {
 
 
 						var index = parseInt( controls.pose );
 						var index = parseInt( controls.pose );
 
 
-						if ( index === -1 ) {
+						if ( index === - 1 ) {
 
 
 							mesh.pose();
 							mesh.pose();
 
 

+ 16 - 18
examples/webgl_loader_x.html

@@ -23,22 +23,22 @@
         a {
         a {
             color: #ff0000
             color: #ff0000
         }
         }
-        
-        #info2 { 
-            color: #fff; 
-            background-color: #000; 
-            position: absolute; 
-            top: 3em; 
-            right : 0px; 
-            width: 10em; 
-            z-index: 200; 
-            display: block;  
+
+        #info2 {
+            color: #fff;
+            background-color: #000;
+            position: absolute;
+            top: 3em;
+            right : 0px;
+            width: 10em;
+            z-index: 200;
+            display: block;
         }
         }
-    
-        td { 
+
+        td {
             padding: 0.5em;
             padding: 0.5em;
         }
         }
-        
+
     </style>
     </style>
 </head>
 </head>
 <body>
 <body>
@@ -71,7 +71,7 @@
 	<script src='js/Detector.js'></script>
 	<script src='js/Detector.js'></script>
 	<script src='js/libs/stats.min.js'></script>
 	<script src='js/libs/stats.min.js'></script>
 	<script src='js/libs/dat.gui.min.js'></script>
 	<script src='js/libs/dat.gui.min.js'></script>
-    
+
     <script>
     <script>
 
 
         if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
         if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
@@ -81,7 +81,6 @@
         var clock = new THREE.Clock();
         var clock = new THREE.Clock();
         var mixers = [];
         var mixers = [];
         var manager = null;
         var manager = null;
-        var Texloader = null;
 
 
         var skeletonHelper = null;
         var skeletonHelper = null;
         var animates = [];
         var animates = [];
@@ -156,8 +155,7 @@
 
 
             };
             };
 
 
-            Texloader = new THREE.TextureLoader();
-            var loader = new THREE.XLoader( manager, Texloader );
+            var loader = new THREE.XLoader( manager );
 
 
             actions[ 0 ] = {};
             actions[ 0 ] = {};
 
 
@@ -244,7 +242,7 @@
 
 
             } else {
             } else {
 
 
-                var loader2 = new THREE.XLoader( manager, Texloader );
+                var loader2 = new THREE.XLoader( manager );
                 loader2.load( [ 'models/xfile/' + animeName + '.x', { putPos: false, putScl: false } ], function () {
                 loader2.load( [ 'models/xfile/' + animeName + '.x', { putPos: false, putScl: false } ], function () {
 
 
                     // !! important!
                     // !! important!

+ 44 - 88
examples/webgl_modifier_simplifier.html

@@ -7,10 +7,13 @@
 		<style>
 		<style>
 			body {
 			body {
 				font-family: Monospace;
 				font-family: Monospace;
-				background-color: #f0f0f0;
+				color: #fff;
 				margin: 0px;
 				margin: 0px;
 				overflow: hidden;
 				overflow: hidden;
 			}
 			}
+			a {
+				color: #ffffff;
+			}
 		</style>
 		</style>
 	</head>
 	</head>
 	<body>
 	<body>
@@ -18,127 +21,80 @@
 		<script src="../build/three.js"></script>
 		<script src="../build/three.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/controls/OrbitControls.js"></script>
 		<script src="js/modifiers/SimplifyModifier.js"></script>
 		<script src="js/modifiers/SimplifyModifier.js"></script>
-		<script src="js/libs/stats.min.js"></script>
 
 
 		<script>
 		<script>
 
 
-			var container, stats;
-
-			var camera, controls, scene, renderer;
-
-			var boxGeometry = new THREE.BoxGeometry( 80, 80, 80, 4, 4, 4 );
-			var torusGeometry = new THREE.TorusGeometry( 50, 25, 8, 8, Math.PI * 2 );
-			var sphereGeometry = new THREE.SphereGeometry( 50, 15, 15 );
-			var planeGeometry = new THREE.PlaneGeometry( 100, 100, 6, 6 );
-
-			var modifer = new THREE.SimplifyModifier();
-			var meshes = [];
-			var count = 0;
-
-			var wireframeMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } );
+			var renderer, scene, camera;
 
 
 			init();
 			init();
-			animate();
-
-
-			function addStuff( geometry ) {
-
-				count ++;
-
-				var mesh, wireframe;
-
-				var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff } );
-
-				var simplified = modifer.modify( geometry, geometry.vertices.length * 0.5 | 0 );
-
-				mesh = new THREE.Mesh( simplified, material );
-				wireframe = new THREE.Mesh( simplified, wireframeMaterial );
-				mesh.add( wireframe );
-				mesh.position.x = - 200;
-				mesh.position.y = count * 150 - 300;
-
-				scene.add( mesh );
-				meshes.push( mesh );
-
-				mesh = new THREE.Mesh( geometry, material );
-				wireframe = new THREE.Mesh( geometry, wireframeMaterial );
-				mesh.add( wireframe );
-				mesh.position.x = 200;
-				mesh.position.y = count * 150 - 300;
-
-				scene.add( mesh );
-				meshes.push ( mesh );
-
-			}
 
 
 			function init() {
 			function init() {
 
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
-
 				var info = document.createElement( 'div' );
 				var info = document.createElement( 'div' );
 				info.style.position = 'absolute';
 				info.style.position = 'absolute';
 				info.style.top = '10px';
 				info.style.top = '10px';
 				info.style.width = '100%';
 				info.style.width = '100%';
 				info.style.textAlign = 'center';
 				info.style.textAlign = 'center';
-				info.innerHTML = '50% Vertex Reduction using SimplifyModifier';
-				container.appendChild( info );
+				info.innerHTML = '<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Vertex Reduction using SimplifyModifier';
+				document.body.appendChild( info );
 
 
-				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
-				camera.position.z = 500;
+				renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				document.body.appendChild( renderer.domElement );
 
 
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
-				scene.background = new THREE.Color( 0xf0f0f0 );
 
 
-				var light = new THREE.PointLight( 0xffffff, 1.5 );
-				light.position.set( 1000, 1000, 2000 );
-				scene.add( light );
+				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
+				camera.position.z = 15;
 
 
-				addStuff( planeGeometry );
-				addStuff( boxGeometry );
-				addStuff( sphereGeometry );
-				addStuff( torusGeometry );
+				var controls = new THREE.OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render ); // use if there is no animation loop
+				controls.enablePan = false;
+				controls.enableZoom = false;
 
 
-				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				container.appendChild( renderer.domElement );
+				scene.add( new THREE.AmbientLight( 0xffffff, 0.2 ) );
 
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+				var light = new THREE.PointLight( 0xffffff, 0.7 );
+				camera.add( light );
+				scene.add( camera );
 
 
-				//
+				new THREE.JSONLoader().load( "models/json/leeperrysmith/LeePerrySmith.json", function ( geometry ) {
 
 
-				controls = new THREE.OrbitControls( camera, renderer.domElement );
+					var material = new THREE.MeshPhongMaterial( { color: 0xAEAED5, shininess: 1 } );
 
 
-				window.addEventListener( 'resize', onWindowResize, false );
+					var mesh = new THREE.Mesh( geometry, material );
+					mesh.position.x = - 3;
+					mesh.rotation.y = Math.PI / 2;
+					scene.add( mesh );
 
 
-			}
+					var modifer = new THREE.SimplifyModifier();
 
 
-			function onWindowResize() {
+					var simplified = modifer.modify( geometry, Math.floor( geometry.vertices.length * 0.9375 ) ); // number of vertices to remove
 
 
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+					var material = new THREE.MeshPhongMaterial( { color: 0xAEAED5, shininess: 1, flatShading: true } );
 
 
-				renderer.setSize( window.innerWidth, window.innerHeight );
+					var mesh = new THREE.Mesh( simplified, material );
+					mesh.position.x = 3;
+					mesh.rotation.y = - Math.PI / 2;
+					scene.add( mesh );
 
 
-			}
+					render();
 
 
-			//
+				} );
 
 
-			function animate() {
+				window.addEventListener( 'resize', onWindowResize, false );
 
 
-				meshes.forEach( function( m ) {
-					m.rotation.x += 0.01;
-					m.rotation.y += 0.01;
-					m.rotation.z += 0.01;
-				} );
+			}
+
+			function onWindowResize() {
+
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 
-				requestAnimationFrame( animate );
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
 
 
-				stats.begin();
 				render();
 				render();
-				stats.end();
 
 
 			}
 			}
 
 

+ 71 - 13
examples/webgl_postprocessing_dof2.html

@@ -96,9 +96,16 @@ Use WEBGL Depth buffer support?
 				renderer.autoClear = false;
 				renderer.autoClear = false;
 				container.appendChild( renderer.domElement );
 				container.appendChild( renderer.domElement );
 
 
-				materialDepth = new THREE.MeshDepthMaterial();
-				materialDepth.depthPacking = THREE.RGBADepthPacking;
-				materialDepth.blending = THREE.NoBlending;
+				var depthShader = THREE.BokehDepthShader;
+
+				materialDepth = new THREE.ShaderMaterial( {
+					uniforms: depthShader.uniforms,
+					vertexShader: depthShader.vertexShader,
+					fragmentShader: depthShader.fragmentShader
+				} );
+
+				materialDepth.uniforms[ 'mNear' ].value = camera.near;
+				materialDepth.uniforms[ 'mFar' ].value = camera.far;
 
 
 				// skybox
 				// skybox
 
 
@@ -110,7 +117,21 @@ Use WEBGL Depth buffer support?
 				var textureCube = new THREE.CubeTextureLoader().load( urls );
 				var textureCube = new THREE.CubeTextureLoader().load( urls );
 				textureCube.format = THREE.RGBFormat;
 				textureCube.format = THREE.RGBFormat;
 
 
-				scene.background = textureCube;
+				var shader = THREE.ShaderLib[ 'cube' ];
+				shader.uniforms[ 'tCube' ].value = textureCube;
+
+				material = new THREE.ShaderMaterial( {
+
+					fragmentShader: shader.fragmentShader,
+					vertexShader: shader.vertexShader,
+					uniforms: shader.uniforms,
+					depthWrite: false,
+					side: THREE.BackSide
+
+				} );
+
+				mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1000, 1000, 1000 ), material );
+				scene.add( mesh );
 
 
 				// plane particles
 				// plane particles
 
 
@@ -226,11 +247,13 @@ Use WEBGL Depth buffer support?
 					jsDepthCalculation: true,
 					jsDepthCalculation: true,
 					shaderFocus: false,
 					shaderFocus: false,
 
 
-					fstop: 10,
+					fstop: 2.2,
 					maxblur: 1.0,
 					maxblur: 1.0,
 
 
+					showFocus: false,
 					focalDepth: 2.8,
 					focalDepth: 2.8,
 					manualdof: false,
 					manualdof: false,
+					vignetting: false,
 					depthblur: false,
 					depthblur: false,
 
 
 					threshold: 0.5,
 					threshold: 0.5,
@@ -272,10 +295,13 @@ Use WEBGL Depth buffer support?
 				gui.add( effectController, 'shaderFocus' ).onChange( matChanger );
 				gui.add( effectController, 'shaderFocus' ).onChange( matChanger );
 				gui.add( effectController, 'focalDepth', 0.0, 200.0 ).listen().onChange( matChanger );
 				gui.add( effectController, 'focalDepth', 0.0, 200.0 ).listen().onChange( matChanger );
 
 
-				gui.add( effectController, 'fstop', 1, 50, 0.1 ).onChange( matChanger );
+				gui.add( effectController, 'fstop', 0.1, 22, 0.001 ).onChange( matChanger );
 				gui.add( effectController, 'maxblur', 0.0, 5.0, 0.025 ).onChange( matChanger );
 				gui.add( effectController, 'maxblur', 0.0, 5.0, 0.025 ).onChange( matChanger );
 
 
+				gui.add( effectController, 'showFocus' ).onChange( matChanger );
 				gui.add( effectController, 'manualdof' ).onChange( matChanger );
 				gui.add( effectController, 'manualdof' ).onChange( matChanger );
+				gui.add( effectController, 'vignetting' ).onChange( matChanger );
+
 				gui.add( effectController, 'depthblur' ).onChange( matChanger );
 				gui.add( effectController, 'depthblur' ).onChange( matChanger );
 
 
 				gui.add( effectController, 'threshold', 0, 1, 0.001 ).onChange( matChanger );
 				gui.add( effectController, 'threshold', 0, 1, 0.001 ).onChange( matChanger );
@@ -284,8 +310,11 @@ Use WEBGL Depth buffer support?
 				gui.add( effectController, 'fringe', 0, 5, 0.001 ).onChange( matChanger );
 				gui.add( effectController, 'fringe', 0, 5, 0.001 ).onChange( matChanger );
 
 
 				gui.add( effectController, 'focalLength', 16, 80, 0.001 ).onChange( matChanger );
 				gui.add( effectController, 'focalLength', 16, 80, 0.001 ).onChange( matChanger );
+
 				gui.add( effectController, 'noise' ).onChange( matChanger );
 				gui.add( effectController, 'noise' ).onChange( matChanger );
+
 				gui.add( effectController, 'dithering', 0, 0.001, 0.0001 ).onChange( matChanger );
 				gui.add( effectController, 'dithering', 0, 0.001, 0.0001 ).onChange( matChanger );
+
 				gui.add( effectController, 'pentagon' ).onChange( matChanger );
 				gui.add( effectController, 'pentagon' ).onChange( matChanger );
 
 
 				gui.add( shaderSettings, 'rings', 1, 8).step(1).onChange( shaderUpdate );
 				gui.add( shaderSettings, 'rings', 1, 8).step(1).onChange( shaderUpdate );
@@ -369,9 +398,7 @@ Use WEBGL Depth buffer support?
 					fragmentShader: bokeh_shader.fragmentShader,
 					fragmentShader: bokeh_shader.fragmentShader,
 					defines: {
 					defines: {
 						RINGS: shaderSettings.rings,
 						RINGS: shaderSettings.rings,
-						SAMPLES: shaderSettings.samples,
-						DEPTH_PACKING: 1, // RGBADepth
-						PERSPECTIVE_CAMERA: 1
+						SAMPLES: shaderSettings.samples
 					}
 					}
 
 
 				} );
 				} );
@@ -399,6 +426,28 @@ Use WEBGL Depth buffer support?
 
 
 			}
 			}
 
 
+			function linearize( depth ) {
+
+				var zfar = camera.far;
+				var znear = camera.near;
+				return - zfar * znear / ( depth * ( zfar - znear ) - zfar );
+
+			}
+
+
+			function smoothstep( near, far, depth ) {
+
+				var x = saturate( ( depth - near ) / ( far - near ) );
+				return x * x * ( 3 - 2 * x );
+
+			}
+
+			function saturate( x ) {
+
+				return Math.max( 0, Math.min( 1, x ) );
+
+			}
+
 			function render() {
 			function render() {
 
 
 				var time = Date.now() * 0.00015;
 				var time = Date.now() * 0.00015;
@@ -417,13 +466,22 @@ Use WEBGL Depth buffer support?
 
 
 					var intersects = raycaster.intersectObjects( scene.children, true );
 					var intersects = raycaster.intersectObjects( scene.children, true );
 
 
-					var targetDistance = ( intersects.length > 0 ) ? intersects[ 0 ].distance : 1000;
 
 
-					distance += ( targetDistance - distance ) * 0.05;
+					if ( intersects.length > 0 ) {
+
+						var targetDistance = intersects[ 0 ].distance;
+
+						distance += (targetDistance - distance) * 0.03;
+
+						var sdistance = smoothstep(camera.near, camera.far, distance);
 
 
-					postprocessing.bokeh_uniforms[ 'focalDepth' ].value = distance;
+						var ldistance = linearize(1 -  sdistance);
 
 
-					effectController[ 'focalDepth' ] = distance;
+						postprocessing.bokeh_uniforms[ 'focalDepth' ].value = ldistance;
+
+						effectController['focalDepth'] = ldistance;
+
+					}
 
 
 				}
 				}
 
 

+ 0 - 1
examples/webgl_shaders_tonemapping.html

@@ -161,7 +161,6 @@
 						THREE.ShaderChunk[ "common" ],
 						THREE.ShaderChunk[ "common" ],
 						THREE.ShaderChunk[ "bsdfs" ],
 						THREE.ShaderChunk[ "bsdfs" ],
 						THREE.ShaderChunk[ "lights_pars_begin" ],
 						THREE.ShaderChunk[ "lights_pars_begin" ],
-						THREE.ShaderChunk[ "lights_pars_maps" ],
 						THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 						THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
 
 
 						"void main() {",
 						"void main() {",

+ 2 - 2
examples/webvr_cubes.html

@@ -5,7 +5,7 @@
 		<meta charset="utf-8">
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-06-19 -->
 		<!-- Origin Trial Token, feature = WebVR (For Chrome M62+), origin = https://threejs.org, expires = 2018-06-19 -->
-		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-06-19" content="Alxt96tYGgIr9l6EXU0eeI360zcmzOY6Kuo3kcTfBGIRDOQbgFIZKRQ1joExQ74WZr1einsE+cUMHgSclNHCQQ4AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUyOTM5NzgyOH0="> 
+		<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M62+)" data-expires="2018-06-19" content="Alxt96tYGgIr9l6EXU0eeI360zcmzOY6Kuo3kcTfBGIRDOQbgFIZKRQ1joExQ74WZr1einsE+cUMHgSclNHCQQ4AAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMU02MiIsImV4cGlyeSI6MTUyOTM5NzgyOH0=">
 		<!-- Origin Trial Token, feature = WebXR Device API, origin = https://threejs.org, expires = 2018-06-15 -->
 		<!-- Origin Trial Token, feature = WebXR Device API, origin = https://threejs.org, expires = 2018-06-15 -->
 		<meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-06-15" content="AtJH9g6nn0B87bnjJt+9m1joZXEYDmLSlRvtMr5qJD52hMcm3S86S7jg5I7y2I5cgQglE0rzsXzti5DECQLb8QkAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUyOTA4NDY2OH0=">
 		<meta http-equiv="origin-trial" data-feature="WebXR Device API" data-expires="2018-06-15" content="AtJH9g6nn0B87bnjJt+9m1joZXEYDmLSlRvtMr5qJD52hMcm3S86S7jg5I7y2I5cgQglE0rzsXzti5DECQLb8QkAAABQeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZSIsImV4cGlyeSI6MTUyOTA4NDY2OH0=">
 		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-06-15 -->
 		<!-- Origin Trial Token, feature = WebXR Gamepad Support, origin = https://threejs.org, expires = 2018-06-15 -->
@@ -180,7 +180,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_daydream.html

@@ -140,7 +140,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_gearvr.html

@@ -165,7 +165,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 5 - 8
examples/webvr_panorama.html

@@ -43,7 +43,7 @@
 			renderer.vr.userHeight = 0; // TOFIX
 			renderer.vr.userHeight = 0; // TOFIX
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
-			document.body.appendChild( WEBVR.createButton( renderer ) );
+			document.body.appendChild( WEBVR.createButton( renderer, { frameOfReferenceType: 'headModel' } ) );
 
 
 			//
 			//
 
 
@@ -95,9 +95,8 @@
 
 
 			}
 			}
 
 
-			var imageObj = new Image();
-
-			imageObj.onload = function() {
+			var loader = new THREE.ImageLoader();
+			loader.load( atlasImgUrl, function ( imageObj ) {
 
 
 				var canvas, context;
 				var canvas, context;
 				var tileWidth = imageObj.height;
 				var tileWidth = imageObj.height;
@@ -114,9 +113,7 @@
 
 
 				}
 				}
 
 
-			};
-
-			imageObj.src = atlasImgUrl;
+			} );
 
 
 			return textures;
 			return textures;
 
 
@@ -133,7 +130,7 @@
 
 
 		function animate() {
 		function animate() {
 
 
-			renderer.animate( render );
+			renderer.setAnimationLoop( render );
 
 
 		}
 		}
 
 

+ 2 - 2
examples/webvr_rollercoaster.html

@@ -40,7 +40,7 @@
 			renderer.vr.userHeight = 0; // TOFIX
 			renderer.vr.userHeight = 0; // TOFIX
 			document.body.appendChild( renderer.domElement );
 			document.body.appendChild( renderer.domElement );
 
 
-			document.body.appendChild( WEBVR.createButton( renderer ) );
+			document.body.appendChild( WEBVR.createButton( renderer, { frameOfReferenceType: 'eyeLevel' } ) );
 
 
 			//
 			//
 
 
@@ -247,7 +247,7 @@
 
 
 			}
 			}
 
 
-			renderer.animate( render );
+			renderer.setAnimationLoop( render );
 
 
 		</script>
 		</script>
 
 

+ 2 - 2
examples/webvr_sandbox.html

@@ -125,7 +125,7 @@
 				//
 				//
 
 
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
 				renderer = new THREE.WebGLRenderer( { antialias: true } );
-				renderer.setClearColor( 0x000000 );
+				renderer.autoClear = false;
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.shadowMap.enabled = true;
 				renderer.shadowMap.enabled = true;
@@ -151,7 +151,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_video.html

@@ -159,7 +159,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_vive.html

@@ -204,7 +204,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_vive_dragging.html

@@ -293,7 +293,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_vive_paint.html

@@ -417,7 +417,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 1 - 1
examples/webvr_vive_sculpt.html

@@ -216,7 +216,7 @@
 
 
 			function animate() {
 			function animate() {
 
 
-				renderer.animate( render );
+				renderer.setAnimationLoop( render );
 
 
 			}
 			}
 
 

+ 5250 - 0
package-lock.json

@@ -0,0 +1,5250 @@
+{
+  "name": "three",
+  "version": "0.92.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@types/estree": {
+      "version": "0.0.39",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+      "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "8.10.17",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.17.tgz",
+      "integrity": "sha1-1IzxDw3G3PWfgn9aP8ekpgBDGNM=",
+      "dev": true
+    },
+    "@zeit/schemas": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-1.1.2.tgz",
+      "integrity": "sha512-1KCchM412X/6h1b5XAU3CUe2Teu7duHa6ECkQVa27PmD4UWzciB3oAlElDv4uqAKJFfwprG1eeqwjtmGIQcJcg==",
+      "dev": true
+    },
+    "acorn": {
+      "version": "5.5.3",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+      "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
+      "dev": true
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+      "dev": true,
+      "requires": {
+        "acorn": "3.3.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+          "dev": true
+        }
+      }
+    },
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "dev": true,
+      "requires": {
+        "co": "4.6.0",
+        "fast-deep-equal": "1.0.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
+      }
+    },
+    "ajv-keywords": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+      "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=",
+      "dev": true,
+      "requires": {
+        "micromatch": "2.3.11",
+        "normalize-path": "2.1.1"
+      }
+    },
+    "arg": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz",
+      "integrity": "sha1-wG5/9pqwWzpKA+vgQH+sTLpldUU=",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "arr-diff": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "1.1.0"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+      "dev": true
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+      "dev": true
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
+      "integrity": "sha1-1NDpudv8p3vwjusKikcVUP454ok=",
+      "dev": true
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "balanced-match": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+      "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "1.0.1",
+        "class-utils": "0.3.6",
+        "component-emitter": "1.2.1",
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "mixin-deep": "1.3.1",
+        "pascalcase": "0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "binary-extensions": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.9.0.tgz",
+      "integrity": "sha1-ZlBsFs5vTWkopbPNajPKQelB43s=",
+      "dev": true
+    },
+    "brace-expansion": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz",
+      "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=",
+      "dev": true,
+      "requires": {
+        "balanced-match": "0.4.2",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+      "dev": true,
+      "requires": {
+        "expand-range": "1.8.2",
+        "preserve": "0.2.0",
+        "repeat-element": "1.1.2"
+      }
+    },
+    "buffer-from": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
+      "integrity": "sha1-h/yqOimDWOCt5uRCz86EB0DRrQQ=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "dev": true
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "1.0.0",
+        "component-emitter": "1.2.1",
+        "get-value": "2.0.6",
+        "has-value": "1.0.0",
+        "isobject": "3.0.1",
+        "set-value": "2.0.0",
+        "to-object-path": "0.3.0",
+        "union-value": "1.0.0",
+        "unset-value": "1.0.0"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+      "dev": true
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "dev": true,
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "chokidar": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+      "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+      "dev": true,
+      "requires": {
+        "anymatch": "1.3.2",
+        "async-each": "1.0.1",
+        "fsevents": "1.2.4",
+        "glob-parent": "2.0.0",
+        "inherits": "2.0.3",
+        "is-binary-path": "1.0.1",
+        "is-glob": "2.0.1",
+        "path-is-absolute": "1.0.1",
+        "readdirp": "2.1.0"
+      }
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "define-property": "0.2.5",
+        "isobject": "3.0.1",
+        "static-extend": "0.1.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "clone": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+      "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
+      "dev": true
+    },
+    "clone-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+      "dev": true
+    },
+    "clone-stats": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+      "dev": true
+    },
+    "cloneable-readable": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
+      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "process-nextick-args": "2.0.0",
+        "readable-stream": "2.3.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "1.0.0",
+        "object-visit": "1.0.1"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
+      "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+      "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
+      "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "1.1.0",
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.6",
+        "typedarray": "0.0.6"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "concurrently": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-3.5.1.tgz",
+      "integrity": "sha1-7otgAYu+hrAt8T5SSUU8bs7NJSE=",
+      "dev": true,
+      "requires": {
+        "chalk": "0.5.1",
+        "commander": "2.6.0",
+        "date-fns": "1.29.0",
+        "lodash": "4.17.4",
+        "rx": "2.3.24",
+        "spawn-command": "0.0.2-1",
+        "supports-color": "3.2.3",
+        "tree-kill": "1.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+          "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+          "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+          "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "1.1.0",
+            "escape-string-regexp": "1.0.5",
+            "has-ansi": "0.1.0",
+            "strip-ansi": "0.3.0",
+            "supports-color": "0.2.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "0.2.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+              "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+              "dev": true
+            }
+          }
+        },
+        "has-ansi": {
+          "version": "0.1.0",
+          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+          "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "0.2.1"
+          }
+        },
+        "has-flag": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.4",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+          "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+          "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "0.2.1"
+          }
+        },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "1.0.0"
+          }
+        }
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+      "dev": true
+    },
+    "cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.3",
+        "shebang-command": "1.2.0",
+        "which": "1.3.1"
+      }
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "dev": true,
+      "requires": {
+        "array-find-index": "1.0.2"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "date-fns": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
+      "integrity": "sha1-EuYJzcuTUScxHQTTMzTilgoqVOY=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.8",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+      "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "dev": true
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha1-xPp8lUBKF6nD6Mp+FTcxK3NjMKw=",
+      "dev": true
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "1.0.2",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.1",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "rimraf": "2.5.4"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "electron": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-2.0.2.tgz",
+      "integrity": "sha1-t34F+DQZzF7JIaLSHzW1Xkv8PWg=",
+      "dev": true,
+      "requires": {
+        "@types/node": "8.10.17",
+        "electron-download": "3.3.0",
+        "extract-zip": "1.6.7"
+      }
+    },
+    "electron-download": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz",
+      "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "fs-extra": "0.30.0",
+        "home-path": "1.0.6",
+        "minimist": "1.2.0",
+        "nugget": "2.0.1",
+        "path-exists": "2.1.0",
+        "rc": "1.2.8",
+        "semver": "5.4.1",
+        "sumchecker": "1.3.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "ensure-posix-path": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.0.2.tgz",
+      "integrity": "sha1-pls+QtC3HPxYXrd0+ZQ8jZuRsMI=",
+      "dev": true
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es6-promise": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+      "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint": {
+      "version": "4.19.1",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.4.1",
+        "concat-stream": "1.6.2",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "eslint-visitor-keys": "1.0.0",
+        "espree": "3.5.4",
+        "esquery": "1.0.1",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "11.5.0",
+        "ignore": "3.3.8",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.1.0",
+        "js-yaml": "3.11.0",
+        "json-stable-stringify-without-jsonify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.10",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "7.0.0",
+        "progress": "2.0.0",
+        "regexpp": "1.1.0",
+        "require-uncached": "1.0.3",
+        "semver": "5.4.1",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.2",
+        "text-table": "0.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "eslint-config-mdcs": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/eslint-config-mdcs/-/eslint-config-mdcs-4.2.3.tgz",
+      "integrity": "sha512-pSiX8roIR7KVZeKBrzQUiRAr2jxLn0H8WUHHCgq2TdoVGSLk/GRNeB78WG1IZnTwENgtSgDtMXq7/UVDBXls+Q==",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.1",
+        "estraverse": "4.2.0"
+      }
+    },
+    "eslint-visitor-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "dev": true
+    },
+    "espree": {
+      "version": "3.5.4",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+      "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.5.3",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "estree-walker": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz",
+      "integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "exists-stat": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/exists-stat/-/exists-stat-1.0.0.tgz",
+      "integrity": "sha1-BmDjUlouidnkRhKUQMJy7foktSk=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+      "dev": true,
+      "requires": {
+        "is-posix-bracket": "0.1.1"
+      }
+    },
+    "expand-range": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+      "dev": true,
+      "requires": {
+        "fill-range": "2.2.3"
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "1.0.1"
+      }
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "1.0.0",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+      "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.23",
+        "tmp": "0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "extract-zip": {
+      "version": "1.6.7",
+      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+      "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "1.6.2",
+        "debug": "2.6.9",
+        "mkdirp": "0.5.1",
+        "yauzl": "2.4.1"
+      },
+      "dependencies": {
+        "concat-stream": {
+          "version": "1.6.2",
+          "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+          "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=",
+          "dev": true,
+          "requires": {
+            "buffer-from": "1.1.0",
+            "inherits": "2.0.3",
+            "readable-stream": "2.3.6",
+            "typedarray": "0.0.6"
+          }
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+          "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+          "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+          "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
+      "dev": true
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fast-url-parser": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz",
+      "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "fd-slicer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+      "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+      "dev": true,
+      "requires": {
+        "pend": "1.2.0"
+      }
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "filename-regex": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
+      "dev": true
+    },
+    "fill-range": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
+      "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+      "dev": true,
+      "requires": {
+        "is-number": "2.1.0",
+        "isobject": "2.1.0",
+        "randomatic": "1.1.7",
+        "repeat-element": "1.1.2",
+        "repeat-string": "1.6.1"
+      }
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "dev": true,
+      "requires": {
+        "path-exists": "2.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "findup-sync": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+      "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+      "dev": true,
+      "requires": {
+        "detect-file": "1.0.0",
+        "is-glob": "3.1.0",
+        "micromatch": "3.1.10",
+        "resolve-dir": "1.0.1"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.8",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-accessor-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+              "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-data-descriptor": {
+              "version": "0.1.4",
+              "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+              "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+              "dev": true,
+              "requires": {
+                "kind-of": "3.2.2"
+              },
+              "dependencies": {
+                "kind-of": {
+                  "version": "3.2.2",
+                  "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+                  "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+                  "dev": true,
+                  "requires": {
+                    "is-buffer": "1.1.5"
+                  }
+                }
+              }
+            },
+            "is-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+              "dev": true,
+              "requires": {
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
+              }
+            },
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "extglob": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+          "dev": true,
+          "requires": {
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "expand-brackets": "2.1.4",
+            "extend-shallow": "2.0.1",
+            "fragment-cache": "0.2.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-number": "3.0.0",
+            "repeat-string": "1.6.1",
+            "to-regex-range": "2.1.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "4.0.0",
+            "array-unique": "0.3.2",
+            "braces": "2.3.2",
+            "define-property": "2.0.2",
+            "extend-shallow": "3.0.2",
+            "extglob": "2.0.4",
+            "fragment-cache": "0.2.1",
+            "kind-of": "6.0.2",
+            "nanomatch": "1.2.9",
+            "object.pick": "1.3.0",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          }
+        }
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+      "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+      "dev": true,
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.6",
+        "mime-types": "2.1.18"
+      }
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "0.2.2"
+      }
+    },
+    "fs-extra": {
+      "version": "0.30.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+      "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "2.4.0",
+        "klaw": "1.3.1",
+        "path-is-absolute": "1.0.1",
+        "rimraf": "2.5.4"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "2.10.0",
+        "node-pre-gyp": "0.10.0"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "1.0.0",
+            "readable-stream": "2.3.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "chownr": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "2.2.4"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "1.2.0",
+            "console-control-strings": "1.1.0",
+            "has-unicode": "2.0.1",
+            "object-assign": "4.1.1",
+            "signal-exit": "3.0.2",
+            "string-width": "1.0.2",
+            "strip-ansi": "3.0.1",
+            "wide-align": "1.1.2"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.4",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "iconv-lite": {
+          "version": "0.4.21",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safer-buffer": "2.1.2"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimatch": "3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "once": "1.4.0",
+            "wrappy": "1.0.2"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "1.0.1"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.11"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "minipass": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1",
+            "yallist": "3.0.2"
+          }
+        },
+        "minizlib": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "2.2.4"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "needle": {
+          "version": "2.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "2.6.9",
+            "iconv-lite": "0.4.21",
+            "sax": "1.2.4"
+          }
+        },
+        "node-pre-gyp": {
+          "version": "0.10.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "1.0.3",
+            "mkdirp": "0.5.1",
+            "needle": "2.2.0",
+            "nopt": "4.0.1",
+            "npm-packlist": "1.1.10",
+            "npmlog": "4.1.2",
+            "rc": "1.2.7",
+            "rimraf": "2.6.2",
+            "semver": "5.5.0",
+            "tar": "4.4.1"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1.1.1",
+            "osenv": "0.1.5"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "npm-packlist": {
+          "version": "1.1.10",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ignore-walk": "3.0.1",
+            "npm-bundled": "1.0.3"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "1.1.4",
+            "console-control-strings": "1.1.0",
+            "gauge": "2.7.4",
+            "set-blocking": "2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1.0.2"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "1.0.2",
+            "os-tmpdir": "1.0.2"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.7",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "0.5.1",
+            "ini": "1.3.5",
+            "minimist": "1.2.0",
+            "strip-json-comments": "2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "2.0.0",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.1.1",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "7.1.2"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.5.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "1.1.0",
+            "is-fullwidth-code-point": "1.0.0",
+            "strip-ansi": "3.0.1"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "4.4.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chownr": "1.0.1",
+            "fs-minipass": "1.2.5",
+            "minipass": "2.2.4",
+            "minizlib": "1.1.0",
+            "mkdirp": "0.5.1",
+            "safe-buffer": "5.1.1",
+            "yallist": "3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wide-align": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "1.0.2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        }
+      }
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+      "dev": true
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "glob-base": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
+      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
+      "dev": true,
+      "requires": {
+        "glob-parent": "2.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-parent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+      "dev": true,
+      "requires": {
+        "is-glob": "2.0.1"
+      }
+    },
+    "glob-slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/glob-slash/-/glob-slash-1.0.0.tgz",
+      "integrity": "sha1-/lLvpDMjP3Si/mTHq7m8hIICq5U=",
+      "dev": true
+    },
+    "glob-slasher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/glob-slasher/-/glob-slasher-1.0.1.tgz",
+      "integrity": "sha1-dHoOW7IiZC7hDT4FRD4QlJPLD44=",
+      "dev": true,
+      "requires": {
+        "glob-slash": "1.0.0",
+        "lodash.isobject": "2.4.1",
+        "toxic": "1.0.0"
+      }
+    },
+    "global-modules": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "1.0.2",
+        "is-windows": "1.0.2",
+        "resolve-dir": "1.0.1"
+      }
+    },
+    "global-prefix": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "2.0.2",
+        "homedir-polyfill": "1.0.1",
+        "ini": "1.3.4",
+        "is-windows": "1.0.2",
+        "which": "1.3.1"
+      }
+    },
+    "globals": {
+      "version": "11.5.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+      "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.1.2",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "google-closure-compiler": {
+      "version": "20180506.0.0",
+      "resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20180506.0.0.tgz",
+      "integrity": "sha1-9ZzDTb+Mmk9I+6Prss8JjSXjRas=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "vinyl": "2.1.0",
+        "vinyl-sourcemaps-apply": "0.2.1"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+      "dev": true
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "har-schema": "2.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "4.6.0",
+            "fast-deep-equal": "1.0.0",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1"
+          }
+        }
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "2.0.6",
+        "has-values": "1.0.0",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "home-path": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz",
+      "integrity": "sha1-1UncJGU4in+GZyQsWzFYjSmvKfw=",
+      "dev": true
+    },
+    "homedir-polyfill": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+      "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "1.0.0"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
+      "integrity": "sha1-IyNbKasjDFdqqw1PE/wEawsDgiI=",
+      "dev": true
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.14.1"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+      "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "2.1.2"
+      }
+    },
+    "ignore": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
+      "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "dev": true,
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+      "dev": true
+    },
+    "ini": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+      "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.1.0",
+        "chalk": "2.4.1",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.2.0",
+        "figures": "2.0.0",
+        "lodash": "4.17.10",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "1.9.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+      "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+      "dev": true
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "0.1.6",
+        "is-data-descriptor": "0.1.4",
+        "kind-of": "5.1.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-dotfile": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
+      "dev": true
+    },
+    "is-equal-shallow": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+      "dev": true,
+      "requires": {
+        "is-primitive": "2.0.0"
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-glob": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "1.0.0"
+      }
+    },
+    "is-number": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "is-odd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+      "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+      "dev": true,
+      "requires": {
+        "is-number": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+      "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.1"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "is-posix-bracket": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
+      "dev": true
+    },
+    "is-primitive": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
+      "dev": true
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "isarray": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+      "dev": true
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "dev": true
+    },
+    "isobject": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+      "dev": true,
+      "requires": {
+        "isarray": "1.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        }
+      }
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "js-reporters": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz",
+      "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=",
+      "dev": true
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.11.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+      "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.10",
+        "esprima": "4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true,
+      "optional": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "dev": true
+    },
+    "json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "jsonfile": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+      "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "dev": true,
+      "requires": {
+        "is-buffer": "1.1.5"
+      }
+    },
+    "klaw": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+      "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.10",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+      "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+      "dev": true
+    },
+    "lodash._objecttypes": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+      "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+      "dev": true
+    },
+    "lodash.isobject": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
+      "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
+      "dev": true,
+      "requires": {
+        "lodash._objecttypes": "2.4.1"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "dev": true,
+      "requires": {
+        "currently-unhandled": "0.4.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "lru-cache": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+      "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "1.0.1"
+      }
+    },
+    "matcher-collection": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.0.5.tgz",
+      "integrity": "sha512-nUCmzKipcJEwYsBVAFh5P+d7JBuhJaW1xs85Hara9xuMLqtCVUrW6DSC0JVIkluxEH2W45nPBM/wjHtBXa/tYA==",
+      "dev": true,
+      "requires": {
+        "minimatch": "3.0.4"
+      }
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "dev": true,
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "micromatch": {
+      "version": "2.3.11",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+      "dev": true,
+      "requires": {
+        "arr-diff": "2.0.0",
+        "array-unique": "0.2.1",
+        "braces": "1.8.5",
+        "expand-brackets": "0.1.5",
+        "extglob": "0.3.2",
+        "filename-regex": "2.0.1",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1",
+        "kind-of": "3.2.2",
+        "normalize-path": "2.1.1",
+        "object.omit": "2.0.1",
+        "parse-glob": "3.0.4",
+        "regex-cache": "0.4.3"
+      }
+    },
+    "mime": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+      "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.33.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+      "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.18",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+      "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=",
+      "dev": true,
+      "requires": {
+        "mime-db": "1.33.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "1.1.11"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        }
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+      "dev": true
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "1.0.2",
+        "is-extendable": "1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+      "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+      "dev": true,
+      "optional": true
+    },
+    "nanomatch": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+      "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "4.0.0",
+        "array-unique": "0.3.2",
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "fragment-cache": "0.2.1",
+        "is-odd": "2.0.0",
+        "is-windows": "1.0.2",
+        "kind-of": "6.0.2",
+        "object.pick": "1.3.0",
+        "regex-not": "1.0.2",
+        "snapdragon": "0.8.2",
+        "to-regex": "3.0.2"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "2.6.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.4.1",
+        "validate-npm-package-license": "3.0.3"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "1.0.2"
+      }
+    },
+    "nugget": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
+      "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "minimist": "1.2.0",
+        "pretty-bytes": "1.0.4",
+        "progress-stream": "1.2.0",
+        "request": "2.87.0",
+        "single-line-log": "1.1.2",
+        "throttleit": "0.0.2"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "0.1.1",
+        "define-property": "0.2.5",
+        "kind-of": "3.2.2"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "object-keys": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+      "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "object.omit": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+      "dev": true,
+      "requires": {
+        "for-own": "0.1.5",
+        "is-extendable": "0.1.1"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "dev": true,
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.2.0"
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "dev": true,
+      "requires": {
+        "deep-is": "0.1.3",
+        "fast-levenshtein": "2.0.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "parse-glob": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+      "dev": true,
+      "requires": {
+        "glob-base": "0.3.0",
+        "is-dotfile": "1.0.3",
+        "is-extglob": "1.0.0",
+        "is-glob": "2.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "dev": true,
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "dev": true,
+      "requires": {
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+      "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz",
+      "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==",
+      "dev": true
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "pend": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+      "dev": true
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pluralize": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+      "dev": true
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "preserve": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
+      "dev": true
+    },
+    "pretty-bytes": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
+      "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1",
+        "meow": "3.7.0"
+      }
+    },
+    "process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+      "dev": true
+    },
+    "progress": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "progress-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
+      "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
+      "dev": true,
+      "requires": {
+        "speedometer": "0.1.4",
+        "through2": "0.2.3"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=",
+      "dev": true
+    },
+    "qunit": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.6.1.tgz",
+      "integrity": "sha512-AaILHe41G+fVC8h5wrp8U31iM2tRxLAVwH1tICtDkRbC1HDgJBjjYq0SMCZE8K3Z16MiZq3vhNhLu18KeDtS6Q==",
+      "dev": true,
+      "requires": {
+        "chokidar": "1.7.0",
+        "commander": "2.12.2",
+        "exists-stat": "1.0.0",
+        "findup-sync": "2.0.0",
+        "js-reporters": "1.2.1",
+        "resolve": "1.5.0",
+        "walk-sync": "0.3.2"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.12.2",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
+          "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
+          "dev": true
+        }
+      }
+    },
+    "randomatic": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
+      "integrity": "sha1-x6vpzIuHwLqodrGf3oP9RkeX44w=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "kind-of": "4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "1.1.5"
+          }
+        }
+      }
+    },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha1-zZJL9SAKB1uDwYjNa54hG3/A0+0=",
+      "dev": true,
+      "requires": {
+        "deep-extend": "0.6.0",
+        "ini": "1.3.4",
+        "minimist": "1.2.0",
+        "strip-json-comments": "2.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+          "dev": true
+        }
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "dev": true,
+      "requires": {
+        "load-json-file": "1.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2",
+        "read-pkg": "1.1.0"
+      }
+    },
+    "readable-stream": {
+      "version": "1.1.14",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+      "dev": true,
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "0.0.1",
+        "string_decoder": "0.10.31"
+      }
+    },
+    "readdirp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+      "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "readable-stream": "2.3.3",
+        "set-immediate-shim": "1.0.1"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.8",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.8"
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.3",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+          "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "safe-buffer": "5.1.1",
+            "string_decoder": "1.0.3",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+          "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "5.1.1"
+          }
+        }
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "dev": true,
+      "requires": {
+        "indent-string": "2.1.0",
+        "strip-indent": "1.0.1"
+      }
+    },
+    "regex-cache": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz",
+      "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=",
+      "dev": true,
+      "requires": {
+        "is-equal-shallow": "0.1.3",
+        "is-primitive": "2.0.0"
+      }
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "regexpp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+      "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
+      "dev": true
+    },
+    "registry-auth-token": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+      "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=",
+      "dev": true,
+      "requires": {
+        "rc": "1.2.8",
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "registry-url": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+      "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+      "dev": true,
+      "requires": {
+        "rc": "1.2.8"
+      }
+    },
+    "remove-trailing-separator": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz",
+      "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
+      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "replace-ext": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+      "dev": true
+    },
+    "request": {
+      "version": "2.87.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
+      "integrity": "sha1-MvACNc0I1IK00NaNuTqCnA7VdW4=",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "0.7.0",
+        "aws4": "1.7.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.6",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.3.2",
+        "har-validator": "5.0.3",
+        "http-signature": "1.2.0",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.18",
+        "oauth-sign": "0.8.2",
+        "performance-now": "2.1.0",
+        "qs": "6.5.2",
+        "safe-buffer": "5.1.1",
+        "tough-cookie": "2.3.4",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.2.1"
+      },
+      "dependencies": {
+        "uuid": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+          "integrity": "sha1-EsUou51Y0LkmXZovbw/ovhf/HxQ=",
+          "dev": true
+        }
+      }
+    },
+    "require-relative": {
+      "version": "0.8.7",
+      "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
+      "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=",
+      "dev": true
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+      "dev": true,
+      "requires": {
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
+      }
+    },
+    "resolve": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
+      "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
+      "dev": true,
+      "requires": {
+        "path-parse": "1.0.5"
+      }
+    },
+    "resolve-dir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "2.0.2",
+        "global-modules": "1.0.0"
+      }
+    },
+    "resolve-from": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "2.0.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.5.4",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
+      "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=",
+      "dev": true,
+      "requires": {
+        "glob": "7.1.1"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.1",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+          "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "1.0.0",
+            "inflight": "1.0.6",
+            "inherits": "2.0.3",
+            "minimatch": "3.0.3",
+            "once": "1.4.0",
+            "path-is-absolute": "1.0.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+          "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.6"
+          }
+        }
+      }
+    },
+    "rollup": {
+      "version": "0.59.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.59.4.tgz",
+      "integrity": "sha512-ISiMqq/aJa+57QxX2MRcvLESHdJ7wSavmr6U1euMr+6UgFe6KM+3QANrYy8LQofwhTC1I7BcAdlLnDiaODs1BA==",
+      "dev": true,
+      "requires": {
+        "@types/estree": "0.0.39",
+        "@types/node": "8.10.17"
+      }
+    },
+    "rollup-pluginutils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz",
+      "integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=",
+      "dev": true,
+      "requires": {
+        "estree-walker": "0.3.1",
+        "micromatch": "2.3.11"
+      }
+    },
+    "rollup-watch": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/rollup-watch/-/rollup-watch-4.3.1.tgz",
+      "integrity": "sha1-WqHq6reHrd82iQXRArOdb8XOSos=",
+      "dev": true,
+      "requires": {
+        "chokidar": "1.7.0",
+        "require-relative": "0.8.7",
+        "rollup-pluginutils": "2.0.1"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "2.1.0"
+      }
+    },
+    "rx": {
+      "version": "2.3.24",
+      "resolved": "https://registry.npmjs.org/rx/-/rx-2.3.24.tgz",
+      "integrity": "sha1-FPlQpCF9fjXapxu8vljv9o6ksrc=",
+      "dev": true
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=",
+      "dev": true
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "0.1.15"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "semver": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
+      "integrity": "sha1-4FnAnYVx8FQII3M0M1BdOi8AsY4=",
+      "dev": true
+    },
+    "serve": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/serve/-/serve-7.1.2.tgz",
+      "integrity": "sha512-j4FUohDvyssavjkE3xJiTPZ2jKxseCT+C/LTgcCBYILouvNEBwbEWpR33sxQNMivWsuNgaNpwcLagNPP8VNuiw==",
+      "dev": true,
+      "requires": {
+        "@zeit/schemas": "1.1.2",
+        "ajv": "6.5.0",
+        "arg": "2.0.0",
+        "chalk": "2.4.1",
+        "serve-handler": "2.3.13",
+        "update-check": "1.5.2"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "6.5.0",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz",
+          "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==",
+          "dev": true,
+          "requires": {
+            "fast-deep-equal": "2.0.1",
+            "fast-json-stable-stringify": "2.0.0",
+            "json-schema-traverse": "0.3.1",
+            "uri-js": "4.2.2"
+          }
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+          "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "serve-handler": {
+      "version": "2.3.13",
+      "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-2.3.13.tgz",
+      "integrity": "sha512-qQTg8i5X8YTtzOdMHEedC2Xr50ptXWVrIt22QWIpKgO0pZXZsFYbPB00yoLc02U4xv/3X884/wZD5q9dr+RfcQ==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.0.0",
+        "fast-url-parser": "1.1.3",
+        "glob-slasher": "1.0.1",
+        "mime": "2.3.1",
+        "minimatch": "3.0.4",
+        "path-to-regexp": "2.2.1"
+      },
+      "dependencies": {
+        "balanced-match": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "1.1.11"
+          }
+        }
+      }
+    },
+    "set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "2.0.1",
+        "is-extendable": "0.1.1",
+        "is-plain-object": "2.0.4",
+        "split-string": "3.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+      "dev": true
+    },
+    "single-line-log": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
+      "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
+      "dev": true,
+      "requires": {
+        "string-width": "1.0.2"
+      }
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+      "dev": true,
+      "requires": {
+        "is-fullwidth-code-point": "2.0.0"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "0.11.2",
+        "debug": "2.6.8",
+        "define-property": "0.2.5",
+        "extend-shallow": "2.0.1",
+        "map-cache": "0.2.2",
+        "source-map": "0.5.6",
+        "source-map-resolve": "0.5.2",
+        "use": "3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "1.0.0",
+        "isobject": "3.0.1",
+        "snapdragon-util": "3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "1.0.2"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "6.0.2"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "1.0.0",
+            "is-data-descriptor": "1.0.0",
+            "kind-of": "6.0.2"
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "source-map": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+      "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+      "dev": true
+    },
+    "source-map-resolve": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "dev": true,
+      "requires": {
+        "atob": "2.1.1",
+        "decode-uri-component": "0.2.0",
+        "resolve-url": "0.2.1",
+        "source-map-url": "0.4.0",
+        "urix": "0.1.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "spawn-command": {
+      "version": "0.0.2-1",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
+      "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+      "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "3.0.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+      "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "2.1.0",
+        "spdx-license-ids": "3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
+      "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=",
+      "dev": true
+    },
+    "speedometer": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
+      "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=",
+      "dev": true
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "3.0.2"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+      "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
+      "dev": true,
+      "requires": {
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "0.2.5",
+        "object-copy": "0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "0.1.6"
+          }
+        }
+      }
+    },
+    "string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "dev": true,
+      "requires": {
+        "code-point-at": "1.1.0",
+        "is-fullwidth-code-point": "1.0.0",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "2.1.1"
+          }
+        }
+      }
+    },
+    "string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+      "dev": true
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "0.2.1"
+      }
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "dev": true,
+      "requires": {
+        "get-stdin": "4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "sumchecker": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz",
+      "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.8",
+        "es6-promise": "4.2.4"
+      }
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "table": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "chalk": "2.4.1",
+        "lodash": "4.17.10",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.1",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.4.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.4.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+          "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
+        }
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "throttleit": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
+      "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
+      "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "1.1.14",
+        "xtend": "2.1.2"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "3.2.2"
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "2.0.2",
+        "extend-shallow": "3.0.2",
+        "regex-not": "1.0.2",
+        "safe-regex": "1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "3.0.0",
+        "repeat-string": "1.6.1"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          }
+        }
+      }
+    },
+    "tough-cookie": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+      "integrity": "sha1-7GDO44rGdQY//JelwYlwV47oNlU=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.4.1"
+      }
+    },
+    "toxic": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toxic/-/toxic-1.0.0.tgz",
+      "integrity": "sha1-8RVNi2rCGHWslDqfdAjfLf4WTqI=",
+      "dev": true,
+      "requires": {
+        "lodash": "2.4.2"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
+          "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
+          "dev": true
+        }
+      }
+    },
+    "tree-kill": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz",
+      "integrity": "sha1-WEZ4Yje0I5AU8F2xVrZDIS1MbzY=",
+      "dev": true
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true,
+      "optional": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "3.3.28",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.28.tgz",
+      "integrity": "sha512-68Rc/aA6cswiaQ5SrE979UJcXX+ADA1z33/ZsPd+fbAiVdjZ16OXdbtGO+rJUUBgK6qdf3SOPhQf3K/ybF5Miw==",
+      "dev": true,
+      "requires": {
+        "commander": "2.15.1",
+        "source-map": "0.6.1"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.15.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+          "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "3.1.0",
+        "get-value": "2.0.6",
+        "is-extendable": "0.1.1",
+        "set-value": "0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "0.1.1"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-extendable": "0.1.1",
+            "is-plain-object": "2.0.4",
+            "to-object-path": "0.3.0"
+          }
+        }
+      }
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "0.3.1",
+        "isobject": "3.0.1"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "2.0.6",
+            "has-values": "0.1.4",
+            "isobject": "2.1.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        }
+      }
+    },
+    "update-check": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz",
+      "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==",
+      "dev": true,
+      "requires": {
+        "registry-auth-token": "3.3.2",
+        "registry-url": "3.1.0"
+      }
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "2.1.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+          "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+          "dev": true
+        }
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "use": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
+      "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
+      "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "3.0.0",
+        "spdx-expression-parse": "3.0.0"
+      }
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      }
+    },
+    "vinyl": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz",
+      "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=",
+      "dev": true,
+      "requires": {
+        "clone": "2.1.1",
+        "clone-buffer": "1.0.0",
+        "clone-stats": "1.0.0",
+        "cloneable-readable": "1.1.2",
+        "remove-trailing-separator": "1.0.2",
+        "replace-ext": "1.0.0"
+      }
+    },
+    "vinyl-sourcemaps-apply": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+      "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.6"
+      }
+    },
+    "walk-sync": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-0.3.2.tgz",
+      "integrity": "sha512-FMB5VqpLqOCcqrzA9okZFc0wq0Qbmdm396qJxvQZhDpyu0W95G9JCmp74tx7iyYnyOcBtUuKJsgIKAqjozvmmQ==",
+      "dev": true,
+      "requires": {
+        "ensure-posix-path": "1.0.2",
+        "matcher-collection": "1.0.5"
+      }
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "requires": {
+        "isexe": "2.0.0"
+      }
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "dev": true
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "xtend": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+      "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+      "dev": true,
+      "requires": {
+        "object-keys": "0.4.0"
+      }
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
+    "yauzl": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+      "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+      "dev": true,
+      "requires": {
+        "fd-slicer": "1.0.1"
+      }
+    }
+  }
+}

+ 13 - 13
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "three",
   "name": "three",
-  "version": "0.92.0",
+  "version": "0.93.0",
   "description": "JavaScript 3D library",
   "description": "JavaScript 3D library",
   "main": "build/three.js",
   "main": "build/three.js",
   "repository": "mrdoob/three.js",
   "repository": "mrdoob/three.js",
@@ -31,8 +31,8 @@
     "build-test": "rollup -c test/rollup.unit.config.js",
     "build-test": "rollup -c test/rollup.unit.config.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-uglify": "rollup -c && uglifyjs build/three.js -cm --preamble \"// threejs.org/license\" > build/three.min.js",
     "build-closure": "rollup -c && java -jar node_modules/google-closure-compiler/compiler.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
     "build-closure": "rollup -c && java -jar node_modules/google-closure-compiler/compiler.jar --warning_level=VERBOSE --jscomp_off=globalThis --jscomp_off=checkTypes --externs utils/build/externs.js --language_in=ECMASCRIPT5_STRICT --js build/three.js --js_output_file build/three.min.js",
-    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"serve --port 8080\"",
-    "dev-test": "concurrently --names \"ROLLUP,ROLLUPTEST,HTTP\" -c \"bgBlue.bold,bgRed.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"rollup -c test/rollup.unit.config.js -w -m inline\" \"serve --port 8080\"",
+    "dev": "concurrently --names \"ROLLUP,HTTP\" -c \"bgBlue.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"serve --listen 8080\"",
+    "dev-test": "concurrently --names \"ROLLUP,ROLLUPTEST,HTTP\" -c \"bgBlue.bold,bgRed.bold,bgGreen.bold\" \"rollup -c -w -m inline\" \"rollup -c test/rollup.unit.config.js -w -m inline\" \"serve --listen 8080\"",
     "start": "npm run dev",
     "start": "npm run dev",
     "lint": "eslint src",
     "lint": "eslint src",
     "test": "npm run build-test && qunit test/unit/three.source.unit.js",
     "test": "npm run build-test && qunit test/unit/three.source.unit.js",
@@ -52,15 +52,15 @@
   },
   },
   "homepage": "https://threejs.org/",
   "homepage": "https://threejs.org/",
   "devDependencies": {
   "devDependencies": {
-    "concurrently": "^3.5.0",
-    "electron": "~1.8.4",
-    "eslint": "^4.1.1",
-    "eslint-config-mdcs": "^4.2.2",
-    "google-closure-compiler": "20180204.0.0",
-    "qunit": "^2.5.1",
-    "rollup": "^0.57.1",
-    "rollup-watch": "^4.0.0",
-    "serve": "~6.5.3",
-    "uglify-js": "^3.0.23"
+    "concurrently": "^3.5.1",
+    "electron": "^2.0.2",
+    "eslint": "^4.19.1",
+    "eslint-config-mdcs": "^4.2.3",
+    "google-closure-compiler": "20180506.0.0",
+    "qunit": "^2.6.1",
+    "rollup": "^0.59.4",
+    "rollup-watch": "^4.3.1",
+    "serve": "^7.1.2",
+    "uglify-js": "^3.3.28"
   }
   }
 }
 }

+ 1 - 1
src/constants.js

@@ -1,4 +1,4 @@
-export var REVISION = '93dev';
+export var REVISION = '94dev';
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };
 export var CullFaceNone = 0;
 export var CullFaceNone = 0;
 export var CullFaceBack = 1;
 export var CullFaceBack = 1;

+ 54 - 0
src/geometries/ExtrudeGeometry.js

@@ -49,6 +49,17 @@ function ExtrudeGeometry( shapes, options ) {
 ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
 ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
 ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
 ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
 
 
+ExtrudeGeometry.prototype.toJSON = function () {
+
+	var data = Geometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+	var options = this.parameters.options;
+
+	return toJSON( shapes, options, data );
+
+};
+
 // ExtrudeBufferGeometry
 // ExtrudeBufferGeometry
 
 
 function ExtrudeBufferGeometry( shapes, options ) {
 function ExtrudeBufferGeometry( shapes, options ) {
@@ -717,6 +728,19 @@ function ExtrudeBufferGeometry( shapes, options ) {
 ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
 ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
 ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
 ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
 
 
+ExtrudeBufferGeometry.prototype.toJSON = function () {
+
+	var data = BufferGeometry.prototype.toJSON.call( this );
+
+	var shapes = this.parameters.shapes;
+	var options = this.parameters.options;
+
+	return toJSON( shapes, options, data );
+
+};
+
+//
+
 var WorldUVGenerator = {
 var WorldUVGenerator = {
 
 
 	generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
 	generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
@@ -774,5 +798,35 @@ var WorldUVGenerator = {
 	}
 	}
 };
 };
 
 
+function toJSON( shapes, options, data ) {
+
+	//
+
+	data.shapes = [];
+
+	if ( Array.isArray( shapes ) ) {
+
+		for ( var i = 0, l = shapes.length; i < l; i ++ ) {
+
+			var shape = shapes[ i ];
+
+			data.shapes.push( shape.uuid );
+
+		}
+
+	} else {
+
+		data.shapes.push( shapes.uuid );
+
+	}
+
+	//
+
+	if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();
+
+	return data;
+
+}
+
 
 
 export { ExtrudeGeometry, ExtrudeBufferGeometry };
 export { ExtrudeGeometry, ExtrudeBufferGeometry };

+ 30 - 0
src/loaders/ObjectLoader.js

@@ -51,6 +51,7 @@ import { BufferGeometryLoader } from './BufferGeometryLoader.js';
 import { JSONLoader } from './JSONLoader.js';
 import { JSONLoader } from './JSONLoader.js';
 import { FileLoader } from './FileLoader.js';
 import { FileLoader } from './FileLoader.js';
 import * as Geometries from '../geometries/Geometries.js';
 import * as Geometries from '../geometries/Geometries.js';
+import * as Curves from '../extras/curves/Curves.js';
 
 
 /**
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
@@ -377,6 +378,35 @@ Object.assign( ObjectLoader.prototype, {
 
 
 						break;
 						break;
 
 
+
+					case 'ExtrudeGeometry':
+					case 'ExtrudeBufferGeometry':
+
+						var geometryShapes = [];
+
+						for ( var j = 0, jl = data.shapes.length; j < jl; j ++ ) {
+
+							var shape = shapes[ data.shapes[ j ] ];
+
+							geometryShapes.push( shape );
+
+						}
+
+						var extrudePath = data.options.extrudePath;
+
+						if ( extrudePath !== undefined ) {
+
+							data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
+
+						}
+
+						geometry = new Geometries[ data.type ](
+							geometryShapes,
+							data.options
+						);
+
+						break;
+
 					case 'BufferGeometry':
 					case 'BufferGeometry':
 
 
 						geometry = bufferGeometryLoader.parse( data );
 						geometry = bufferGeometryLoader.parse( data );

+ 10 - 0
src/math/Matrix4.js

@@ -125,6 +125,8 @@ Object.assign( Matrix4.prototype, {
 
 
 		return function extractRotation( m ) {
 		return function extractRotation( m ) {
 
 
+			// this method does not support reflection matrices
+
 			var te = this.elements;
 			var te = this.elements;
 			var me = m.elements;
 			var me = m.elements;
 
 
@@ -135,14 +137,22 @@ Object.assign( Matrix4.prototype, {
 			te[ 0 ] = me[ 0 ] * scaleX;
 			te[ 0 ] = me[ 0 ] * scaleX;
 			te[ 1 ] = me[ 1 ] * scaleX;
 			te[ 1 ] = me[ 1 ] * scaleX;
 			te[ 2 ] = me[ 2 ] * scaleX;
 			te[ 2 ] = me[ 2 ] * scaleX;
+			te[ 3 ] = 0;
 
 
 			te[ 4 ] = me[ 4 ] * scaleY;
 			te[ 4 ] = me[ 4 ] * scaleY;
 			te[ 5 ] = me[ 5 ] * scaleY;
 			te[ 5 ] = me[ 5 ] * scaleY;
 			te[ 6 ] = me[ 6 ] * scaleY;
 			te[ 6 ] = me[ 6 ] * scaleY;
+			te[ 7 ] = 0;
 
 
 			te[ 8 ] = me[ 8 ] * scaleZ;
 			te[ 8 ] = me[ 8 ] * scaleZ;
 			te[ 9 ] = me[ 9 ] * scaleZ;
 			te[ 9 ] = me[ 9 ] * scaleZ;
 			te[ 10 ] = me[ 10 ] * scaleZ;
 			te[ 10 ] = me[ 10 ] * scaleZ;
+			te[ 11 ] = 0;
+
+			te[ 12 ] = 0;
+			te[ 13 ] = 0;
+			te[ 14 ] = 0;
+			te[ 15 ] = 1;
 
 
 			return this;
 			return this;
 
 

+ 12 - 2
src/renderers/WebGLRenderer.js

@@ -123,6 +123,8 @@ function WebGLRenderer( parameters ) {
 
 
 		// internal state cache
 		// internal state cache
 
 
+		_framebuffer = null,
+
 		_currentRenderTarget = null,
 		_currentRenderTarget = null,
 		_currentFramebuffer = null,
 		_currentFramebuffer = null,
 		_currentMaterialId = - 1,
 		_currentMaterialId = - 1,
@@ -290,7 +292,7 @@ function WebGLRenderer( parameters ) {
 
 
 	// vr
 	// vr
 
 
-	var vr = ( 'xr' in navigator ) ? new WebXRManager( _gl ) : new WebVRManager( _this );
+	var vr = ( 'xr' in navigator ) ? new WebXRManager( _this ) : new WebVRManager( _this );
 
 
 	this.vr = vr;
 	this.vr = vr;
 
 
@@ -2396,6 +2398,14 @@ function WebGLRenderer( parameters ) {
 
 
 	}() );
 	}() );
 
 
+	//
+
+	this.setFramebuffer = function ( value ) {
+
+		_framebuffer = value;
+
+	};
+
 	this.getRenderTarget = function () {
 	this.getRenderTarget = function () {
 
 
 		return _currentRenderTarget;
 		return _currentRenderTarget;
@@ -2412,7 +2422,7 @@ function WebGLRenderer( parameters ) {
 
 
 		}
 		}
 
 
-		var framebuffer = null;
+		var framebuffer = _framebuffer;
 		var isCube = false;
 		var isCube = false;
 
 
 		if ( renderTarget ) {
 		if ( renderTarget ) {

+ 0 - 1
src/renderers/shaders/ShaderLib/meshlambert_frag.glsl

@@ -24,7 +24,6 @@ varying vec3 vLightFront;
 #include <envmap_pars_fragment>
 #include <envmap_pars_fragment>
 #include <bsdfs>
 #include <bsdfs>
 #include <lights_pars_begin>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <fog_pars_fragment>
 #include <fog_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <shadowmask_pars_fragment>
 #include <shadowmask_pars_fragment>

+ 0 - 1
src/renderers/shaders/ShaderLib/meshlambert_vert.glsl

@@ -14,7 +14,6 @@ varying vec3 vLightFront;
 #include <envmap_pars_vertex>
 #include <envmap_pars_vertex>
 #include <bsdfs>
 #include <bsdfs>
 #include <lights_pars_begin>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <color_pars_vertex>
 #include <color_pars_vertex>
 #include <fog_pars_vertex>
 #include <fog_pars_vertex>
 #include <morphtarget_pars_vertex>
 #include <morphtarget_pars_vertex>

+ 0 - 1
src/renderers/shaders/ShaderLib/meshphong_frag.glsl

@@ -22,7 +22,6 @@ uniform float opacity;
 #include <fog_pars_fragment>
 #include <fog_pars_fragment>
 #include <bsdfs>
 #include <bsdfs>
 #include <lights_pars_begin>
 #include <lights_pars_begin>
-#include <lights_pars_maps>
 #include <lights_phong_pars_fragment>
 #include <lights_phong_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <shadowmap_pars_fragment>
 #include <bumpmap_pars_fragment>
 #include <bumpmap_pars_fragment>

+ 1 - 1
src/renderers/webgl/WebGLAnimation.js

@@ -49,7 +49,7 @@ function WebGLAnimation() {
 
 
 		}
 		}
 
 
-	}
+	};
 
 
 }
 }
 
 

+ 2 - 0
src/renderers/webgl/WebGLUniforms.js

@@ -1,5 +1,7 @@
 /**
 /**
  * @author tschw
  * @author tschw
+ * @author Mugen87 / https://github.com/Mugen87
+ * @author mrdoob / http://mrdoob.com/
  *
  *
  * Uniforms of a program.
  * Uniforms of a program.
  * Those form a tree structure with a special top-level container for the root,
  * Those form a tree structure with a special top-level container for the root,

+ 0 - 8
src/renderers/webvr/WebVRManager.js

@@ -261,14 +261,6 @@ function WebVRManager( renderer ) {
 
 
 	};
 	};
 
 
-	// DEPRECATED
-
-	this.requestAnimationFrame = function ( callback ) {
-
-		// device.requestAnimationFrame( callback );
-
-	};
-
 }
 }
 
 
 export { WebVRManager };
 export { WebVRManager };

+ 57 - 19
src/renderers/webvr/WebXRManager.js

@@ -2,23 +2,19 @@
  * @author mrdoob / http://mrdoob.com/
  * @author mrdoob / http://mrdoob.com/
  */
  */
 
 
-import { Matrix4 } from '../../math/Matrix4.js';
 import { Vector4 } from '../../math/Vector4.js';
 import { Vector4 } from '../../math/Vector4.js';
-import { Vector3 } from '../../math/Vector3.js';
-import { Quaternion } from '../../math/Quaternion.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { ArrayCamera } from '../../cameras/ArrayCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { PerspectiveCamera } from '../../cameras/PerspectiveCamera.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 import { WebGLAnimation } from '../webgl/WebGLAnimation.js';
 
 
-function WebXRManager( gl ) {
+function WebXRManager( renderer ) {
 
 
-	var scope = this;
+	var gl = renderer.context;
 
 
 	var device = null;
 	var device = null;
 	var session = null;
 	var session = null;
 
 
 	var frameOfRef = null;
 	var frameOfRef = null;
-	var isExclusive = false;
 
 
 	var pose = null;
 	var pose = null;
 
 
@@ -62,7 +58,7 @@ function WebXRManager( gl ) {
 
 
 	//
 	//
 
 
-	this.setSession = function ( value ) {
+	this.setSession = function ( value, options ) {
 
 
 		session = value;
 		session = value;
 
 
@@ -70,16 +66,17 @@ function WebXRManager( gl ) {
 
 
 			session.addEventListener( 'end', function () {
 			session.addEventListener( 'end', function () {
 
 
-				gl.bindFramebuffer( gl.FRAMEBUFFER, null );
+				renderer.setFramebuffer( null );
 				animation.stop();
 				animation.stop();
 
 
 			} );
 			} );
 
 
 			session.baseLayer = new XRWebGLLayer( session, gl );
 			session.baseLayer = new XRWebGLLayer( session, gl );
-			session.requestFrameOfReference( 'stage' ).then( function ( value ) {
+			session.requestFrameOfReference( options.frameOfReferenceType ).then( function ( value ) {
 
 
 				frameOfRef = value;
 				frameOfRef = value;
-				isExclusive = session.exclusive;
+
+				renderer.setFramebuffer( session.baseLayer.framebuffer );
 
 
 				animation.setContext( session );
 				animation.setContext( session );
 				animation.start();
 				animation.start();
@@ -90,9 +87,56 @@ function WebXRManager( gl ) {
 
 
 	};
 	};
 
 
+	function updateCamera( camera, parent ) {
+
+		if ( parent === null ) {
+
+			camera.matrixWorld.copy( camera.matrix );
+
+		} else {
+
+			camera.matrixWorld.multiplyMatrices( parent.matrixWorld, camera.matrix );
+
+		}
+
+		camera.matrixWorldInverse.getInverse( camera.matrixWorld );
+
+	}
+
 	this.getCamera = function ( camera ) {
 	this.getCamera = function ( camera ) {
 
 
-		return isPresenting() ? cameraVR : camera;
+		if ( isPresenting() ) {
+
+			var parent = camera.parent;
+			var cameras = cameraVR.cameras;
+
+			// apply camera.parent to cameraVR
+
+			updateCamera( cameraVR, parent );
+
+			for ( var i = 0; i < cameras.length; i ++ ) {
+
+				updateCamera( cameras[ i ], parent );
+
+			}
+
+			// update camera and its children
+
+			camera.matrixWorld.copy( cameraVR.matrixWorld );
+
+			var children = camera.children;
+
+			for ( var i = 0, l = children.length; i < l; i ++ ) {
+
+				children[ i ].updateMatrixWorld( true );
+
+			}
+
+			return cameraVR;
+
+		}
+
+		return camera;
 
 
 	};
 	};
 
 
@@ -116,15 +160,13 @@ function WebXRManager( gl ) {
 			var viewMatrix = pose.getViewMatrix( view );
 			var viewMatrix = pose.getViewMatrix( view );
 
 
 			var camera = cameraVR.cameras[ i ];
 			var camera = cameraVR.cameras[ i ];
+			camera.matrix.fromArray( viewMatrix ).getInverse( camera.matrix );
 			camera.projectionMatrix.fromArray( view.projectionMatrix );
 			camera.projectionMatrix.fromArray( view.projectionMatrix );
-			camera.matrixWorldInverse.fromArray( viewMatrix );
-			camera.matrixWorld.getInverse( camera.matrixWorldInverse );
 			camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
 			camera.viewport.set( viewport.x, viewport.y, viewport.width, viewport.height );
 
 
 			if ( i === 0 ) {
 			if ( i === 0 ) {
 
 
-				cameraVR.matrixWorld.copy( camera.matrixWorld );
-				cameraVR.matrixWorldInverse.copy( camera.matrixWorldInverse );
+				cameraVR.matrix.copy( camera.matrix );
 
 
 				// HACK (mrdoob)
 				// HACK (mrdoob)
 				// https://github.com/w3c/webvr/issues/203
 				// https://github.com/w3c/webvr/issues/203
@@ -135,8 +177,6 @@ function WebXRManager( gl ) {
 
 
 		}
 		}
 
 
-		gl.bindFramebuffer( gl.FRAMEBUFFER, session.baseLayer.framebuffer );
-
 		if ( onAnimationFrameCallback ) onAnimationFrameCallback();
 		if ( onAnimationFrameCallback ) onAnimationFrameCallback();
 
 
 	}
 	}
@@ -159,8 +199,6 @@ function WebXRManager( gl ) {
 
 
 	};
 	};
 
 
-	this.requestAnimationFrame = function () {};
-
 	this.submitFrame = function () {};
 	this.submitFrame = function () {};
 
 
 }
 }

+ 0 - 3
utils/exporters/blender/.gitignore

@@ -1,3 +0,0 @@
-tests/review
-__pycache__/
-tmp/

+ 1 - 66
utils/exporters/blender/README.md

@@ -1,68 +1,3 @@
 # Three.js Blender Export
 # Three.js Blender Export
 
 
-Exports Three.js' ASCII JSON format.
-
-## IMPORTANT
-
-The exporter (r69 and earlier) has been completely replaced. Please ensure you have removed the io_three_mesh addon from your Blender addons directory before installing the current addon (io_three).
-
-## Installation
-
-
-Recommended Blender version **>= 2.73.0**
-
-Copy the io_three folder to the scripts/addons folder. If it doesn't exist, create it. The full path is OS-dependent (see below).
-
-Once that is done, you need to activate the plugin. Open Blender preferences, look for
-Addons, search for `three`, enable the checkbox next to the `Import-Export: Three.js Format` entry.
-
-Goto Usage.
-
-### Windows
-
-Should look like this:
-
-    C:\Program Files\Blender Foundation\Blender\2.7X\scripts\addons
-    
-OR (for 2.6)
-    
-    C:\Users\USERNAME\AppData\Roaming\Blender Foundation\Blender\2.6X\scripts\addons
-
-### OSX
-
-In your user's library for user installed Blender addons:
-
-    /Users/(myuser)/Library/Application Support/Blender/2.7X/scripts/addons
-    
-OR (for 2.79)
-    
-    /Applications/Blender/blender.app/Contents/Resources/2.79/scripts/addons
-
-### Linux
-
-By default, this should look like:
-
-    /home/USERNAME/.config/blender/2.6X/scripts/addons
-
-For Ubuntu users who installed Blender 2.68 via apt-get, this is the location:
-
-    /usr/lib/blender/scripts/addons
-
-For Ubuntu users who installed Blender 2.7x via apt-get, this is the location:
-
-    /usr/share/blender/scripts/addons
-
-
-## Usage
-
-Activate the Import-Export addon under "User Preferences" > "Addons" and then use the regular Export menu within Blender, select `Three.js (json)`.
-
-
-## Enabling msgpack
-
-To enable msgpack compression copy the msgpack to scripts/modules.
-
-
-## Importer
-
-Currently there is no import functionality available.
+> **NOTICE:** The Blender exporter for the Three.js JSON format has been removed, to focus on better support for other workflows. For recommended alternatives, see [Loading 3D Models](https://threejs.org/docs/#manual/introduction/loading-3d-models). The Three.js JSON format is still fully supported for use with [Object3D.toJSON](https://threejs.org/docs/#api/core/Object3D.toJSON), the [Editor](https://threejs.org/editor/), [THREE.ObjectLoader](https://threejs.org/docs/#api/loaders/ObjectLoader), [THREE.JSONLoader](https://threejs.org/docs/#api/loaders/JSONLoader), and [converters](https://github.com/mrdoob/three.js/tree/dev/utils/converters).

+ 0 - 1059
utils/exporters/blender/addons/io_three/__init__.py

@@ -1,1059 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-import os
-import json
-import logging
-
-import bpy
-from bpy_extras.io_utils import ExportHelper
-from bpy.props import (
-    EnumProperty,
-    BoolProperty,
-    FloatProperty,
-    IntProperty,
-    StringProperty
-)
-
-from . import constants
-
-logging.basicConfig(
-    format='%(levelname)s:THREE:%(message)s',
-    level=logging.DEBUG)
-
-bl_info = {
-    'name': "Three.js Format",
-    'author': "repsac, mrdoob, yomotsu, mpk, jpweeks, rkusa, tschw, jackcaron, bhouston",
-    'version': (1, 5, 0),
-    'blender': (2, 74, 0),
-    'location': "File > Export",
-    'description': "Export Three.js formatted JSON files.",
-    'warning': "Importer not included.",
-    'wiki_url': "https://github.com/mrdoob/three.js/tree/"\
-        "master/utils/exporters/blender",
-    'tracker_url':  "https://github.com/mrdoob/three.js/issues",
-    'category': 'Import-Export'
-}
-
-
-def _geometry_types():
-    """The valid geometry types that are supported by Three.js
-
-    :return: list of tuples
-
-    """
-    keys = (constants.GLOBAL,
-            constants.GEOMETRY,
-            constants.BUFFER_GEOMETRY)
-    types = []
-    for key in keys:
-        types.append((key, key.title(), key))
-
-    return types
-
-bpy.types.Mesh.THREE_geometry_type = EnumProperty(
-    name="Geometry type",
-    description="Geometry type",
-    items=_geometry_types(),
-    default=constants.GLOBAL)
-
-class ThreeMesh(bpy.types.Panel):
-    """Creates custom properties on a mesh node"""
-
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'data'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        row = self.layout.row()
-        if context.mesh:
-            row.prop(context.mesh,
-                     'THREE_geometry_type',
-                     text="Type")
-
-def _blending_types(index):
-    """Supported blending types for Three.js
-
-    :param index:
-    :type index: int
-    :returns: tuple if types (str, str, str)
-
-    """
-    types = (constants.BLENDING_TYPES.NONE,
-             constants.BLENDING_TYPES.NORMAL,
-             constants.BLENDING_TYPES.ADDITIVE,
-             constants.BLENDING_TYPES.SUBTRACTIVE,
-             constants.BLENDING_TYPES.MULTIPLY,
-             constants.BLENDING_TYPES.CUSTOM)
-    return (types[index], types[index], types[index])
-
-bpy.types.Material.THREE_blending_type = EnumProperty(
-    name="Blending type",
-    description="Blending type",
-    items=[_blending_types(x) for x in range(6)],
-    default=constants.BLENDING_TYPES.NORMAL)
-
-bpy.types.Material.THREE_depth_write = BoolProperty(default=True)
-bpy.types.Material.THREE_depth_test = BoolProperty(default=True)
-bpy.types.Material.THREE_double_sided = BoolProperty(default=False)
-
-class ThreeMaterial(bpy.types.Panel):
-    """Adds custom properties to the Materials of an object"""
-
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'material'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        mat = context.material
-
-        if mat is not None:
-            row = layout.row()
-            row.label(text="Selected material: %s" % mat.name)
-
-            row = layout.row()
-            row.prop(mat, 'THREE_blending_type',
-                     text="Blending type")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_depth_write',
-                     text="Enable depth writing")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_depth_test',
-                     text="Enable depth testing")
-
-            row = layout.row()
-            row.prop(mat, 'THREE_double_sided',
-                     text="Double-sided")
-
-def _mag_filters(index):
-    """Three.js mag filters
-
-    :param index:
-    :type index: int
-    :returns: tuple with the filter values
-
-    """
-    types = (constants.LINEAR_FILTERS.LINEAR,
-             constants.NEAREST_FILTERS.NEAREST)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_mag_filter = EnumProperty(
-    name="Mag Filter",
-    items=[_mag_filters(x) for x in range(2)],
-    default=constants.LINEAR_FILTERS.LINEAR)
-
-def _min_filters(index):
-    """Three.js min filters
-
-    :param index:
-    :type index: int
-    :returns: tuple with the filter values
-
-    """
-    types = (constants.LINEAR_FILTERS.LINEAR,
-             constants.LINEAR_FILTERS.MIP_MAP_NEAREST,
-             constants.LINEAR_FILTERS.MIP_MAP_LINEAR,
-             constants.NEAREST_FILTERS.NEAREST,
-             constants.NEAREST_FILTERS.MIP_MAP_NEAREST,
-             constants.NEAREST_FILTERS.MIP_MAP_LINEAR)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_min_filter = EnumProperty(
-    name="Min Filter",
-    items=[_min_filters(x) for x in range(6)],
-    default=constants.LINEAR_FILTERS.MIP_MAP_LINEAR)
-
-def _mapping(index):
-    """Three.js texture mappings types
-
-    :param index:
-    :type index: int
-    :returns: tuple with the mapping values
-
-    """
-    types = (constants.MAPPING_TYPES.UV,
-             constants.MAPPING_TYPES.CUBE_REFLECTION,
-             constants.MAPPING_TYPES.CUBE_REFRACTION,
-             constants.MAPPING_TYPES.SPHERICAL_REFLECTION)
-    return (types[index], types[index], types[index])
-
-bpy.types.Texture.THREE_mapping = EnumProperty(
-    name="Mapping",
-    items=[_mapping(x) for x in range(4)],
-    default=constants.MAPPING_TYPES.UV)
-
-class ThreeTexture(bpy.types.Panel):
-    """Adds custom properties to a texture"""
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'texture'
-
-    #@TODO: possible to make cycles compatible?
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        tex = context.texture
-
-        if tex is not None:
-            row = layout.row()
-            row.prop(tex, 'THREE_mapping', text="Mapping")
-
-            row = layout.row()
-            row.prop(tex, 'THREE_mag_filter', text="Mag Filter")
-
-            row = layout.row()
-            row.prop(tex, 'THREE_min_filter', text="Min Filter")
-
-bpy.types.Object.THREE_export = bpy.props.BoolProperty(default=True)
-
-class ThreeObject(bpy.types.Panel):
-    """Adds custom properties to an object"""
-    bl_label = 'THREE'
-    bl_space_type = 'PROPERTIES'
-    bl_region_type = 'WINDOW'
-    bl_context = 'object'
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-        layout = self.layout
-        obj = context.object
-
-        row = layout.row()
-        row.prop(obj, 'THREE_export', text='Export')
-
-class ThreeExportSettings(bpy.types.Operator):
-    """Save the current export settings (gets saved in .blend)"""
-    bl_label = "Save Settings"
-    bl_idname = "scene.three_export_settings_set"
-
-    def execute(self, context):
-        cycles = context.scene.cycles
-        cycles.use_samples_final = True
-
-        context.scene[constants.EXPORT_SETTINGS_KEY] = set_settings(context.active_operator.properties)
-
-        self.report({"INFO"}, "Three Export Settings Saved")
-
-        return {"FINISHED"}
-
-def restore_export_settings(properties, settings):
-    """Restore the settings
-
-    :param properties:
-
-    """
-
-    ## Geometry {
-    properties.option_vertices = settings.get(
-        constants.VERTICES,
-        constants.EXPORT_OPTIONS[constants.VERTICES])
-
-    properties.option_faces = settings.get(
-        constants.FACES,
-        constants.EXPORT_OPTIONS[constants.FACES])
-    properties.option_normals = settings.get(
-        constants.NORMALS,
-        constants.EXPORT_OPTIONS[constants.NORMALS])
-
-    properties.option_skinning = settings.get(
-        constants.SKINNING,
-        constants.EXPORT_OPTIONS[constants.SKINNING])
-
-    properties.option_bones = settings.get(
-        constants.BONES,
-        constants.EXPORT_OPTIONS[constants.BONES])
-
-    properties.option_influences = settings.get(
-        constants.INFLUENCES_PER_VERTEX,
-        constants.EXPORT_OPTIONS[constants.INFLUENCES_PER_VERTEX])
-
-    properties.option_apply_modifiers = settings.get(
-        constants.APPLY_MODIFIERS,
-        constants.EXPORT_OPTIONS[constants.APPLY_MODIFIERS])
-
-    properties.option_extra_vgroups = settings.get(
-        constants.EXTRA_VGROUPS,
-        constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
-
-    properties.option_geometry_type = settings.get(
-        constants.GEOMETRY_TYPE,
-        constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
-
-    properties.option_index_type = settings.get(
-        constants.INDEX_TYPE,
-        constants.EXPORT_OPTIONS[constants.INDEX_TYPE])
-    ## }
-
-    ## Materials {
-    properties.option_materials = settings.get(
-        constants.MATERIALS,
-        constants.EXPORT_OPTIONS[constants.MATERIALS])
-
-    properties.option_uv_coords = settings.get(
-        constants.UVS,
-        constants.EXPORT_OPTIONS[constants.UVS])
-
-    properties.option_face_materials = settings.get(
-        constants.FACE_MATERIALS,
-        constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
-
-    properties.option_maps = settings.get(
-        constants.MAPS,
-        constants.EXPORT_OPTIONS[constants.MAPS])
-
-    properties.option_colors = settings.get(
-        constants.COLORS,
-        constants.EXPORT_OPTIONS[constants.COLORS])
-
-    properties.option_mix_colors = settings.get(
-        constants.MIX_COLORS,
-        constants.EXPORT_OPTIONS[constants.MIX_COLORS])
-    ## }
-
-    ## Settings {
-    properties.option_scale = settings.get(
-        constants.SCALE,
-        constants.EXPORT_OPTIONS[constants.SCALE])
-
-    properties.option_round_off = settings.get(
-        constants.ENABLE_PRECISION,
-        constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
-
-    properties.option_round_value = settings.get(
-        constants.PRECISION,
-        constants.EXPORT_OPTIONS[constants.PRECISION])
-
-    properties.option_custom_properties = settings.get(
-        constants.CUSTOM_PROPERTIES,
-        constants.EXPORT_OPTIONS[constants.CUSTOM_PROPERTIES])
-
-    properties.option_logging = settings.get(
-        constants.LOGGING,
-        constants.EXPORT_OPTIONS[constants.LOGGING])
-
-    properties.option_compression = settings.get(
-        constants.COMPRESSION,
-        constants.NONE)
-
-    properties.option_indent = settings.get(
-        constants.INDENT,
-        constants.EXPORT_OPTIONS[constants.INDENT])
-
-    properties.option_export_textures = settings.get(
-        constants.EXPORT_TEXTURES,
-        constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES])
-
-    properties.option_embed_textures = settings.get(
-        constants.EMBED_TEXTURES,
-        constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
-
-    properties.option_texture_folder = settings.get(
-        constants.TEXTURE_FOLDER,
-        constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER])
-
-    properties.option_embed_animation = settings.get(
-        constants.EMBED_ANIMATION,
-        constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
-    ## }
-
-    ## Scene {
-    properties.option_export_scene = settings.get(
-        constants.SCENE,
-        constants.EXPORT_OPTIONS[constants.SCENE])
-
-    #properties.option_embed_geometry = settings.get(
-    #    constants.EMBED_GEOMETRY,
-    #    constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
-
-    properties.option_lights = settings.get(
-        constants.LIGHTS,
-        constants.EXPORT_OPTIONS[constants.LIGHTS])
-
-    properties.option_cameras = settings.get(
-        constants.CAMERAS,
-        constants.EXPORT_OPTIONS[constants.CAMERAS])
-
-    properties.option_hierarchy = settings.get(
-        constants.HIERARCHY,
-        constants.EXPORT_OPTIONS[constants.HIERARCHY])
-    ## }
-
-    ## Animation {
-    properties.option_animation_morph = settings.get(
-        constants.MORPH_TARGETS,
-        constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
-
-    properties.option_blend_shape = settings.get(
-        constants.BLEND_SHAPES,
-        constants.EXPORT_OPTIONS[constants.BLEND_SHAPES])
-
-    properties.option_animation_skeletal = settings.get(
-        constants.ANIMATION,
-        constants.EXPORT_OPTIONS[constants.ANIMATION])
-
-    properties.option_keyframes = settings.get(
-        constants.KEYFRAMES,
-        constants.EXPORT_OPTIONS[constants.KEYFRAMES])
-
-    properties.option_bake_keyframes = settings.get(
-        constants.BAKE_KEYFRAMES,
-        constants.EXPORT_OPTIONS[constants.BAKE_KEYFRAMES])
-
-    properties.option_frame_step = settings.get(
-        constants.FRAME_STEP,
-        constants.EXPORT_OPTIONS[constants.FRAME_STEP])
-
-    properties.option_frame_index_as_time = settings.get(
-        constants.FRAME_INDEX_AS_TIME,
-        constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
-    ## }
-
-def set_settings(properties):
-    """Set the export settings to the correct keys.
-
-    :param properties:
-    :returns: settings
-    :rtype: dict
-
-    """
-    settings = {
-        constants.VERTICES: properties.option_vertices,
-        constants.FACES: properties.option_faces,
-        constants.NORMALS: properties.option_normals,
-        constants.SKINNING: properties.option_skinning,
-        constants.BONES: properties.option_bones,
-        constants.EXTRA_VGROUPS: properties.option_extra_vgroups,
-        constants.APPLY_MODIFIERS: properties.option_apply_modifiers,
-        constants.GEOMETRY_TYPE: properties.option_geometry_type,
-        constants.INDEX_TYPE: properties.option_index_type,
-
-        constants.MATERIALS: properties.option_materials,
-        constants.UVS: properties.option_uv_coords,
-        constants.FACE_MATERIALS: properties.option_face_materials,
-        constants.MAPS: properties.option_maps,
-        constants.COLORS: properties.option_colors,
-        constants.MIX_COLORS: properties.option_mix_colors,
-
-        constants.SCALE: properties.option_scale,
-        constants.ENABLE_PRECISION: properties.option_round_off,
-        constants.PRECISION: properties.option_round_value,
-        constants.CUSTOM_PROPERTIES: properties.option_custom_properties,
-        constants.LOGGING: properties.option_logging,
-        constants.COMPRESSION: properties.option_compression,
-        constants.INDENT: properties.option_indent,
-        constants.EXPORT_TEXTURES: properties.option_export_textures,
-        constants.EMBED_TEXTURES: properties.option_embed_textures,
-        constants.TEXTURE_FOLDER: properties.option_texture_folder,
-
-        constants.SCENE: properties.option_export_scene,
-        #constants.EMBED_GEOMETRY: properties.option_embed_geometry,
-        constants.EMBED_ANIMATION: properties.option_embed_animation,
-        constants.LIGHTS: properties.option_lights,
-        constants.CAMERAS: properties.option_cameras,
-        constants.HIERARCHY: properties.option_hierarchy,
-
-        constants.MORPH_TARGETS: properties.option_animation_morph,
-        constants.BLEND_SHAPES: properties.option_blend_shape,
-        constants.ANIMATION: properties.option_animation_skeletal,
-        constants.KEYFRAMES: properties.option_keyframes,
-        constants.BAKE_KEYFRAMES: properties.option_bake_keyframes,
-        constants.FRAME_STEP: properties.option_frame_step,
-        constants.FRAME_INDEX_AS_TIME: properties.option_frame_index_as_time,
-        constants.INFLUENCES_PER_VERTEX: properties.option_influences
-    }
-
-    return settings
-
-
-def compression_types():
-    """Supported compression formats
-
-    :rtype: tuple
-
-    """
-    types = [(constants.NONE, constants.NONE, constants.NONE)]
-
-    try:
-        import msgpack
-        types.append((constants.MSGPACK, constants.MSGPACK,
-                      constants.MSGPACK))
-    except ImportError:
-        pass
-
-    return types
-
-
-def animation_options():
-    """The supported skeletal animation types
-
-    :returns: list of tuples
-
-    """
-    anim = [
-        (constants.OFF, constants.OFF.title(), constants.OFF),
-        (constants.POSE, constants.POSE.title(), constants.POSE),
-        (constants.REST, constants.REST.title(), constants.REST)
-    ]
-
-    return anim
-
-def resolve_conflicts(self, context):
-    if(not self.option_export_textures):
-        self.option_embed_textures = False;
-
-class ExportThree(bpy.types.Operator, ExportHelper):
-    """Class that handles the export properties"""
-
-    bl_idname = 'export.three'
-    bl_label = 'Export THREE'
-    bl_options = {'PRESET'}
-
-    filename_ext = constants.EXTENSION
-
-    option_vertices = BoolProperty(
-        name="Vertices",
-        description="Export vertices",
-        default=constants.EXPORT_OPTIONS[constants.VERTICES])
-
-    option_faces = BoolProperty(
-        name="Faces",
-        description="Export faces (Geometry only)",
-        default=constants.EXPORT_OPTIONS[constants.FACES])
-
-    option_normals = BoolProperty(
-        name="Normals",
-        description="Export normals",
-        default=constants.EXPORT_OPTIONS[constants.NORMALS])
-
-    option_colors = BoolProperty(
-        name="Vertex Colors",
-        description="Export vertex colors",
-        default=constants.EXPORT_OPTIONS[constants.COLORS])
-
-    option_mix_colors = BoolProperty(
-        name="Mix Colors",
-        description="Mix material and vertex colors",
-        default=constants.EXPORT_OPTIONS[constants.MIX_COLORS])
-
-    option_uv_coords = BoolProperty(
-        name="UVs",
-        description="Export texture coordinates",
-        default=constants.EXPORT_OPTIONS[constants.UVS])
-
-    option_materials = BoolProperty(
-        name="Materials",
-        description="Export materials",
-        default=constants.EXPORT_OPTIONS[constants.MATERIALS])
-
-    option_face_materials = BoolProperty(
-        name="Face Materials",
-        description="Face mapping materials (Geometry only)",
-        default=constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
-
-    option_maps = BoolProperty(
-        name="Textures",
-        description="Include texture maps",
-        default=constants.EXPORT_OPTIONS[constants.MAPS])
-
-    option_skinning = BoolProperty(
-        name="Skinning",
-        description="Export skin data",
-        default=constants.EXPORT_OPTIONS[constants.SKINNING])
-
-    option_bones = BoolProperty(
-        name="Bones",
-        description="Export bones",
-        default=constants.EXPORT_OPTIONS[constants.BONES])
-
-    option_extra_vgroups = StringProperty(
-        name="Extra Vertex Groups",
-        description="Non-skinning vertex groups to export (comma-separated, w/ star wildcard, BufferGeometry only).",
-        default=constants.EXPORT_OPTIONS[constants.EXTRA_VGROUPS])
-
-    option_apply_modifiers = BoolProperty(
-        name="Apply Modifiers",
-        description="Apply Modifiers to mesh objects",
-        default=constants.EXPORT_OPTIONS[constants.APPLY_MODIFIERS]
-    )
-
-    index_buffer_types = [
-        (constants.NONE,) * 3,
-        (constants.UINT_16,) * 3,
-        (constants.UINT_32,) * 3]
-
-    option_index_type = EnumProperty(
-        name="Index Buffer",
-        description="Index buffer type that will be used for BufferGeometry objects.",
-        items=index_buffer_types,
-        default=constants.EXPORT_OPTIONS[constants.INDEX_TYPE])
-
-    option_scale = FloatProperty(
-        name="Scale",
-        description="Scale vertices",
-        min=0.01,
-        max=1000.0,
-        soft_min=0.01,
-        soft_max=1000.0,
-        default=constants.EXPORT_OPTIONS[constants.SCALE])
-
-    option_round_off = BoolProperty(
-        name="Enable Precision",
-        description="Round off floating point values",
-        default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
-
-    option_round_value = IntProperty(
-        name="",
-        min=0,
-        max=16,
-        description="Floating point precision",
-        default=constants.EXPORT_OPTIONS[constants.PRECISION])
-
-    option_custom_properties = BoolProperty(
-        name="Custom Properties",
-        description="Export custom properties as userData",
-        default=False)
-
-    logging_types = [
-        (constants.DISABLED, constants.DISABLED, constants.DISABLED),
-        (constants.DEBUG, constants.DEBUG, constants.DEBUG),
-        (constants.INFO, constants.INFO, constants.INFO),
-        (constants.WARNING, constants.WARNING, constants.WARNING),
-        (constants.ERROR, constants.ERROR, constants.ERROR),
-        (constants.CRITICAL, constants.CRITICAL, constants.CRITICAL)]
-
-    option_logging = EnumProperty(
-        name="",
-        description="Logging verbosity level",
-        items=logging_types,
-        default=constants.DISABLED)
-
-    option_geometry_type = EnumProperty(
-        name="Type",
-        description="Geometry type",
-        items=_geometry_types()[1:],
-        default=constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
-
-    option_export_scene = BoolProperty(
-        name="Scene",
-        description="Export scene",
-        default=constants.EXPORT_OPTIONS[constants.SCENE])
-
-    #@TODO: removing this option since the ObjectLoader doesn't have
-    #       support for handling external geometry data
-    #option_embed_geometry = BoolProperty(
-    #    name="Embed geometry",
-    #    description="Embed geometry",
-    #    default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
-
-    option_embed_animation = BoolProperty(
-        name="Embed animation",
-        description="Embed animation data with the geometry data",
-        default=constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
-
-    option_export_textures = BoolProperty(
-        name="Export textures",
-        description="Export textures",
-        default=constants.EXPORT_OPTIONS[constants.EXPORT_TEXTURES],
-        update=resolve_conflicts)
-
-    option_embed_textures = BoolProperty(
-        name="Embed textures",
-        description="Embed base64 textures in .json",
-        default=constants.EXPORT_OPTIONS[constants.EMBED_TEXTURES])
-
-    option_texture_folder = StringProperty(
-        name="Texture folder",
-        description="add this folder to textures path",
-        default=constants.EXPORT_OPTIONS[constants.TEXTURE_FOLDER])
-
-    option_lights = BoolProperty(
-        name="Lights",
-        description="Export default scene lights",
-        default=False)
-
-    option_cameras = BoolProperty(
-        name="Cameras",
-        description="Export default scene cameras",
-        default=False)
-
-    option_hierarchy = BoolProperty(
-        name="Hierarchy",
-        description="Export object hierarchy",
-        default=False)
-
-    option_animation_morph = BoolProperty(
-        name="Morph animation",
-        description="Export animation (morphs)",
-        default=constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
-
-    option_blend_shape = BoolProperty(
-        name="Blend Shape animation",
-        description="Export Blend Shapes",
-        default=constants.EXPORT_OPTIONS[constants.BLEND_SHAPES])
-
-    option_animation_skeletal = EnumProperty(
-        name="",
-        description="Export animation (skeletal)",
-        items=animation_options(),
-        default=constants.OFF)
-
-    option_keyframes = BoolProperty(
-        name="Keyframe animation",
-        description="Export animation (keyframes)",
-        default=constants.EXPORT_OPTIONS[constants.KEYFRAMES])
-
-    option_bake_keyframes = BoolProperty(
-        name="Bake keyframe animation",
-        description="Bake keyframe animation each frame step",
-        default=constants.EXPORT_OPTIONS[constants.BAKE_KEYFRAMES])
-
-    option_frame_index_as_time = BoolProperty(
-        name="Frame index as time",
-        description="Use (original) frame index as frame time",
-        default=constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
-
-    option_frame_step = IntProperty(
-        name="Frame step",
-        description="Animation frame step",
-        min=1,
-        max=1000,
-        soft_min=1,
-        soft_max=1000,
-        default=1)
-
-    option_indent = BoolProperty(
-        name="Indent JSON",
-        description="Disable this to reduce the file size",
-        default=constants.EXPORT_OPTIONS[constants.INDENT])
-
-    option_compression = EnumProperty(
-        name="",
-        description="Compression options",
-        items=compression_types(),
-        default=constants.NONE)
-
-    option_influences = IntProperty(
-        name="Influences",
-        description="Maximum number of bone influences",
-        min=1,
-        max=4,
-        default=2)
-
-    def invoke(self, context, event):
-        
-        settings = context.scene.get(constants.EXPORT_SETTINGS_KEY)
-        if settings:
-            try:
-                restore_export_settings(self.properties, settings)
-            except AttributeError as e:
-                logging.error("Loading export settings failed:")
-                logging.exception(e)
-                logging.debug("Removed corrupted settings")
-
-                del context.scene[constants.EXPORT_SETTINGS_KEY]
-
-        return ExportHelper.invoke(self, context, event)
-
-    @classmethod
-    def poll(cls, context):
-        """
-
-        :param context:
-
-        """
-        return context.active_object is not None
-
-    def execute(self, context):
-        """
-
-        :param context:
-
-        """
-
-        if not self.properties.filepath:
-            raise Exception("filename not set")
-
-        settings = set_settings(self.properties)
-        settings['addon_version'] = bl_info['version']
-
-        filepath = self.filepath
-        if settings[constants.COMPRESSION] == constants.MSGPACK:
-            filepath = "%s%s" % (filepath[:-4], constants.PACK)
-
-        from io_three import exporter
-        if settings[constants.SCENE]:
-            exporter.export_scene(filepath, settings)
-        else:
-            exporter.export_geometry(filepath, settings)
-
-        return {'FINISHED'}
-
-    def draw(self, context):
-        """
-
-        :param context:
-
-        """
-
-        using_geometry = self.option_geometry_type == constants.GEOMETRY
-
-        layout = self.layout
-
-        ## Scene {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="SCENE", icon="SCENE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_export_scene')
-        row.prop(self.properties, 'option_materials')
-
-        #row = box.row()
-        #row.prop(self.properties, 'option_embed_geometry')
-
-        row = box.row()
-        row.prop(self.properties, 'option_lights')
-        row.prop(self.properties, 'option_cameras')
-
-        row = box.row()
-        row.prop(self.properties, 'option_hierarchy')
-        ## }
-
-        layout.separator()
-
-        ## Geometry {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="GEOMETRY", icon="MESH_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_geometry_type')
-
-        row = box.row()
-        row.prop(self.properties, 'option_index_type')
-
-        row = box.row()
-        row.prop(self.properties, 'option_vertices')
-        col = row.column()
-        col.prop(self.properties, 'option_faces')
-        col.enabled = using_geometry
-
-        row = box.row()
-        row.prop(self.properties, 'option_normals')
-        row.prop(self.properties, 'option_uv_coords')
-
-        row = box.row()
-        row.prop(self.properties, 'option_apply_modifiers')
-
-        row = box.row()
-        row.prop(self.properties, 'option_extra_vgroups')
-        row.enabled = not using_geometry
-        ## }
-
-        layout.separator()
-
-        ## Materials {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-        row.label(text="MATERIAL", icon="MATERIAL_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_colors')
-        row.prop(self.properties, 'option_mix_colors')
-
-        row = box.row()
-        row.prop(self.properties, 'option_face_materials')
-        row.enabled = using_geometry
-        ## }
-
-        layout.separator()
-
-        ## Textures {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="TEXTURE", icon="TEXTURE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_maps')
-        row.prop(self.properties, 'option_export_textures')
-
-        row = box.row()
-        row.prop(self.properties, 'option_embed_textures')
-        row.enabled = self.properties.option_export_textures
-
-        row = box.row()
-        row.prop(self.properties, 'option_texture_folder')
-        ## }
-
-        layout.separator()
-
-        ## Armature {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="ARMATURE", icon="ARMATURE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_bones')
-        row.prop(self.properties, 'option_skinning')
-        ## }
-
-        layout.separator()
-
-        ## Animation {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="ANIMATION", icon="POSE_DATA")
-
-        row = box.row()
-        row.prop(self.properties, 'option_animation_morph')
-        row.prop(self.properties, 'option_blend_shape')
-
-        row = box.row()
-        row.label(text="Skeletal animations:")
-        row.prop(self.properties, 'option_animation_skeletal')
-
-        row = box.row()
-        row.prop(self.properties, 'option_keyframes')
-
-        row = box.row()
-        row.prop(self.properties, 'option_bake_keyframes')
-
-        row = box.row()
-        row.prop(self.properties, 'option_influences')
-
-        row = box.row()
-        row.prop(self.properties, 'option_frame_step')
-
-        row = box.row()
-        row.prop(self.properties, 'option_frame_index_as_time')
-
-        row = box.row()
-        row.prop(self.properties, 'option_embed_animation')
-        ## }
-
-        layout.separator()
-
-        ## Settings {
-        box = layout.box()
-        column = box.column(True)
-        row = column.row(True)
-        row.alignment = 'CENTER'
-
-        row.label(text="SETTINGS", icon="SETTINGS")
-
-        row = box.row()
-        row.prop(self.properties, 'option_scale')
-
-        row = box.row()
-        row.prop(self.properties, 'option_round_off')
-        row.prop(self.properties, 'option_round_value')
-
-        row = box.row()
-        row.prop(self.properties, 'option_custom_properties')
-
-        row = box.row()
-        row.prop(self.properties, 'option_indent')
-
-        row = box.row()
-        row.label(text="Logging verbosity:")
-        row.prop(self.properties, 'option_logging')
-
-        row = box.row()
-        row.label(text="File compression format:")
-        row.prop(self.properties, 'option_compression')
-        ## }
-
-        ## Operators {
-        has_settings = context.scene.get(constants.EXPORT_SETTINGS_KEY, False)
-        row = layout.row()
-        row.operator(
-            ThreeExportSettings.bl_idname,
-            ThreeExportSettings.bl_label,
-            icon="%s" % "PINNED" if has_settings else "UNPINNED")
-        ## }
-
-
-
-def menu_func_export(self, context):
-    """
-
-    :param self:
-    :param context:
-
-    """
-    default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION)
-    text = "Three.js (%s)" % constants.EXTENSION
-    operator = self.layout.operator(ExportThree.bl_idname, text=text)
-    operator.filepath = default_path
-
-
-def register():
-    """Registers the addon (Blender boilerplate)"""
-    bpy.utils.register_module(__name__)
-    bpy.types.INFO_MT_file_export.append(menu_func_export)
-
-
-def unregister():
-    """Unregisters the addon (Blender boilerplate)"""
-    bpy.utils.unregister_module(__name__)
-    bpy.types.INFO_MT_file_export.remove(menu_func_export)
-
-
-if __name__ == '__main__':
-    register()

+ 0 - 398
utils/exporters/blender/addons/io_three/constants.py

@@ -1,398 +0,0 @@
-'''
-All constant data used in the package should be defined here.
-'''
-
-from collections import OrderedDict as BASE_DICT
-
-BLENDING_TYPES = type('Blending', (), {
-    'NONE': 'NoBlending',
-    'NORMAL': 'NormalBlending',
-    'ADDITIVE': 'AdditiveBlending',
-    'SUBTRACTIVE': 'SubtractiveBlending',
-    'MULTIPLY': 'MultiplyBlending',
-    'CUSTOM': 'CustomBlending'
-})
-
-BLENDING_CONSTANTS = type('BlendingConstant', (), {
-    'NoBlending':0,
-    'NormalBlending':1,
-    'AdditiveBlending':2,
-    'SubtractiveBlending':3,
-    'MultiplyBlending':4,
-    'CustomBlending':5
-})
-
-NEAREST_FILTERS = type('NearestFilters', (), {
-    'NEAREST': 'NearestFilter',
-    'MIP_MAP_NEAREST': 'NearestMipMapNearestFilter',
-    'MIP_MAP_LINEAR': 'NearestMipMapLinearFilter'
-})
-
-LINEAR_FILTERS = type('LinearFilters', (), {
-    'LINEAR': 'LinearFilter',
-    'MIP_MAP_NEAREST': 'LinearMipMapNearestFilter',
-    'MIP_MAP_LINEAR': 'LinearMipMapLinearFilter'
-})
-
-MAPPING_TYPES = type('Mapping', (), {
-    'UV': 'UVMapping',
-    'CUBE_REFLECTION': 'CubeReflectionMapping',
-    'CUBE_REFRACTION': 'CubeRefractionMapping',
-    'SPHERICAL_REFLECTION': 'SphericalReflectionMapping'
-})
-
-NUMERIC = {
-    'UVMapping': 300,
-    'CubeReflectionMapping': 301,
-    'CubeRefractionMapping': 302,
-    'EquirectangularReflectionMapping': 303,
-    'EquirectangularRefractionMapping': 304,
-    'SphericalReflectionMapping': 305,
-
-    'RepeatWrapping': 1000,
-    'repeat': 1000,
-    'ClampToEdgeWrapping': 1001,
-    'MirroredRepeatWrapping': 1002,
-
-    'NearestFilter': 1003,
-    'NearestMipMapNearestFilter': 1004,
-    'NearestMipMapLinearFilter': 1005,
-    'LinearFilter': 1006,
-    'LinearMipMapNearestFilter': 1007,
-    'LinearMipMapLinearFilter': 1008
-}
-JSON = 'json'
-EXTENSION = '.%s' % JSON
-INDENT = 'indent'
-
-
-MATERIALS = 'materials'
-SCENE = 'scene'
-VERTICES = 'vertices'
-FACES = 'faces'
-NORMALS = 'normals'
-BONES = 'bones'
-UVS = 'uvs'
-APPLY_MODIFIERS = 'applyModifiers'
-COLORS = 'colors'
-MIX_COLORS = 'mixColors'
-EXTRA_VGROUPS = 'extraVertexGroups'
-INDEX = 'index'
-DRAW_CALLS = 'drawcalls'
-DC_START = 'start'
-DC_COUNT = 'count'
-DC_INDEX = 'index'
-
-GROUPS = 'groups'
-
-SCALE = 'scale'
-COMPRESSION = 'compression'
-MAPS = 'maps'
-FRAME_STEP = 'frameStep'
-FRAME_INDEX_AS_TIME = 'frameIndexAsTime'
-ANIMATION = 'animations'
-CLIPS="clips"
-KEYFRAMES = 'tracks'
-BAKE_KEYFRAMES = 'bake_tracks'
-MORPH_TARGETS = 'morphTargets'
-MORPH_TARGETS_ANIM = 'morphTargetsAnimation'
-BLEND_SHAPES = 'blendShapes'
-POSE = 'pose'
-REST = 'rest'
-SKIN_INDICES = 'skinIndices'
-SKIN_WEIGHTS = 'skinWeights'
-LOGGING = 'logging'
-CAMERAS = 'cameras'
-LIGHTS = 'lights'
-HIERARCHY = 'hierarchy'
-FACE_MATERIALS = 'faceMaterials'
-SKINNING = 'skinning'
-EXPORT_TEXTURES = 'exportTextures'
-EMBED_TEXTURES = 'embedTextures'
-TEXTURE_FOLDER = 'textureFolder'
-ENABLE_PRECISION = 'enablePrecision'
-PRECISION = 'precision'
-DEFAULT_PRECISION = 6
-CUSTOM_PROPERTIES = 'customProperties'
-EMBED_GEOMETRY = 'embedGeometry'
-EMBED_ANIMATION = 'embedAnimation'
-OFF = 'off'
-
-GLOBAL = 'global'
-BUFFER_GEOMETRY = 'BufferGeometry'
-GEOMETRY = 'geometry'
-GEOMETRY_TYPE = 'geometryType'
-INDEX_TYPE = 'indexType'
-
-CRITICAL = 'critical'
-ERROR = 'error'
-WARNING = 'warning'
-INFO = 'info'
-DEBUG = 'debug'
-DISABLED = 'disabled'
-
-NONE = 'None'
-MSGPACK = 'msgpack'
-
-PACK = 'pack'
-
-FLOAT_32 = 'Float32Array'
-UINT_16 = 'Uint16Array'
-UINT_32 = 'Uint32Array'
-
-INFLUENCES_PER_VERTEX = 'influencesPerVertex'
-
-EXPORT_OPTIONS = {
-    FACES: True,
-    VERTICES: True,
-    NORMALS: True,
-    UVS: True,
-    APPLY_MODIFIERS: True,
-    COLORS: False,
-    EXTRA_VGROUPS: '',
-    INDEX_TYPE: UINT_16,
-    MATERIALS: False,
-    FACE_MATERIALS: False,
-    SCALE: 1,
-    FRAME_STEP: 1,
-    FRAME_INDEX_AS_TIME: False,
-    SCENE: False,
-    MIX_COLORS: False,
-    COMPRESSION: None,
-    MAPS: False,
-    ANIMATION: OFF,
-    KEYFRAMES: False,
-    BAKE_KEYFRAMES: False,
-    BONES: False,
-    SKINNING: False,
-    MORPH_TARGETS: False,
-    BLEND_SHAPES: False,
-    CAMERAS: False,
-    LIGHTS: False,
-    HIERARCHY: False,
-    EXPORT_TEXTURES: True,
-    EMBED_TEXTURES: False,
-    TEXTURE_FOLDER: '',
-    LOGGING: DEBUG,
-    ENABLE_PRECISION: False,
-    PRECISION: DEFAULT_PRECISION,
-    CUSTOM_PROPERTIES: False,
-    EMBED_GEOMETRY: True,
-    EMBED_ANIMATION: True,
-    GEOMETRY_TYPE: BUFFER_GEOMETRY,
-    INFLUENCES_PER_VERTEX: 2,
-    INDENT: True
-}
-
-
-FORMAT_VERSION = 4.4
-VERSION = 'version'
-THREE = 'io_three'
-GENERATOR = 'generator'
-SOURCE_FILE = 'sourceFile'
-VALID_DATA_TYPES = (str, int, float, bool, list, tuple, dict)
-
-JSON = 'json'
-GZIP = 'gzip'
-
-EXTENSIONS = {
-    JSON: '.json',
-    MSGPACK: '.pack',
-    GZIP: '.gz'
-}
-
-METADATA = 'metadata'
-GEOMETRIES = 'geometries'
-IMAGES = 'images'
-TEXTURE = 'texture'
-TEXTURES = 'textures'
-
-USER_DATA = 'userData'
-DATA = 'data'
-TYPE = 'type'
-
-MATERIAL = 'material'
-OBJECT = 'object'
-PERSPECTIVE_CAMERA = 'PerspectiveCamera'
-ORTHOGRAPHIC_CAMERA = 'OrthographicCamera'
-AMBIENT_LIGHT = 'AmbientLight'
-DIRECTIONAL_LIGHT = 'DirectionalLight'
-POINT_LIGHT = 'PointLight'
-SPOT_LIGHT = 'SpotLight'
-# TODO (abelnation): confirm this is correct area light string for exporter
-RECT_AREA_LIGHT = 'RectAreaLight'
-HEMISPHERE_LIGHT = 'HemisphereLight'
-# TODO: RectAreaLight support
-MESH = 'Mesh'
-EMPTY = 'Empty'
-SPRITE = 'Sprite'
-
-DEFAULT_METADATA = {
-    VERSION: FORMAT_VERSION,
-    TYPE: OBJECT.title(),
-    GENERATOR: THREE
-}
-
-UUID = 'uuid'
-
-MATRIX = 'matrix'
-POSITION = 'position'
-QUATERNION = 'quaternion'
-ROTATION = 'rotation'
-SCALE = 'scale'
-
-UV = 'uv'
-UV2 = 'uv2'
-ATTRIBUTES = 'attributes'
-NORMAL = 'normal'
-ITEM_SIZE = 'itemSize'
-ARRAY = 'array'
-
-VISIBLE = 'visible'
-CAST_SHADOW = 'castShadow'
-RECEIVE_SHADOW = 'receiveShadow'
-QUAD = 'quad'
-
-MASK = {
-    QUAD: 0,
-    MATERIALS: 1,
-    UVS: 3,
-    NORMALS: 5,
-    COLORS: 7
-}
-
-
-CHILDREN = 'children'
-
-URL = 'url'
-WRAP = 'wrap'
-REPEAT = 'repeat'
-WRAPPING = type('Wrapping', (), {
-    'REPEAT': 'repeat',
-    'CLAMP': 'clamp',
-    'MIRROR': 'mirror'
-})
-ANISOTROPY = 'anisotropy'
-MAG_FILTER = 'magFilter'
-MIN_FILTER = 'minFilter'
-MAPPING = 'mapping'
-
-IMAGE = 'image'
-
-NAME = 'name'
-PARENT = 'parent'
-LENGTH = 'length'
-FPS = 'fps'
-HIERARCHY = 'hierarchy'
-POS = 'pos'
-ROTQ = 'rotq'
-ROT = 'rot'
-SCL = 'scl'
-TIME = 'time'
-KEYS = 'keys'
-
-COLOR = 'color'
-EMISSIVE = 'emissive'
-SPECULAR = 'specular'
-SPECULAR_COEF = 'specularCoef'
-SHININESS = 'shininess'
-SIDE = 'side'
-OPACITY = 'opacity'
-TRANSPARENT = 'transparent'
-WIREFRAME = 'wireframe'
-BLENDING = 'blending'
-VERTEX_COLORS = 'vertexColors'
-DEPTH_WRITE = 'depthWrite'
-DEPTH_TEST = 'depthTest'
-
-MAP = 'map'
-SPECULAR_MAP = 'specularMap'
-LIGHT_MAP = 'lightMap'
-BUMP_MAP = 'bumpMap'
-BUMP_SCALE = 'bumpScale'
-NORMAL_MAP = 'normalMap'
-NORMAL_SCALE = 'normalScale'
-
-#@TODO ENV_MAP, REFLECTIVITY, REFRACTION_RATIO, COMBINE
-
-MAP_DIFFUSE = 'mapDiffuse'
-MAP_DIFFUSE_REPEAT = 'mapDiffuseRepeat'
-MAP_DIFFUSE_WRAP = 'mapDiffuseWrap'
-MAP_DIFFUSE_ANISOTROPY = 'mapDiffuseAnisotropy'
-
-MAP_SPECULAR = 'mapSpecular'
-MAP_SPECULAR_REPEAT = 'mapSpecularRepeat'
-MAP_SPECULAR_WRAP = 'mapSpecularWrap'
-MAP_SPECULAR_ANISOTROPY = 'mapSpecularAnisotropy'
-
-MAP_LIGHT = 'mapLight'
-MAP_LIGHT_REPEAT = 'mapLightRepeat'
-MAP_LIGHT_WRAP = 'mapLightWrap'
-MAP_LIGHT_ANISOTROPY = 'mapLightAnisotropy'
-
-MAP_NORMAL = 'mapNormal'
-MAP_NORMAL_FACTOR = 'mapNormalFactor'
-MAP_NORMAL_REPEAT = 'mapNormalRepeat'
-MAP_NORMAL_WRAP = 'mapNormalWrap'
-MAP_NORMAL_ANISOTROPY = 'mapNormalAnisotropy'
-
-MAP_BUMP = 'mapBump'
-MAP_BUMP_REPEAT = 'mapBumpRepeat'
-MAP_BUMP_WRAP = 'mapBumpWrap'
-MAP_BUMP_ANISOTROPY = 'mapBumpAnisotropy'
-MAP_BUMP_SCALE = 'mapBumpScale'
-
-NORMAL_BLENDING = 0
-
-VERTEX_COLORS_ON = 2
-VERTEX_COLORS_OFF = 0
-
-SIDE_DOUBLE = 2
-
-THREE_BASIC = 'MeshBasicMaterial'
-THREE_LAMBERT = 'MeshLambertMaterial'
-THREE_PHONG = 'MeshPhongMaterial'
-
-INTENSITY = 'intensity'
-DISTANCE = 'distance'
-ANGLE = 'angle'
-DECAY = 'decayExponent'
-
-FOV = 'fov'
-ASPECT = 'aspect'
-NEAR = 'near'
-FAR = 'far'
-
-LEFT = 'left'
-RIGHT = 'right'
-TOP = 'top'
-BOTTOM = 'bottom'
-
-SHADING = 'shading'
-COLOR_DIFFUSE = 'colorDiffuse'
-COLOR_EMISSIVE = 'colorEmissive'
-COLOR_SPECULAR = 'colorSpecular'
-DBG_NAME = 'DbgName'
-DBG_COLOR = 'DbgColor'
-DBG_INDEX = 'DbgIndex'
-EMIT = 'emit'
-
-PHONG = 'phong'
-LAMBERT = 'lambert'
-BASIC = 'basic'
-
-NORMAL_BLENDING = 'NormalBlending'
-
-DBG_COLORS = (0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee,
-              0xeeee00, 0x00eeee, 0xee00ee)
-
-DOUBLE_SIDED = 'doubleSided'
-
-EXPORT_SETTINGS_KEY = 'threeExportSettings'
-
-# flips vectors
-
-XZ_Y = "XZ_Y"
-X_ZY = "X_ZY"
-XYZ = "XYZ"
-_XY_Z = "_XY_Z"

+ 0 - 112
utils/exporters/blender/addons/io_three/dialogs.py

@@ -1,112 +0,0 @@
-from bpy import context
-
-CONTEXT = {
-    0: {
-        'title': "Error Message",
-        'icon': 'CANCEL'
-    },
-    1: {
-        'title': "Warning Message",
-        'icon': 'ERROR' # I prefer this icon for warnings
-    },
-    2: {
-        'title': "Message",
-        'icon': 'NONE'
-    },
-    3: {
-        'title': "Question",
-        'icon': 'QUESTION'
-    }
-}
-
-
-def error(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 0)
-
-
-def warning(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 1)
-
-
-
-def info(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 2)
-
-
-
-def question(message, title="", wrap=40):
-    """Creates an error dialog.
-
-    :param message: text of the message body
-    :param title: text to append to the title
-                  (Default value = "")
-    :param wrap: line width (Default value = 40)
-
-    """
-    _draw(message, title, wrap, 3)
-
-
-
-# Great idea borrowed from
-# http://community.cgcookie.com/t/code-snippet-easy-error-messages/203
-def _draw(message, title, wrap, key):
-    """
-
-    :type message: str
-    :type title: str
-    :type wrap: int
-    :type key: int
-
-    """
-    lines = []
-    if wrap > 0:
-        while len(message) > wrap:
-            i = message.rfind(' ', 0, wrap)
-            if i == -1:
-                lines += [message[:wrap]]
-                message = message[wrap:]
-            else:
-                lines += [message[:i]]
-                message = message[i+1:]
-    if message:
-        lines += [message]
-
-    def draw(self, *args):
-        """
-
-        :param self:
-        :param *args:
-
-        """
-        for line in lines:
-            self.layout.label(line)
-
-    title = "%s: %s" % (title, CONTEXT[key]['title'])
-    icon = CONTEXT[key]['icon']
-
-    context.window_manager.popup_menu(
-        draw, title=title.strip(), icon=icon)

+ 0 - 9
utils/exporters/blender/addons/io_three/exceptions.py

@@ -1,9 +0,0 @@
-class ThreeError(Exception): pass
-class UnimplementedFeatureError(ThreeError): pass
-class ThreeValueError(ThreeError): pass
-class UnsupportedObjectType(ThreeError): pass
-class GeometryError(ThreeError): pass
-class MaterialError(ThreeError): pass
-class SelectionError(ThreeError): pass
-class NGonError(ThreeError): pass
-class BufferGeometryError(ThreeError): pass

+ 0 - 96
utils/exporters/blender/addons/io_three/exporter/__init__.py

@@ -1,96 +0,0 @@
-import os
-import sys
-import traceback
-from .. import constants, logger, exceptions, dialogs
-from . import scene, geometry, api, base_classes
-
-
-def _error_handler(func):
-    
-    def inner(filepath, options, *args, **kwargs):
-        level = options.get(constants.LOGGING, constants.DISABLED)
-        version = options.get('addon_version')
-        if level != constants.DISABLED:
-            logger.init('io_three.export.log', level=level)
-        if version is not None:
-            logger.debug("Addon Version %s", version)
-        api.init()
-        
-        try:
-            func(filepath, options, *args, **kwargs)
-        except:
-            info = sys.exc_info()
-            trace = traceback.format_exception(
-                info[0], info[1], info[2].tb_next)
-            trace = ''.join(trace)
-            logger.error(trace)
-            
-            print('Error recorded to %s' % logger.LOG_FILE)
-
-            raise
-        else:
-            print('Log: %s' % logger.LOG_FILE)
-
-    return inner
-
-
-@_error_handler
-def export_scene(filepath, options):
-    selected = []
-
-    # during scene exports unselect everything. this is needed for
-    # applying modifiers, if it is necessary
-    # record the selected nodes so that selection is restored later
-    for obj in api.selected_objects():
-        api.object.unselect(obj)
-        selected.append(obj)
-    active = api.active_object()
-
-    try:
-        scene_ = scene.Scene(filepath, options=options)
-        scene_.parse()
-        scene_.write()
-    except:
-        _restore_selection(selected, active)
-        raise
-        
-    _restore_selection(selected, active)
-
-
-@_error_handler
-def export_geometry(filepath, options, node=None):
-    msg = ""
-    exception = None
-    if node is None:
-        node = api.active_object()
-        if node is None:
-            msg = "Nothing selected"
-            logger.error(msg)
-            exception = exceptions.SelectionError
-        if node.type != 'MESH':
-            msg = "%s is not a valid mesh object" % node.name
-            logger.error(msg)
-            exception = exceptions.GeometryError
-    
-        if exception is not None:
-            if api.batch_mode():
-                raise exception(msg)
-            else:
-                dialogs.error(msg)
-                return
-
-    mesh = api.object.mesh(node, options)
-    parent = base_classes.BaseScene(filepath, options)
-    geo = geometry.Geometry(mesh, parent)
-    geo.parse()
-    geo.write()
-    
-    if not options.get(constants.EMBED_ANIMATION, True):
-        geo.write_animation(os.path.dirname(filepath))
-
-
-def _restore_selection(objects, active):
-    for obj in objects:
-        api.object.select(obj)
-
-    api.set_active_object(active)

+ 0 - 208
utils/exporters/blender/addons/io_three/exporter/_json.py

@@ -1,208 +0,0 @@
-import json
-from .. import constants
-
-ROUND = constants.DEFAULT_PRECISION
-
-## THREE override function
-def _json_floatstr(o):
-    if ROUND is not None:
-        o = round(o, ROUND)
-        
-    return '%g' % o
-
-
-def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
-        _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
-        ## HACK: hand-optimized bytecode; turn globals into locals
-        ValueError=ValueError,
-        dict=dict,
-        float=float,
-        id=id,
-        int=int,
-        isinstance=isinstance,
-        list=list,
-        str=str,
-        tuple=tuple,
-    ):
-    '''
-    Overwrite json.encoder for Python 2.7 and above to not
-    assign each index of a list or tuple to its own row as
-    this is completely asinine behaviour 
-    '''
-
-    ## @THREE
-    # Override the function
-    _floatstr = _json_floatstr
-
-    if _indent is not None and not isinstance(_indent, str):
-        _indent = ' ' * _indent
-
-    def _iterencode_list(lst, _current_indent_level):
-        if not lst:
-            yield '[]'
-            return
-        if markers is not None:
-            markerid = id(lst)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = lst
-        buf = '['
-        ## @THREEJS
-        # -  block the moronic functionality that puts each
-        #    index on its own line causing insane row counts
-        #if _indent is not None:
-        #    _current_indent_level += 1
-        #    newline_indent = '\n' + _indent * _current_indent_level
-        #    separator = _item_separator + newline_indent
-        #    buf += newline_indent
-        #else:
-        newline_indent = None
-        separator = _item_separator
-        first = True
-        for value in lst:
-            if first:
-                first = False
-            else:
-                buf = separator
-            if isinstance(value, str):
-                yield buf + _encoder(value)
-            elif value is None:
-                yield buf + 'null'
-            elif value is True:
-                yield buf + 'true'
-            elif value is False:
-                yield buf + 'false'
-            elif isinstance(value, int):
-                yield buf + str(value)
-            elif isinstance(value, float):
-                yield buf + _floatstr(value)
-            else:
-                yield buf
-                if isinstance(value, (list, tuple)):
-                    chunks = _iterencode_list(value, _current_indent_level)
-                elif isinstance(value, dict):
-                    chunks = _iterencode_dict(value, _current_indent_level)
-                else:
-                    chunks = _iterencode(value, _current_indent_level)
-                for chunk in chunks:
-                    yield chunk
-        if newline_indent is not None:
-            _current_indent_level -= 1
-            yield '\n' + _indent * _current_indent_level
-        yield ']'
-        if markers is not None:
-            del markers[markerid]
-
-    def _iterencode_dict(dct, _current_indent_level):
-        if not dct:
-            yield '{}'
-            return
-        if markers is not None:
-            markerid = id(dct)
-            if markerid in markers:
-                raise ValueError("Circular reference detected")
-            markers[markerid] = dct
-        yield '{'
-        if _indent is not None:
-            _current_indent_level += 1
-            newline_indent = '\n' + _indent * _current_indent_level
-            item_separator = _item_separator + newline_indent
-            yield newline_indent
-        else:
-            newline_indent = None
-            item_separator = _item_separator
-        first = True
-        if _sort_keys:
-            items = sorted(dct.items(), key=lambda kv: kv[0])
-        else:
-            items = dct.items()
-        for key, value in items:
-            if isinstance(key, str):
-                pass
-            # JavaScript is weakly typed for these, so it makes sense to
-            # also allow them.  Many encoders seem to do something like this.
-            elif isinstance(key, float):
-                key = _floatstr(key)
-            elif key is True:
-                key = 'true'
-            elif key is False:
-                key = 'false'
-            elif key is None:
-                key = 'null'
-            elif isinstance(key, int):
-                key = str(key)
-            elif _skipkeys:
-                continue
-            else:
-                raise TypeError("key " + repr(key) + " is not a string")
-            if first:
-                first = False
-            else:
-                yield item_separator
-            yield _encoder(key)
-            yield _key_separator
-            if isinstance(value, str):
-                yield _encoder(value)
-            elif value is None:
-                yield 'null'
-            elif value is True:
-                yield 'true'
-            elif value is False:
-                yield 'false'
-            elif isinstance(value, int):
-                yield str(value)
-            elif isinstance(value, float):
-                yield _floatstr(value)
-            else:
-                if isinstance(value, (list, tuple)):
-                    chunks = _iterencode_list(value, _current_indent_level)
-                elif isinstance(value, dict):
-                    chunks = _iterencode_dict(value, _current_indent_level)
-                else:
-                    chunks = _iterencode(value, _current_indent_level)
-                for chunk in chunks:
-                    yield chunk
-        if newline_indent is not None:
-            _current_indent_level -= 1
-            yield '\n' + _indent * _current_indent_level
-        yield '}'
-        if markers is not None:
-            del markers[markerid]
-
-    def _iterencode(o, _current_indent_level):
-        if isinstance(o, str):
-            yield _encoder(o)
-        elif o is None:
-            yield 'null'
-        elif o is True:
-            yield 'true'
-        elif o is False:
-            yield 'false'
-        elif isinstance(o, int):
-            yield str(o)
-        elif isinstance(o, float):
-            yield _floatstr(o)
-        elif isinstance(o, (list, tuple)):
-            for chunk in _iterencode_list(o, _current_indent_level):
-                yield chunk
-        elif isinstance(o, dict):
-            for chunk in _iterencode_dict(o, _current_indent_level):
-                yield chunk
-        else:
-            if markers is not None:
-                markerid = id(o)
-                if markerid in markers:
-                    raise ValueError("Circular reference detected")
-                markers[markerid] = o
-            o = _default(o)
-            for chunk in _iterencode(o, _current_indent_level):
-                yield chunk
-            if markers is not None:
-                del markers[markerid]
-    return _iterencode
-
-
-# override the encoder
-json.encoder._make_iterencode = _make_iterencode 
-
-

+ 0 - 77
utils/exporters/blender/addons/io_three/exporter/api/__init__.py

@@ -1,77 +0,0 @@
-import os
-import bpy
-from . import object as object_, mesh, material, camera, light
-from .. import logger
-
-
-def active_object():
-    """
-
-    :return: The actively selected object
-
-    """
-    return bpy.context.scene.objects.active
-
-
-def batch_mode():
-    """
-
-    :return: Whether or not the session is interactive
-    :rtype: bool
-
-    """
-    return bpy.context.area is None
-
-
-def data(node):
-    """
-
-    :param node: name of an object node
-    :returns: the data block of the node
-
-    """
-    try:
-        return bpy.data.objects[node].data
-    except KeyError:
-        pass
-
-
-def init():
-    """Initializing the api module. Required first step before
-    initializing the actual export process.
-    """
-    logger.debug("Initializing API")
-    object_.clear_mesh_map()
-
-
-def selected_objects(valid_types=None):
-    """Selected objects.
-
-    :param valid_types: Filter for valid types (Default value = None)
-
-    """
-    logger.debug("api.selected_objects(%s)", valid_types)
-    for node in bpy.context.selected_objects:
-        if valid_types is None:
-            yield node.name
-        elif valid_types is not None and node.type in valid_types:
-            yield node.name
-
-
-def set_active_object(obj):
-    """Set the object as active in the scene
-
-    :param obj:
-
-    """
-    logger.debug("api.set_active_object(%s)", obj)
-    bpy.context.scene.objects.active = obj
-
-
-def scene_name():
-    """
-
-    :return: name of the current scene
-
-    """
-    return os.path.basename(bpy.data.filepath)

+ 0 - 683
utils/exporters/blender/addons/io_three/exporter/api/animation.py

@@ -1,683 +0,0 @@
-"""
-Module for handling the parsing of skeletal animation data.
-updated on 2/07/2016: bones scaling support (@uthor verteAzur [email protected])
-"""
-
-import math
-import mathutils
-from bpy import data, context, ops
-from .. import constants, logger
-
-def pose_animation(armature, options):
-    """Query armature animation using pose bones
-
-    :param armature:
-    :param options:
-    :returns: list dictionaries containing animationdata
-    :rtype: [{}, {}, ...]
-
-    """
-    logger.debug("animation.pose_animation(%s)", armature)
-    func = _parse_pose_action
-    return _parse_action(func, armature, options)
-
-
-def rest_animation(armature, options):
-    """Query armature animation (REST position)
-
-    :param armature:
-    :param options:
-    :returns: list dictionaries containing animationdata
-    :rtype: [{}, {}, ...]
-
-    """
-    logger.debug("animation.rest_animation(%s)", armature)
-    func = _parse_rest_action
-    return _parse_action(func, armature, options)
-
-
-def _parse_action(func, armature, options):
-    """
-
-    :param func:
-    :param armature:
-    :param options:
-
-    """
-    animations = []
-    logger.info("Parsing %d actions", len(data.actions))
-    for action in data.actions:
-        logger.info("Parsing action %s", action.name)
-        animation = func(action, armature, options)
-        animations.append(animation)
-    return animations
-
-
-def _parse_rest_action(action, armature, options):
-    """
-
-    :param action:
-    :param armature:
-    :param options:
-
-    """
-    end_frame = action.frame_range[1]
-    start_frame = action.frame_range[0]
-    frame_length = end_frame - start_frame
-    rot = armature.matrix_world.decompose()[1]
-    rotation_matrix = rot.to_matrix()
-    hierarchy = []
-    parent_index = -1
-    frame_step = options.get(constants.FRAME_STEP, 1)
-    fps = context.scene.render.fps
-
-    start = int(start_frame)
-    end = int(end_frame / frame_step) + 1
-
-    for bone in armature.data.bones:
-        # I believe this was meant to skip control bones, may
-        # not be useful. needs more testing
-        if bone.use_deform is False:
-            logger.info("Skipping animation data for bone %s", bone.name)
-            continue
-
-        logger.info("Parsing animation data for bone %s", bone.name)
-
-        keys = []
-        for frame in range(start, end):
-            computed_frame = frame * frame_step
-            pos, pchange = _position(bone, computed_frame,
-                                     action, armature.matrix_world)
-            rot, rchange = _rotation(bone, computed_frame,
-                                     action, rotation_matrix)
-            rot = _normalize_quaternion(rot)
-
-            sca, schange = _scale(bone, computed_frame,
-                                     action, armature.matrix_world)
-
-            pos_x, pos_y, pos_z = pos.x, pos.z, -pos.y
-            rot_x, rot_y, rot_z, rot_w = rot.x, rot.z, -rot.y, rot.w
-            sca_x, sca_y, sca_z = sca.x, sca.z, sca.y
-
-            if frame == start_frame:
-
-                time = (frame * frame_step - start_frame) / fps
-                
-                keyframe = {
-                    constants.TIME: time,
-                    constants.POS: [pos_x, pos_y, pos_z],
-                    constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                    constants.SCL: [sca_x, sca_y, sca_z]
-                }
-                keys.append(keyframe)
-
-            # END-FRAME: needs pos, rot and scl attributes
-            # with animation length (required frame)
-
-            elif frame == end_frame / frame_step:
-
-                time = frame_length / fps
-                keyframe = {
-                    constants.TIME: time,
-                    constants.POS: [pos_x, pos_y, pos_z],
-                    constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                    constants.SCL: [sca_x, sca_y, sca_z]
-                }
-                keys.append(keyframe)
-
-            # MIDDLE-FRAME: needs only one of the attributes,
-            # can be an empty frame (optional frame)
-
-            elif pchange is True or rchange is True or schange is True:
-
-                time = (frame * frame_step - start_frame) / fps
-
-                if pchange is True and rchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.POS: [pos_x, pos_y, pos_z],
-                        constants.ROT: [rot_x, rot_y, rot_z, rot_w],
-                        constants.SCL: [sca_x, sca_y, sca_z]
-                    }
-                elif pchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.POS: [pos_x, pos_y, pos_z]
-                    }
-                elif rchange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.ROT: [rot_x, rot_y, rot_z, rot_w]
-                    }
-                elif schange is True:
-                    keyframe = {
-                        constants.TIME: time,
-                        constants.SCL: [sca_x, sca_y, sca_z]
-                    }
-
-                keys.append(keyframe)
-
-        hierarchy.append({
-            constants.KEYS: keys,
-            constants.PARENT: parent_index
-        })
-        parent_index += 1
-
-    animation = {
-        constants.HIERARCHY: hierarchy,
-        constants.LENGTH: frame_length / fps,
-        constants.FPS: fps,
-        constants.NAME: action.name
-    }
-
-    return animation
-
-
-def _parse_pose_action(action, armature, options):
-    """
-
-    :param action:
-    :param armature:
-    :param options:
-
-    """
-    try:
-        current_context = context.area.type
-    except AttributeError:
-        for window in context.window_manager.windows:
-            screen = window.screen
-            for area in screen.areas:
-                if area.type != 'VIEW_3D':
-                    continue
-
-                override = {
-                    'window': window,
-                    'screen': screen,
-                    'area': area
-                }
-                ops.screen.screen_full_area(override)
-                break
-        current_context = context.area.type
-
-    context.scene.objects.active = armature
-    context.area.type = 'DOPESHEET_EDITOR'
-    context.space_data.mode = 'ACTION'
-    context.area.spaces.active.action = action
-
-    armature_matrix = armature.matrix_world
-    fps = context.scene.render.fps
-
-    end_frame = action.frame_range[1]
-    start_frame = action.frame_range[0]
-    frame_length = end_frame - start_frame
-
-    frame_step = options.get(constants.FRAME_STEP, 1)
-    used_frames = int(frame_length / frame_step) + 1
-
-    keys = []
-    channels_location = []
-    channels_rotation = []
-    channels_scale = []
-
-    for pose_bone in armature.pose.bones:
-        logger.info("Processing channels for %s",
-                    pose_bone.bone.name)
-        keys.append([])
-        channels_location.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'location'))
-        channels_rotation.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'rotation_quaternion'))
-        channels_rotation.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'rotation_euler'))
-        channels_scale.append(
-            _find_channels(action,
-                           pose_bone.bone,
-                           'scale'))
-
-    frame_step = options[constants.FRAME_STEP]
-    frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME]
-    for frame_index in range(0, used_frames):
-        if frame_index == used_frames - 1:
-            frame = end_frame
-        else:
-            frame = start_frame + frame_index * frame_step
-
-        logger.info("Processing frame %d", frame)
-
-        time = frame - start_frame
-        if frame_index_as_time is False:
-            time = time / fps
-
-        context.scene.frame_set(frame)
-
-        bone_index = 0
-
-        def has_keyframe_at(channels, frame):
-            """
-
-            :param channels:
-            :param frame:
-
-            """
-            def find_keyframe_at(channel, frame):
-                """
-
-                :param channel:
-                :param frame:
-
-                """
-                for keyframe in channel.keyframe_points:
-                    if keyframe.co[0] == frame:
-                        return keyframe
-                return None
-
-            for channel in channels:
-                if not find_keyframe_at(channel, frame) is None:
-                    return True
-            return False
-
-        for pose_bone in armature.pose.bones:
-
-            logger.info("Processing bone %s", pose_bone.bone.name)
-            if pose_bone.parent is None:
-                bone_matrix = armature_matrix * pose_bone.matrix
-            else:
-                parent_matrix = armature_matrix * pose_bone.parent.matrix
-                bone_matrix = armature_matrix * pose_bone.matrix
-                bone_matrix = parent_matrix.inverted() * bone_matrix
-
-            pos, rot, scl = bone_matrix.decompose()
-            rot = _normalize_quaternion(rot)
-
-            pchange = True or has_keyframe_at(
-                channels_location[bone_index], frame)
-            rchange = True or has_keyframe_at(
-                channels_rotation[bone_index], frame)
-            schange = True or has_keyframe_at(
-                channels_scale[bone_index], frame)
-
-            pos = (pos.x, pos.z, -pos.y)
-            rot = (rot.x, rot.z, -rot.y, rot.w)
-            scl = (scl.x, scl.z, scl.y)
-
-            keyframe = {constants.TIME: time}
-            if frame == start_frame or frame == end_frame:
-                keyframe.update({
-                    constants.POS: pos,
-                    constants.ROT: rot,
-                    constants.SCL: scl
-                })
-            elif any([pchange, rchange, schange]):
-                if pchange is True:
-                    keyframe[constants.POS] = pos
-                if rchange is True:
-                    keyframe[constants.ROT] = rot
-                if schange is True:
-                    keyframe[constants.SCL] = scl
-
-            if len(keyframe.keys()) > 1:
-                logger.info("Recording keyframe data for %s %s",
-                            pose_bone.bone.name, str(keyframe))
-                keys[bone_index].append(keyframe)
-            else:
-                logger.info("No anim data to record for %s",
-                            pose_bone.bone.name)
-
-            bone_index += 1
-
-    hierarchy = []
-    bone_index = 0
-    for pose_bone in armature.pose.bones:
-        hierarchy.append({
-            constants.PARENT: bone_index - 1,
-            constants.KEYS: keys[bone_index]
-        })
-        bone_index += 1
-
-    if frame_index_as_time is False:
-        frame_length = frame_length / fps
-
-    context.scene.frame_set(start_frame)
-    context.area.type = current_context
-
-    animation = {
-        constants.HIERARCHY: hierarchy,
-        constants.LENGTH: frame_length,
-        constants.FPS: fps,
-        constants.NAME: action.name
-    }
-
-    return animation
-
-
-def _find_channels(action, bone, channel_type):
-    """
-
-    :param action:
-    :param bone:
-    :param channel_type:
-
-    """
-    result = []
-
-    if len(action.groups):
-
-        group_index = -1
-        for index, group in enumerate(action.groups):
-            if group.name == bone.name:
-                group_index = index
-                # @TODO: break?
-
-        if group_index > -1:
-            for channel in action.groups[group_index].channels:
-                if channel_type in channel.data_path:
-                    result.append(channel)
-
-    else:
-        bone_label = '"%s"' % bone.name
-        for channel in action.fcurves:
-            data_path = [bone_label in channel.data_path,
-                         channel_type in channel.data_path]
-            if all(data_path):
-                result.append(channel)
-
-    return result
-
-
-def _position(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-
-    position = mathutils.Vector((0, 0, 0))
-    change = False
-
-    ngroups = len(action.groups)
-
-    if ngroups > 0:
-
-        index = 0
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-                index = i
-
-        for channel in action.groups[index].channels:
-            if "location" in channel.data_path:
-                has_changed = _handle_position_channel(
-                    channel, frame, position)
-                change = change or has_changed
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "location" in data_path:
-                has_changed = _handle_position_channel(
-                    channel, frame, position)
-                change = change or has_changed
-
-    position = position * bone.matrix_local.inverted()
-
-    if bone.parent is None:
-
-        position.x += bone.head.x
-        position.y += bone.head.y
-        position.z += bone.head.z
-
-    else:
-
-        parent = bone.parent
-
-        parent_matrix = parent.matrix_local.inverted()
-        diff = parent.tail_local - parent.head_local
-
-        position.x += (bone.head * parent_matrix).x + diff.x
-        position.y += (bone.head * parent_matrix).y + diff.y
-        position.z += (bone.head * parent_matrix).z + diff.z
-
-    return armature_matrix*position, change
-
-
-def _rotation(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-
-    # TODO: calculate rotation also from rotation_euler channels
-
-    rotation = mathutils.Vector((0, 0, 0, 1))
-
-    change = False
-
-    ngroups = len(action.groups)
-
-    # animation grouped by bones
-
-    if ngroups > 0:
-
-        index = -1
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-                index = i
-
-        if index > -1:
-            for channel in action.groups[index].channels:
-                if "quaternion" in channel.data_path:
-                    has_changed = _handle_rotation_channel(
-                        channel, frame, rotation)
-                    change = change or has_changed
-
-    # animation in raw fcurves
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "quaternion" in data_path:
-                has_changed = _handle_rotation_channel(
-                    channel, frame, rotation)
-                change = change or has_changed
-
-    rot3 = rotation.to_3d()
-    rotation.xyz = rot3 * bone.matrix_local.inverted()
-    rotation.xyz = armature_matrix * rotation.xyz
-
-    return rotation, change
-
-def _scale(bone, frame, action, armature_matrix):
-    """
-
-    :param bone:
-    :param frame:
-    :param action:
-    :param armature_matrix:
-
-    """
-    scale = mathutils.Vector((1.0, 1.0, 1.0))
-
-    change = False
-
-    ngroups = len(action.groups)
-
-    # animation grouped by bones
-	
-    if ngroups > 0:
-
-        index = -1
-
-        for i in range(ngroups):
-            if action.groups[i].name == bone.name:
-		
-                print(action.groups[i].name)
-
-                index = i
-
-        if index > -1:
-            for channel in action.groups[index].channels:
- 
-                if "scale" in channel.data_path:
-                    has_changed = _handle_scale_channel(
-                        channel, frame, scale)
-                    change = change or has_changed
-                    
-    # animation in raw fcurves
-
-    else:
-
-        bone_label = '"%s"' % bone.name
-	
-        for channel in action.fcurves:
-            data_path = channel.data_path
-            if bone_label in data_path and "scale" in data_path:
-                has_changed = _handle_scale_channel(
-                    channel, frame, scale)
-                change = change or has_changed
-    	
-   
-    #scale.xyz = armature_matrix * scale.xyz
-
-    return scale, change
-
-
-def _handle_rotation_channel(channel, frame, rotation):
-    """
-
-    :param channel:
-    :param frame:
-    :param rotation:
-
-    """
-
-    change = False
-
-    if channel.array_index in [0, 1, 2, 3]:
-
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-
-        value = channel.evaluate(frame)
-
-        if channel.array_index == 1:
-            rotation.x = value
-
-        elif channel.array_index == 2:
-            rotation.y = value
-
-        elif channel.array_index == 3:
-            rotation.z = value
-
-        elif channel.array_index == 0:
-            rotation.w = value
-
-    return change
-
-
-def _handle_position_channel(channel, frame, position):
-    """
-
-    :param channel:
-    :param frame:
-    :param position:
-
-    """
-
-    change = False
-
-    if channel.array_index in [0, 1, 2]:
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-
-        value = channel.evaluate(frame)
-
-        if channel.array_index == 0:
-            position.x = value
-
-        if channel.array_index == 1:
-            position.y = value
-
-        if channel.array_index == 2:
-            position.z = value
-
-    return change
-
-def _handle_scale_channel(channel, frame, scale):
-    """
-
-    :param channel:
-    :param frame:
-    :param position:
-
-    """
-    change = False
-
-    if channel.array_index in [0, 1, 2]:
-        for keyframe in channel.keyframe_points:
-            if keyframe.co[0] == frame:
-                change = True
-       
-        value = channel.evaluate(frame)
-      
-        if channel.array_index == 0:
-            scale.x = value
-
-        if channel.array_index == 1:
-            scale.y = value
-
-        if channel.array_index == 2:
-            scale.z = value
-
-    return change
-
-
-def _quaternion_length(quat):
-    """Calculate the length of a quaternion
-
-    :param quat: Blender quaternion object
-    :rtype: float
-
-    """
-    return math.sqrt(quat.x * quat.x + quat.y * quat.y +
-                     quat.z * quat.z + quat.w * quat.w)
-
-
-def _normalize_quaternion(quat):
-    """Normalize a quaternion
-
-    :param quat: Blender quaternion object
-    :returns: generic quaternion enum object with normalized values
-    :rtype: object
-
-    """
-    enum = type('Enum', (), {'x': 0, 'y': 0, 'z': 0, 'w': 1})
-    length = _quaternion_length(quat)
-    if length is not 0:
-        length = 1 / length
-        enum.x = quat.x * length
-        enum.y = quat.y * length
-        enum.z = quat.z * length
-        enum.w = quat.w * length
-    return enum

+ 0 - 130
utils/exporters/blender/addons/io_three/exporter/api/camera.py

@@ -1,130 +0,0 @@
-import math
-from bpy import data, types, context
-from .. import logger
-
-
-def _camera(func):
-    """
-
-    :param func:
-
-    """
-
-    def inner(name, *args, **kwargs):
-        """
-
-        :param name:
-        :param *args:
-        :param **kwargs:
-
-        """
-
-        if isinstance(name, types.Camera):
-            camera = name
-        else:
-            camera = data.cameras[name]
-
-        return func(camera, *args, **kwargs)
-
-    return inner
-
-
-@_camera
-def aspect(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.aspect(%s)", camera)
-    render = context.scene.render
-    return render.resolution_x/render.resolution_y
-
-
-@_camera
-def bottom(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.bottom(%s)", camera)
-    return -(camera.angle_y * camera.ortho_scale)
-
-
-@_camera
-def far(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.far(%s)", camera)
-    return camera.clip_end
-
-
-@_camera
-def fov(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.fov(%s)", camera)
-    fov_in_radians = camera.angle
-    aspect_ratio = aspect(camera)
-    if aspect_ratio > 1:
-        fov_in_radians = 2 * math.atan(math.tan(fov_in_radians / 2) / aspect_ratio)
-    return math.degrees(fov_in_radians)
-
-
-@_camera
-def left(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.left(%s)", camera)
-    return -(camera.angle_x * camera.ortho_scale)
-
-
-@_camera
-def near(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.near(%s)", camera)
-    return camera.clip_start
-
-
-@_camera
-def right(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.right(%s)", camera)
-    return camera.angle_x * camera.ortho_scale
-
-
-@_camera
-def top(camera):
-    """
-
-    :param camera:
-    :rtype: float
-
-    """
-    logger.debug("camera.top(%s)", camera)
-    return camera.angle_y * camera.ortho_scale

+ 0 - 29
utils/exporters/blender/addons/io_three/exporter/api/constants.py

@@ -1,29 +0,0 @@
-MESH = 'MESH'
-LAMP = 'LAMP'
-EMPTY = 'EMPTY'
-ARMATURE = 'ARMATURE'
-
-SPOT = 'SPOT'
-POINT = 'POINT'
-SUN = 'SUN'
-HEMI = 'HEMI'
-AREA = 'AREA'
-
-NO_SHADOW = 'NOSHADOW'
-
-CAMERA = 'CAMERA'
-PERSP = 'PERSP'
-ORTHO = 'ORTHO'
-
-RENDER = 'RENDER'
-
-ZYX = 'ZYX'
-
-MULTIPLY = 'MULTIPLY'
-
-WIRE = 'WIRE'
-IMAGE = 'IMAGE'
-
-MAG_FILTER = 'LinearFilter'
-MIN_FILTER = 'LinearMipMapLinearFilter'
-MAPPING = 'UVMapping'

Some files were not shown because too many files changed in this diff