diff --git a/README.md b/README.md
index 7e06061a..855043be 100644
--- a/README.md
+++ b/README.md
@@ -72,10 +72,10 @@ Basic Example
My Networked-Aframe Scene
-
+
-
+
diff --git a/dist/networked-aframe.js b/dist/networked-aframe.js
index 9fcafb4d..48ae94d9 100644
--- a/dist/networked-aframe.js
+++ b/dist/networked-aframe.js
@@ -94,7 +94,7 @@
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n/* global THREE */\n\n\nvar INITIALIZING = 0;\nvar BUFFERING = 1;\nvar PLAYING = 2;\nvar MODE_LERP = 0;\nvar MODE_HERMITE = 1;\nvar vectorPool = [];\nvar quatPool = [];\nvar framePool = [];\n\nvar getPooledVector = function getPooledVector() {\n return vectorPool.shift() || new THREE.Vector3();\n};\n\nvar getPooledQuaternion = function getPooledQuaternion() {\n return quatPool.shift() || new THREE.Quaternion();\n};\n\nvar getPooledFrame = function getPooledFrame() {\n var frame = framePool.pop();\n\n if (!frame) {\n frame = {\n position: new THREE.Vector3(),\n velocity: new THREE.Vector3(),\n scale: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n time: 0\n };\n }\n\n return frame;\n};\n\nvar freeFrame = function freeFrame(f) {\n return framePool.push(f);\n};\n\nvar InterpolationBuffer = function () {\n function InterpolationBuffer() {\n var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MODE_LERP;\n var bufferTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;\n\n _classCallCheck(this, InterpolationBuffer);\n\n this.state = INITIALIZING;\n this.buffer = [];\n this.bufferTime = bufferTime * 1000;\n this.time = 0;\n this.mode = mode;\n this.originFrame = getPooledFrame();\n this.position = new THREE.Vector3();\n this.quaternion = new THREE.Quaternion();\n this.scale = new THREE.Vector3(1, 1, 1);\n }\n\n _createClass(InterpolationBuffer, [{\n key: \"hermite\",\n value: function hermite(target, t, p1, p2, v1, v2) {\n var t2 = t * t;\n var t3 = t * t * t;\n var a = 2 * t3 - 3 * t2 + 1;\n var b = -2 * t3 + 3 * t2;\n var c = t3 - 2 * t2 + t;\n var d = t3 - t2;\n target.copy(p1.multiplyScalar(a));\n target.add(p2.multiplyScalar(b));\n target.add(v1.multiplyScalar(c));\n target.add(v2.multiplyScalar(d));\n }\n }, {\n key: \"lerp\",\n value: function lerp(target, v1, v2, alpha) {\n target.lerpVectors(v1, v2, alpha);\n }\n }, {\n key: \"slerp\",\n value: function slerp(target, r1, r2, alpha) {\n THREE.Quaternion.slerp(r1, r2, target, alpha);\n }\n }, {\n key: \"updateOriginFrameToBufferTail\",\n value: function updateOriginFrameToBufferTail() {\n freeFrame(this.originFrame);\n this.originFrame = this.buffer.shift();\n }\n }, {\n key: \"appendBuffer\",\n value: function appendBuffer(position, velocity, quaternion, scale) {\n var tail = this.buffer.length > 0 ? this.buffer[this.buffer.length - 1] : null; // update the last entry in the buffer if this is the same frame\n\n if (tail && tail.time === this.time) {\n if (position) {\n tail.position.copy(position);\n }\n\n if (velocity) {\n tail.velocity.copy(velocity);\n }\n\n if (quaternion) {\n tail.quaternion.copy(quaternion);\n }\n\n if (scale) {\n tail.scale.copy(scale);\n }\n } else {\n var priorFrame = tail || this.originFrame;\n var newFrame = getPooledFrame();\n newFrame.position.copy(position || priorFrame.position);\n newFrame.velocity.copy(velocity || priorFrame.velocity);\n newFrame.quaternion.copy(quaternion || priorFrame.quaternion);\n newFrame.scale.copy(scale || priorFrame.scale);\n newFrame.time = this.time;\n this.buffer.push(newFrame);\n }\n }\n }, {\n key: \"setTarget\",\n value: function setTarget(position, velocity, quaternion, scale) {\n this.appendBuffer(position, velocity, quaternion, scale);\n }\n }, {\n key: \"setPosition\",\n value: function setPosition(position, velocity) {\n this.appendBuffer(position, velocity, null, null);\n }\n }, {\n key: \"setQuaternion\",\n value: function setQuaternion(quaternion) {\n this.appendBuffer(null, null, quaternion, null);\n }\n }, {\n key: \"setScale\",\n value: function setScale(scale) {\n this.appendBuffer(null, null, null, scale);\n }\n }, {\n key: \"update\",\n value: function update(delta) {\n if (this.state === INITIALIZING) {\n if (this.buffer.length > 0) {\n this.updateOriginFrameToBufferTail();\n this.position.copy(this.originFrame.position);\n this.quaternion.copy(this.originFrame.quaternion);\n this.scale.copy(this.originFrame.scale);\n this.state = BUFFERING;\n }\n }\n\n if (this.state === BUFFERING) {\n if (this.buffer.length > 0 && this.time > this.bufferTime) {\n this.state = PLAYING;\n }\n }\n\n if (this.state === PLAYING) {\n var mark = this.time - this.bufferTime; //Purge this.buffer of expired frames\n\n while (this.buffer.length > 0 && mark > this.buffer[0].time) {\n //if this is the last frame in the buffer, just update the time and reuse it\n if (this.buffer.length > 1) {\n this.updateOriginFrameToBufferTail();\n } else {\n this.originFrame.position.copy(this.buffer[0].position);\n this.originFrame.velocity.copy(this.buffer[0].velocity);\n this.originFrame.quaternion.copy(this.buffer[0].quaternion);\n this.originFrame.scale.copy(this.buffer[0].scale);\n this.originFrame.time = this.buffer[0].time;\n this.buffer[0].time = this.time + delta;\n }\n }\n\n if (this.buffer.length > 0 && this.buffer[0].time > 0) {\n var targetFrame = this.buffer[0];\n var delta_time = targetFrame.time - this.originFrame.time;\n var alpha = (mark - this.originFrame.time) / delta_time;\n\n if (this.mode === MODE_LERP) {\n this.lerp(this.position, this.originFrame.position, targetFrame.position, alpha);\n } else if (this.mode === MODE_HERMITE) {\n this.hermite(this.position, alpha, this.originFrame.position, targetFrame.position, this.originFrame.velocity.multiplyScalar(delta_time), targetFrame.velocity.multiplyScalar(delta_time));\n }\n\n this.slerp(this.quaternion, this.originFrame.quaternion, targetFrame.quaternion, alpha);\n this.lerp(this.scale, this.originFrame.scale, targetFrame.scale, alpha);\n }\n }\n\n if (this.state !== INITIALIZING) {\n this.time += delta;\n }\n }\n }, {\n key: \"getPosition\",\n value: function getPosition() {\n return this.position;\n }\n }, {\n key: \"getQuaternion\",\n value: function getQuaternion() {\n return this.quaternion;\n }\n }, {\n key: \"getScale\",\n value: function getScale() {\n return this.scale;\n }\n }]);\n\n return InterpolationBuffer;\n}();\n\nmodule.exports = InterpolationBuffer;\n\n//# sourceURL=webpack:///./node_modules/buffered-interpolation/dist/buffered-interpolation.js?");
+eval("\n\nvar _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n}();\n\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n/* global THREE */\n\n\nvar INITIALIZING = 0;\nvar BUFFERING = 1;\nvar PLAYING = 2;\nvar MODE_LERP = 0;\nvar MODE_HERMITE = 1;\nvar vectorPool = [];\nvar quatPool = [];\nvar framePool = [];\n\nvar getPooledVector = function getPooledVector() {\n return vectorPool.shift() || new THREE.Vector3();\n};\n\nvar getPooledQuaternion = function getPooledQuaternion() {\n return quatPool.shift() || new THREE.Quaternion();\n};\n\nvar getPooledFrame = function getPooledFrame() {\n var frame = framePool.pop();\n\n if (!frame) {\n frame = {\n position: new THREE.Vector3(),\n velocity: new THREE.Vector3(),\n scale: new THREE.Vector3(),\n quaternion: new THREE.Quaternion(),\n time: 0\n };\n }\n\n return frame;\n};\n\nvar freeFrame = function freeFrame(f) {\n return framePool.push(f);\n};\n\nvar InterpolationBuffer = function () {\n function InterpolationBuffer() {\n var mode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : MODE_LERP;\n var bufferTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.15;\n\n _classCallCheck(this, InterpolationBuffer);\n\n this.state = INITIALIZING;\n this.buffer = [];\n this.bufferTime = bufferTime * 1000;\n this.time = 0;\n this.mode = mode;\n this.originFrame = getPooledFrame();\n this.position = new THREE.Vector3();\n this.quaternion = new THREE.Quaternion();\n this.scale = new THREE.Vector3(1, 1, 1);\n }\n\n _createClass(InterpolationBuffer, [{\n key: \"hermite\",\n value: function hermite(target, t, p1, p2, v1, v2) {\n var t2 = t * t;\n var t3 = t * t * t;\n var a = 2 * t3 - 3 * t2 + 1;\n var b = -2 * t3 + 3 * t2;\n var c = t3 - 2 * t2 + t;\n var d = t3 - t2;\n target.copy(p1.multiplyScalar(a));\n target.add(p2.multiplyScalar(b));\n target.add(v1.multiplyScalar(c));\n target.add(v2.multiplyScalar(d));\n }\n }, {\n key: \"lerp\",\n value: function lerp(target, v1, v2, alpha) {\n target.lerpVectors(v1, v2, alpha);\n }\n }, {\n key: \"slerp\",\n value: function slerp(target, r1, r2, alpha) {\n target.slerpQuaternions(r1, r2, alpha);\n }\n }, {\n key: \"updateOriginFrameToBufferTail\",\n value: function updateOriginFrameToBufferTail() {\n freeFrame(this.originFrame);\n this.originFrame = this.buffer.shift();\n }\n }, {\n key: \"appendBuffer\",\n value: function appendBuffer(position, velocity, quaternion, scale) {\n var tail = this.buffer.length > 0 ? this.buffer[this.buffer.length - 1] : null; // update the last entry in the buffer if this is the same frame\n\n if (tail && tail.time === this.time) {\n if (position) {\n tail.position.copy(position);\n }\n\n if (velocity) {\n tail.velocity.copy(velocity);\n }\n\n if (quaternion) {\n tail.quaternion.copy(quaternion);\n }\n\n if (scale) {\n tail.scale.copy(scale);\n }\n } else {\n var priorFrame = tail || this.originFrame;\n var newFrame = getPooledFrame();\n newFrame.position.copy(position || priorFrame.position);\n newFrame.velocity.copy(velocity || priorFrame.velocity);\n newFrame.quaternion.copy(quaternion || priorFrame.quaternion);\n newFrame.scale.copy(scale || priorFrame.scale);\n newFrame.time = this.time;\n this.buffer.push(newFrame);\n }\n }\n }, {\n key: \"setTarget\",\n value: function setTarget(position, velocity, quaternion, scale) {\n this.appendBuffer(position, velocity, quaternion, scale);\n }\n }, {\n key: \"setPosition\",\n value: function setPosition(position, velocity) {\n this.appendBuffer(position, velocity, null, null);\n }\n }, {\n key: \"setQuaternion\",\n value: function setQuaternion(quaternion) {\n this.appendBuffer(null, null, quaternion, null);\n }\n }, {\n key: \"setScale\",\n value: function setScale(scale) {\n this.appendBuffer(null, null, null, scale);\n }\n }, {\n key: \"update\",\n value: function update(delta) {\n if (this.state === INITIALIZING) {\n if (this.buffer.length > 0) {\n this.updateOriginFrameToBufferTail();\n this.position.copy(this.originFrame.position);\n this.quaternion.copy(this.originFrame.quaternion);\n this.scale.copy(this.originFrame.scale);\n this.state = BUFFERING;\n }\n }\n\n if (this.state === BUFFERING) {\n if (this.buffer.length > 0 && this.time > this.bufferTime) {\n this.state = PLAYING;\n }\n }\n\n if (this.state === PLAYING) {\n var mark = this.time - this.bufferTime; //Purge this.buffer of expired frames\n\n while (this.buffer.length > 0 && mark > this.buffer[0].time) {\n //if this is the last frame in the buffer, just update the time and reuse it\n if (this.buffer.length > 1) {\n this.updateOriginFrameToBufferTail();\n } else {\n this.originFrame.position.copy(this.buffer[0].position);\n this.originFrame.velocity.copy(this.buffer[0].velocity);\n this.originFrame.quaternion.copy(this.buffer[0].quaternion);\n this.originFrame.scale.copy(this.buffer[0].scale);\n this.originFrame.time = this.buffer[0].time;\n this.buffer[0].time = this.time + delta;\n }\n }\n\n if (this.buffer.length > 0 && this.buffer[0].time > 0) {\n var targetFrame = this.buffer[0];\n var delta_time = targetFrame.time - this.originFrame.time;\n var alpha = (mark - this.originFrame.time) / delta_time;\n\n if (this.mode === MODE_LERP) {\n this.lerp(this.position, this.originFrame.position, targetFrame.position, alpha);\n } else if (this.mode === MODE_HERMITE) {\n this.hermite(this.position, alpha, this.originFrame.position, targetFrame.position, this.originFrame.velocity.multiplyScalar(delta_time), targetFrame.velocity.multiplyScalar(delta_time));\n }\n\n this.slerp(this.quaternion, this.originFrame.quaternion, targetFrame.quaternion, alpha);\n this.lerp(this.scale, this.originFrame.scale, targetFrame.scale, alpha);\n }\n }\n\n if (this.state !== INITIALIZING) {\n this.time += delta;\n }\n }\n }, {\n key: \"getPosition\",\n value: function getPosition() {\n return this.position;\n }\n }, {\n key: \"getQuaternion\",\n value: function getQuaternion() {\n return this.quaternion;\n }\n }, {\n key: \"getScale\",\n value: function getScale() {\n return this.scale;\n }\n }]);\n\n return InterpolationBuffer;\n}();\n\nmodule.exports = InterpolationBuffer;\n\n//# sourceURL=webpack:///./node_modules/buffered-interpolation/dist/buffered-interpolation.js?");
/***/ }),
@@ -130,7 +130,7 @@ eval("// Patched version of fast-deep-equal which does not\n// allocate memory v
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("\n\nvar options = __webpack_require__(/*! ./options */ \"./src/options.js\");\n\nvar utils = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\nvar NafLogger = __webpack_require__(/*! ./NafLogger */ \"./src/NafLogger.js\");\n\nvar Schemas = __webpack_require__(/*! ./Schemas */ \"./src/Schemas.js\");\n\nvar NetworkEntities = __webpack_require__(/*! ./NetworkEntities */ \"./src/NetworkEntities.js\");\n\nvar NetworkConnection = __webpack_require__(/*! ./NetworkConnection */ \"./src/NetworkConnection.js\");\n\nvar AdapterFactory = __webpack_require__(/*! ./adapters/AdapterFactory */ \"./src/adapters/AdapterFactory.js\");\n\nvar naf = {};\nnaf.app = '';\nnaf.room = '';\nnaf.clientId = '';\nnaf.options = options;\nnaf.utils = utils;\nnaf.log = new NafLogger();\nnaf.schemas = new Schemas();\nnaf.version = \"0.8.3\";\nnaf.adapters = new AdapterFactory();\nvar entities = new NetworkEntities();\nvar connection = new NetworkConnection(entities);\nnaf.connection = connection;\nnaf.entities = entities;\nmodule.exports = window.NAF = naf;\n\n//# sourceURL=webpack:///./src/NafIndex.js?");
+eval("\n\nvar options = __webpack_require__(/*! ./options */ \"./src/options.js\");\n\nvar utils = __webpack_require__(/*! ./utils */ \"./src/utils.js\");\n\nvar NafLogger = __webpack_require__(/*! ./NafLogger */ \"./src/NafLogger.js\");\n\nvar Schemas = __webpack_require__(/*! ./Schemas */ \"./src/Schemas.js\");\n\nvar NetworkEntities = __webpack_require__(/*! ./NetworkEntities */ \"./src/NetworkEntities.js\");\n\nvar NetworkConnection = __webpack_require__(/*! ./NetworkConnection */ \"./src/NetworkConnection.js\");\n\nvar AdapterFactory = __webpack_require__(/*! ./adapters/AdapterFactory */ \"./src/adapters/AdapterFactory.js\");\n\nvar naf = {};\nnaf.app = '';\nnaf.room = '';\nnaf.clientId = '';\nnaf.options = options;\nnaf.utils = utils;\nnaf.log = new NafLogger();\nnaf.schemas = new Schemas();\nnaf.version = \"0.9.0\";\nnaf.adapters = new AdapterFactory();\nvar entities = new NetworkEntities();\nvar connection = new NetworkConnection(entities);\nnaf.connection = connection;\nnaf.entities = entities;\nmodule.exports = window.NAF = naf;\n\n//# sourceURL=webpack:///./src/NafIndex.js?");
/***/ }),
diff --git a/dist/networked-aframe.min.js b/dist/networked-aframe.min.js
index d07ef7a1..0459ea96 100644
--- a/dist/networked-aframe.min.js
+++ b/dist/networked-aframe.min.js
@@ -1 +1 @@
-!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){"use strict";var i=n(3),o=n(4),r=n(5),a=n(6),s=n(7),c=n(9),u=n(10),l={app:"",room:"",clientId:""};l.options=i,l.utils=o,l.log=new r,l.schemas=new a,l.version="0.8.3",l.adapters=new u;var d=new s,h=new c(d);l.connection=h,l.entities=d,e.exports=window.NAF=l},function(e,t,n){"use strict";function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n is defined."));if(!this.validateTemplate(e,t))return;this.templateCache[e.template]=document.importNode(t.content,!0)}else NAF.log.error("Schema not valid: ",e),NAF.log.error("See https://github.com/networked-aframe/networked-aframe#syncing-custom-components")}},{key:"getCachedTemplate",value:function(e){return this.templateIsCached(e)||(this.templateExistsInScene(e)?this.add(this.createDefaultSchema(e)):NAF.log.error("Template el for ".concat(e," is not in the scene, add the template to and register with NAF.schemas.add."))),this.templateCache[e].firstElementChild.cloneNode(!0)}},{key:"templateIsCached",value:function(e){return!!this.templateCache[e]}},{key:"getComponents",value:function(e){var t=["position","rotation"];return this.hasTemplate(e)&&(t=this.schemaDict[e].components),t}},{key:"hasTemplate",value:function(e){return!!this.schemaDict[e]}},{key:"templateExistsInScene",value:function(e){var t=document.querySelector(e);return t&&this.isTemplateTag(t)}},{key:"validateSchema",value:function(e){return!(!e.template||!e.components)}},{key:"validateTemplate",value:function(e,t){return this.isTemplateTag(t)?!!this.templateHasOneOrZeroChildren(t)||(NAF.log.error("Template for ".concat(e.template," has more than one child. Templates must have one direct child element, no more. Template found:"),t),!1):(NAF.log.error("Template for ".concat(e.template," is not a tag. Instead found: ").concat(t.tagName)),!1)}},{key:"isTemplateTag",value:function(e){return"template"===e.tagName.toLowerCase()}},{key:"templateHasOneOrZeroChildren",value:function(e){return e.content.childElementCount<2}},{key:"remove",value:function(e){delete this.schemaDict[e]}},{key:"clear",value:function(){this.schemaDict={}}}])&&i(t.prototype,n),o&&i(t,o),e}();e.exports=o},function(e,t,n){"use strict";function i(e,t){for(var n=0;n3&&void 0!==arguments[3]&&arguments[3],o=arguments.length>4&&void 0!==arguments[4]&&arguments[4];NAF.app=t,NAF.room=n,this.adapter.setServerUrl(e),this.adapter.setApp(t),this.adapter.setRoom(n);var r={audio:i,video:o,datachannel:!0};return this.adapter.setWebRtcOptions(r),this.adapter.setServerConnectListeners(this.connectSuccess.bind(this),this.connectFailure.bind(this)),this.adapter.setDataChannelListeners(this.dataChannelOpen.bind(this),this.dataChannelClosed.bind(this),this.receivedData.bind(this)),this.adapter.setRoomOccupantListener(this.occupantsReceived.bind(this)),this.adapter.connect()}},{key:"onConnect",value:function(e){this.onConnectCallback=e,this.isConnected()?e():document.body.addEventListener("connected",e,!1)}},{key:"connectSuccess",value:function(e){NAF.log.write("Networked-Aframe Client ID:",e),NAF.clientId=e;var t=new CustomEvent("connected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"connectFailure",value:function(e,t){NAF.log.error(e,"failure to connect")}},{key:"occupantsReceived",value:function(e){var t=Object.assign({},this.connectedClients);this.connectedClients=e,this.checkForDisconnectingClients(t,e),this.checkForConnectingClients(e)}},{key:"checkForDisconnectingClients",value:function(e,t){for(var n in e)t[n]||(NAF.log.write("Closing stream to",n),this.adapter.closeStreamConnection(n))}},{key:"checkForConnectingClients",value:function(e){for(var t in e)this.isNewClient(t)&&this.adapter.shouldStartConnectionTo(e[t])&&(NAF.log.write("Opening datachannel to",t),this.adapter.startStreamConnection(t))}},{key:"getConnectedClients",value:function(){return this.connectedClients}},{key:"isConnected",value:function(){return!!NAF.clientId}},{key:"isMineAndConnected",value:function(e){return this.isConnected()&&NAF.clientId===e}},{key:"isNewClient",value:function(e){return!this.isConnectedTo(e)}},{key:"isConnectedTo",value:function(e){return this.adapter.getConnectStatus(e)===NAF.adapters.IS_CONNECTED}},{key:"dataChannelOpen",value:function(e){NAF.log.write("Opened data channel from "+e),this.activeDataChannels[e]=!0,this.entities.completeSync(e,!0);var t=new CustomEvent("clientConnected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"dataChannelClosed",value:function(e){NAF.log.write("Closed data channel from "+e),this.activeDataChannels[e]=!1,this.entities.removeEntitiesOfClient(e);var t=new CustomEvent("clientDisconnected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"hasActiveDataChannel",value:function(e){return!!this.activeDataChannels[e]}},{key:"broadcastData",value:function(e,t){this.adapter.broadcastData(e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){this.adapter.broadcastDataGuaranteed(e,t)}},{key:"sendData",value:function(e,t,n,i){this.hasActiveDataChannel(e)&&(i?this.adapter.sendDataGuaranteed(e,t,n):this.adapter.sendData(e,t,n))}},{key:"sendDataGuaranteed",value:function(e,t,n){this.sendData(e,t,n,!0)}},{key:"subscribeToDataChannel",value:function(e,t){this.isReservedDataType(e)?NAF.log.error("NetworkConnection@subscribeToDataChannel: "+e+" is a reserved dataType. Choose another"):this.dataChannelSubs[e]=t}},{key:"unsubscribeToDataChannel",value:function(e){this.isReservedDataType(e)?NAF.log.error("NetworkConnection@unsubscribeToDataChannel: "+e+" is a reserved dataType. Choose another"):delete this.dataChannelSubs[e]}},{key:"isReservedDataType",value:function(e){return e==o||e==a}},{key:"receivedData",value:function(e,t,n,i){this.dataChannelSubs[t]?this.dataChannelSubs[t](e,t,n,i):NAF.log.write("NetworkConnection@receivedData: "+t+" has not been subscribed to yet. Call subscribeToDataChannel()")}},{key:"getServerTime",value:function(){return this.adapter.getServerTime()}},{key:"disconnect",value:function(){this.entities.removeRemoteEntities(),this.adapter&&this.adapter.disconnect(),NAF.app="",NAF.room="",NAF.clientId="",this.connectedClients={},this.activeDataChannels={},this.adapter=null,this.setupDefaultDataSubscriptions(),document.body.removeEventListener("connected",this.onConnectCallback)}}])&&i(t.prototype,n),s&&i(t,s),e}();e.exports=s},function(e,t,n){"use strict";function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,i=new Array(t);n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"connect",value:function(){var e=this;Promise.all([this.updateTimeOffset(),new Promise((function(t,n){e.easyrtc.connect(e.app,t,n)}))]).then((function(t){var n=o(t,2),i=(n[0],n[1]);e.connectSuccess(i)})).catch(this.connectFailure)}},{key:"shouldStartConnectionTo",value:function(e){return!0}},{key:"startStreamConnection",value:function(e){this.connectedClients.push(e),this.openListener(e)}},{key:"closeStreamConnection",value:function(e){var t=this.connectedClients.indexOf(e);t>-1&&this.connectedClients.splice(t,1),this.closedListener(e)}},{key:"sendData",value:function(e,t,n){this.easyrtc.sendDataWS(e,t,n)}},{key:"sendDataGuaranteed",value:function(e,t,n){this.sendData(e,t,n)}},{key:"broadcastData",value:function(e,t){var n={targetRoom:this.room};this.easyrtc.sendDataWS(n,e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){this.broadcastData(e,t)}},{key:"getConnectStatus",value:function(e){return-1!=this.connectedClients.indexOf(e)?NAF.adapters.IS_CONNECTED:NAF.adapters.NOT_CONNECTED}},{key:"getServerTime",value:function(){return Date.now()+this.avgTimeOffset}},{key:"disconnect",value:function(){this.easyrtc.disconnect()}}])&&a(t.prototype,n),i&&a(t,i),u}(n(1));e.exports=d},function(e,t,n){"use strict";function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,i=new Array(t);n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"connect",value:function(){var e=this;Promise.all([this.updateTimeOffset(),new Promise((function(t,n){e._connect(t,n)}))]).then((function(t){var n=o(t,2),i=(n[0],n[1]);e._myRoomJoinTime=e._getRoomJoinTime(i),e.connectSuccess(i)})).catch(this.connectFailure)}},{key:"shouldStartConnectionTo",value:function(e){return this._myRoomJoinTime<=e.roomJoinTime}},{key:"startStreamConnection",value:function(e){this.easyrtc.call(e,(function(e,t){"datachannel"===t&&NAF.log.write("Successfully started datachannel to ",e)}),(function(e,t){NAF.log.error(e,t)}),(function(e){}))}},{key:"closeStreamConnection",value:function(e){this.easyrtc.hangup(e)}},{key:"sendData",value:function(e,t,n){this.easyrtc.sendData(e,t,n)}},{key:"sendDataGuaranteed",value:function(e,t,n){this.easyrtc.sendDataWS(e,t,n)}},{key:"broadcastData",value:function(e,t){var n=this.easyrtc.getRoomOccupantsAsMap(this.room);for(var i in n)n[i]&&i!==this.easyrtc.myEasyrtcid&&this.easyrtc.sendData(i,e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){var n={targetRoom:this.room};this.easyrtc.sendDataWS(n,e,t)}},{key:"getConnectStatus",value:function(e){var t=this.easyrtc.getConnectStatus(e);return t==this.easyrtc.IS_CONNECTED?NAF.adapters.IS_CONNECTED:t==this.easyrtc.NOT_CONNECTED?NAF.adapters.NOT_CONNECTED:NAF.adapters.CONNECTING}},{key:"getMediaStream",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"audio";if(this.mediaStreams[e]&&this.mediaStreams[e][t])return NAF.log.write("Already had ".concat(t," for ").concat(e)),Promise.resolve(this.mediaStreams[e][t]);if(NAF.log.write("Waiting on ".concat(t," for ").concat(e)),!this.pendingMediaRequests.has(e)){var n={},i=new Promise((function(e,t){n.audio={resolve:e,reject:t}})).catch((function(t){return NAF.log.warn("".concat(e," getMediaStream Audio Error"),t)}));n.audio.promise=i;var o=new Promise((function(e,t){n.video={resolve:e,reject:t}})).catch((function(t){return NAF.log.warn("".concat(e," getMediaStream Video Error"),t)}));n.video.promise=o,this.pendingMediaRequests.set(e,n)}var r=this.pendingMediaRequests.get(e);if(!r[t]){var a=new Promise((function(e,n){r[t]={resolve:e,reject:n}})).catch((function(n){return NAF.log.warn("".concat(e,' getMediaStream "').concat(t,'" Error'),n)}));r[t].promise=a}return this.pendingMediaRequests.get(e)[t].promise}},{key:"setMediaStream",value:function(e,t,n){var i=this.pendingMediaRequests.get(e),o=this.mediaStreams[e]=this.mediaStreams[e]||{};if("default"===n){var r=t.getAudioTracks();if(r.length>0){var a=new MediaStream;try{r.forEach((function(e){return a.addTrack(e)})),o.audio=a}catch(t){NAF.log.warn("".concat(e,' setMediaStream "audio" alias Error'),t)}i&&i.audio.resolve(a)}var s=t.getVideoTracks();if(s.length>0){var c=new MediaStream;try{s.forEach((function(e){return c.addTrack(e)})),o.video=c}catch(t){NAF.log.warn("".concat(e,' setMediaStream "video" alias Error'),t)}i&&i.video.resolve(c)}}else o[n]=t,i&&i[n]&&i[n].resolve(t)}},{key:"addLocalMediaStream",value:function(e,t){var n=this.easyrtc;t=t||e.id,this.setMediaStream("local",e,t),n.register3rdPartyLocalMediaStream(e,t),Object.keys(this.remoteClients).forEach((function(e){n.getConnectStatus(e)!==n.NOT_CONNECTED&&n.addStreamToCall(e,t)}))}},{key:"removeLocalMediaStream",value:function(e){this.easyrtc.closeLocalMediaStream(e),delete this.mediaStreams.local[e]}},{key:"enableMicrophone",value:function(e){this.easyrtc.enableMicrophone(e)}},{key:"enableCamera",value:function(e){this.easyrtc.enableCamera(e)}},{key:"disconnect",value:function(){this.easyrtc.disconnect()}},{key:"_connect",value:function(e,t){var n=this;this.easyrtc.setStreamAcceptor(this.setMediaStream.bind(this)),this.easyrtc.setOnStreamClosed((function(e,t,n){delete this.mediaStreams[e][n]})),n.easyrtc.audioEnabled||n.easyrtc.videoEnabled?navigator.mediaDevices.getUserMedia({video:n.easyrtc.videoEnabled,audio:n.easyrtc.audioEnabled}).then((function(i){n.addLocalMediaStream(i,"default"),n.easyrtc.connect(n.app,e,t)}),(function(e,t){NAF.log.error(e,t)})):n.easyrtc.connect(n.app,e,t)}},{key:"_getRoomJoinTime",value:function(e){var t=NAF.room;return this.easyrtc.getRoomOccupantsAsMap(t)[e].roomJoinTime}},{key:"getServerTime",value:function(){return Date.now()+this.avgTimeOffset}}])&&a(t.prototype,n),i&&a(t,i),u}(n(1));e.exports=d},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"getServerTime",value:function(){return(new Date).getTime()+this.avgTimeOffset}}]),e}();e.exports=s},function(e,t,n){"use strict";function i(e,t){for(var n=0;n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"getServerTime",value:function(){return(new Date).getTime()+this.avgTimeOffset}},{key:"disconnect",value:function(){this.socket.disconnect()}}])&&i(t.prototype,n),o&&i(t,o),e}();e.exports=o},function(e,t,n){"use strict";AFRAME.registerComponent("networked-scene",{schema:{serverURL:{default:"/"},app:{default:"default"},room:{default:"default"},connectOnLoad:{default:!0},onConnect:{default:"onConnect"},adapter:{default:"wseasyrtc"},audio:{default:!1},video:{default:!1},debug:{default:!1}},init:function(){var e=this.el;this.connect=this.connect.bind(this),e.addEventListener("connect",this.connect),this.data.connectOnLoad&&e.emit("connect",null,!1)},connect:function(){return NAF.log.setDebug(this.data.debug),NAF.log.write("Networked-Aframe Connecting..."),this.checkDeprecatedProperties(),this.setupNetworkAdapter(),this.hasOnConnectFunction()&&this.callOnConnect(),NAF.connection.connect(this.data.serverURL,this.data.app,this.data.room,this.data.audio,this.data.video)},checkDeprecatedProperties:function(){},setupNetworkAdapter:function(){var e=this.data.adapter,t=NAF.adapters.make(e);NAF.connection.setNetworkAdapter(t),this.el.emit("adapter-ready",t,!1)},hasOnConnectFunction:function(){return""!=this.data.onConnect&&window[this.data.onConnect]},callOnConnect:function(){NAF.connection.onConnect(window[this.data.onConnect])},remove:function(){NAF.log.write("networked-scene disconnected"),this.el.removeEventListener("connect",this.connect),NAF.connection.disconnect()}})},function(e,t,n){"use strict";var i=n(18),o=n(19),r=THREE.Math.DEG2RAD,a=["position","rotation","scale"];function s(e){return!(!e.isVector3||isNaN(e.x)||isNaN(e.y)||isNaN(e.z)||null===e.x||null===e.y||null===e.z)}var c,u=(c=0,function(e,t){var n=Date.now();n-c>t&&(c=n,e())});function l(){NAF.log.warn("Received invalid network update.")}AFRAME.registerSystem("networked",{init:function(){this.components=[],this.nextSyncTime=0},register:function(e){this.components.push(e)},deregister:function(e){var t=this.components.indexOf(e);t>-1&&this.components.splice(t,1)},tick:function(){if(NAF.connection.adapter&&!(this.el.clock.elapsedTime0&&NAF.connection.broadcastData("um",e),this.updateNextSyncTime()}},updateNextSyncTime:function(){this.nextSyncTime=this.el.clock.elapsedTime+1/NAF.options.updateRate}}),AFRAME.registerComponent("networked",{schema:{template:{default:""},attachTemplateToLocal:{default:!0},persistent:{default:!1},networkId:{default:""},owner:{default:""},creator:{default:""}},init:function(){this.OWNERSHIP_GAINED="ownership-gained",this.OWNERSHIP_CHANGED="ownership-changed",this.OWNERSHIP_LOST="ownership-lost",this.onOwnershipGainedEvent={el:this.el},this.onOwnershipChangedEvent={el:this.el},this.onOwnershipLostEvent={el:this.el},this.conversionEuler=new THREE.Euler,this.conversionEuler.order="YXZ",this.bufferInfos=[],this.bufferPosition=new THREE.Vector3,this.bufferQuaternion=new THREE.Quaternion,this.bufferScale=new THREE.Vector3;var e,t=this.wasCreatedByNetwork();this.onConnected=this.onConnected.bind(this),this.syncData={},this.componentSchemas=NAF.schemas.getComponents(this.data.template),this.cachedElements=new Array(this.componentSchemas.length),this.networkUpdatePredicates=this.componentSchemas.map((function(e){return e.requiresNetworkUpdate&&e.requiresNetworkUpdate()||(t=null,function(e){return!(null!==t&&i(t,e)||(t=AFRAME.utils.clone(e),0))});var t})),this.invalidateCachedElements(),this.initNetworkParent(),""===this.data.networkId?(e=NAF.utils.createNetworkId(),this.el.setAttribute(this.name,{networkId:e})):e=this.data.networkId,this.el.id||this.el.setAttribute("id","naf-"+e),t?this.firstUpdate():(this.data.attachTemplateToLocal&&this.attachTemplateToLocal(),this.registerEntity(this.data.networkId)),this.lastOwnerTime=-1,NAF.clientId?this.onConnected():document.body.addEventListener("connected",this.onConnected,!1),document.body.dispatchEvent(this.entityCreatedEvent()),this.el.dispatchEvent(new CustomEvent("instantiated",{detail:{el:this.el}})),this.el.sceneEl.systems.networked.register(this)},attachTemplateToLocal:function(){for(var e=NAF.schemas.getCachedTemplate(this.data.template),t=e.attributes,n=0;ne.owner)&&void 0!==this.data){if(this.data.owner!==e.owner){var t=this.isMine();this.lastOwnerTime=e.lastOwnerTime;var n=this.data.owner,i=e.owner;this.el.setAttribute("networked",{owner:e.owner}),t&&(this.onOwnershipLostEvent.newOwner=i,this.el.emit(this.OWNERSHIP_LOST,this.onOwnershipLostEvent)),this.onOwnershipChangedEvent.oldOwner=n,this.onOwnershipChangedEvent.newOwner=i,this.el.emit(this.OWNERSHIP_CHANGED,this.onOwnershipChangedEvent)}this.data.persistent!==e.persistent&&this.el.setAttribute("networked",{persistent:e.persistent}),this.updateNetworkedComponents(e.components)}},updateNetworkedComponents:function(e){for(var t=0,n=this.componentSchemas.length;t0&&void 0!==arguments[0]?arguments[0]:0,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.15;o(this,e),this.state=0,this.buffer=[],this.bufferTime=1e3*n,this.time=0,this.mode=t,this.originFrame=a(),this.position=new THREE.Vector3,this.quaternion=new THREE.Quaternion,this.scale=new THREE.Vector3(1,1,1)}return i(e,[{key:"hermite",value:function(e,t,n,i,o,r){var a=t*t,s=t*t*t,c=2*s-3*a+1,u=-2*s+3*a,l=s-2*a+t,d=s-a;e.copy(n.multiplyScalar(c)),e.add(i.multiplyScalar(u)),e.add(o.multiplyScalar(l)),e.add(r.multiplyScalar(d))}},{key:"lerp",value:function(e,t,n,i){e.lerpVectors(t,n,i)}},{key:"slerp",value:function(e,t,n,i){THREE.Quaternion.slerp(t,n,e,i)}},{key:"updateOriginFrameToBufferTail",value:function(){var e;e=this.originFrame,r.push(e),this.originFrame=this.buffer.shift()}},{key:"appendBuffer",value:function(e,t,n,i){var o=this.buffer.length>0?this.buffer[this.buffer.length-1]:null;if(o&&o.time===this.time)e&&o.position.copy(e),t&&o.velocity.copy(t),n&&o.quaternion.copy(n),i&&o.scale.copy(i);else{var r=o||this.originFrame,s=a();s.position.copy(e||r.position),s.velocity.copy(t||r.velocity),s.quaternion.copy(n||r.quaternion),s.scale.copy(i||r.scale),s.time=this.time,this.buffer.push(s)}}},{key:"setTarget",value:function(e,t,n,i){this.appendBuffer(e,t,n,i)}},{key:"setPosition",value:function(e,t){this.appendBuffer(e,t,null,null)}},{key:"setQuaternion",value:function(e){this.appendBuffer(null,null,e,null)}},{key:"setScale",value:function(e){this.appendBuffer(null,null,null,e)}},{key:"update",value:function(e){if(0===this.state&&this.buffer.length>0&&(this.updateOriginFrameToBufferTail(),this.position.copy(this.originFrame.position),this.quaternion.copy(this.originFrame.quaternion),this.scale.copy(this.originFrame.scale),this.state=1),1===this.state&&this.buffer.length>0&&this.time>this.bufferTime&&(this.state=2),2===this.state){for(var t=this.time-this.bufferTime;this.buffer.length>0&&t>this.buffer[0].time;)this.buffer.length>1?this.updateOriginFrameToBufferTail():(this.originFrame.position.copy(this.buffer[0].position),this.originFrame.velocity.copy(this.buffer[0].velocity),this.originFrame.quaternion.copy(this.buffer[0].quaternion),this.originFrame.scale.copy(this.buffer[0].scale),this.originFrame.time=this.buffer[0].time,this.buffer[0].time=this.time+e);if(this.buffer.length>0&&this.buffer[0].time>0){var n=this.buffer[0],i=n.time-this.originFrame.time,o=(t-this.originFrame.time)/i;0===this.mode?this.lerp(this.position,this.originFrame.position,n.position,o):1===this.mode&&this.hermite(this.position,o,this.originFrame.position,n.position,this.originFrame.velocity.multiplyScalar(i),n.velocity.multiplyScalar(i)),this.slerp(this.quaternion,this.originFrame.quaternion,n.quaternion,o),this.lerp(this.scale,this.originFrame.scale,n.scale,o)}}0!==this.state&&(this.time+=e)}},{key:"getPosition",value:function(){return this.position}},{key:"getQuaternion",value:function(){return this.quaternion}},{key:"getScale",value:function(){return this.scale}}]),e}();e.exports=s},function(e,t,n){"use strict";var i=n(0);AFRAME.registerComponent("networked-audio-source",{schema:{streamName:{default:"audio"},positional:{default:!0},distanceModel:{default:"inverse",oneOf:["linear","inverse","exponential"]},maxDistance:{default:1e4},refDistance:{default:1},rolloffFactor:{default:1}},init:function(){var e=this;this.listener=null,this.stream=null,this._setMediaStream=this._setMediaStream.bind(this),NAF.utils.getNetworkedEntity(this.el).then((function(t){var n=t.components.networked.data.owner;n&&NAF.connection.adapter.getMediaStream(n,e.data.streamName).then(e._setMediaStream).catch((function(e){return i.log.error("Error getting media stream for ".concat(n),e)}))}))},update:function(){this._setPannerProperties()},_setMediaStream:function(e){if(this.sound||this.setupSound(),e!=this.stream){if(this.stream&&this.sound.disconnect(),e){/chrome/i.test(navigator.userAgent)&&(this.audioEl=new Audio,this.audioEl.setAttribute("autoplay","autoplay"),this.audioEl.setAttribute("playsinline","playsinline"),this.audioEl.srcObject=e,this.audioEl.volume=0);var t=this.sound.context.createMediaStreamSource(e);this.sound.setNodeSource(t),this.el.emit("sound-source-set",{soundSource:t})}this.stream=e}},_setPannerProperties:function(){this.sound&&this.data.positional&&(this.sound.setDistanceModel(this.data.distanceModel),this.sound.setMaxDistance(this.data.maxDistance),this.sound.setRefDistance(this.data.refDistance),this.sound.setRolloffFactor(this.data.rolloffFactor))},remove:function(){this.sound&&(this.el.removeObject3D(this.attrName),this.stream&&this.sound.disconnect(),this.audioEl&&(this.audioEl.pause(),this.audioEl.srcObject=null,this.audioEl.load(),this.audioEl=null))},setupSound:function(){var e=this.el,t=e.sceneEl;this.sound&&e.removeObject3D(this.attrName),t.audioListener||(t.audioListener=new THREE.AudioListener,t.camera&&t.camera.add(t.audioListener),t.addEventListener("camera-set-active",(function(e){e.detail.cameraEl.getObject3D("camera").add(t.audioListener)}))),this.listener=t.audioListener,this.sound=this.data.positional?new THREE.PositionalAudio(this.listener):new THREE.Audio(this.listener),e.setObject3D(this.attrName,this.sound),this._setPannerProperties()}})},function(e,t,n){"use strict";var i=n(0);AFRAME.registerComponent("networked-video-source",{schema:{streamName:{default:"video"}},dependencies:["material"],init:function(){var e=this;this.videoTexture=null,this.video=null,this.stream=null,this._setMediaStream=this._setMediaStream.bind(this),NAF.utils.getNetworkedEntity(this.el).then((function(t){var n=t.components.networked.data.owner;n&&NAF.connection.adapter.getMediaStream(n,e.data.streamName).then(e._setMediaStream).catch((function(e){return i.log.error("Error getting media stream for ".concat(n),e)}))}))},_setMediaStream:function(e){if(this.video||this.setupVideo(),e!=this.stream){if(this.stream&&this._clearMediaStream(),e){this.video.srcObject=e;var t=this.video.play();t instanceof Promise&&t.catch((function(e){return i.log.error("Error play video stream",e)})),this.videoTexture&&this.videoTexture.dispose(),this.videoTexture=new THREE.VideoTexture(this.video);var n=this.el.getObject3D("mesh");n.material.map=this.videoTexture,n.material.needsUpdate=!0}this.stream=e}},_clearMediaStream:function(){if(this.stream=null,this.videoTexture){if(this.videoTexture.image instanceof HTMLVideoElement){var e=this.videoTexture.image;e.pause(),e.srcObject=null,e.load()}this.videoTexture.dispose(),this.videoTexture=null}},remove:function(){this._clearMediaStream()},setupVideo:function(){if(!this.video){var e=document.createElement("video");e.setAttribute("autoplay",!0),e.setAttribute("playsinline",!0),e.setAttribute("muted",!0),this.video=e}}})}]);
\ No newline at end of file
+!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){"use strict";var i=n(3),o=n(4),r=n(5),a=n(6),s=n(7),c=n(9),u=n(10),l={app:"",room:"",clientId:""};l.options=i,l.utils=o,l.log=new r,l.schemas=new a,l.version="0.9.0",l.adapters=new u;var d=new s,h=new c(d);l.connection=h,l.entities=d,e.exports=window.NAF=l},function(e,t,n){"use strict";function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n is defined."));if(!this.validateTemplate(e,t))return;this.templateCache[e.template]=document.importNode(t.content,!0)}else NAF.log.error("Schema not valid: ",e),NAF.log.error("See https://github.com/networked-aframe/networked-aframe#syncing-custom-components")}},{key:"getCachedTemplate",value:function(e){return this.templateIsCached(e)||(this.templateExistsInScene(e)?this.add(this.createDefaultSchema(e)):NAF.log.error("Template el for ".concat(e," is not in the scene, add the template to and register with NAF.schemas.add."))),this.templateCache[e].firstElementChild.cloneNode(!0)}},{key:"templateIsCached",value:function(e){return!!this.templateCache[e]}},{key:"getComponents",value:function(e){var t=["position","rotation"];return this.hasTemplate(e)&&(t=this.schemaDict[e].components),t}},{key:"hasTemplate",value:function(e){return!!this.schemaDict[e]}},{key:"templateExistsInScene",value:function(e){var t=document.querySelector(e);return t&&this.isTemplateTag(t)}},{key:"validateSchema",value:function(e){return!(!e.template||!e.components)}},{key:"validateTemplate",value:function(e,t){return this.isTemplateTag(t)?!!this.templateHasOneOrZeroChildren(t)||(NAF.log.error("Template for ".concat(e.template," has more than one child. Templates must have one direct child element, no more. Template found:"),t),!1):(NAF.log.error("Template for ".concat(e.template," is not a tag. Instead found: ").concat(t.tagName)),!1)}},{key:"isTemplateTag",value:function(e){return"template"===e.tagName.toLowerCase()}},{key:"templateHasOneOrZeroChildren",value:function(e){return e.content.childElementCount<2}},{key:"remove",value:function(e){delete this.schemaDict[e]}},{key:"clear",value:function(){this.schemaDict={}}}])&&i(t.prototype,n),o&&i(t,o),e}();e.exports=o},function(e,t,n){"use strict";function i(e,t){for(var n=0;n3&&void 0!==arguments[3]&&arguments[3],o=arguments.length>4&&void 0!==arguments[4]&&arguments[4];NAF.app=t,NAF.room=n,this.adapter.setServerUrl(e),this.adapter.setApp(t),this.adapter.setRoom(n);var r={audio:i,video:o,datachannel:!0};return this.adapter.setWebRtcOptions(r),this.adapter.setServerConnectListeners(this.connectSuccess.bind(this),this.connectFailure.bind(this)),this.adapter.setDataChannelListeners(this.dataChannelOpen.bind(this),this.dataChannelClosed.bind(this),this.receivedData.bind(this)),this.adapter.setRoomOccupantListener(this.occupantsReceived.bind(this)),this.adapter.connect()}},{key:"onConnect",value:function(e){this.onConnectCallback=e,this.isConnected()?e():document.body.addEventListener("connected",e,!1)}},{key:"connectSuccess",value:function(e){NAF.log.write("Networked-Aframe Client ID:",e),NAF.clientId=e;var t=new CustomEvent("connected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"connectFailure",value:function(e,t){NAF.log.error(e,"failure to connect")}},{key:"occupantsReceived",value:function(e){var t=Object.assign({},this.connectedClients);this.connectedClients=e,this.checkForDisconnectingClients(t,e),this.checkForConnectingClients(e)}},{key:"checkForDisconnectingClients",value:function(e,t){for(var n in e)t[n]||(NAF.log.write("Closing stream to",n),this.adapter.closeStreamConnection(n))}},{key:"checkForConnectingClients",value:function(e){for(var t in e)this.isNewClient(t)&&this.adapter.shouldStartConnectionTo(e[t])&&(NAF.log.write("Opening datachannel to",t),this.adapter.startStreamConnection(t))}},{key:"getConnectedClients",value:function(){return this.connectedClients}},{key:"isConnected",value:function(){return!!NAF.clientId}},{key:"isMineAndConnected",value:function(e){return this.isConnected()&&NAF.clientId===e}},{key:"isNewClient",value:function(e){return!this.isConnectedTo(e)}},{key:"isConnectedTo",value:function(e){return this.adapter.getConnectStatus(e)===NAF.adapters.IS_CONNECTED}},{key:"dataChannelOpen",value:function(e){NAF.log.write("Opened data channel from "+e),this.activeDataChannels[e]=!0,this.entities.completeSync(e,!0);var t=new CustomEvent("clientConnected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"dataChannelClosed",value:function(e){NAF.log.write("Closed data channel from "+e),this.activeDataChannels[e]=!1,this.entities.removeEntitiesOfClient(e);var t=new CustomEvent("clientDisconnected",{detail:{clientId:e}});document.body.dispatchEvent(t)}},{key:"hasActiveDataChannel",value:function(e){return!!this.activeDataChannels[e]}},{key:"broadcastData",value:function(e,t){this.adapter.broadcastData(e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){this.adapter.broadcastDataGuaranteed(e,t)}},{key:"sendData",value:function(e,t,n,i){this.hasActiveDataChannel(e)&&(i?this.adapter.sendDataGuaranteed(e,t,n):this.adapter.sendData(e,t,n))}},{key:"sendDataGuaranteed",value:function(e,t,n){this.sendData(e,t,n,!0)}},{key:"subscribeToDataChannel",value:function(e,t){this.isReservedDataType(e)?NAF.log.error("NetworkConnection@subscribeToDataChannel: "+e+" is a reserved dataType. Choose another"):this.dataChannelSubs[e]=t}},{key:"unsubscribeToDataChannel",value:function(e){this.isReservedDataType(e)?NAF.log.error("NetworkConnection@unsubscribeToDataChannel: "+e+" is a reserved dataType. Choose another"):delete this.dataChannelSubs[e]}},{key:"isReservedDataType",value:function(e){return e==o||e==a}},{key:"receivedData",value:function(e,t,n,i){this.dataChannelSubs[t]?this.dataChannelSubs[t](e,t,n,i):NAF.log.write("NetworkConnection@receivedData: "+t+" has not been subscribed to yet. Call subscribeToDataChannel()")}},{key:"getServerTime",value:function(){return this.adapter.getServerTime()}},{key:"disconnect",value:function(){this.entities.removeRemoteEntities(),this.adapter&&this.adapter.disconnect(),NAF.app="",NAF.room="",NAF.clientId="",this.connectedClients={},this.activeDataChannels={},this.adapter=null,this.setupDefaultDataSubscriptions(),document.body.removeEventListener("connected",this.onConnectCallback)}}])&&i(t.prototype,n),s&&i(t,s),e}();e.exports=s},function(e,t,n){"use strict";function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,i=new Array(t);n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"connect",value:function(){var e=this;Promise.all([this.updateTimeOffset(),new Promise((function(t,n){e.easyrtc.connect(e.app,t,n)}))]).then((function(t){var n=o(t,2),i=(n[0],n[1]);e.connectSuccess(i)})).catch(this.connectFailure)}},{key:"shouldStartConnectionTo",value:function(e){return!0}},{key:"startStreamConnection",value:function(e){this.connectedClients.push(e),this.openListener(e)}},{key:"closeStreamConnection",value:function(e){var t=this.connectedClients.indexOf(e);t>-1&&this.connectedClients.splice(t,1),this.closedListener(e)}},{key:"sendData",value:function(e,t,n){this.easyrtc.sendDataWS(e,t,n)}},{key:"sendDataGuaranteed",value:function(e,t,n){this.sendData(e,t,n)}},{key:"broadcastData",value:function(e,t){var n={targetRoom:this.room};this.easyrtc.sendDataWS(n,e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){this.broadcastData(e,t)}},{key:"getConnectStatus",value:function(e){return-1!=this.connectedClients.indexOf(e)?NAF.adapters.IS_CONNECTED:NAF.adapters.NOT_CONNECTED}},{key:"getServerTime",value:function(){return Date.now()+this.avgTimeOffset}},{key:"disconnect",value:function(){this.easyrtc.disconnect()}}])&&a(t.prototype,n),i&&a(t,i),u}(n(1));e.exports=d},function(e,t,n){"use strict";function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,i=new Array(t);n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"connect",value:function(){var e=this;Promise.all([this.updateTimeOffset(),new Promise((function(t,n){e._connect(t,n)}))]).then((function(t){var n=o(t,2),i=(n[0],n[1]);e._myRoomJoinTime=e._getRoomJoinTime(i),e.connectSuccess(i)})).catch(this.connectFailure)}},{key:"shouldStartConnectionTo",value:function(e){return this._myRoomJoinTime<=e.roomJoinTime}},{key:"startStreamConnection",value:function(e){this.easyrtc.call(e,(function(e,t){"datachannel"===t&&NAF.log.write("Successfully started datachannel to ",e)}),(function(e,t){NAF.log.error(e,t)}),(function(e){}))}},{key:"closeStreamConnection",value:function(e){this.easyrtc.hangup(e)}},{key:"sendData",value:function(e,t,n){this.easyrtc.sendData(e,t,n)}},{key:"sendDataGuaranteed",value:function(e,t,n){this.easyrtc.sendDataWS(e,t,n)}},{key:"broadcastData",value:function(e,t){var n=this.easyrtc.getRoomOccupantsAsMap(this.room);for(var i in n)n[i]&&i!==this.easyrtc.myEasyrtcid&&this.easyrtc.sendData(i,e,t)}},{key:"broadcastDataGuaranteed",value:function(e,t){var n={targetRoom:this.room};this.easyrtc.sendDataWS(n,e,t)}},{key:"getConnectStatus",value:function(e){var t=this.easyrtc.getConnectStatus(e);return t==this.easyrtc.IS_CONNECTED?NAF.adapters.IS_CONNECTED:t==this.easyrtc.NOT_CONNECTED?NAF.adapters.NOT_CONNECTED:NAF.adapters.CONNECTING}},{key:"getMediaStream",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"audio";if(this.mediaStreams[e]&&this.mediaStreams[e][t])return NAF.log.write("Already had ".concat(t," for ").concat(e)),Promise.resolve(this.mediaStreams[e][t]);if(NAF.log.write("Waiting on ".concat(t," for ").concat(e)),!this.pendingMediaRequests.has(e)){var n={},i=new Promise((function(e,t){n.audio={resolve:e,reject:t}})).catch((function(t){return NAF.log.warn("".concat(e," getMediaStream Audio Error"),t)}));n.audio.promise=i;var o=new Promise((function(e,t){n.video={resolve:e,reject:t}})).catch((function(t){return NAF.log.warn("".concat(e," getMediaStream Video Error"),t)}));n.video.promise=o,this.pendingMediaRequests.set(e,n)}var r=this.pendingMediaRequests.get(e);if(!r[t]){var a=new Promise((function(e,n){r[t]={resolve:e,reject:n}})).catch((function(n){return NAF.log.warn("".concat(e,' getMediaStream "').concat(t,'" Error'),n)}));r[t].promise=a}return this.pendingMediaRequests.get(e)[t].promise}},{key:"setMediaStream",value:function(e,t,n){var i=this.pendingMediaRequests.get(e),o=this.mediaStreams[e]=this.mediaStreams[e]||{};if("default"===n){var r=t.getAudioTracks();if(r.length>0){var a=new MediaStream;try{r.forEach((function(e){return a.addTrack(e)})),o.audio=a}catch(t){NAF.log.warn("".concat(e,' setMediaStream "audio" alias Error'),t)}i&&i.audio.resolve(a)}var s=t.getVideoTracks();if(s.length>0){var c=new MediaStream;try{s.forEach((function(e){return c.addTrack(e)})),o.video=c}catch(t){NAF.log.warn("".concat(e,' setMediaStream "video" alias Error'),t)}i&&i.video.resolve(c)}}else o[n]=t,i&&i[n]&&i[n].resolve(t)}},{key:"addLocalMediaStream",value:function(e,t){var n=this.easyrtc;t=t||e.id,this.setMediaStream("local",e,t),n.register3rdPartyLocalMediaStream(e,t),Object.keys(this.remoteClients).forEach((function(e){n.getConnectStatus(e)!==n.NOT_CONNECTED&&n.addStreamToCall(e,t)}))}},{key:"removeLocalMediaStream",value:function(e){this.easyrtc.closeLocalMediaStream(e),delete this.mediaStreams.local[e]}},{key:"enableMicrophone",value:function(e){this.easyrtc.enableMicrophone(e)}},{key:"enableCamera",value:function(e){this.easyrtc.enableCamera(e)}},{key:"disconnect",value:function(){this.easyrtc.disconnect()}},{key:"_connect",value:function(e,t){var n=this;this.easyrtc.setStreamAcceptor(this.setMediaStream.bind(this)),this.easyrtc.setOnStreamClosed((function(e,t,n){delete this.mediaStreams[e][n]})),n.easyrtc.audioEnabled||n.easyrtc.videoEnabled?navigator.mediaDevices.getUserMedia({video:n.easyrtc.videoEnabled,audio:n.easyrtc.audioEnabled}).then((function(i){n.addLocalMediaStream(i,"default"),n.easyrtc.connect(n.app,e,t)}),(function(e,t){NAF.log.error(e,t)})):n.easyrtc.connect(n.app,e,t)}},{key:"_getRoomJoinTime",value:function(e){var t=NAF.room;return this.easyrtc.getRoomOccupantsAsMap(t)[e].roomJoinTime}},{key:"getServerTime",value:function(){return Date.now()+this.avgTimeOffset}}])&&a(t.prototype,n),i&&a(t,i),u}(n(1));e.exports=d},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"getServerTime",value:function(){return(new Date).getTime()+this.avgTimeOffset}}]),e}();e.exports=s},function(e,t,n){"use strict";function i(e,t){for(var n=0;n10?setTimeout((function(){return e.updateTimeOffset()}),3e5):e.updateTimeOffset()}))}},{key:"getServerTime",value:function(){return(new Date).getTime()+this.avgTimeOffset}},{key:"disconnect",value:function(){this.socket.disconnect()}}])&&i(t.prototype,n),o&&i(t,o),e}();e.exports=o},function(e,t,n){"use strict";AFRAME.registerComponent("networked-scene",{schema:{serverURL:{default:"/"},app:{default:"default"},room:{default:"default"},connectOnLoad:{default:!0},onConnect:{default:"onConnect"},adapter:{default:"wseasyrtc"},audio:{default:!1},video:{default:!1},debug:{default:!1}},init:function(){var e=this.el;this.connect=this.connect.bind(this),e.addEventListener("connect",this.connect),this.data.connectOnLoad&&e.emit("connect",null,!1)},connect:function(){return NAF.log.setDebug(this.data.debug),NAF.log.write("Networked-Aframe Connecting..."),this.checkDeprecatedProperties(),this.setupNetworkAdapter(),this.hasOnConnectFunction()&&this.callOnConnect(),NAF.connection.connect(this.data.serverURL,this.data.app,this.data.room,this.data.audio,this.data.video)},checkDeprecatedProperties:function(){},setupNetworkAdapter:function(){var e=this.data.adapter,t=NAF.adapters.make(e);NAF.connection.setNetworkAdapter(t),this.el.emit("adapter-ready",t,!1)},hasOnConnectFunction:function(){return""!=this.data.onConnect&&window[this.data.onConnect]},callOnConnect:function(){NAF.connection.onConnect(window[this.data.onConnect])},remove:function(){NAF.log.write("networked-scene disconnected"),this.el.removeEventListener("connect",this.connect),NAF.connection.disconnect()}})},function(e,t,n){"use strict";var i=n(18),o=n(19),r=THREE.Math.DEG2RAD,a=["position","rotation","scale"];function s(e){return!(!e.isVector3||isNaN(e.x)||isNaN(e.y)||isNaN(e.z)||null===e.x||null===e.y||null===e.z)}var c,u=(c=0,function(e,t){var n=Date.now();n-c>t&&(c=n,e())});function l(){NAF.log.warn("Received invalid network update.")}AFRAME.registerSystem("networked",{init:function(){this.components=[],this.nextSyncTime=0},register:function(e){this.components.push(e)},deregister:function(e){var t=this.components.indexOf(e);t>-1&&this.components.splice(t,1)},tick:function(){if(NAF.connection.adapter&&!(this.el.clock.elapsedTime0&&NAF.connection.broadcastData("um",e),this.updateNextSyncTime()}},updateNextSyncTime:function(){this.nextSyncTime=this.el.clock.elapsedTime+1/NAF.options.updateRate}}),AFRAME.registerComponent("networked",{schema:{template:{default:""},attachTemplateToLocal:{default:!0},persistent:{default:!1},networkId:{default:""},owner:{default:""},creator:{default:""}},init:function(){this.OWNERSHIP_GAINED="ownership-gained",this.OWNERSHIP_CHANGED="ownership-changed",this.OWNERSHIP_LOST="ownership-lost",this.onOwnershipGainedEvent={el:this.el},this.onOwnershipChangedEvent={el:this.el},this.onOwnershipLostEvent={el:this.el},this.conversionEuler=new THREE.Euler,this.conversionEuler.order="YXZ",this.bufferInfos=[],this.bufferPosition=new THREE.Vector3,this.bufferQuaternion=new THREE.Quaternion,this.bufferScale=new THREE.Vector3;var e,t=this.wasCreatedByNetwork();this.onConnected=this.onConnected.bind(this),this.syncData={},this.componentSchemas=NAF.schemas.getComponents(this.data.template),this.cachedElements=new Array(this.componentSchemas.length),this.networkUpdatePredicates=this.componentSchemas.map((function(e){return e.requiresNetworkUpdate&&e.requiresNetworkUpdate()||(t=null,function(e){return!(null!==t&&i(t,e)||(t=AFRAME.utils.clone(e),0))});var t})),this.invalidateCachedElements(),this.initNetworkParent(),""===this.data.networkId?(e=NAF.utils.createNetworkId(),this.el.setAttribute(this.name,{networkId:e})):e=this.data.networkId,this.el.id||this.el.setAttribute("id","naf-"+e),t?this.firstUpdate():(this.data.attachTemplateToLocal&&this.attachTemplateToLocal(),this.registerEntity(this.data.networkId)),this.lastOwnerTime=-1,NAF.clientId?this.onConnected():document.body.addEventListener("connected",this.onConnected,!1),document.body.dispatchEvent(this.entityCreatedEvent()),this.el.dispatchEvent(new CustomEvent("instantiated",{detail:{el:this.el}})),this.el.sceneEl.systems.networked.register(this)},attachTemplateToLocal:function(){for(var e=NAF.schemas.getCachedTemplate(this.data.template),t=e.attributes,n=0;ne.owner)&&void 0!==this.data){if(this.data.owner!==e.owner){var t=this.isMine();this.lastOwnerTime=e.lastOwnerTime;var n=this.data.owner,i=e.owner;this.el.setAttribute("networked",{owner:e.owner}),t&&(this.onOwnershipLostEvent.newOwner=i,this.el.emit(this.OWNERSHIP_LOST,this.onOwnershipLostEvent)),this.onOwnershipChangedEvent.oldOwner=n,this.onOwnershipChangedEvent.newOwner=i,this.el.emit(this.OWNERSHIP_CHANGED,this.onOwnershipChangedEvent)}this.data.persistent!==e.persistent&&this.el.setAttribute("networked",{persistent:e.persistent}),this.updateNetworkedComponents(e.components)}},updateNetworkedComponents:function(e){for(var t=0,n=this.componentSchemas.length;t0&&void 0!==arguments[0]?arguments[0]:0,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.15;o(this,e),this.state=0,this.buffer=[],this.bufferTime=1e3*n,this.time=0,this.mode=t,this.originFrame=a(),this.position=new THREE.Vector3,this.quaternion=new THREE.Quaternion,this.scale=new THREE.Vector3(1,1,1)}return i(e,[{key:"hermite",value:function(e,t,n,i,o,r){var a=t*t,s=t*t*t,c=2*s-3*a+1,u=-2*s+3*a,l=s-2*a+t,d=s-a;e.copy(n.multiplyScalar(c)),e.add(i.multiplyScalar(u)),e.add(o.multiplyScalar(l)),e.add(r.multiplyScalar(d))}},{key:"lerp",value:function(e,t,n,i){e.lerpVectors(t,n,i)}},{key:"slerp",value:function(e,t,n,i){e.slerpQuaternions(t,n,i)}},{key:"updateOriginFrameToBufferTail",value:function(){var e;e=this.originFrame,r.push(e),this.originFrame=this.buffer.shift()}},{key:"appendBuffer",value:function(e,t,n,i){var o=this.buffer.length>0?this.buffer[this.buffer.length-1]:null;if(o&&o.time===this.time)e&&o.position.copy(e),t&&o.velocity.copy(t),n&&o.quaternion.copy(n),i&&o.scale.copy(i);else{var r=o||this.originFrame,s=a();s.position.copy(e||r.position),s.velocity.copy(t||r.velocity),s.quaternion.copy(n||r.quaternion),s.scale.copy(i||r.scale),s.time=this.time,this.buffer.push(s)}}},{key:"setTarget",value:function(e,t,n,i){this.appendBuffer(e,t,n,i)}},{key:"setPosition",value:function(e,t){this.appendBuffer(e,t,null,null)}},{key:"setQuaternion",value:function(e){this.appendBuffer(null,null,e,null)}},{key:"setScale",value:function(e){this.appendBuffer(null,null,null,e)}},{key:"update",value:function(e){if(0===this.state&&this.buffer.length>0&&(this.updateOriginFrameToBufferTail(),this.position.copy(this.originFrame.position),this.quaternion.copy(this.originFrame.quaternion),this.scale.copy(this.originFrame.scale),this.state=1),1===this.state&&this.buffer.length>0&&this.time>this.bufferTime&&(this.state=2),2===this.state){for(var t=this.time-this.bufferTime;this.buffer.length>0&&t>this.buffer[0].time;)this.buffer.length>1?this.updateOriginFrameToBufferTail():(this.originFrame.position.copy(this.buffer[0].position),this.originFrame.velocity.copy(this.buffer[0].velocity),this.originFrame.quaternion.copy(this.buffer[0].quaternion),this.originFrame.scale.copy(this.buffer[0].scale),this.originFrame.time=this.buffer[0].time,this.buffer[0].time=this.time+e);if(this.buffer.length>0&&this.buffer[0].time>0){var n=this.buffer[0],i=n.time-this.originFrame.time,o=(t-this.originFrame.time)/i;0===this.mode?this.lerp(this.position,this.originFrame.position,n.position,o):1===this.mode&&this.hermite(this.position,o,this.originFrame.position,n.position,this.originFrame.velocity.multiplyScalar(i),n.velocity.multiplyScalar(i)),this.slerp(this.quaternion,this.originFrame.quaternion,n.quaternion,o),this.lerp(this.scale,this.originFrame.scale,n.scale,o)}}0!==this.state&&(this.time+=e)}},{key:"getPosition",value:function(){return this.position}},{key:"getQuaternion",value:function(){return this.quaternion}},{key:"getScale",value:function(){return this.scale}}]),e}();e.exports=s},function(e,t,n){"use strict";var i=n(0);AFRAME.registerComponent("networked-audio-source",{schema:{streamName:{default:"audio"},positional:{default:!0},distanceModel:{default:"inverse",oneOf:["linear","inverse","exponential"]},maxDistance:{default:1e4},refDistance:{default:1},rolloffFactor:{default:1}},init:function(){var e=this;this.listener=null,this.stream=null,this._setMediaStream=this._setMediaStream.bind(this),NAF.utils.getNetworkedEntity(this.el).then((function(t){var n=t.components.networked.data.owner;n&&NAF.connection.adapter.getMediaStream(n,e.data.streamName).then(e._setMediaStream).catch((function(e){return i.log.error("Error getting media stream for ".concat(n),e)}))}))},update:function(){this._setPannerProperties()},_setMediaStream:function(e){if(this.sound||this.setupSound(),e!=this.stream){if(this.stream&&this.sound.disconnect(),e){/chrome/i.test(navigator.userAgent)&&(this.audioEl=new Audio,this.audioEl.setAttribute("autoplay","autoplay"),this.audioEl.setAttribute("playsinline","playsinline"),this.audioEl.srcObject=e,this.audioEl.volume=0);var t=this.sound.context.createMediaStreamSource(e);this.sound.setNodeSource(t),this.el.emit("sound-source-set",{soundSource:t})}this.stream=e}},_setPannerProperties:function(){this.sound&&this.data.positional&&(this.sound.setDistanceModel(this.data.distanceModel),this.sound.setMaxDistance(this.data.maxDistance),this.sound.setRefDistance(this.data.refDistance),this.sound.setRolloffFactor(this.data.rolloffFactor))},remove:function(){this.sound&&(this.el.removeObject3D(this.attrName),this.stream&&this.sound.disconnect(),this.audioEl&&(this.audioEl.pause(),this.audioEl.srcObject=null,this.audioEl.load(),this.audioEl=null))},setupSound:function(){var e=this.el,t=e.sceneEl;this.sound&&e.removeObject3D(this.attrName),t.audioListener||(t.audioListener=new THREE.AudioListener,t.camera&&t.camera.add(t.audioListener),t.addEventListener("camera-set-active",(function(e){e.detail.cameraEl.getObject3D("camera").add(t.audioListener)}))),this.listener=t.audioListener,this.sound=this.data.positional?new THREE.PositionalAudio(this.listener):new THREE.Audio(this.listener),e.setObject3D(this.attrName,this.sound),this._setPannerProperties()}})},function(e,t,n){"use strict";var i=n(0);AFRAME.registerComponent("networked-video-source",{schema:{streamName:{default:"video"}},dependencies:["material"],init:function(){var e=this;this.videoTexture=null,this.video=null,this.stream=null,this._setMediaStream=this._setMediaStream.bind(this),NAF.utils.getNetworkedEntity(this.el).then((function(t){var n=t.components.networked.data.owner;n&&NAF.connection.adapter.getMediaStream(n,e.data.streamName).then(e._setMediaStream).catch((function(e){return i.log.error("Error getting media stream for ".concat(n),e)}))}))},_setMediaStream:function(e){if(this.video||this.setupVideo(),e!=this.stream){if(this.stream&&this._clearMediaStream(),e){this.video.srcObject=e;var t=this.video.play();t instanceof Promise&&t.catch((function(e){return i.log.error("Error play video stream",e)})),this.videoTexture&&this.videoTexture.dispose(),this.videoTexture=new THREE.VideoTexture(this.video);var n=this.el.getObject3D("mesh");n.material.map=this.videoTexture,n.material.needsUpdate=!0}this.stream=e}},_clearMediaStream:function(){if(this.stream=null,this.videoTexture){if(this.videoTexture.image instanceof HTMLVideoElement){var e=this.videoTexture.image;e.pause(),e.srcObject=null,e.load()}this.videoTexture.dispose(),this.videoTexture=null}},remove:function(){this._clearMediaStream()},setupVideo:function(){if(!this.video){var e=document.createElement("video");e.setAttribute("autoplay",!0),e.setAttribute("playsinline",!0),e.setAttribute("muted",!0),this.video=e}}})}]);
\ No newline at end of file
diff --git a/docs/getting-started-local.md b/docs/getting-started-local.md
index 59147c87..bcab44b8 100644
--- a/docs/getting-started-local.md
+++ b/docs/getting-started-local.md
@@ -36,7 +36,7 @@ Now let's setup the required dependencies. Create a file called `package.json` a
},
"author": "YOUR_NAME",
"dependencies": {
- "networked-aframe": "^0.8.0"
+ "networked-aframe": "^0.9.0"
}
}
```
@@ -110,10 +110,10 @@ Here's the template we'll start with:
```html
-
+
-
+
@@ -122,8 +122,8 @@ Here's the template we'll start with:
```
Please don't use `https://unpkg.com/networked-aframe/dist/networked-aframe.min.js` for production, this will download the latest major release that may contain breaking changes.
-It's ok for a testing environment to specify "@^0.8.0" in the url so it downloads the latest minor version that shouldn't have breaking changes.
-For production you want to pin to a specific version like `https://unpkg.com/networked-aframe@0.8.3/dist/networked-aframe.min.js`.
+It's ok for a testing environment to specify "@^0.9.0" in the url so it downloads the latest minor version that shouldn't have breaking changes.
+For production you want to pin to a specific version like `https://unpkg.com/networked-aframe@0.9.0/dist/networked-aframe.min.js`.
If you want to use a more recent build from github master that is not released yet, you can use:
diff --git a/examples/360.html b/examples/360.html
index 36000b0b..990c71b2 100644
--- a/examples/360.html
+++ b/examples/360.html
@@ -5,7 +5,7 @@
360 Image Example — Networked-Aframe
-
+
diff --git a/examples/adapter-test/adapter-test-receive.html b/examples/adapter-test/adapter-test-receive.html
index aa6c8e94..6f20a051 100644
--- a/examples/adapter-test/adapter-test-receive.html
+++ b/examples/adapter-test/adapter-test-receive.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/adapter-test/adapter-test-send.html b/examples/adapter-test/adapter-test-send.html
index 1f2cf014..81889b4f 100644
--- a/examples/adapter-test/adapter-test-send.html
+++ b/examples/adapter-test/adapter-test-send.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/basic-ar.html b/examples/basic-ar.html
index 58000187..7c03a33f 100644
--- a/examples/basic-ar.html
+++ b/examples/basic-ar.html
@@ -4,7 +4,7 @@
Basic AR Example — Networked-Aframe
-
+
diff --git a/examples/basic-audio.html b/examples/basic-audio.html
index a553a664..bd0b3b56 100644
--- a/examples/basic-audio.html
+++ b/examples/basic-audio.html
@@ -4,7 +4,7 @@
Positional Audio Example — Networked-Aframe
-
+
diff --git a/examples/basic-events.html b/examples/basic-events.html
index 6e7070f0..432fb84f 100644
--- a/examples/basic-events.html
+++ b/examples/basic-events.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/basic-multi-streams.html b/examples/basic-multi-streams.html
index 4143800a..97ffdb9c 100644
--- a/examples/basic-multi-streams.html
+++ b/examples/basic-multi-streams.html
@@ -4,7 +4,7 @@
Multi Streams Example — Networked-Aframe
-
+
diff --git a/examples/basic-video.html b/examples/basic-video.html
index 79fd0113..2d2c72ea 100644
--- a/examples/basic-video.html
+++ b/examples/basic-video.html
@@ -4,7 +4,7 @@
Video Streaming Example — Networked-Aframe
-
+
diff --git a/examples/basic.html b/examples/basic.html
index 6d45cb28..b782695c 100644
--- a/examples/basic.html
+++ b/examples/basic.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/child-entities.html b/examples/child-entities.html
index 0a17d0da..ecfa622e 100644
--- a/examples/child-entities.html
+++ b/examples/child-entities.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/disconnect.html b/examples/disconnect.html
index 2e8da7a9..0dd2c59d 100644
--- a/examples/disconnect.html
+++ b/examples/disconnect.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/google-blocks.html b/examples/google-blocks.html
index 51077509..66111f91 100644
--- a/examples/google-blocks.html
+++ b/examples/google-blocks.html
@@ -4,7 +4,7 @@
Basic Example — Networked-Aframe
-
+
@@ -14,7 +14,9 @@
-
diff --git a/examples/ownership-transfer.html b/examples/ownership-transfer.html
index d26d23e1..20eb7224 100644
--- a/examples/ownership-transfer.html
+++ b/examples/ownership-transfer.html
@@ -4,7 +4,7 @@
Dev Example — Networked-Aframe
-
+
diff --git a/examples/shooter-ar.html b/examples/shooter-ar.html
index 0df709e3..8f3fca54 100644
--- a/examples/shooter-ar.html
+++ b/examples/shooter-ar.html
@@ -4,7 +4,7 @@
Shooter AR Example — Networked-Aframe
-
+
diff --git a/examples/shooter.html b/examples/shooter.html
index 1a7ad821..6aaed1fa 100644
--- a/examples/shooter.html
+++ b/examples/shooter.html
@@ -4,7 +4,7 @@
Shooter Example — Networked-Aframe
-
+
diff --git a/examples/tracked-controllers.html b/examples/tracked-controllers.html
index c71990d9..5b08736e 100644
--- a/examples/tracked-controllers.html
+++ b/examples/tracked-controllers.html
@@ -4,7 +4,7 @@
Tracked Controllers — Networked-Aframe
-
+
@@ -66,7 +66,7 @@
-
+
+
diff --git a/package-lock.json b/package-lock.json
index c3944675..ea40cfa0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "networked-aframe",
- "version": "0.8.3",
+ "version": "0.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1117,9 +1117,9 @@
"dev": true
},
"aframe": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/aframe/-/aframe-1.2.0.tgz",
- "integrity": "sha512-e4lGvxLQ5CAptlbCqmnR4+qUf9s3f5SSnkMQaBsIFlJ2QMZhzEBr/SSV3+NEvMhsQf88EOvSpN1Vez942mBLcQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/aframe/-/aframe-1.3.0.tgz",
+ "integrity": "sha512-f6OQaDf49SzdSxVskJPvPWldOwHpYMsGttmQHhU6FRiASsnyULKG1nqZom9pDuS3fFYEzQVqRMakQ2AhXeLkFg==",
"dev": true,
"requires": {
"custom-event-polyfill": "^1.0.6",
@@ -1131,8 +1131,8 @@
"present": "0.0.6",
"promise-polyfill": "^3.1.0",
"super-animejs": "^3.1.0",
- "super-three": "^0.125.1",
- "three-bmfont-text": "github:dmarcos/three-bmfont-text#1babdf8507c731a18f8af3b807292e2b9740955e",
+ "super-three": "^0.137.0",
+ "three-bmfont-text": "github:dmarcos/three-bmfont-text#21d017046216e318362c48abd1a48bddfb6e0733",
"webvr-polyfill": "^0.10.12"
},
"dependencies": {
@@ -1882,9 +1882,8 @@
"dev": true
},
"buffered-interpolation": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/buffered-interpolation/-/buffered-interpolation-0.2.5.tgz",
- "integrity": "sha512-LauOWiVXZppapDpc8y2yzcf3/pKU1Exal/+H0EZeNVxttnWHqtyhEaJ2J4U5yia71FWqZvywnhx8xneh073xbA=="
+ "version": "github:Infinitelee/buffered-interpolation#5bb18421ebf2bf11664645cdc7a15bd77ee2156b",
+ "from": "github:Infinitelee/buffered-interpolation"
},
"builtin-status-codes": {
"version": "3.0.0",
@@ -6427,9 +6426,9 @@
}
},
"parse-headers": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz",
- "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
+ "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==",
"dev": true
},
"parse-json": {
@@ -8220,9 +8219,9 @@
"dev": true
},
"super-three": {
- "version": "0.125.1",
- "resolved": "https://registry.npmjs.org/super-three/-/super-three-0.125.1.tgz",
- "integrity": "sha512-poTMpd0fa5tWVJDtWKSFWuqbb+h2Z0m1Eop66hRsfaeOE2p9xnl78MDJmj0S/jYI0Ly4iMQOWIkS0LyKCZe0SA==",
+ "version": "0.137.0",
+ "resolved": "https://registry.npmjs.org/super-three/-/super-three-0.137.0.tgz",
+ "integrity": "sha512-8jM8DiYiXQoalUoeFRxKWbW6KFQo3GFwgw+3vE2y6SJU/einw+JvuvgK+WhbIYRfz4LQV68nyOQ2eEZqAuouGw==",
"dev": true
},
"supports-color": {
@@ -8434,8 +8433,8 @@
"dev": true
},
"three-bmfont-text": {
- "version": "github:dmarcos/three-bmfont-text#1babdf8507c731a18f8af3b807292e2b9740955e",
- "from": "github:dmarcos/three-bmfont-text#1babdf8507c731a18f8af3b807292e2b9740955e",
+ "version": "github:dmarcos/three-bmfont-text#21d017046216e318362c48abd1a48bddfb6e0733",
+ "from": "github:dmarcos/three-bmfont-text#21d017046216e318362c48abd1a48bddfb6e0733",
"dev": true,
"requires": {
"array-shuffle": "^1.0.1",
diff --git a/package.json b/package.json
index 34713a83..4b3b1029 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "networked-aframe",
- "version": "0.8.3",
+ "version": "0.9.0",
"description": "A web framework for building multi-user virtual reality experiences.",
"homepage": "",
"main": "src/index.js",
@@ -28,7 +28,7 @@
},
"repository": "networked-aframe/networked-aframe",
"dependencies": {
- "buffered-interpolation": "^0.2.5",
+ "buffered-interpolation": "github:Infinitelee/buffered-interpolation",
"express": "^4.17.1",
"open-easyrtc": "^2.0.5",
"socket.io": "^2.3.0"
@@ -36,7 +36,7 @@
"devDependencies": {
"@babel/core": "~7.8.3",
"@babel/preset-env": "~7.8.3",
- "aframe": "~1.2.0",
+ "aframe": "~1.3.0",
"babel-loader": "8.0.0-beta.1",
"chai": "^3.5.0",
"chai-shallow-deep-equal": "^1.4.0",
diff --git a/src/NafIndex.js b/src/NafIndex.js
index 27289b37..ee84da18 100644
--- a/src/NafIndex.js
+++ b/src/NafIndex.js
@@ -14,7 +14,7 @@ naf.options = options;
naf.utils = utils;
naf.log = new NafLogger();
naf.schemas = new Schemas();
-naf.version = "0.8.3";
+naf.version = "0.9.0";
naf.adapters = new AdapterFactory();
var entities = new NetworkEntities();