text: (window["webpackJsonp"] = window["webpackJsonp"] || []).push([["main"],{
  
  /***/ "./src/css/app.scss":
  /*!**************************!*\
    !*** ./src/css/app.scss ***!
    \**************************/
  /*! no static exports found */
  /***/ (function(module, exports, __webpack_require__) {
  
  eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./src/css/app.scss?");
  
  /***/ }),
  
  /***/ "./src/js/app.js":
  /*!***********************!*\
    !*** ./src/js/app.js ***!
    \***********************/
  /*! no exports provided */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./data/config */ \"./src/js/data/config.js\");\n/* harmony import */ var _utils_detector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/detector */ \"./src/js/utils/detector.js\");\n/* harmony import */ var _app_main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app/main */ \"./src/js/app/main.js\");\n/* harmony import */ var _css_app_scss__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./../css/app.scss */ \"./src/css/app.scss\");\n/* harmony import */ var _css_app_scss__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_css_app_scss__WEBPACK_IMPORTED_MODULE_3__);\n\n\n // Styles\n\n // Check environment and set the Config helper\n\nif (true) {\n  console.log('----- RUNNING IN DEV ENVIRONMENT! -----');\n  _data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].isDev = true;\n}\n\nfunction init() {\n  // Check for webGL capabilities\n  if (!_utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].webgl) {\n    _utils_detector__WEBPACK_IMPORTED_MODULE_1__[\"default\"].addGetWebGLMessage();\n  } else {\n    var container = document.getElementById('appContainer');\n    new _app_main__WEBPACK_IMPORTED_MODULE_2__[\"default\"](container);\n  }\n}\n\ninit();\n\n//# sourceURL=webpack:///./src/js/app.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/components/camera.js":
  /*!*****************************************!*\
    !*** ./src/js/app/components/camera.js ***!
    \*****************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Camera; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n // Class that creates and updates the main camera\n\nvar Camera =\n/*#__PURE__*/\nfunction () {\n  function Camera(renderer) {\n    var _this = this;\n\n    _classCallCheck(this, Camera);\n\n    var width = renderer.domElement.width;\n    var height = renderer.domElement.height; // Create and position a Perspective Camera\n\n    this.threeCamera = new three__WEBPACK_IMPORTED_MODULE_0__[\"PerspectiveCamera\"](_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.fov, width / height, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.near, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.far);\n    this.threeCamera.position.set(_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.posX, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.posY, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].camera.posZ); // Initial sizing\n\n    this.updateSize(renderer); // Listeners\n\n    window.addEventListener('resize', function () {\n      return _this.updateSize(renderer);\n    }, false);\n  }\n\n  _createClass(Camera, [{\n    key: \"updateSize\",\n    value: function updateSize(renderer) {\n      // Update camera aspect ratio with window aspect ratio\n      this.threeCamera.aspect = renderer.domElement.width / renderer.domElement.height; // Always call updateProjectionMatrix on camera change\n\n      this.threeCamera.updateProjectionMatrix();\n    }\n  }]);\n\n  return Camera;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/components/camera.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/components/controls.js":
  /*!*******************************************!*\
    !*** ./src/js/app/components/controls.js ***!
    \*******************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Controls; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _utils_orbitControls__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/orbitControls */ \"./src/js/utils/orbitControls.js\");\n/* harmony import */ var _utils_orbitControls__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_utils_orbitControls__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\n // Controls based on orbit controls\n\nvar Controls =\n/*#__PURE__*/\nfunction () {\n  function Controls(camera, container) {\n    _classCallCheck(this, Controls);\n\n    // Orbit controls first needs to pass in THREE to constructor\n    var orbitControls = new _utils_orbitControls__WEBPACK_IMPORTED_MODULE_1___default.a(three__WEBPACK_IMPORTED_MODULE_0__);\n    this.threeControls = new orbitControls(camera, container);\n    this.init();\n  }\n\n  _createClass(Controls, [{\n    key: \"init\",\n    value: function init() {\n      this.threeControls.target.set(_data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.target.x, _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.target.y, _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.target.z);\n      this.threeControls.autoRotate = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.autoRotate;\n      this.threeControls.autoRotateSpeed = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.autoRotateSpeed;\n      this.threeControls.rotateSpeed = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.rotateSpeed;\n      this.threeControls.zoomSpeed = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.zoomSpeed;\n      this.threeControls.minDistance = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.minDistance;\n      this.threeControls.maxDistance = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.maxDistance;\n      this.threeControls.minPolarAngle = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.minPolarAngle;\n      this.threeControls.maxPolarAngle = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.maxPolarAngle;\n      this.threeControls.enableDamping = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.enableDamping;\n      this.threeControls.enableZoom = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.enableZoom;\n      this.threeControls.dampingFactor = _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].controls.dampingFactor;\n    }\n  }]);\n\n  return Controls;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/components/controls.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/components/light.js":
  /*!****************************************!*\
    !*** ./src/js/app/components/light.js ***!
    \****************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Light; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n // Sets up and places all lights in scene\n\nvar Light =\n/*#__PURE__*/\nfunction () {\n  function Light(scene) {\n    _classCallCheck(this, Light);\n\n    this.scene = scene;\n    this.init();\n  }\n\n  _createClass(Light, [{\n    key: \"init\",\n    value: function init() {\n      // Ambient\n      this.ambientLight = new three__WEBPACK_IMPORTED_MODULE_0__[\"AmbientLight\"](_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].ambientLight.color);\n      this.ambientLight.visible = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].ambientLight.enabled; // Point light\n\n      this.pointLight = new three__WEBPACK_IMPORTED_MODULE_0__[\"PointLight\"](_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.color, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.intensity, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.distance);\n      this.pointLight.position.set(_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.x, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.y, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.z);\n      this.pointLight.visible = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].pointLight.enabled; // Directional light\n\n      this.directionalLight = new three__WEBPACK_IMPORTED_MODULE_0__[\"DirectionalLight\"](_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.color, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.intensity);\n      this.directionalLight.position.set(_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.x, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.y, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.z);\n      this.directionalLight.visible = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].directionalLight.enabled; // Shadow map\n\n      this.directionalLight.castShadow = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.enabled;\n      this.directionalLight.shadow.bias = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.bias;\n      this.directionalLight.shadow.camera.near = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.near;\n      this.directionalLight.shadow.camera.far = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.far;\n      this.directionalLight.shadow.camera.left = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.left;\n      this.directionalLight.shadow.camera.right = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.right;\n      this.directionalLight.shadow.camera.top = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.top;\n      this.directionalLight.shadow.camera.bottom = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.bottom;\n      this.directionalLight.shadow.mapSize.width = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.mapWidth;\n      this.directionalLight.shadow.mapSize.height = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.mapHeight; // Shadow camera helper\n\n      this.directionalLightHelper = new three__WEBPACK_IMPORTED_MODULE_0__[\"CameraHelper\"](this.directionalLight.shadow.camera);\n      this.directionalLightHelper.visible = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].shadow.helperEnabled; // Hemisphere light\n\n      this.hemiLight = new three__WEBPACK_IMPORTED_MODULE_0__[\"HemisphereLight\"](_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.color, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.groundColor, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.intensity);\n      this.hemiLight.position.set(_data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.x, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.y, _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.z);\n      this.hemiLight.visible = _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].hemiLight.enabled;\n    }\n  }, {\n    key: \"place\",\n    value: function place(lightName) {\n      switch (lightName) {\n        case 'ambient':\n          this.scene.add(this.ambientLight);\n          break;\n\n        case 'directional':\n          this.scene.add(this.directionalLight);\n          this.scene.add(this.directionalLightHelper);\n          break;\n\n        case 'point':\n          this.scene.add(this.pointLight);\n          break;\n\n        case 'hemi':\n          this.scene.add(this.hemiLight);\n          break;\n      }\n    }\n  }]);\n\n  return Light;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/components/light.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/components/renderer.js":
  /*!*******************************************!*\
    !*** ./src/js/app/components/renderer.js ***!
    \*******************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Renderer; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n // Main webGL renderer class\n\nvar Renderer =\n/*#__PURE__*/\nfunction () {\n  function Renderer(scene, container) {\n    var _this = this;\n\n    _classCallCheck(this, Renderer);\n\n    // Properties\n    this.scene = scene;\n    this.container = container; // Create WebGL renderer and set its antialias\n\n    this.threeRenderer = new three__WEBPACK_IMPORTED_MODULE_0__[\"WebGLRenderer\"]({\n      antialias: true\n    }); // Set clear color to fog to enable fog or to hex color for no fog\n\n    this.threeRenderer.setClearColor(scene.fog.color);\n    this.threeRenderer.setPixelRatio(window.devicePixelRatio); // For retina\n    // Appends canvas\n\n    container.appendChild(this.threeRenderer.domElement); // Shadow map options\n\n    this.threeRenderer.shadowMap.enabled = true;\n    this.threeRenderer.shadowMap.type = three__WEBPACK_IMPORTED_MODULE_0__[\"PCFSoftShadowMap\"]; // Get anisotropy for textures\n\n    _data_config__WEBPACK_IMPORTED_MODULE_1__[\"default\"].maxAnisotropy = this.threeRenderer.getMaxAnisotropy(); // Initial size update set to canvas container\n\n    this.updateSize(); // Listeners\n\n    document.addEventListener('DOMContentLoaded', function () {\n      return _this.updateSize();\n    }, false);\n    window.addEventListener('resize', function () {\n      return _this.updateSize();\n    }, false);\n  }\n\n  _createClass(Renderer, [{\n    key: \"updateSize\",\n    value: function updateSize() {\n      this.threeRenderer.setSize(this.container.offsetWidth, this.container.offsetHeight);\n    }\n  }, {\n    key: \"render\",\n    value: function render(scene, camera) {\n      // Renders scene to canvas target\n      this.threeRenderer.render(scene, camera);\n    }\n  }]);\n\n  return Renderer;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/components/renderer.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/helpers/geometry.js":
  /*!****************************************!*\
    !*** ./src/js/app/helpers/geometry.js ***!
    \****************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Geometry; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _material__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./material */ \"./src/js/app/helpers/material.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\n // This helper class can be used to create and then place geometry in the scene\n\nvar Geometry =\n/*#__PURE__*/\nfunction () {\n  function Geometry(scene) {\n    _classCallCheck(this, Geometry);\n\n    this.scene = scene;\n    this.geo = null;\n  }\n\n  _createClass(Geometry, [{\n    key: \"make\",\n    value: function make(type) {\n      var _this = this;\n\n      if (type === 'plane') {\n        return function (width, height) {\n          var widthSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n          var heightSegments = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;\n          _this.geo = new three__WEBPACK_IMPORTED_MODULE_0__[\"PlaneGeometry\"](width, height, widthSegments, heightSegments);\n        };\n      }\n\n      if (type === 'sphere') {\n        return function (radius) {\n          var widthSegments = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 32;\n          var heightSegments = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 32;\n          _this.geo = new three__WEBPACK_IMPORTED_MODULE_0__[\"SphereGeometry\"](radius, widthSegments, heightSegments);\n        };\n      }\n    }\n  }, {\n    key: \"place\",\n    value: function place(position, rotation) {\n      var _mesh$position, _mesh$rotation;\n\n      var material = new _material__WEBPACK_IMPORTED_MODULE_1__[\"default\"](0xeeeeee).standard;\n      var mesh = new three__WEBPACK_IMPORTED_MODULE_0__[\"Mesh\"](this.geo, material); // Use ES6 spread to set position and rotation from passed in array\n\n      (_mesh$position = mesh.position).set.apply(_mesh$position, _toConsumableArray(position));\n\n      (_mesh$rotation = mesh.rotation).set.apply(_mesh$rotation, _toConsumableArray(rotation));\n\n      if (_data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].shadow.enabled) {\n        mesh.receiveShadow = true;\n      }\n\n      this.scene.add(mesh);\n    }\n  }]);\n\n  return Geometry;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/geometry.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/helpers/material.js":
  /*!****************************************!*\
    !*** ./src/js/app/helpers/material.js ***!
    \****************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Material; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n\n // USe this class as a helper to set up some default materials\n\nvar Material = function Material(color) {\n  _classCallCheck(this, Material);\n\n  this.basic = new three__WEBPACK_IMPORTED_MODULE_0__[\"MeshBasicMaterial\"]({\n    color: color,\n    side: three__WEBPACK_IMPORTED_MODULE_0__[\"DoubleSide\"]\n  });\n  this.standard = new three__WEBPACK_IMPORTED_MODULE_0__[\"MeshStandardMaterial\"]({\n    color: color,\n    shading: three__WEBPACK_IMPORTED_MODULE_0__[\"FlatShading\"],\n    roughness: 1,\n    metalness: 0,\n    side: three__WEBPACK_IMPORTED_MODULE_0__[\"DoubleSide\"]\n  });\n  this.wire = new three__WEBPACK_IMPORTED_MODULE_0__[\"MeshBasicMaterial\"]({\n    wireframe: true\n  });\n};\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/material.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/helpers/meshHelper.js":
  /*!******************************************!*\
    !*** ./src/js/app/helpers/meshHelper.js ***!
    \******************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return MeshHelper; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n // Simple mesh helper that shows edges, wireframes, and face and vertex normals\n\nvar MeshHelper = function MeshHelper(scene, mesh) {\n  _classCallCheck(this, MeshHelper);\n\n  var wireframe = new three__WEBPACK_IMPORTED_MODULE_0__[\"WireframeGeometry\"](mesh.geometry);\n  var wireLine = new three__WEBPACK_IMPORTED_MODULE_0__[\"LineSegments\"](wireframe);\n  wireLine.material.depthTest = false;\n  wireLine.material.opacity = 0.25;\n  wireLine.material.transparent = true;\n  mesh.add(wireLine);\n  var edges = new three__WEBPACK_IMPORTED_MODULE_0__[\"EdgesGeometry\"](mesh.geometry);\n  var edgesLine = new three__WEBPACK_IMPORTED_MODULE_0__[\"LineSegments\"](edges);\n  edgesLine.material.depthTest = false;\n  edgesLine.material.opacity = 0.25;\n  edgesLine.material.transparent = true;\n  mesh.add(edgesLine);\n  scene.add(new three__WEBPACK_IMPORTED_MODULE_0__[\"BoxHelper\"](mesh));\n  scene.add(new three__WEBPACK_IMPORTED_MODULE_0__[\"FaceNormalsHelper\"](mesh, 2));\n  scene.add(new three__WEBPACK_IMPORTED_MODULE_0__[\"VertexNormalsHelper\"](mesh, 2));\n};\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/meshHelper.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/helpers/stats.js":
  /*!*************************************!*\
    !*** ./src/js/app/helpers/stats.js ***!
    \*************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Stats; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// Local vars for rStats\nvar rS, bS, glS, tS;\n\nvar Stats =\n/*#__PURE__*/\nfunction () {\n  function Stats(renderer) {\n    _classCallCheck(this, Stats);\n\n    this.renderer = renderer;\n  }\n\n  _createClass(Stats, [{\n    key: \"setUp\",\n    value: function setUp() {\n      bS = new BrowserStats();\n      glS = new glStats();\n      tS = new threeStats(this.renderer.threeRenderer);\n      rS = new rStats({\n        CSSPath: './css/',\n        userTimingAPI: true,\n        values: {\n          frame: {\n            caption: 'Total frame time (ms)',\n            over: 16,\n            average: true,\n            avgMs: 100\n          },\n          fps: {\n            caption: 'Framerate (FPS)',\n            below: 30\n          },\n          calls: {\n            caption: 'Calls (three.js)',\n            over: 3000\n          },\n          raf: {\n            caption: 'Time since last rAF (ms)',\n            average: true,\n            avgMs: 100\n          },\n          rstats: {\n            caption: 'rStats update (ms)',\n            average: true,\n            avgMs: 100\n          },\n          texture: {\n            caption: 'GenTex',\n            average: true,\n            avgMs: 100\n          }\n        },\n        groups: [{\n          caption: 'Framerate',\n          values: ['fps', 'raf']\n        }, {\n          caption: 'Frame Budget',\n          values: ['frame', 'texture', 'setup', 'render']\n        }],\n        fractions: [{\n          base: 'frame',\n          steps: ['texture', 'setup', 'render']\n        }],\n        plugins: [bS, tS, glS]\n      });\n    }\n  }], [{\n    key: \"start\",\n    value: function start() {\n      rS('frame').start();\n      glS.start();\n      rS('rAF').tick();\n      rS('FPS').frame();\n      rS('render').start();\n    }\n  }, {\n    key: \"end\",\n    value: function end() {\n      rS('render').end(); // render finished\n\n      rS('frame').end(); // frame finished\n      // Local rStats update\n\n      rS('rStats').start();\n      rS().update();\n      rS('rStats').end();\n    }\n  }]);\n\n  return Stats;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/helpers/stats.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/main.js":
  /*!****************************!*\
    !*** ./src/js/app/main.js ***!
    \****************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Main; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var tween_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tween.js */ \"./node_modules/tween.js/src/Tween.js\");\n/* harmony import */ var tween_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(tween_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _components_renderer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/renderer */ \"./src/js/app/components/renderer.js\");\n/* harmony import */ var _components_camera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/camera */ \"./src/js/app/components/camera.js\");\n/* harmony import */ var _components_light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/light */ \"./src/js/app/components/light.js\");\n/* harmony import */ var _components_controls__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/controls */ \"./src/js/app/components/controls.js\");\n/* harmony import */ var _helpers_geometry__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./helpers/geometry */ \"./src/js/app/helpers/geometry.js\");\n/* harmony import */ var _helpers_stats__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./helpers/stats */ \"./src/js/app/helpers/stats.js\");\n/* harmony import */ var _model_texture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./model/texture */ \"./src/js/app/model/texture.js\");\n/* harmony import */ var _model_model__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./model/model */ \"./src/js/app/model/model.js\");\n/* harmony import */ var _managers_interaction__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./managers/interaction */ \"./src/js/app/managers/interaction.js\");\n/* harmony import */ var _managers_datGUI__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./managers/datGUI */ \"./src/js/app/managers/datGUI.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// Global imports -\n\n // Local imports -\n// Components\n\n\n\n\n // Helpers\n\n\n // Model\n\n\n // Managers\n\n\n // data\n\n // -- End of imports\n// This class instantiates and ties all of the components together, starts the loading process and renders the main loop\n\nvar Main =\n/*#__PURE__*/\nfunction () {\n  function Main(container) {\n    var _this = this;\n\n    _classCallCheck(this, Main);\n\n    // Set container property to container element\n    this.container = container; // Start Three clock\n\n    this.clock = new three__WEBPACK_IMPORTED_MODULE_0__[\"Clock\"](); // Main scene creation\n\n    this.scene = new three__WEBPACK_IMPORTED_MODULE_0__[\"Scene\"]();\n    this.scene.fog = new three__WEBPACK_IMPORTED_MODULE_0__[\"FogExp2\"](_data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].fog.color, _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].fog.near); // Get Device Pixel Ratio first for retina\n\n    if (window.devicePixelRatio) {\n      _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].dpr = window.devicePixelRatio;\n    } // Main renderer constructor\n\n\n    this.renderer = new _components_renderer__WEBPACK_IMPORTED_MODULE_2__[\"default\"](this.scene, container); // Components instantiations\n\n    this.camera = new _components_camera__WEBPACK_IMPORTED_MODULE_3__[\"default\"](this.renderer.threeRenderer);\n    this.controls = new _components_controls__WEBPACK_IMPORTED_MODULE_5__[\"default\"](this.camera.threeCamera, container);\n    this.light = new _components_light__WEBPACK_IMPORTED_MODULE_4__[\"default\"](this.scene); // Create and place lights in scene\n\n    var lights = ['ambient', 'directional', 'point', 'hemi'];\n    lights.forEach(function (light) {\n      return _this.light.place(light);\n    }); // Create and place geo in scene\n\n    this.geometry = new _helpers_geometry__WEBPACK_IMPORTED_MODULE_6__[\"default\"](this.scene);\n    this.geometry.make('plane')(150, 150, 10, 10);\n    this.geometry.place([0, -20, 0], [Math.PI / 2, 0, 0]); // Set up rStats if dev environment\n\n    if (_data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isDev && _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isShowingStats) {\n      this.stats = new _helpers_stats__WEBPACK_IMPORTED_MODULE_7__[\"default\"](this.renderer);\n      this.stats.setUp();\n    } // Instantiate texture class\n\n\n    this.texture = new _model_texture__WEBPACK_IMPORTED_MODULE_8__[\"default\"](); // Start loading the textures and then go on to load the model after the texture Promises have resolved\n\n    this.texture.load().then(function () {\n      _this.manager = new three__WEBPACK_IMPORTED_MODULE_0__[\"LoadingManager\"](); // Textures loaded, load model\n\n      _this.model = new _model_model__WEBPACK_IMPORTED_MODULE_9__[\"default\"](_this.scene, _this.manager, _this.texture.textures);\n\n      _this.model.load(); // onProgress callback\n\n\n      _this.manager.onProgress = function (item, loaded, total) {\n        console.log(\"\".concat(item, \": \").concat(loaded, \" \").concat(total));\n      }; // All loaders done now\n\n\n      _this.manager.onLoad = function () {\n        // Set up interaction manager with the app now that the model is finished loading\n        new _managers_interaction__WEBPACK_IMPORTED_MODULE_10__[\"default\"](_this.renderer.threeRenderer, _this.scene, _this.camera.threeCamera, _this.controls.threeControls); // Add dat.GUI controls if dev\n\n        if (_data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isDev) {\n          new _managers_datGUI__WEBPACK_IMPORTED_MODULE_11__[\"default\"](_this, _this.model.obj);\n        } // Everything is now fully loaded\n\n\n        _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isLoaded = true;\n        _this.container.querySelector('#loading').style.display = 'none';\n      };\n    }); // Start render which does not wait for model fully loaded\n\n    this.render();\n  }\n\n  _createClass(Main, [{\n    key: \"render\",\n    value: function render() {\n      // Render rStats if Dev\n      if (_data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isDev && _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isShowingStats) {\n        _helpers_stats__WEBPACK_IMPORTED_MODULE_7__[\"default\"].start();\n      } // Call render function and pass in created scene and camera\n\n\n      this.renderer.render(this.scene, this.camera.threeCamera); // rStats has finished determining render call now\n\n      if (_data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isDev && _data_config__WEBPACK_IMPORTED_MODULE_12__[\"default\"].isShowingStats) {\n        _helpers_stats__WEBPACK_IMPORTED_MODULE_7__[\"default\"].end();\n      } // Delta time is sometimes needed for certain updates\n      //const delta = this.clock.getDelta();\n      // Call any vendor or module frame updates here\n\n\n      tween_js__WEBPACK_IMPORTED_MODULE_1___default.a.update();\n      this.controls.threeControls.update(); // RAF\n\n      requestAnimationFrame(this.render.bind(this)); // Bind the main class instead of window object\n    }\n  }]);\n\n  return Main;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/main.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/managers/datGUI.js":
  /*!***************************************!*\
    !*** ./src/js/app/managers/datGUI.js ***!
    \***************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return DatGUI; });\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n // Manages all dat.GUI interactions\n\nvar DatGUI = function DatGUI(main, mesh) {\n  var _this = this;\n\n  _classCallCheck(this, DatGUI);\n\n  var gui = new dat.GUI();\n  this.camera = main.camera.threeCamera;\n  this.controls = main.controls.threeControls;\n  this.light = main.light;\n  /* Global */\n  //gui.close();\n\n  /* Camera */\n\n  var cameraFolder = gui.addFolder('Camera');\n  var cameraFOVGui = cameraFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].camera, 'fov', 0, 180).name('Camera FOV');\n  cameraFOVGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.camera.fov = value;\n  });\n  cameraFOVGui.onFinishChange(function () {\n    _this.camera.updateProjectionMatrix();\n\n    _this.controls.enableRotate = true;\n  });\n  var cameraAspectGui = cameraFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].camera, 'aspect', 0, 4).name('Camera Aspect');\n  cameraAspectGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.camera.aspect = value;\n  });\n  cameraAspectGui.onFinishChange(function () {\n    _this.camera.updateProjectionMatrix();\n\n    _this.controls.enableRotate = true;\n  });\n  var cameraFogColorGui = cameraFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].fog, 'color').name('Fog Color');\n  cameraFogColorGui.onChange(function (value) {\n    main.scene.fog.color.setHex(value);\n  });\n  var cameraFogNearGui = cameraFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].fog, 'near', 0.000, 0.010).name('Fog Near');\n  cameraFogNearGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    main.scene.fog.density = value;\n  });\n  cameraFogNearGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  /* Controls */\n\n  var controlsFolder = gui.addFolder('Controls');\n  controlsFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].controls, 'autoRotate').name('Auto Rotate').onChange(function (value) {\n    _this.controls.autoRotate = value;\n  });\n  var controlsAutoRotateSpeedGui = controlsFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].controls, 'autoRotateSpeed', -1, 1).name('Rotation Speed');\n  controlsAutoRotateSpeedGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.controls.autoRotateSpeed = value;\n  });\n  controlsAutoRotateSpeedGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  /* Mesh */\n\n  var meshFolder = gui.addFolder('Mesh');\n  meshFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].mesh, 'translucent', true).name('Translucent').onChange(function (value) {\n    if (value) {\n      mesh.material.transparent = true;\n      mesh.material.opacity = 0.5;\n    } else {\n      mesh.material.opacity = 1.0;\n    }\n  });\n  meshFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].mesh, 'wireframe', true).name('Wireframe').onChange(function (value) {\n    mesh.material.wireframe = value;\n  });\n  /* Lights */\n  // Ambient Light\n\n  var ambientLightFolder = gui.addFolder('Ambient Light');\n  ambientLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].ambientLight, 'enabled').name('Enabled').onChange(function (value) {\n    _this.light.ambientLight.visible = value;\n  });\n  ambientLightFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].ambientLight, 'color').name('Color').onChange(function (value) {\n    _this.light.ambientLight.color.setHex(value);\n  }); // Directional Light\n\n  var directionalLightFolder = gui.addFolder('Directional Light');\n  directionalLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'enabled').name('Enabled').onChange(function (value) {\n    _this.light.directionalLight.visible = value;\n  });\n  directionalLightFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'color').name('Color').onChange(function (value) {\n    _this.light.directionalLight.color.setHex(value);\n  });\n  var directionalLightIntensityGui = directionalLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'intensity', 0, 2).name('Intensity');\n  directionalLightIntensityGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.intensity = value;\n  });\n  directionalLightIntensityGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var directionalLightPositionXGui = directionalLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'x', -1000, 1000).name('Position X');\n  directionalLightPositionXGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.position.x = value;\n  });\n  directionalLightPositionXGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var directionalLightPositionYGui = directionalLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'y', -1000, 1000).name('Position Y');\n  directionalLightPositionYGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.position.y = value;\n  });\n  directionalLightPositionYGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var directionalLightPositionZGui = directionalLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].directionalLight, 'z', -1000, 1000).name('Position Z');\n  directionalLightPositionZGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.position.z = value;\n  });\n  directionalLightPositionZGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  }); // Shadow Map\n\n  var shadowFolder = gui.addFolder('Shadow Map');\n  shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'enabled').name('Enabled').onChange(function (value) {\n    _this.light.directionalLight.castShadow = value;\n  });\n  shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'helperEnabled').name('Helper Enabled').onChange(function (value) {\n    _this.light.directionalLightHelper.visible = value;\n  });\n  var shadowNearGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'near', 0, 400).name('Near');\n  shadowNearGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.near = value;\n  });\n  shadowNearGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowFarGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'far', 0, 1200).name('Far');\n  shadowFarGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.far = value;\n  });\n  shadowFarGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowTopGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'top', -400, 400).name('Top');\n  shadowTopGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.top = value;\n  });\n  shadowTopGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowRightGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'right', -400, 400).name('Right');\n  shadowRightGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.right = value;\n  });\n  shadowRightGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowBottomGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'bottom', -400, 400).name('Bottom');\n  shadowBottomGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.bottom = value;\n  });\n  shadowBottomGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowLeftGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'left', -400, 400).name('Left');\n  shadowLeftGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.camera.left = value;\n  });\n  shadowLeftGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  });\n  var shadowBiasGui = shadowFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].shadow, 'bias', -0.000010, 1).name('Bias');\n  shadowBiasGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.directionalLight.shadow.bias = value;\n  });\n  shadowBiasGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n\n    _this.light.directionalLight.shadow.map.dispose();\n\n    _this.light.directionalLight.shadow.map = null;\n\n    _this.light.directionalLightHelper.update();\n  }); // Point Light\n\n  var pointLightFolder = gui.addFolder('Point Light');\n  pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'enabled').name('Enabled').onChange(function (value) {\n    _this.light.pointLight.visible = value;\n  });\n  pointLightFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'color').name('Color').onChange(function (value) {\n    _this.light.pointLight.color.setHex(value);\n  });\n  var pointLightIntensityGui = pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'intensity', 0, 2).name('Intensity');\n  pointLightIntensityGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.pointLight.intensity = value;\n  });\n  pointLightIntensityGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var pointLightDistanceGui = pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'distance', 0, 1000).name('Distance');\n  pointLightDistanceGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.pointLight.distance = value;\n  });\n  pointLightDistanceGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var pointLightPositionXGui = pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'x', -1000, 1000).name('Position X');\n  pointLightPositionXGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.pointLight.position.x = value;\n  });\n  pointLightPositionXGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var pointLightPositionYGui = pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'y', -1000, 1000).name('Position Y');\n  pointLightPositionYGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.pointLight.position.y = value;\n  });\n  pointLightPositionYGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var pointLightPositionZGui = pointLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].pointLight, 'z', -1000, 1000).name('Position Z');\n  pointLightPositionZGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.pointLight.position.z = value;\n  });\n  pointLightPositionZGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  }); // Hemi Light\n\n  var hemiLightFolder = gui.addFolder('Hemi Light');\n  hemiLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'enabled').name('Enabled').onChange(function (value) {\n    _this.light.hemiLight.visible = value;\n  });\n  hemiLightFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'color').name('Color').onChange(function (value) {\n    _this.light.hemiLight.color.setHex(value);\n  });\n  hemiLightFolder.addColor(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'groundColor').name('ground Color').onChange(function (value) {\n    _this.light.hemiLight.groundColor.setHex(value);\n  });\n  var hemiLightIntensityGui = hemiLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'intensity', 0, 2).name('Intensity');\n  hemiLightIntensityGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.hemiLight.intensity = value;\n  });\n  hemiLightIntensityGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var hemiLightPositionXGui = hemiLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'x', -1000, 1000).name('Position X');\n  hemiLightPositionXGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.hemiLight.position.x = value;\n  });\n  hemiLightPositionXGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var hemiLightPositionYGui = hemiLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'y', -500, 1000).name('Position Y');\n  hemiLightPositionYGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.hemiLight.position.y = value;\n  });\n  hemiLightPositionYGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n  var hemiLightPositionZGui = hemiLightFolder.add(_data_config__WEBPACK_IMPORTED_MODULE_0__[\"default\"].hemiLight, 'z', -1000, 1000).name('Position Z');\n  hemiLightPositionZGui.onChange(function (value) {\n    _this.controls.enableRotate = false;\n    _this.light.hemiLight.position.z = value;\n  });\n  hemiLightPositionZGui.onFinishChange(function () {\n    _this.controls.enableRotate = true;\n  });\n};\n\n\n\n//# sourceURL=webpack:///./src/js/app/managers/datGUI.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/managers/interaction.js":
  /*!********************************************!*\
    !*** ./src/js/app/managers/interaction.js ***!
    \********************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Interaction; });\n/* harmony import */ var _utils_keyboard__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../utils/keyboard */ \"./src/js/utils/keyboard.js\");\n/* harmony import */ var _utils_helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/helpers */ \"./src/js/utils/helpers.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\n // Manages all input interactions\n\nvar Interaction =\n/*#__PURE__*/\nfunction () {\n  function Interaction(renderer, scene, camera, controls) {\n    var _this = this;\n\n    _classCallCheck(this, Interaction);\n\n    // Properties\n    this.renderer = renderer;\n    this.scene = scene;\n    this.camera = camera;\n    this.controls = controls;\n    this.timeout = null; // Instantiate keyboard helper\n\n    this.keyboard = new _utils_keyboard__WEBPACK_IMPORTED_MODULE_0__[\"default\"](); // Listeners\n    // Mouse events\n\n    this.renderer.domElement.addEventListener('mousemove', function (event) {\n      return _utils_helpers__WEBPACK_IMPORTED_MODULE_1__[\"default\"].throttle(_this.onMouseMove(event), 250);\n    }, false);\n    this.renderer.domElement.addEventListener('mouseleave', function (event) {\n      return _this.onMouseLeave(event);\n    }, false);\n    this.renderer.domElement.addEventListener('mouseover', function (event) {\n      return _this.onMouseOver(event);\n    }, false); // Keyboard events\n\n    this.keyboard.domElement.addEventListener('keydown', function (event) {\n      // Only once\n      if (event.repeat) {\n        return;\n      }\n\n      if (_this.keyboard.eventMatches(event, 'escape')) {\n        console.log('Escape pressed');\n      }\n    });\n  }\n\n  _createClass(Interaction, [{\n    key: \"onMouseOver\",\n    value: function onMouseOver(event) {\n      event.preventDefault();\n      _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isMouseOver = true;\n    }\n  }, {\n    key: \"onMouseLeave\",\n    value: function onMouseLeave(event) {\n      event.preventDefault();\n      _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isMouseOver = false;\n    }\n  }, {\n    key: \"onMouseMove\",\n    value: function onMouseMove(event) {\n      event.preventDefault();\n      clearTimeout(this.timeout);\n      this.timeout = setTimeout(function () {\n        _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isMouseMoving = false;\n      }, 200);\n      _data_config__WEBPACK_IMPORTED_MODULE_2__[\"default\"].isMouseMoving = true;\n    }\n  }]);\n\n  return Interaction;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/managers/interaction.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/model/model.js":
  /*!***********************************!*\
    !*** ./src/js/app/model/model.js ***!
    \***********************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Model; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var _helpers_material__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../helpers/material */ \"./src/js/app/helpers/material.js\");\n/* harmony import */ var _helpers_meshHelper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../helpers/meshHelper */ \"./src/js/app/helpers/meshHelper.js\");\n/* harmony import */ var _utils_helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../utils/helpers */ \"./src/js/utils/helpers.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n\n\n\n\n // Loads in a single object from the config file\n\nvar Model =\n/*#__PURE__*/\nfunction () {\n  function Model(scene, manager, textures) {\n    _classCallCheck(this, Model);\n\n    this.scene = scene;\n    this.textures = textures; // Manager is passed in to loader to determine when loading done in main\n\n    this.loader = new three__WEBPACK_IMPORTED_MODULE_0__[\"ObjectLoader\"](manager);\n    this.obj = null;\n  }\n\n  _createClass(Model, [{\n    key: \"load\",\n    value: function load() {\n      var _this = this;\n\n      // Load model with ObjectLoader\n      this.loader.load(_data_config__WEBPACK_IMPORTED_MODULE_4__[\"default\"].model.path, function (obj) {\n        obj.traverse(function (child) {\n          if (child instanceof three__WEBPACK_IMPORTED_MODULE_0__[\"Mesh\"]) {\n            // Create material for mesh and set its map to texture by name from preloaded textures\n            var material = new _helpers_material__WEBPACK_IMPORTED_MODULE_1__[\"default\"](0xffffff).standard;\n            material.map = _this.textures.UV;\n            child.material = material; // Set to cast and receive shadow if enabled\n\n            if (_data_config__WEBPACK_IMPORTED_MODULE_4__[\"default\"].shadow.enabled) {\n              child.receiveShadow = true;\n              child.castShadow = true;\n            }\n          }\n        }); // Add mesh helper if Dev\n\n        if (_data_config__WEBPACK_IMPORTED_MODULE_4__[\"default\"].isDev && _data_config__WEBPACK_IMPORTED_MODULE_4__[\"default\"].mesh.enableHelper) {\n          new _helpers_meshHelper__WEBPACK_IMPORTED_MODULE_2__[\"default\"](_this.scene, obj);\n        } // Set prop to obj so it can be accessed from outside the class\n\n\n        _this.obj = obj;\n        obj.scale.multiplyScalar(_data_config__WEBPACK_IMPORTED_MODULE_4__[\"default\"].model.scale);\n\n        _this.scene.add(obj);\n      }, _utils_helpers__WEBPACK_IMPORTED_MODULE_3__[\"default\"].logProgress(), _utils_helpers__WEBPACK_IMPORTED_MODULE_3__[\"default\"].logError());\n    }\n  }]);\n\n  return Model;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/model/model.js?");
  
  /***/ }),
  
  /***/ "./src/js/app/model/texture.js":
  /*!*************************************!*\
    !*** ./src/js/app/model/texture.js ***!
    \*************************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Texture; });\n/* harmony import */ var three__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! three */ \"./node_modules/three/build/three.module.js\");\n/* harmony import */ var es6_promise__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! es6-promise */ \"./node_modules/es6-promise/dist/es6-promise.js\");\n/* harmony import */ var es6_promise__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(es6_promise__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _utils_helpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../utils/helpers */ \"./src/js/utils/helpers.js\");\n/* harmony import */ var _data_config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../data/config */ \"./src/js/data/config.js\");\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n // Promise polyfill for IE\n\n\n\n // This class preloads all textures in the imageFiles array in the Config via ES6 Promises.\n// Once all textures are done loading the model itself will be loaded after the Promise .then() callback.\n// Using promises to preload textures prevents issues when applying textures to materials\n// before the textures have loaded.\n\nvar Texture =\n/*#__PURE__*/\nfunction () {\n  function Texture() {\n    _classCallCheck(this, Texture);\n\n    // Prop that will contain all loaded textures\n    this.textures = {};\n  }\n\n  _createClass(Texture, [{\n    key: \"load\",\n    value: function load() {\n      var _this = this;\n\n      var loader = new three__WEBPACK_IMPORTED_MODULE_0__[\"TextureLoader\"]();\n      var maxAnisotropy = _data_config__WEBPACK_IMPORTED_MODULE_3__[\"default\"].maxAnisotropy;\n      var imageFiles = _data_config__WEBPACK_IMPORTED_MODULE_3__[\"default\"].texture.imageFiles;\n      var promiseArray = [];\n      loader.setPath(_data_config__WEBPACK_IMPORTED_MODULE_3__[\"default\"].texture.path);\n      imageFiles.forEach(function (imageFile) {\n        // Add an individual Promise for each image in array\n        promiseArray.push(new es6_promise__WEBPACK_IMPORTED_MODULE_1__[\"Promise\"](function (resolve, reject) {\n          // Each Promise will attempt to load the image file\n          loader.load(imageFile.image, // This gets called on load with the loaded texture\n          function (texture) {\n            texture.anisotropy = maxAnisotropy; // Resolve Promise with object of texture if it is instance of THREE.Texture\n\n            var modelOBJ = {};\n            modelOBJ[imageFile.name] = texture;\n            if (modelOBJ[imageFile.name] instanceof three__WEBPACK_IMPORTED_MODULE_0__[\"Texture\"]) resolve(modelOBJ);\n          }, _utils_helpers__WEBPACK_IMPORTED_MODULE_2__[\"default\"].logProgress(), function (xhr) {\n            return reject(new Error(xhr + 'An error occurred loading while loading ' + imageFile.image));\n          });\n        }));\n      }); // Iterate through all Promises in array and return another Promise when all have resolved or console log reason when any reject\n\n      return es6_promise__WEBPACK_IMPORTED_MODULE_1__[\"Promise\"].all(promiseArray).then(function (textures) {\n        // Set the textures prop object to have name be the resolved texture\n        for (var i = 0; i < textures.length; i++) {\n          _this.textures[Object.keys(textures[i])[0]] = textures[i][Object.keys(textures[i])[0]];\n        }\n      }, function (reason) {\n        return console.log(reason);\n      });\n    }\n  }]);\n\n  return Texture;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/app/model/texture.js?");
  
  /***/ }),
  
  /***/ "./src/js/data/config.js":
  /*!*******************************!*\
    !*** ./src/js/data/config.js ***!
    \*******************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var tween_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tween.js */ \"./node_modules/tween.js/src/Tween.js\");\n/* harmony import */ var tween_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tween_js__WEBPACK_IMPORTED_MODULE_0__);\n // This object contains the state of the app\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n  isDev: false,\n  isShowingStats: true,\n  isLoaded: false,\n  isTweening: false,\n  isRotating: true,\n  isMouseMoving: false,\n  isMouseOver: false,\n  maxAnisotropy: 1,\n  dpr: 1,\n  easing: tween_js__WEBPACK_IMPORTED_MODULE_0___default.a.Easing.Quadratic.InOut,\n  duration: 500,\n  model: {\n    path: './assets/models/Teapot.json',\n    scale: 20\n  },\n  texture: {\n    path: './assets/textures/',\n    imageFiles: [{\n      name: 'UV',\n      image: 'UV_Grid_Sm.jpg'\n    }]\n  },\n  mesh: {\n    enableHelper: false,\n    wireframe: false,\n    translucent: false,\n    material: {\n      color: 0xffffff,\n      emissive: 0xffffff\n    }\n  },\n  fog: {\n    color: 0xffffff,\n    near: 0.0008\n  },\n  camera: {\n    fov: 40,\n    near: 2,\n    far: 1000,\n    aspect: 1,\n    posX: 0,\n    posY: 30,\n    posZ: 40\n  },\n  controls: {\n    autoRotate: true,\n    autoRotateSpeed: -0.5,\n    rotateSpeed: 0.5,\n    zoomSpeed: 0.8,\n    minDistance: 200,\n    maxDistance: 600,\n    minPolarAngle: Math.PI / 5,\n    maxPolarAngle: Math.PI / 2,\n    minAzimuthAngle: -Infinity,\n    maxAzimuthAngle: Infinity,\n    enableDamping: true,\n    dampingFactor: 0.5,\n    enableZoom: true,\n    target: {\n      x: 0,\n      y: 0,\n      z: 0\n    }\n  },\n  ambientLight: {\n    enabled: true,\n    color: 0x141414\n  },\n  directionalLight: {\n    enabled: true,\n    color: 0xf0f0f0,\n    intensity: 0.4,\n    x: -75,\n    y: 280,\n    z: 150\n  },\n  shadow: {\n    enabled: true,\n    helperEnabled: true,\n    bias: 0,\n    mapWidth: 2048,\n    mapHeight: 2048,\n    near: 250,\n    far: 400,\n    top: 100,\n    right: 100,\n    bottom: -100,\n    left: -100\n  },\n  pointLight: {\n    enabled: true,\n    color: 0xffffff,\n    intensity: 0.34,\n    distance: 115,\n    x: 0,\n    y: 0,\n    z: 0\n  },\n  hemiLight: {\n    enabled: true,\n    color: 0xc8c8c8,\n    groundColor: 0xffffff,\n    intensity: 0.55,\n    x: 0,\n    y: 0,\n    z: 0\n  }\n});\n\n//# sourceURL=webpack:///./src/js/data/config.js?");
  
  /***/ }),
  
  /***/ "./src/js/utils/detector.js":
  /*!**********************************!*\
    !*** ./src/js/utils/detector.js ***!
    \**********************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/**\n * @author alteredq / http://alteredqualia.com/\n * @author mr.doob / http://mrdoob.com/\n */\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n  canvas: !!window.CanvasRenderingContext2D,\n  webgl: function () {\n    try {\n      var canvas = document.createElement('canvas');\n      return !!(window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')));\n    } catch (e) {\n      return false;\n    }\n  }(),\n  workers: !!window.Worker,\n  fileapi: window.File && window.FileReader && window.FileList && window.Blob,\n  getWebGLErrorMessage: function getWebGLErrorMessage() {\n    var element = document.createElement('div');\n    element.id = 'webgl-error-message';\n    element.style.fontFamily = 'monospace';\n    element.style.fontSize = '13px';\n    element.style.fontWeight = 'normal';\n    element.style.textAlign = 'center';\n    element.style.background = '#fff';\n    element.style.color = '#000';\n    element.style.padding = '1.5em';\n    element.style.width = '400px';\n    element.style.margin = '5em auto 0';\n\n    if (!this.webgl) {\n      element.innerHTML = window.WebGLRenderingContext ? ['Your graphics card does not seem to support <a href=\"http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation\" style=\"color:#000000\">WebGL</a>.<br />', 'Find out how to get it <a href=\"http://get.webgl.org/\" style=\"color:#000000\">here</a>.'].join('\\n') : ['Your browser does not seem to support <a href=\"http://khronos.org/webgl/wiki/Getting_a_WebGL_Implementation\" style=\"color:#000000\">WebGL</a>.<br/>', 'Find out how to get it <a href=\"http://get.webgl.org/\" style=\"color:#000000\">here</a>.'].join('\\n');\n    }\n\n    return element;\n  },\n  addGetWebGLMessage: function addGetWebGLMessage(parameters) {\n    var parent, id, element;\n    parameters = parameters || {};\n    parent = parameters.parent !== undefined ? parameters.parent : document.body;\n    id = parameters.id !== undefined ? parameters.id : 'oldie';\n    element = this.getWebGLErrorMessage();\n    element.id = id;\n    parent.appendChild(element);\n  }\n});\n\n//# sourceURL=webpack:///./src/js/utils/detector.js?");
  
  /***/ }),
  
  /***/ "./src/js/utils/helpers.js":
  /*!*********************************!*\
    !*** ./src/js/utils/helpers.js ***!
    \*********************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Helpers; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// Provides simple static functions that are used multiple times in the app\nvar Helpers =\n/*#__PURE__*/\nfunction () {\n  function Helpers() {\n    _classCallCheck(this, Helpers);\n  }\n\n  _createClass(Helpers, null, [{\n    key: \"throttle\",\n    value: function throttle(fn, threshhold, scope) {\n      threshhold || (threshhold = 250);\n      var last, deferTimer;\n      return function () {\n        var context = scope || this;\n        var now = +new Date(),\n            args = arguments;\n\n        if (last && now < last + threshhold) {\n          clearTimeout(deferTimer);\n          deferTimer = setTimeout(function () {\n            last = now;\n            fn.apply(context, args);\n          }, threshhold);\n        } else {\n          last = now;\n          fn.apply(context, args);\n        }\n      };\n    }\n  }, {\n    key: \"logProgress\",\n    value: function logProgress() {\n      return function (xhr) {\n        if (xhr.lengthComputable) {\n          var percentComplete = xhr.loaded / xhr.total * 100;\n          console.log(Math.round(percentComplete, 2) + '% downloaded');\n        }\n      };\n    }\n  }, {\n    key: \"logError\",\n    value: function logError() {\n      return function (xhr) {\n        console.error(xhr);\n      };\n    }\n  }, {\n    key: \"handleColorChange\",\n    value: function handleColorChange(color) {\n      return function (value) {\n        if (typeof value === 'string') {\n          value = value.replace('#', '0x');\n        }\n\n        color.setHex(value);\n      };\n    }\n  }, {\n    key: \"update\",\n    value: function update(mesh) {\n      this.needsUpdate(mesh.material, mesh.geometry);\n    }\n  }, {\n    key: \"needsUpdate\",\n    value: function needsUpdate(material, geometry) {\n      return function () {\n        material.shading = +material.shading; //Ensure number\n\n        material.vertexColors = +material.vertexColors; //Ensure number\n\n        material.side = +material.side; //Ensure number\n\n        material.needsUpdate = true;\n        geometry.verticesNeedUpdate = true;\n        geometry.normalsNeedUpdate = true;\n        geometry.colorsNeedUpdate = true;\n      };\n    }\n  }, {\n    key: \"updateTexture\",\n    value: function updateTexture(material, materialKey, textures) {\n      return function (key) {\n        material[materialKey] = textures[key];\n        material.needsUpdate = true;\n      };\n    }\n  }]);\n\n  return Helpers;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/utils/helpers.js?");
  
  /***/ }),
  
  /***/ "./src/js/utils/keyboard.js":
  /*!**********************************!*\
    !*** ./src/js/utils/keyboard.js ***!
    \**********************************/
  /*! exports provided: default */
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
  
  "use strict";
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return Keyboard; });\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar ALIAS = {\n  'left': 37,\n  'up': 38,\n  'right': 39,\n  'down': 40,\n  'space': 32,\n  'tab': 9,\n  'escape': 27\n};\n\nvar Keyboard =\n/*#__PURE__*/\nfunction () {\n  function Keyboard(domElement) {\n    var _this = this;\n\n    _classCallCheck(this, Keyboard);\n\n    this.domElement = domElement || document;\n    this.keyCodes = {}; // bind keyEvents\n\n    this.domElement.addEventListener('keydown', function (event) {\n      return _this.onKeyChange(event);\n    }, false);\n    this.domElement.addEventListener('keyup', function (event) {\n      return _this.onKeyChange(event);\n    }, false); // bind window blur\n\n    window.addEventListener('blur', function () {\n      return _this.onBlur;\n    }, false);\n  }\n\n  _createClass(Keyboard, [{\n    key: \"destroy\",\n    value: function destroy() {\n      var _this2 = this;\n\n      this.domElement.removeEventListener('keydown', function (event) {\n        return _this2.onKeyChange(event);\n      }, false);\n      this.domElement.removeEventListener('keyup', function (event) {\n        return _this2.onKeyChange(event);\n      }, false); // unbind window blur event\n\n      window.removeEventListener('blur', function () {\n        return _this2.onBlur;\n      }, false);\n    }\n  }, {\n    key: \"onBlur\",\n    value: function onBlur() {\n      for (var prop in this.keyCodes) {\n        this.keyCodes[prop] = false;\n      }\n    }\n  }, {\n    key: \"onKeyChange\",\n    value: function onKeyChange(event) {\n      // log to debug\n      //console.log('onKeyChange', event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)\n      // update this.keyCodes\n      var keyCode = event.keyCode;\n      this.keyCodes[keyCode] = event.type === 'keydown';\n    }\n  }, {\n    key: \"pressed\",\n    value: function pressed(keyDesc) {\n      var keys = keyDesc.split('+');\n\n      for (var i = 0; i < keys.length; i++) {\n        var key = keys[i];\n        var pressed = false;\n\n        if (Object.keys(ALIAS).indexOf(key) != -1) {\n          pressed = this.keyCodes[ALIAS[key]];\n        } else {\n          pressed = this.keyCodes[key.toUpperCase().charCodeAt(0)];\n        }\n\n        if (!pressed) return false;\n      }\n\n      return true;\n    }\n  }, {\n    key: \"eventMatches\",\n    value: function eventMatches(event, keyDesc) {\n      var aliases = ALIAS;\n      var aliasKeys = Object.keys(aliases);\n      var keys = keyDesc.split('+'); // log to debug\n      // console.log('eventMatches', event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)\n\n      for (var i = 0; i < keys.length; i++) {\n        var key = keys[i];\n        var pressed = false;\n\n        if (key === 'shift') {\n          pressed = event.shiftKey ? true : false;\n        } else if (key === 'ctrl') {\n          pressed = event.ctrlKey ? true : false;\n        } else if (key === 'alt') {\n          pressed = event.altKey ? true : false;\n        } else if (key === 'meta') {\n          pressed = event.metaKey ? true : false;\n        } else if (aliasKeys.indexOf(key) !== -1) {\n          pressed = event.keyCode === aliases[key];\n        } else if (event.keyCode === key.toUpperCase().charCodeAt(0)) {\n          pressed = true;\n        }\n\n        if (!pressed) return false;\n      }\n\n      return true;\n    }\n  }]);\n\n  return Keyboard;\n}();\n\n\n\n//# sourceURL=webpack:///./src/js/utils/keyboard.js?");
  
  /***/ }),
  
  /***/ "./src/js/utils/orbitControls.js":
  /*!***************************************!*\
    !*** ./src/js/utils/orbitControls.js ***!
    \***************************************/
  /*! no static exports found */
  /***/ (function(module, exports) {
  
  eval("module.exports = function (THREE) {\n  var MOUSE = THREE.MOUSE;\n  if (!MOUSE) MOUSE = {\n    LEFT: 0,\n    MIDDLE: 1,\n    RIGHT: 2\n  };\n  /**\n   * @author qiao / https://github.com/qiao\n   * @author mrdoob / http://mrdoob.com\n   * @author alteredq / http://alteredqualia.com/\n   * @author WestLangley / http://github.com/WestLangley\n   * @author erich666 / http://erichaines.com\n   */\n\n  /*global THREE, console */\n\n  function OrbitConstraint(object) {\n    this.object = object; // \"target\" sets the location of focus, where the object orbits around\n    // and where it pans with respect to.\n\n    this.target = new THREE.Vector3(); // Limits to how far you can dolly in and out ( PerspectiveCamera only )\n\n    this.minDistance = 0;\n    this.maxDistance = Infinity; // Limits to how far you can zoom in and out ( OrthographicCamera only )\n\n    this.minZoom = 0;\n    this.maxZoom = Infinity; // How far you can orbit vertically, upper and lower limits.\n    // Range is 0 to Math.PI radians.\n\n    this.minPolarAngle = 0; // radians\n\n    this.maxPolarAngle = Math.PI; // radians\n    // How far you can orbit horizontally, upper and lower limits.\n    // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\n    this.minAzimuthAngle = -Infinity; // radians\n\n    this.maxAzimuthAngle = Infinity; // radians\n    // Set to true to enable damping (inertia)\n    // If damping is enabled, you must call controls.update() in your animation loop\n\n    this.enableDamping = false;\n    this.dampingFactor = 0.25; ////////////\n    // internals\n\n    var scope = this;\n    var EPS = 0.000001; // Current position in spherical coordinate system.\n\n    var theta;\n    var phi; // Pending changes\n\n    var phiDelta = 0;\n    var thetaDelta = 0;\n    var scale = 1;\n    var panOffset = new THREE.Vector3();\n    var zoomChanged = false; // API\n\n    this.getPolarAngle = function () {\n      return phi;\n    };\n\n    this.getAzimuthalAngle = function () {\n      return theta;\n    };\n\n    this.rotateLeft = function (angle) {\n      thetaDelta -= angle;\n    };\n\n    this.rotateUp = function (angle) {\n      phiDelta -= angle;\n    }; // pass in distance in world space to move left\n\n\n    this.panLeft = function () {\n      var v = new THREE.Vector3();\n      return function panLeft(distance) {\n        var te = this.object.matrix.elements; // get X column of matrix\n\n        v.set(te[0], te[1], te[2]);\n        v.multiplyScalar(-distance);\n        panOffset.add(v);\n      };\n    }(); // pass in distance in world space to move up\n\n\n    this.panUp = function () {\n      var v = new THREE.Vector3();\n      return function panUp(distance) {\n        var te = this.object.matrix.elements; // get Y column of matrix\n\n        v.set(te[4], te[5], te[6]);\n        v.multiplyScalar(distance);\n        panOffset.add(v);\n      };\n    }(); // pass in x,y of change desired in pixel space,\n    // right and down are positive\n\n\n    this.pan = function (deltaX, deltaY, screenWidth, screenHeight) {\n      if (scope.object instanceof THREE.PerspectiveCamera) {\n        // perspective\n        var position = scope.object.position;\n        var offset = position.clone().sub(scope.target);\n        var targetDistance = offset.length(); // half of the fov is center to top of screen\n\n        targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180.0); // we actually don't use screenWidth, since perspective camera is fixed to screen height\n\n        scope.panLeft(2 * deltaX * targetDistance / screenHeight);\n        scope.panUp(2 * deltaY * targetDistance / screenHeight);\n      } else if (scope.object instanceof THREE.OrthographicCamera) {\n        // orthographic\n        scope.panLeft(deltaX * (scope.object.right - scope.object.left) / screenWidth);\n        scope.panUp(deltaY * (scope.object.top - scope.object.bottom) / screenHeight);\n      } else {\n        // camera neither orthographic or perspective\n        console.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');\n      }\n    };\n\n    this.dollyIn = function (dollyScale) {\n      if (scope.object instanceof THREE.PerspectiveCamera) {\n        scale /= dollyScale;\n      } else if (scope.object instanceof THREE.OrthographicCamera) {\n        scope.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom * dollyScale));\n        scope.object.updateProjectionMatrix();\n        zoomChanged = true;\n      } else {\n        console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n      }\n    };\n\n    this.dollyOut = function (dollyScale) {\n      if (scope.object instanceof THREE.PerspectiveCamera) {\n        scale *= dollyScale;\n      } else if (scope.object instanceof THREE.OrthographicCamera) {\n        scope.object.zoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.object.zoom / dollyScale));\n        scope.object.updateProjectionMatrix();\n        zoomChanged = true;\n      } else {\n        console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n      }\n    };\n\n    this.update = function () {\n      var offset = new THREE.Vector3(); // so camera.up is the orbit axis\n\n      var quat = new THREE.Quaternion().setFromUnitVectors(object.up, new THREE.Vector3(0, 1, 0));\n      var quatInverse = quat.clone().inverse();\n      var lastPosition = new THREE.Vector3();\n      var lastQuaternion = new THREE.Quaternion();\n      return function () {\n        var position = this.object.position;\n        offset.copy(position).sub(this.target); // rotate offset to \"y-axis-is-up\" space\n\n        offset.applyQuaternion(quat); // angle from z-axis around y-axis\n\n        theta = Math.atan2(offset.x, offset.z); // angle from y-axis\n\n        phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);\n        theta += thetaDelta;\n        phi += phiDelta; // restrict theta to be between desired limits\n\n        theta = Math.max(this.minAzimuthAngle, Math.min(this.maxAzimuthAngle, theta)); // restrict phi to be between desired limits\n\n        phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, phi)); // restrict phi to be betwee EPS and PI-EPS\n\n        phi = Math.max(EPS, Math.min(Math.PI - EPS, phi));\n        var radius = offset.length() * scale; // restrict radius to be between desired limits\n\n        radius = Math.max(this.minDistance, Math.min(this.maxDistance, radius)); // move target to panned location\n\n        this.target.add(panOffset);\n        offset.x = radius * Math.sin(phi) * Math.sin(theta);\n        offset.y = radius * Math.cos(phi);\n        offset.z = radius * Math.sin(phi) * Math.cos(theta); // rotate offset back to \"camera-up-vector-is-up\" space\n\n        offset.applyQuaternion(quatInverse);\n        position.copy(this.target).add(offset);\n        this.object.lookAt(this.target);\n\n        if (this.enableDamping === true) {\n          thetaDelta *= 1 - this.dampingFactor;\n          phiDelta *= 1 - this.dampingFactor;\n        } else {\n          thetaDelta = 0;\n          phiDelta = 0;\n        }\n\n        scale = 1;\n        panOffset.set(0, 0, 0); // update condition is:\n        // min(camera displacement, camera rotation in radians)^2 > EPS\n        // using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n        if (zoomChanged || lastPosition.distanceToSquared(this.object.position) > EPS || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS) {\n          lastPosition.copy(this.object.position);\n          lastQuaternion.copy(this.object.quaternion);\n          zoomChanged = false;\n          return true;\n        }\n\n        return false;\n      };\n    }();\n  }\n\n  ; // This set of controls performs orbiting, dollying (zooming), and panning. It maintains\n  // the \"up\" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is\n  // supported.\n  //\n  //    Orbit - left mouse / touch: one finger move\n  //    Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n  //    Pan - right mouse, or arrow keys / touch: three finter swipe\n\n  function OrbitControls(object, domElement) {\n    var constraint = new OrbitConstraint(object);\n    this.domElement = domElement !== undefined ? domElement : document; // API\n\n    Object.defineProperty(this, 'constraint', {\n      get: function get() {\n        return constraint;\n      }\n    });\n\n    this.getPolarAngle = function () {\n      return constraint.getPolarAngle();\n    };\n\n    this.getAzimuthalAngle = function () {\n      return constraint.getAzimuthalAngle();\n    }; // Set to false to disable this control\n\n\n    this.enabled = true; // center is old, deprecated; use \"target\" instead\n\n    this.center = this.target; // This option actually enables dollying in and out; left as \"zoom\" for\n    // backwards compatibility.\n    // Set to false to disable zooming\n\n    this.enableZoom = true;\n    this.zoomSpeed = 1.0; // Set to false to disable rotating\n\n    this.enableRotate = true;\n    this.rotateSpeed = 1.0; // Set to false to disable panning\n\n    this.enablePan = true;\n    this.keyPanSpeed = 7.0; // pixels moved per arrow key push\n    // Set to true to automatically rotate around the target\n    // If auto-rotate is enabled, you must call controls.update() in your animation loop\n\n    this.autoRotate = false;\n    this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n    // Set to false to disable use of the keys\n\n    this.enableKeys = true; // The four arrow keys\n\n    this.keys = {\n      LEFT: 37,\n      UP: 38,\n      RIGHT: 39,\n      BOTTOM: 40\n    }; // Mouse buttons\n\n    this.mouseButtons = {\n      ORBIT: THREE.MOUSE.LEFT,\n      ZOOM: THREE.MOUSE.MIDDLE,\n      PAN: THREE.MOUSE.RIGHT\n    }; ////////////\n    // internals\n\n    var scope = this;\n    var rotateStart = new THREE.Vector2();\n    var rotateEnd = new THREE.Vector2();\n    var rotateDelta = new THREE.Vector2();\n    var panStart = new THREE.Vector2();\n    var panEnd = new THREE.Vector2();\n    var panDelta = new THREE.Vector2();\n    var dollyStart = new THREE.Vector2();\n    var dollyEnd = new THREE.Vector2();\n    var dollyDelta = new THREE.Vector2();\n    var STATE = {\n      NONE: -1,\n      ROTATE: 0,\n      DOLLY: 1,\n      PAN: 2,\n      TOUCH_ROTATE: 3,\n      TOUCH_DOLLY: 4,\n      TOUCH_PAN: 5\n    };\n    var state = STATE.NONE; // for reset\n\n    this.target0 = this.target.clone();\n    this.position0 = this.object.position.clone();\n    this.zoom0 = this.object.zoom; // events\n\n    var changeEvent = {\n      type: 'change'\n    };\n    var startEvent = {\n      type: 'start'\n    };\n    var endEvent = {\n      type: 'end'\n    }; // pass in x,y of change desired in pixel space,\n    // right and down are positive\n\n    function pan(deltaX, deltaY) {\n      var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n      constraint.pan(deltaX, deltaY, element.clientWidth, element.clientHeight);\n    }\n\n    this.update = function () {\n      if (this.autoRotate && state === STATE.NONE) {\n        constraint.rotateLeft(getAutoRotationAngle());\n      }\n\n      if (constraint.update() === true) {\n        this.dispatchEvent(changeEvent);\n      }\n    };\n\n    this.reset = function () {\n      state = STATE.NONE;\n      this.target.copy(this.target0);\n      this.object.position.copy(this.position0);\n      this.object.zoom = this.zoom0;\n      this.object.updateProjectionMatrix();\n      this.dispatchEvent(changeEvent);\n      this.update();\n    };\n\n    function getAutoRotationAngle() {\n      return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n    }\n\n    function getZoomScale() {\n      return Math.pow(0.95, scope.zoomSpeed);\n    }\n\n    function onMouseDown(event) {\n      if (scope.enabled === false) return;\n      event.preventDefault();\n\n      if (event.button === scope.mouseButtons.ORBIT) {\n        if (scope.enableRotate === false) return;\n        state = STATE.ROTATE;\n        rotateStart.set(event.clientX, event.clientY);\n      } else if (event.button === scope.mouseButtons.ZOOM) {\n        if (scope.enableZoom === false) return;\n        state = STATE.DOLLY;\n        dollyStart.set(event.clientX, event.clientY);\n      } else if (event.button === scope.mouseButtons.PAN) {\n        if (scope.enablePan === false) return;\n        state = STATE.PAN;\n        panStart.set(event.clientX, event.clientY);\n      }\n\n      if (state !== STATE.NONE) {\n        document.addEventListener('mousemove', onMouseMove, false);\n        document.addEventListener('mouseup', onMouseUp, false);\n        scope.dispatchEvent(startEvent);\n      }\n    }\n\n    function onMouseMove(event) {\n      if (scope.enabled === false) return;\n      event.preventDefault();\n      var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n      if (state === STATE.ROTATE) {\n        if (scope.enableRotate === false) return;\n        rotateEnd.set(event.clientX, event.clientY);\n        rotateDelta.subVectors(rotateEnd, rotateStart); // rotating across whole screen goes 360 degrees around\n\n        constraint.rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed); // rotating up and down along whole screen attempts to go 360, but limited to 180\n\n        constraint.rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n        rotateStart.copy(rotateEnd);\n      } else if (state === STATE.DOLLY) {\n        if (scope.enableZoom === false) return;\n        dollyEnd.set(event.clientX, event.clientY);\n        dollyDelta.subVectors(dollyEnd, dollyStart);\n\n        if (dollyDelta.y > 0) {\n          constraint.dollyIn(getZoomScale());\n        } else if (dollyDelta.y < 0) {\n          constraint.dollyOut(getZoomScale());\n        }\n\n        dollyStart.copy(dollyEnd);\n      } else if (state === STATE.PAN) {\n        if (scope.enablePan === false) return;\n        panEnd.set(event.clientX, event.clientY);\n        panDelta.subVectors(panEnd, panStart);\n        pan(panDelta.x, panDelta.y);\n        panStart.copy(panEnd);\n      }\n\n      if (state !== STATE.NONE) scope.update();\n    }\n\n    function onMouseUp()\n    /* event */\n    {\n      if (scope.enabled === false) return;\n      document.removeEventListener('mousemove', onMouseMove, false);\n      document.removeEventListener('mouseup', onMouseUp, false);\n      scope.dispatchEvent(endEvent);\n      state = STATE.NONE;\n    }\n\n    function onMouseWheel(event) {\n      if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;\n      event.preventDefault();\n      event.stopPropagation();\n      var delta = 0;\n\n      if (event.wheelDelta !== undefined) {\n        // WebKit / Opera / Explorer 9\n        delta = event.wheelDelta;\n      } else if (event.detail !== undefined) {\n        // Firefox\n        delta = -event.detail;\n      }\n\n      if (delta > 0) {\n        constraint.dollyOut(getZoomScale());\n      } else if (delta < 0) {\n        constraint.dollyIn(getZoomScale());\n      }\n\n      scope.update();\n      scope.dispatchEvent(startEvent);\n      scope.dispatchEvent(endEvent);\n    }\n\n    function onKeyDown(event) {\n      if (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false) return;\n\n      switch (event.keyCode) {\n        case scope.keys.UP:\n          pan(0, scope.keyPanSpeed);\n          scope.update();\n          break;\n\n        case scope.keys.BOTTOM:\n          pan(0, -scope.keyPanSpeed);\n          scope.update();\n          break;\n\n        case scope.keys.LEFT:\n          pan(scope.keyPanSpeed, 0);\n          scope.update();\n          break;\n\n        case scope.keys.RIGHT:\n          pan(-scope.keyPanSpeed, 0);\n          scope.update();\n          break;\n      }\n    }\n\n    function touchstart(event) {\n      if (scope.enabled === false) return;\n\n      switch (event.touches.length) {\n        case 1:\n          // one-fingered touch: rotate\n          if (scope.enableRotate === false) return;\n          state = STATE.TOUCH_ROTATE;\n          rotateStart.set(event.touches[0].pageX, event.touches[0].pageY);\n          break;\n\n        case 2:\n          // two-fingered touch: dolly\n          if (scope.enableZoom === false) return;\n          state = STATE.TOUCH_DOLLY;\n          var dx = event.touches[0].pageX - event.touches[1].pageX;\n          var dy = event.touches[0].pageY - event.touches[1].pageY;\n          var distance = Math.sqrt(dx * dx + dy * dy);\n          dollyStart.set(0, distance);\n          break;\n\n        case 3:\n          // three-fingered touch: pan\n          if (scope.enablePan === false) return;\n          state = STATE.TOUCH_PAN;\n          panStart.set(event.touches[0].pageX, event.touches[0].pageY);\n          break;\n\n        default:\n          state = STATE.NONE;\n      }\n\n      if (state !== STATE.NONE) scope.dispatchEvent(startEvent);\n    }\n\n    function touchmove(event) {\n      if (scope.enabled === false) return;\n      event.preventDefault();\n      event.stopPropagation();\n      var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n      switch (event.touches.length) {\n        case 1:\n          // one-fingered touch: rotate\n          if (scope.enableRotate === false) return;\n          if (state !== STATE.TOUCH_ROTATE) return;\n          rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n          rotateDelta.subVectors(rotateEnd, rotateStart); // rotating across whole screen goes 360 degrees around\n\n          constraint.rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed); // rotating up and down along whole screen attempts to go 360, but limited to 180\n\n          constraint.rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n          rotateStart.copy(rotateEnd);\n          scope.update();\n          break;\n\n        case 2:\n          // two-fingered touch: dolly\n          if (scope.enableZoom === false) return;\n          if (state !== STATE.TOUCH_DOLLY) return;\n          var dx = event.touches[0].pageX - event.touches[1].pageX;\n          var dy = event.touches[0].pageY - event.touches[1].pageY;\n          var distance = Math.sqrt(dx * dx + dy * dy);\n          dollyEnd.set(0, distance);\n          dollyDelta.subVectors(dollyEnd, dollyStart);\n\n          if (dollyDelta.y > 0) {\n            constraint.dollyOut(getZoomScale());\n          } else if (dollyDelta.y < 0) {\n            constraint.dollyIn(getZoomScale());\n          }\n\n          dollyStart.copy(dollyEnd);\n          scope.update();\n          break;\n\n        case 3:\n          // three-fingered touch: pan\n          if (scope.enablePan === false) return;\n          if (state !== STATE.TOUCH_PAN) return;\n          panEnd.set(event.touches[0].pageX, event.touches[0].pageY);\n          panDelta.subVectors(panEnd, panStart);\n          pan(panDelta.x, panDelta.y);\n          panStart.copy(panEnd);\n          scope.update();\n          break;\n\n        default:\n          state = STATE.NONE;\n      }\n    }\n\n    function touchend()\n    /* event */\n    {\n      if (scope.enabled === false) return;\n      scope.dispatchEvent(endEvent);\n      state = STATE.NONE;\n    }\n\n    function contextmenu(event) {\n      event.preventDefault();\n    }\n\n    this.dispose = function () {\n      this.domElement.removeEventListener('contextmenu', contextmenu, false);\n      this.domElement.removeEventListener('mousedown', onMouseDown, false);\n      this.domElement.removeEventListener('mousewheel', onMouseWheel, false);\n      this.domElement.removeEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\n      this.domElement.removeEventListener('touchstart', touchstart, false);\n      this.domElement.removeEventListener('touchend', touchend, false);\n      this.domElement.removeEventListener('touchmove', touchmove, false);\n      document.removeEventListener('mousemove', onMouseMove, false);\n      document.removeEventListener('mouseup', onMouseUp, false);\n      window.removeEventListener('keydown', onKeyDown, false);\n    };\n\n    this.domElement.addEventListener('contextmenu', contextmenu, false);\n    this.domElement.addEventListener('mousedown', onMouseDown, false);\n    this.domElement.addEventListener('mousewheel', onMouseWheel, false);\n    this.domElement.addEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\n    this.domElement.addEventListener('touchstart', touchstart, false);\n    this.domElement.addEventListener('touchend', touchend, false);\n    this.domElement.addEventListener('touchmove', touchmove, false);\n    window.addEventListener('keydown', onKeyDown, false); // force an update at start\n\n    this.update();\n  }\n\n  ;\n  OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype);\n  OrbitControls.prototype.constructor = OrbitControls;\n  Object.defineProperties(OrbitControls.prototype, {\n    object: {\n      get: function get() {\n        return this.constraint.object;\n      }\n    },\n    target: {\n      get: function get() {\n        return this.constraint.target;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: target is now immutable. Use target.set() instead.');\n        this.constraint.target.copy(value);\n      }\n    },\n    minDistance: {\n      get: function get() {\n        return this.constraint.minDistance;\n      },\n      set: function set(value) {\n        this.constraint.minDistance = value;\n      }\n    },\n    maxDistance: {\n      get: function get() {\n        return this.constraint.maxDistance;\n      },\n      set: function set(value) {\n        this.constraint.maxDistance = value;\n      }\n    },\n    minZoom: {\n      get: function get() {\n        return this.constraint.minZoom;\n      },\n      set: function set(value) {\n        this.constraint.minZoom = value;\n      }\n    },\n    maxZoom: {\n      get: function get() {\n        return this.constraint.maxZoom;\n      },\n      set: function set(value) {\n        this.constraint.maxZoom = value;\n      }\n    },\n    minPolarAngle: {\n      get: function get() {\n        return this.constraint.minPolarAngle;\n      },\n      set: function set(value) {\n        this.constraint.minPolarAngle = value;\n      }\n    },\n    maxPolarAngle: {\n      get: function get() {\n        return this.constraint.maxPolarAngle;\n      },\n      set: function set(value) {\n        this.constraint.maxPolarAngle = value;\n      }\n    },\n    minAzimuthAngle: {\n      get: function get() {\n        return this.constraint.minAzimuthAngle;\n      },\n      set: function set(value) {\n        this.constraint.minAzimuthAngle = value;\n      }\n    },\n    maxAzimuthAngle: {\n      get: function get() {\n        return this.constraint.maxAzimuthAngle;\n      },\n      set: function set(value) {\n        this.constraint.maxAzimuthAngle = value;\n      }\n    },\n    enableDamping: {\n      get: function get() {\n        return this.constraint.enableDamping;\n      },\n      set: function set(value) {\n        this.constraint.enableDamping = value;\n      }\n    },\n    dampingFactor: {\n      get: function get() {\n        return this.constraint.dampingFactor;\n      },\n      set: function set(value) {\n        this.constraint.dampingFactor = value;\n      }\n    },\n    // backward compatibility\n    noZoom: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n        return !this.enableZoom;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n        this.enableZoom = !value;\n      }\n    },\n    noRotate: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n        return !this.enableRotate;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n        this.enableRotate = !value;\n      }\n    },\n    noPan: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n        return !this.enablePan;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n        this.enablePan = !value;\n      }\n    },\n    noKeys: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n        return !this.enableKeys;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n        this.enableKeys = !value;\n      }\n    },\n    staticMoving: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n        return !this.constraint.enableDamping;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n        this.constraint.enableDamping = !value;\n      }\n    },\n    dynamicDampingFactor: {\n      get: function get() {\n        console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n        return this.constraint.dampingFactor;\n      },\n      set: function set(value) {\n        console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n        this.constraint.dampingFactor = value;\n      }\n    }\n  });\n  return OrbitControls;\n};\n\n//# sourceURL=webpack:///./src/js/utils/orbitControls.js?");
  
  /***/ }),
  
  /***/ 0:
  /*!*****************************!*\
    !*** multi ./src/js/app.js ***!
    \*****************************/
  /*! no static exports found */
  /***/ (function(module, exports, __webpack_require__) {
  
  eval("module.exports = __webpack_require__(/*! ./src/js/app.js */\"./src/js/app.js\");\n\n\n//# sourceURL=webpack:///multi_./src/js/app.js?");
  
  /***/ })
  
  },[[0,"runtime","vendors"]]]);