diff --git a/components/mouse-manipulation/README.md b/components/mouse-manipulation/README.md index ad336c7..d5289e5 100644 --- a/components/mouse-manipulation/README.md +++ b/components/mouse-manipulation/README.md @@ -24,7 +24,7 @@ Controls are as follows: Via CDN ``` - + ``` Or via [npm](https://www.npmjs.com/package/aframe-laser-manipulation) @@ -61,6 +61,7 @@ npm install aframe-mouse-manipulation | grabEvents | Whether to generate events when an entity is grabbed / released | false | | grabEvent | If `grabEvents` is true, the name of the event to generate when an entity is grabbed | laserGrab | | releaseEvent | If `grabEvents` is true, the name of the event to generate when an entity is released | laserRelease | +| controlMethod | Either 'parent' or 'transform'.
'parent' mode re-parents the object to become a descendant of the controller. This is a simpler method, and may be more performant and stable. However re-parenting can cause issues if code in other components makes assumptions about objects' positions in the THREE.js scene graph. 'transform' mode leaves the object in the same position in the THREE.js scene graph, and instead adjusts its transform every tick as required. | parent | diff --git a/components/mouse-manipulation/dist/mouse-manipulation.js b/components/mouse-manipulation/dist/mouse-manipulation.js index 4089eec..28c1ab2 100644 --- a/components/mouse-manipulation/dist/mouse-manipulation.js +++ b/components/mouse-manipulation/dist/mouse-manipulation.js @@ -15,7 +15,7 @@ \******************/ /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => { -eval("if (!AFRAME.components['object-parent']) __webpack_require__(/*! aframe-object-parent */ \"./node_modules/aframe-object-parent/index.js\")\r\nif (!AFRAME.components['cursor-tracker']) __webpack_require__(/*! aframe-cursor-tracker */ \"./node_modules/aframe-cursor-tracker/index.js\")\r\nif (!AFRAME.components['label']) __webpack_require__(/*! aframe-label */ \"./node_modules/aframe-label/index.js\")\r\n\r\n// Add this to the same entity as the cursor component.\r\nAFRAME.registerComponent('mouse-manipulation', {\r\n\r\n schema: {\r\n debug: {type: 'boolean', default: false},\r\n showHints: {type: 'boolean', default: true},\r\n grabEvents: {type: 'boolean', default: false},\r\n grabEvent: {type: 'string', default: 'mouseGrab'},\r\n releaseEvent: {type: 'string', default: 'mouseRelease'}\r\n },\r\n\r\n events: {\r\n mousedown: function(evt) { this.mouseDown(evt) }, \r\n mouseup: function(evt) { this.mouseUp(evt) },\r\n mouseenter: function(evt) { this.mouseEnter(evt) }, \r\n mouseleave: function(evt) { this.mouseLeave(evt) }\r\n },\r\n \r\n init() {\r\n // cursor must have an ID so that we can reference it when attaching an object-parent\r\n if (!this.el.id) {\r\n this.el.id = \"cursor-\" + THREE.MathUtils.generateUUID()\r\n }\r\n \r\n // This is a rate per second. We scale distance by this factor per second.\r\n // Take a root of this to get a scaling factor.\r\n this.moveSpeed = 3;\r\n \r\n // variable to track any grabbed element\r\n this.grabbedEl = null;\r\n\r\n // We create 2 children beneath the camera\r\n // - cursorTracker. This is set up to match the orientation of the cursor\r\n // (which does not match the camera, when using rayOrigin: mouse)\r\n this.camera = document.querySelector('[camera]')\r\n this.cursorTracker = document.createElement('a-entity')\r\n this.cursorTracker.setAttribute('cursor-tracker', `cursor:#${this.el.id}`)\r\n this.camera.appendChild(this.cursorTracker)\r\n\r\n // A container for any entity that can be grabbed.\r\n // For mouse controls, this is a child of the cursor tracker.\r\n // (this helps with move in/out, rotation etc. of grabbed entity)\r\n this.cursorContactPoint = document.createElement('a-entity')\r\n this.cursorContactPoint.setAttribute('id', `${this.el.id}-cursor-contact-point`)\r\n if (this.data.debug) {\r\n this.cursorContactPoint.setAttribute('geometry', \"primitive:box; height:0.1; width: 0.1; depth:0.1\")\r\n this.cursorContactPoint.setAttribute('material', \"color: blue\")\r\n }\r\n \r\n this.cursorTracker.appendChild(this.cursorContactPoint)\r\n\r\n // A container for any entity that can be grabbed.\r\n // This is a child of the camera, for controls where the object\r\n // shouldn't follow the mouse pointer, e.g. rotation.\r\n // (this helps with move in/out, rotation etc. of grabbed entity)\r\n this.cameraContactPoint = document.createElement('a-entity')\r\n this.cameraContactPoint.setAttribute('id', `${this.el.id}-camera-contact-point`)\r\n if (this.data.debug) {\r\n this.cameraContactPoint.setAttribute('geometry', \"primitive:box; height:0.1; width: 0.1; depth:0.1\")\r\n this.cameraContactPoint.setAttribute('material', \"color: red\")\r\n }\r\n this.camera.appendChild(this.cameraContactPoint)\r\n\r\n // for working\r\n this.vector1 = new THREE.Vector3()\r\n this.vector2 = new THREE.Vector3()\r\n\r\n this.windowMouseUp = this.windowMouseUp.bind(this)\r\n this.windowMouseDown = this.windowMouseDown.bind(this)\r\n\r\n window.addEventListener('mouseup', this.windowMouseUp);\r\n window.addEventListener('mousedown', this.windowMouseDown);\r\n window.addEventListener('contextmenu', event => event.preventDefault());\r\n\r\n // state of mouse buttons\r\n this.lbDown = false\r\n this.mbDown = false\r\n this.rbDown = false\r\n\r\n // adjustments to control ratio of mouse pixels to radians for otations.\r\n this.radiansPerMousePixel = 0.01\r\n },\r\n\r\n update: function() {\r\n \r\n if (this.data.showHints) {\r\n this.createHints()\r\n }\r\n else {\r\n this.removeHints()\r\n }\r\n \r\n },\r\n\r\n remove() {\r\n\r\n this.removeHints()\r\n\r\n this.cursorTracker.parentNode.removeChild(this.cursorTracker)\r\n this.cameraContactPoint.parentNode.removeChild(this.cameraContactPoint)\r\n\r\n window.removeEventListener('mouseup', this.windowMouseUp);\r\n window.removeEventListener('mousedown', this.windowMouseDown);\r\n },\r\n\r\n windowMouseDown(evt) {\r\n\r\n // we are looking for the original mouseEvent, which has details of buttons pressed\r\n // And we need to have registered an element to be grabbed.\r\n if (evt.buttons === undefined) return;\r\n if (!this.grabbedEl) return;\r\n\r\n if (this.data.debug) console.log(\"MouseDown:\", evt)\r\n\r\n this.recordMouseButtonsState(evt)\r\n this.updateMouseControls()\r\n this.updateHints()\r\n\r\n if (this.lbDown) {\r\n // left button is pressed (either just pressed or already down) \r\n // - grab to cursor contact point\r\n this.grabElToContactPoint(this.cursorContactPoint,\r\n `#${this.el.id}-cursor-contact-point`)\r\n\r\n }\r\n else {\r\n // right or middle button - grab to camera contact point\r\n this.grabElToContactPoint(this.cameraContactPoint,\r\n `#${this.el.id}-camera-contact-point`)\r\n }\r\n },\r\n\r\n windowMouseUp(evt) {\r\n // we are looking for the original mouseEvent, which has details of buttons pressed\r\n // And we need to have a grabbed element.\r\n if (evt.buttons === undefined) return;\r\n if (!this.grabbedEl) return;\r\n\r\n if (this.data.debug) console.log(\"MouseUp:\", evt)\r\n\r\n this.recordMouseButtonsState(evt)\r\n this.updateMouseControls()\r\n this.updateHints()\r\n \r\n // Reparenting\r\n if (this.lbDown) {\r\n // left button is still down\r\n // leave attached to cursor contact point.\r\n if (this.data.debug) console.log(\"Left button still down\")\r\n }\r\n else if (evt.buttons === 0){\r\n // no button now pressed.\r\n if (this.data.debug) console.log(\"No buttons down - releasing\")\r\n this.releaseEl()\r\n }\r\n else if (evt.button === 0) {\r\n if (this.data.debug) console.log(\"Left button released, middle or right still down\")\r\n // left button released, but right or middle button still down \r\n // - grab to camera contact point\r\n this.grabElToContactPoint(this.cameraContactPoint,\r\n `#${this.el.id}-camera-contact-point`)\r\n }\r\n },\r\n\r\n recordMouseButtonsState(evt) {\r\n this.lbDown = (evt.buttons & 1)\r\n this.mbDown = (evt.buttons & 4)\r\n this.rbDown = (evt.buttons & 2)\r\n\r\n if (this.data.debug) {\r\n console.log(\"this.lbDown:\", this.lbDown)\r\n console.log(\"this.rbDown:\", this.rbDown)\r\n console.log(\"this.mbDown:\", this.mbDown)\r\n }\r\n },\r\n\r\n updateMouseControls() {\r\n\r\n if (this.lbDown) {\r\n this.cursorContactPoint.setAttribute(\"mouse-dolly\", \"\")\r\n }\r\n else if (this.rbDown){\r\n this.cursorContactPoint.removeAttribute(\"mouse-dolly\")\r\n this.cameraContactPoint.setAttribute(\"mouse-dolly\", \"\")\r\n\r\n }\r\n else {\r\n this.cursorContactPoint.removeAttribute(\"mouse-dolly\")\r\n this.cameraContactPoint.removeAttribute(\"mouse-dolly\")\r\n }\r\n\r\n if (this.rbDown) {\r\n this.cameraContactPoint.setAttribute(\"mouse-pitch-yaw\", \"\")\r\n }\r\n else {\r\n this.cameraContactPoint.removeAttribute(\"mouse-pitch-yaw\")\r\n }\r\n\r\n if (this.mbDown) {\r\n this.cameraContactPoint.setAttribute(\"mouse-roll\", \"\")\r\n }\r\n else {\r\n this.cameraContactPoint.removeAttribute(\"mouse-roll\")\r\n }\r\n },\r\n\r\n createHints() {\r\n\r\n if (!this.data.showHints) return\r\n\r\n this.hints = document.createElement('a-entity')\r\n this.hints.setAttribute(\"label\", \"overwrite: true; forceDesktopMode: true\") \r\n this.hints.setAttribute(\"mouse-manipulation-hints\", \"\")\r\n this.el.appendChild(this.hints)\r\n\r\n this.updateHints()\r\n },\r\n\r\n updateHints() {\r\n\r\n if (!this.data.showHints) return\r\n\r\n const show = (x) => { this.hints.setAttribute(\"mouse-manipulation-hints\", \"view\", x) }\r\n \r\n if (this.lbDown) {\r\n show(\"left\")\r\n }\r\n else if (this.rbDown) {\r\n show(\"right\")\r\n }\r\n else if (this.mbDown) {\r\n show(\"middle\")\r\n }\r\n else if (this.hoverEl) {\r\n show(\"hover\")\r\n }\r\n else {\r\n show(\"none\")\r\n }\r\n },\r\n\r\n removeHints() {\r\n\r\n if (this.hints) {\r\n this.hints.parentNode.removeChild(this.hints)\r\n this.hints = null\r\n }\r\n },\r\n\r\n // records details of grabbed object, but actual grabbing is deferred to be handled on MouseEvent\r\n // based on detail about which button is pressed (not avalable on this event)\r\n mouseDown(evt) {\r\n \r\n const intersections = this.getIntersections(evt.target);\r\n \r\n if (intersections.length === 0) return;\r\n \r\n const element = intersections[0]\r\n var newGrabbedEl = this.getRaycastTarget(element)\r\n\r\n if (this.grabbedEl && \r\n this.grabbedEl !== newGrabbedEl) {\r\n console.warn(\"Grabbed 2nd element without releasing the first:\", newGrabbedEl.id, this.grabbedEl.id)\r\n }\r\n\r\n this.grabbedEl = newGrabbedEl\r\n \r\n },\r\n\r\n // Ensure an element has a usable ID.\r\n // If it has no ID, add one.\r\n // If it has an ID but it's not usable to identify the element...\r\n // ...log an error (preferable to creating confusion by modifying existing IDs)\r\n assureUsableId(el) {\r\n\r\n if (!el.id) {\r\n // No ID, just set one\r\n el.setAttribute(\"id\", Math.random().toString(36).slice(2))\r\n }\r\n else {\r\n const reference = document.getElementById(el.id)\r\n if (reference !== el) {\r\n console.error(`Element ID for ${el.id} does not unambiguously identify it. Check for duplicate IDs.`)\r\n }\r\n }\r\n },\r\n\r\n // Get scene graph parent element of an element.\r\n // Includes the case where the parent is the a-scene.\r\n getParentEl(el) {\r\n\r\n const parentObject = el.object3D.parent\r\n\r\n if (parentObject.type === 'Scene') {\r\n return(this.el.sceneEl)\r\n }\r\n else {\r\n return parentObject.el\r\n }\r\n },\r\n\r\n grabElToContactPoint(contactPoint, contactPointSelector) {\r\n\r\n // Save record of original parent, and make sure it has a usable ID.\r\n if (!this.originalParentEl) {\r\n this.originalParentEl = this.getParentEl(this.grabbedEl)\r\n }\r\n this.assureUsableId(this.originalParentEl)\r\n\r\n // set up a contact point at the position of the grabbed entity\r\n const pos = contactPoint.object3D.position\r\n this.grabbedEl.object3D.getWorldPosition(pos)\r\n contactPoint.object3D.parent.worldToLocal(pos)\r\n this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector)\r\n\r\n this.hints.object3D.position.set(0, 0 , 0)\r\n contactPoint.object3D.add(this.hints.object3D)\r\n\r\n if (this.data.grabEvents) {\r\n this.grabbedEl.emit(this.data.grabEvent)\r\n }\r\n },\r\n\r\n releaseEl() {\r\n const contactPoint = this.grabbedEl.object3D.parent\r\n this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`)\r\n\r\n if (this.data.grabEvents) {\r\n this.grabbedEl.emit(this.data.releaseEvent)\r\n }\r\n\r\n this.grabbedEl = null\r\n this.originalParentEl = null\r\n \r\n this.el.object3D.add(this.hints.object3D)\r\n\r\n if (this.hoverEl) {\r\n const pos = this.hints.object3D.position\r\n this.hoverEl.object3D.getWorldPosition(pos)\r\n this.hints.object3D.parent.worldToLocal(pos)\r\n }\r\n },\r\n\r\n mouseUp() {\r\n // all work done on MouseEvent, where we have detail as to *which* button is pressed.\r\n },\r\n\r\n getRaycastTarget(el) {\r\n if (el.components['raycast-target']) {\r\n return el.components['raycast-target'].target\r\n }\r\n else {\r\n return el\r\n }\r\n },\r\n\r\n mouseEnter(evt) {\r\n\r\n // similar logic to mouseDown - could be commonized\r\n // or we could even *only* do some of this processing on mouseenter?\r\n const intersections = this.getIntersections(evt.target);\r\n \r\n if (intersections.length === 0) return;\r\n \r\n const element = intersections[0]\r\n\r\n this.hoverEl = this.getRaycastTarget(element)\r\n if (this.data.debug) console.log(\"HoverEl set:\", this.hoverEl)\r\n \r\n // don't do actual hover display behaviour when another entity is already grabbed.\r\n // (but do do the state tracking bits - above).\r\n if (this.grabbedEl) return;\r\n\r\n const contactPoint = this.cursorContactPoint\r\n const pos = this.hints.object3D.position\r\n this.hoverEl.object3D.getWorldPosition(pos)\r\n this.hints.object3D.parent.worldToLocal(pos)\r\n\r\n this.updateHints()\r\n },\r\n\r\n mouseLeave(evt) {\r\n this.hoverEl = null\r\n if (this.data.debug) console.log(\"HoverEl cleared\")\r\n this.updateHints()\r\n },\r\n\r\n getIntersections(cursorEl) {\r\n \r\n const els = cursorEl.components.raycaster.intersectedEls\r\n return els\r\n }\r\n\r\n});\r\n\r\nAFRAME.registerComponent('mouse-manipulation-hints', {\r\n schema: {\r\n view: {type: 'string',\r\n oneOf: ['none', 'hover', 'left', 'middle', 'right'],\r\n default: 'none'}\r\n },\r\n\r\n init() {\r\n this.views = {}\r\n const views = this.views\r\n\r\n this.createHoverView()\r\n this.createLeftView()\r\n this.createRightView()\r\n this.createMiddleView()\r\n },\r\n\r\n createHoverView() {\r\n\r\n const views = this.views\r\n views.hover = document.createElement('a-entity')\r\n views.hover.setAttribute('id', 'hint-hover')\r\n this.el.appendChild(views.hover)\r\n\r\n const rows = [[\"left-mouse\", \"move-arrows\", \"left-mouse\", \"pitch-yaw-arrow\"],\r\n [\"mouse-wheel\", \"in-out-arrow\", \"middle-mouse\", \"roll\"]]\r\n\r\n const rotations = [[0, 0, 0, 0],\r\n [0, 0, 0, 0]]\r\n \r\n const reflections = [[1, 1, -1, 1],\r\n [1, 1, 1, 1]]\r\n\r\n this.addRowsToView(views.hover, rows, rotations, reflections, \"above\")\r\n },\r\n\r\n createLeftView() {\r\n\r\n const views = this.views\r\n views.left = document.createElement('a-entity')\r\n views.left.setAttribute('id', 'hint-left')\r\n //views.left.setAttribute(\"text\", \"value: left; align: center; anchor: center\") \r\n this.el.appendChild(views.left)\r\n\r\n const rows = [[\"mouse-wheel\", \"in-out-arrow\"]]\r\n const rotations = [[0, 0]]\r\n const reflections = [[1, 1]]\r\n\r\n this.addRowsToView(views.left, rows, rotations, reflections, \"below\")\r\n\r\n const cRows = [[\"left-arrow\"],\r\n [\"left-arrow\"],\r\n [\"left-arrow\"],\r\n [\"left-arrow\"]]\r\n const cRotations = [[270], [90], [0], [180]]\r\n const cReflections = [[1], [1], [1], [1]]\r\n\r\n this.addRowsToView(views.left, cRows, cRotations, cReflections, \"compass\")\r\n },\r\n\r\n createRightView() {\r\n\r\n const views = this.views\r\n views.right = document.createElement('a-entity')\r\n views.right.setAttribute('id', 'hint-right')\r\n this.el.appendChild(views.right)\r\n\r\n const rows = [[\"mouse-wheel\", \"in-out-arrow\"]]\r\n const rotations = [[0, 0]]\r\n const reflections = [[1, 1]]\r\n\r\n this.addRowsToView(views.right, rows, rotations, reflections, \"below\")\r\n\r\n const cRows = [[\"yaw-arrow\"],\r\n [\"yaw-arrow\"],\r\n [\"yaw-arrow\"],\r\n [\"yaw-arrow\"]]\r\n const cRotations = [[90], [90], [0], [0]]\r\n const cReflections = [[1], [-1], [-1], [1]]\r\n\r\n this.addRowsToView(views.right, cRows, cRotations, cReflections, \"compass\")\r\n },\r\n\r\n createMiddleView() {\r\n\r\n const views = this.views\r\n\r\n views.middle = document.createElement('a-entity')\r\n views.middle.setAttribute('id', 'hint-middle')\r\n this.el.appendChild(views.middle)\r\n\r\n const rows = [[\"roll\"]]\r\n const aRotations = [[0]]\r\n const bRotations = [[180]]\r\n const reflections = [[1]]\r\n\r\n this.addRowsToView(views.middle, rows, aRotations, reflections, \"above\")\r\n this.addRowsToView(views.middle, rows, bRotations, reflections, \"below\")\r\n },\r\n\r\n addRowsToView(view, rows, rotations, reflections, layout) {\r\n\r\n const spacing = 0.15\r\n const imgSize = 0.1\r\n const iconsPath = \"https://cdn.jsdelivr.net/gh/diarmidmackenzie/aframe-components@latest/assets/icons/\"\r\n\r\n var xOffset, yOffset\r\n \r\n xOffset = -((rows[0].length - 1) * spacing / 2)\r\n yOffset = 0.2 + rows.length * spacing / 2 \r\n \r\n if (layout === \"below\") {\r\n yOffset -= 0.5\r\n }\r\n \r\n function createIcon(iconName, xPos, yPos, rotation, reflect) {\r\n\r\n const icon = document.createElement('a-image')\r\n const src = `${iconsPath}${iconName}.svg`\r\n\r\n icon.setAttribute(\"src\", src)\r\n icon.object3D.position.set(xPos, yPos, 0)\r\n icon.object3D.rotation.set(0, 0, THREE.MathUtils.degToRad(rotation))\r\n icon.object3D.scale.set(imgSize * reflect, imgSize, imgSize)\r\n view.appendChild(icon)\r\n }\r\n\r\n function createRow(row, xStart, yPos, rowIndex) {\r\n\r\n row.forEach((iconName, index) => {\r\n createIcon(iconName, xStart + (index * spacing), yPos,\r\n rotations[rowIndex][index],\r\n reflections[rowIndex][index])\r\n })\r\n }\r\n\r\n if ((layout === \"above\") ||\r\n (layout === \"below\"))\r\n {\r\n // lay rows out in a grid above the entity\r\n rows.forEach((row, index) => {\r\n createRow(row, xOffset, yOffset - (index * spacing), index)\r\n })\r\n }\r\n else if (layout === \"compass\") {\r\n // lay rows out at N, S, E & W positions.\r\n console.assert(rows.length == 4)\r\n\r\n const radius = 0.4\r\n \r\n createRow(rows[0], 0, radius, 0) // N\r\n createRow(rows[1], 0, -radius, 1) // S\r\n createRow(rows[2], -radius, 0, 2) // E\r\n createRow(rows[3], radius, 0, 3) // W\r\n\r\n }\r\n },\r\n\r\n update() {\r\n\r\n const show = (x) => { x.object3D.visible = true }\r\n const hide = (x) => { x.object3D.visible = false }\r\n\r\n const views = this.views\r\n\r\n hide(views.hover)\r\n hide(views.left)\r\n hide(views.right)\r\n hide(views.middle)\r\n \r\n const viewToShow = views[this.data.view]\r\n if (viewToShow) {\r\n show(viewToShow)\r\n }\r\n }\r\n})\r\n \r\nAFRAME.registerComponent('mouse-pitch-yaw', {\r\n\r\n schema: {\r\n // whether to only allow rotation on a single axis (whichever moves first)\r\n singleAxis : {type: 'boolean', default: false},\r\n // Number of mouse pixels movement required to lock onto an axis.\r\n threshold : {type: 'number', default: 5}\r\n },\r\n\r\n init: function () {\r\n \r\n this.axis = null\r\n this.cumX = 0\r\n this.cumY = 0\r\n\r\n this.xQuaternion = new THREE.Quaternion();\r\n this.yQuaternion = new THREE.Quaternion();\r\n this.yAxis = new THREE.Vector3(0, 1, 0);\r\n this.xAxis = new THREE.Vector3(1, 0, 0);\r\n \r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n document.addEventListener('mousemove', this.onMouseMove);\r\n },\r\n\r\n\r\n remove() {\r\n document.removeEventListener('mousemove', this.onMouseMove);\r\n },\r\n \r\n onMouseMove: function (evt) {\r\n this.rotateModel(evt);\r\n },\r\n \r\n rotateModel: function (evt) {\r\n\r\n // get normalized vector perpendicular to camera to use as xAxis (to pitch around)\r\n this.xAxis.copy(this.el.object3D.position)\r\n this.xAxis.normalize()\r\n this.xAxis.cross(this.yAxis)\r\n //console.log(\"xAxis: \", this.xAxis)\r\n\r\n var dX = evt.movementX;\r\n var dY = evt.movementY;\r\n\r\n // constrain to single axis if required.\r\n if (this.data.singleAxis) {\r\n\r\n // cumulative movements in X & Y. Used to measure vs. threshold for\r\n // single axis movement.\r\n this.cumX += dX\r\n this.cumY += dY\r\n\r\n if (!this.axis && \r\n ((Math.abs(this.cumX) > this.data.threshold) ||\r\n (Math.abs(this.cumY) > this.data.threshold))) {\r\n this.axis = (Math.abs(this.cumX) > Math.abs(this.cumY)) ? \"x\" : \"y\"\r\n }\r\n\r\n if (this.axis === \"x\") {\r\n dY = 0\r\n }\r\n else if (this.axis === \"y\"){\r\n dX = 0\r\n }\r\n else {\r\n // if not locked onto an axis yet, don't allow amny movement.\r\n dX = 0\r\n dY = 0\r\n }\r\n }\r\n \r\n this.xQuaternion.setFromAxisAngle(this.yAxis, dX / 200)\r\n this.yQuaternion.setFromAxisAngle(this.xAxis, dY / 200)\r\n \r\n this.el.object3D.quaternion.premultiply(this.xQuaternion);\r\n this.el.object3D.quaternion.premultiply(this.yQuaternion);\r\n\r\n // avoid issues that can result from accumulation of small Floating Point inaccuracies.\r\n this.el.object3D.quaternion.normalize()\r\n }\r\n});\r\n\r\nAFRAME.registerComponent('mouse-roll', {\r\n\r\n schema: {\r\n slowdownRadius: {type: 'number', default: 50}\r\n },\r\n\r\n init: function () {\r\n \r\n this.zQuaternion = new THREE.Quaternion();\r\n this.zAxis = new THREE.Vector3(0, 0, 1);\r\n \r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n document.addEventListener('mousemove', this.onMouseMove);\r\n\r\n this.currPointer = new THREE.Vector2()\r\n this.prevPointer = new THREE.Vector2()\r\n\r\n this.el.setAttribute(\"entity-screen-position\", \"\")\r\n\r\n this.modelPos = new THREE.Vector2()\r\n this.el.components['entity-screen-position'].getEntityScreenPosition(this.modelPos)\r\n },\r\n \r\n\r\n remove() {\r\n this.el.removeAttribute(\"entity-screen-position\")\r\n document.removeEventListener('mousemove', this.onMouseMove);\r\n },\r\n \r\n onMouseMove: function (evt) {\r\n this.rotateModel(evt);\r\n },\r\n \r\n rotateModel: function (evt) {\r\n\r\n // get normalized vector away from camera to use as zAxis (to roll around)\r\n this.zAxis.copy(this.el.object3D.position)\r\n this.zAxis.multiplyScalar(-1)\r\n this.zAxis.normalize()\r\n //console.log(\"zAxis: \", this.zAxis)\r\n\r\n this.el.components['entity-screen-position'].getEntityScreenPosition(this.modelPos)\r\n //console.log(\"Model position on screen:\", this.modelPos)\r\n\r\n const dX = evt.movementX;\r\n const dY = evt.movementY;\r\n this.currPointer.set(evt.clientX, evt.clientY)\r\n this.currPointer.sub(this.modelPos)\r\n this.prevPointer.set(evt.clientX - dX, evt.clientY - dY)\r\n this.prevPointer.sub(this.modelPos)\r\n\r\n let angle = this.prevPointer.angle() - this.currPointer.angle()\r\n\r\n // Normalize to rangw PI -> -PI, so that scaling angle down doesn't give unexpected results.\r\n if (angle < (-Math.PI)) angle += (2 * Math.PI)\r\n if (angle > (Math.PI)) angle -= (2 * Math.PI)\r\n \r\n const distanceToCenter = Math.min(this.currPointer.length(), this.prevPointer.length())\r\n if (distanceToCenter < this.data.slowdownRadius) {\r\n const scaleFactor = distanceToCenter / this.data.slowdownRadius\r\n angle *= scaleFactor\r\n }\r\n \r\n this.zQuaternion.setFromAxisAngle(this.zAxis, angle)\r\n this.el.object3D.quaternion.premultiply(this.zQuaternion);\r\n }\r\n});\r\n\r\n// Make available the screen position of an entity\r\nAFRAME.registerComponent('entity-screen-position', {\r\n\r\n init: function () {\r\n \r\n this.vector = new THREE.Vector3()\r\n\r\n // need to keep an up-to-date view of canvs bounds\r\n this.canvasBounds = document.body.getBoundingClientRect();\r\n this.updateCanvasBounds = AFRAME.utils.debounce(() => {\r\n this.canvasBounds = this.el.sceneEl.canvas.getBoundingClientRect()\r\n }, 500);\r\n \r\n window.addEventListener('resize', this.updateCanvasBounds);\r\n window.addEventListener('scroll', this.updateCanvasBounds);\r\n\r\n this.getEntityScreenPosition = this.getEntityScreenPosition.bind(this)\r\n },\r\n \r\n\r\n remove() {\r\n window.removeEventListener('resize', this.updateCanvasBounds);\r\n window.removeEventListener('scroll', this.updateCanvasBounds);\r\n },\r\n\r\n getEntityScreenPosition(vector2) {\r\n\r\n this.el.object3D.getWorldPosition(this.vector)\r\n //console.log(\"World Position:\", this.vector)\r\n this.vector.project(this.el.sceneEl.camera)\r\n\r\n //console.log(\"Projected vector x, y:\", this.vector.x, this.vector.y)\r\n\r\n const bounds = this.canvasBounds;\r\n //console.log(\"Canvas Bounds:\", bounds)\r\n vector2.set((this.vector.x + 1) * bounds.width / 2,\r\n bounds.height - ((this.vector.y + 1) * bounds.height / 2))\r\n //console.log(\"Model position on screen:\", vector2)\r\n\r\n return vector2\r\n }\r\n});\r\n\r\nAFRAME.registerComponent('mouse-dolly', {\r\n\r\n init: function () {\r\n\r\n // 1 - no movement; < 1 = reverse movement.\r\n this.moveSpeed = 1.3\r\n \r\n this.zQuaternion = new THREE.Quaternion();\r\n this.zAxis = new THREE.Vector3(0, 0, 1);\r\n \r\n this.onMouseWheel = this.onMouseWheel.bind(this);\r\n document.addEventListener('mousewheel', this.onMouseWheel);\r\n },\r\n\r\n remove() {\r\n document.removeEventListener('mousewheel', this.onMouseWheel);\r\n },\r\n \r\n onMouseWheel: function (evt) {\r\n this.dollyModel(evt);\r\n },\r\n \r\n dollyModel: function (evt) {\r\n\r\n const dY = evt.deltaY;\r\n\r\n const scalar = Math.pow(this.moveSpeed, -dY/400);\r\n this.el.object3D.position.multiplyScalar(scalar)\r\n }\r\n});\r\n \n\n//# sourceURL=webpack://aframe-mouse-manipulation/./index.js?"); +eval("if (!AFRAME.components['object-parent']) __webpack_require__(/*! aframe-object-parent */ \"./node_modules/aframe-object-parent/index.js\")\r\nif (!AFRAME.components['cursor-tracker']) __webpack_require__(/*! aframe-cursor-tracker */ \"./node_modules/aframe-cursor-tracker/index.js\")\r\nif (!AFRAME.components['label']) __webpack_require__(/*! aframe-label */ \"./node_modules/aframe-label/index.js\")\r\n\r\n// Add this to the same entity as the cursor component.\r\nAFRAME.registerComponent('mouse-manipulation', {\r\n\r\n schema: {\r\n debug: {type: 'boolean', default: false},\r\n showHints: {type: 'boolean', default: true},\r\n grabEvents: {type: 'boolean', default: false},\r\n grabEvent: {type: 'string', default: 'mouseGrab'},\r\n releaseEvent: {type: 'string', default: 'mouseRelease'},\r\n controlMethod: {type: 'string', default: 'parent', oneOf: ['parent', 'transform']}\r\n },\r\n\r\n events: {\r\n mousedown: function(evt) { this.mouseDown(evt) }, \r\n mouseup: function(evt) { this.mouseUp(evt) },\r\n mouseenter: function(evt) { this.mouseEnter(evt) }, \r\n mouseleave: function(evt) { this.mouseLeave(evt) }\r\n },\r\n \r\n init() {\r\n // cursor must have an ID so that we can reference it when attaching an object-parent\r\n if (!this.el.id) {\r\n this.el.id = \"cursor-\" + THREE.MathUtils.generateUUID()\r\n }\r\n \r\n // This is a rate per second. We scale distance by this factor per second.\r\n // Take a root of this to get a scaling factor.\r\n this.moveSpeed = 3;\r\n \r\n // variable to track any grabbed element, and active controls state.\r\n this.grabbedEl = null;\r\n this.activeContactPoint = null;\r\n this.activeControlMethod = '';\r\n\r\n // We create 2 children beneath the camera\r\n // - cursorTracker. This is set up to match the orientation of the cursor\r\n // (which does not match the camera, when using rayOrigin: mouse)\r\n this.camera = document.querySelector('[camera]')\r\n this.cursorTracker = document.createElement('a-entity')\r\n this.cursorTracker.setAttribute('cursor-tracker', `cursor:#${this.el.id}`)\r\n this.camera.appendChild(this.cursorTracker)\r\n\r\n // A container for any entity that can be grabbed.\r\n // For mouse controls, this is a child of the cursor tracker.\r\n // (this helps with move in/out, rotation etc. of grabbed entity)\r\n this.cursorContactPoint = document.createElement('a-entity')\r\n this.cursorContactPoint.setAttribute('id', `${this.el.id}-cursor-contact-point`)\r\n if (this.data.debug) {\r\n this.cursorContactPoint.setAttribute('geometry', \"primitive:box; height:0.1; width: 0.1; depth:0.1\")\r\n this.cursorContactPoint.setAttribute('material', \"color: blue\")\r\n }\r\n \r\n this.cursorTracker.appendChild(this.cursorContactPoint)\r\n\r\n // A container for any entity that can be grabbed.\r\n // This is a child of the camera, for controls where the object\r\n // shouldn't follow the mouse pointer, e.g. rotation.\r\n // (this helps with move in/out, rotation etc. of grabbed entity)\r\n this.cameraContactPoint = document.createElement('a-entity')\r\n this.cameraContactPoint.setAttribute('id', `${this.el.id}-camera-contact-point`)\r\n if (this.data.debug) {\r\n this.cameraContactPoint.setAttribute('geometry', \"primitive:box; height:0.1; width: 0.1; depth:0.1\")\r\n this.cameraContactPoint.setAttribute('material', \"color: red\")\r\n }\r\n this.camera.appendChild(this.cameraContactPoint)\r\n\r\n // for working\r\n this.vector1 = new THREE.Vector3()\r\n this.vector2 = new THREE.Vector3()\r\n\r\n this.windowMouseUp = this.windowMouseUp.bind(this)\r\n this.windowMouseDown = this.windowMouseDown.bind(this)\r\n\r\n window.addEventListener('mouseup', this.windowMouseUp);\r\n window.addEventListener('mousedown', this.windowMouseDown);\r\n window.addEventListener('contextmenu', event => event.preventDefault());\r\n\r\n // state of mouse buttons\r\n this.lbDown = false\r\n this.mbDown = false\r\n this.rbDown = false\r\n\r\n // adjustments to control ratio of mouse pixels to radians for otations.\r\n this.radiansPerMousePixel = 0.01\r\n\r\n this.lastContactPointTransform = new THREE.Object3D()\r\n },\r\n\r\n update: function() {\r\n \r\n if (this.data.showHints) {\r\n this.createHints()\r\n }\r\n else {\r\n this.removeHints()\r\n }\r\n \r\n },\r\n\r\n remove() {\r\n\r\n this.removeHints()\r\n\r\n this.cursorTracker.parentNode.removeChild(this.cursorTracker)\r\n this.cameraContactPoint.parentNode.removeChild(this.cameraContactPoint)\r\n\r\n window.removeEventListener('mouseup', this.windowMouseUp);\r\n window.removeEventListener('mousedown', this.windowMouseDown);\r\n },\r\n\r\n windowMouseDown(evt) {\r\n\r\n // we are looking for the original mouseEvent, which has details of buttons pressed\r\n // And we need to have registered an element to be grabbed.\r\n if (evt.buttons === undefined) return;\r\n if (!this.grabbedEl) return;\r\n\r\n if (this.data.debug) console.log(\"MouseDown:\", evt)\r\n\r\n this.recordMouseButtonsState(evt)\r\n this.updateMouseControls()\r\n this.updateHints()\r\n\r\n if (this.lbDown) {\r\n // left button is pressed (either just pressed or already down) \r\n // - grab to cursor contact point\r\n this.grabElToContactPoint(this.cursorContactPoint,\r\n `#${this.el.id}-cursor-contact-point`)\r\n\r\n }\r\n else {\r\n // right or middle button - grab to camera contact point\r\n this.grabElToContactPoint(this.cameraContactPoint,\r\n `#${this.el.id}-camera-contact-point`)\r\n }\r\n },\r\n\r\n windowMouseUp(evt) {\r\n // we are looking for the original mouseEvent, which has details of buttons pressed\r\n // And we need to have a grabbed element.\r\n if (evt.buttons === undefined) return;\r\n if (!this.grabbedEl) return;\r\n\r\n if (this.data.debug) console.log(\"MouseUp:\", evt)\r\n\r\n this.recordMouseButtonsState(evt)\r\n this.updateMouseControls()\r\n this.updateHints()\r\n \r\n // Reparenting\r\n if (this.lbDown) {\r\n // left button is still down\r\n // leave attached to cursor contact point.\r\n if (this.data.debug) console.log(\"Left button still down\")\r\n }\r\n else if (evt.buttons === 0){\r\n // no button now pressed.\r\n if (this.data.debug) console.log(\"No buttons down - releasing\")\r\n this.releaseEl()\r\n }\r\n else if (evt.button === 0) {\r\n if (this.data.debug) console.log(\"Left button released, middle or right still down\")\r\n // left button released, but right or middle button still down \r\n // - grab to camera contact point\r\n this.grabElToContactPoint(this.cameraContactPoint,\r\n `#${this.el.id}-camera-contact-point`)\r\n }\r\n },\r\n\r\n recordMouseButtonsState(evt) {\r\n this.lbDown = (evt.buttons & 1)\r\n this.mbDown = (evt.buttons & 4)\r\n this.rbDown = (evt.buttons & 2)\r\n\r\n if (this.data.debug) {\r\n console.log(\"this.lbDown:\", this.lbDown)\r\n console.log(\"this.rbDown:\", this.rbDown)\r\n console.log(\"this.mbDown:\", this.mbDown)\r\n }\r\n },\r\n\r\n updateMouseControls() {\r\n\r\n if (this.lbDown) {\r\n this.cursorContactPoint.setAttribute(\"mouse-dolly\", \"\")\r\n }\r\n else if (this.rbDown){\r\n this.cursorContactPoint.removeAttribute(\"mouse-dolly\")\r\n this.cameraContactPoint.setAttribute(\"mouse-dolly\", \"\")\r\n\r\n }\r\n else {\r\n this.cursorContactPoint.removeAttribute(\"mouse-dolly\")\r\n this.cameraContactPoint.removeAttribute(\"mouse-dolly\")\r\n }\r\n\r\n if (this.rbDown) {\r\n this.cameraContactPoint.setAttribute(\"mouse-pitch-yaw\", \"\")\r\n }\r\n else {\r\n this.cameraContactPoint.removeAttribute(\"mouse-pitch-yaw\")\r\n }\r\n\r\n if (this.mbDown) {\r\n this.cameraContactPoint.setAttribute(\"mouse-roll\", \"\")\r\n }\r\n else {\r\n this.cameraContactPoint.removeAttribute(\"mouse-roll\")\r\n }\r\n },\r\n\r\n createHints() {\r\n\r\n if (!this.data.showHints) return\r\n\r\n this.hints = document.createElement('a-entity')\r\n this.hints.setAttribute(\"label\", \"overwrite: true; forceDesktopMode: true\") \r\n this.hints.setAttribute(\"mouse-manipulation-hints\", \"\")\r\n this.el.appendChild(this.hints)\r\n\r\n this.updateHints()\r\n },\r\n\r\n updateHints() {\r\n\r\n if (!this.data.showHints) return\r\n\r\n const show = (x) => { this.hints.setAttribute(\"mouse-manipulation-hints\", \"view\", x) }\r\n \r\n if (this.lbDown) {\r\n show(\"left\")\r\n }\r\n else if (this.rbDown) {\r\n show(\"right\")\r\n }\r\n else if (this.mbDown) {\r\n show(\"middle\")\r\n }\r\n else if (this.hoverEl) {\r\n show(\"hover\")\r\n }\r\n else {\r\n show(\"none\")\r\n }\r\n },\r\n\r\n removeHints() {\r\n\r\n if (this.hints) {\r\n this.hints.parentNode.removeChild(this.hints)\r\n this.hints = null\r\n }\r\n },\r\n\r\n // records details of grabbed object, but actual grabbing is deferred to be handled on MouseEvent\r\n // based on detail about which button is pressed (not avalable on this event)\r\n mouseDown(evt) {\r\n \r\n const intersections = this.getIntersections(evt.target);\r\n \r\n if (intersections.length === 0) return;\r\n \r\n const element = intersections[0]\r\n var newGrabbedEl = this.getRaycastTarget(element)\r\n\r\n if (this.grabbedEl && \r\n this.grabbedEl !== newGrabbedEl) {\r\n console.warn(\"Grabbed 2nd element without releasing the first:\", newGrabbedEl.id, this.grabbedEl.id)\r\n }\r\n\r\n this.grabbedEl = newGrabbedEl\r\n \r\n },\r\n\r\n // Ensure an element has a usable ID.\r\n // If it has no ID, add one.\r\n // If it has an ID but it's not usable to identify the element...\r\n // ...log an error (preferable to creating confusion by modifying existing IDs)\r\n assureUsableId(el) {\r\n\r\n if (!el.id) {\r\n // No ID, just set one\r\n el.setAttribute(\"id\", Math.random().toString(36).slice(2))\r\n }\r\n else {\r\n const reference = document.getElementById(el.id)\r\n if (reference !== el) {\r\n console.error(`Element ID for ${el.id} does not unambiguously identify it. Check for duplicate IDs.`)\r\n }\r\n }\r\n },\r\n\r\n // Get scene graph parent element of an element.\r\n // Includes the case where the parent is the a-scene.\r\n getParentEl(el) {\r\n\r\n const parentObject = el.object3D.parent\r\n\r\n if (parentObject.type === 'Scene') {\r\n return(this.el.sceneEl)\r\n }\r\n else {\r\n return parentObject.el\r\n }\r\n },\r\n\r\n grabElToContactPoint(contactPoint, contactPointSelector) {\r\n\r\n // Save record of original parent, and make sure it has a usable ID.\r\n if (!this.originalParentEl) {\r\n this.originalParentEl = this.getParentEl(this.grabbedEl)\r\n }\r\n this.assureUsableId(this.originalParentEl)\r\n\r\n // set up a contact point at the position of the grabbed entity\r\n const pos = contactPoint.object3D.position\r\n this.grabbedEl.object3D.getWorldPosition(pos)\r\n contactPoint.object3D.parent.worldToLocal(pos)\r\n\r\n if (this.data.controlMethod === 'parent') {\r\n this.activeControlMethod = 'parent'\r\n this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector)\r\n }\r\n else {\r\n this.activeControlMethod = 'transform'\r\n this.saveContactPointTransform(contactPoint)\r\n }\r\n\r\n this.hints.object3D.position.set(0, 0 , 0)\r\n contactPoint.object3D.add(this.hints.object3D)\r\n\r\n if (this.data.grabEvents) {\r\n this.grabbedEl.emit(this.data.grabEvent)\r\n }\r\n },\r\n\r\n releaseEl() {\r\n const contactPoint = this.grabbedEl.object3D.parent\r\n\r\n if (this.activeControlMethod === 'parent') {\r\n this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`)\r\n }\r\n\r\n if (this.data.grabEvents) {\r\n // defer event to next schedule, to allow reparenting to have completed.\r\n const releasedEl = this.grabbedEl\r\n setTimeout(() => {\r\n releasedEl.emit(this.data.releaseEvent)\r\n })\r\n }\r\n\r\n this.grabbedEl = null\r\n this.activeControlMethod = ''\r\n this.originalParentEl = null\r\n \r\n this.el.object3D.add(this.hints.object3D)\r\n\r\n if (this.hoverEl) {\r\n const pos = this.hints.object3D.position\r\n this.hoverEl.object3D.getWorldPosition(pos)\r\n this.hints.object3D.parent.worldToLocal(pos)\r\n }\r\n },\r\n\r\n mouseUp() {\r\n // all work done on MouseEvent, where we have detail as to *which* button is pressed.\r\n },\r\n\r\n getRaycastTarget(el) {\r\n if (el.components['raycast-target']) {\r\n return el.components['raycast-target'].target\r\n }\r\n else {\r\n return el\r\n }\r\n },\r\n\r\n mouseEnter(evt) {\r\n\r\n // similar logic to mouseDown - could be commonized\r\n // or we could even *only* do some of this processing on mouseenter?\r\n const intersections = this.getIntersections(evt.target);\r\n \r\n if (intersections.length === 0) return;\r\n \r\n const element = intersections[0]\r\n\r\n this.hoverEl = this.getRaycastTarget(element)\r\n if (this.data.debug) console.log(\"HoverEl set:\", this.hoverEl)\r\n \r\n // don't do actual hover display behaviour when another entity is already grabbed.\r\n // (but do do the state tracking bits - above).\r\n if (this.grabbedEl) return;\r\n\r\n const contactPoint = this.cursorContactPoint\r\n const pos = this.hints.object3D.position\r\n this.hoverEl.object3D.getWorldPosition(pos)\r\n this.hints.object3D.parent.worldToLocal(pos)\r\n\r\n this.updateHints()\r\n },\r\n\r\n mouseLeave(evt) {\r\n this.hoverEl = null\r\n if (this.data.debug) console.log(\"HoverEl cleared\")\r\n this.updateHints()\r\n },\r\n\r\n getIntersections(cursorEl) {\r\n \r\n const els = cursorEl.components.raycaster.intersectedEls\r\n return els\r\n },\r\n\r\n saveContactPointTransform(contactPoint) {\r\n const transform = this.lastContactPointTransform\r\n transform.quaternion.identity()\r\n transform.position.set(0, 0, 0)\r\n transform.scale.set(1, 1, 1)\r\n contactPoint.object3D.add(transform)\r\n this.el.sceneEl.object3D.attach(transform)\r\n\r\n this.activeContactPoint = contactPoint\r\n },\r\n\r\n followContactPoint() {\r\n const object = this.grabbedEl.object3D\r\n this.lastContactPointTransform.attach(object)\r\n this.saveContactPointTransform(this.activeContactPoint)\r\n this.originalParentEl.object3D.attach(object)\r\n },\r\n \r\n tick() {\r\n if (this.activeControlMethod === 'transform') {\r\n this.followContactPoint()\r\n }\r\n }\r\n});\r\n\r\nAFRAME.registerComponent('mouse-manipulation-hints', {\r\n schema: {\r\n view: {type: 'string',\r\n oneOf: ['none', 'hover', 'left', 'middle', 'right'],\r\n default: 'none'}\r\n },\r\n\r\n init() {\r\n this.views = {}\r\n const views = this.views\r\n\r\n this.createHoverView()\r\n this.createLeftView()\r\n this.createRightView()\r\n this.createMiddleView()\r\n },\r\n\r\n createHoverView() {\r\n\r\n const views = this.views\r\n views.hover = document.createElement('a-entity')\r\n views.hover.setAttribute('id', 'hint-hover')\r\n this.el.appendChild(views.hover)\r\n\r\n const rows = [[\"left-mouse\", \"move-arrows\", \"left-mouse\", \"pitch-yaw-arrow\"],\r\n [\"mouse-wheel\", \"in-out-arrow\", \"middle-mouse\", \"roll\"]]\r\n\r\n const rotations = [[0, 0, 0, 0],\r\n [0, 0, 0, 0]]\r\n \r\n const reflections = [[1, 1, -1, 1],\r\n [1, 1, 1, 1]]\r\n\r\n this.addRowsToView(views.hover, rows, rotations, reflections, \"above\")\r\n },\r\n\r\n createLeftView() {\r\n\r\n const views = this.views\r\n views.left = document.createElement('a-entity')\r\n views.left.setAttribute('id', 'hint-left')\r\n //views.left.setAttribute(\"text\", \"value: left; align: center; anchor: center\") \r\n this.el.appendChild(views.left)\r\n\r\n const rows = [[\"mouse-wheel\", \"in-out-arrow\"]]\r\n const rotations = [[0, 0]]\r\n const reflections = [[1, 1]]\r\n\r\n this.addRowsToView(views.left, rows, rotations, reflections, \"below\")\r\n\r\n const cRows = [[\"left-arrow\"],\r\n [\"left-arrow\"],\r\n [\"left-arrow\"],\r\n [\"left-arrow\"]]\r\n const cRotations = [[270], [90], [0], [180]]\r\n const cReflections = [[1], [1], [1], [1]]\r\n\r\n this.addRowsToView(views.left, cRows, cRotations, cReflections, \"compass\")\r\n },\r\n\r\n createRightView() {\r\n\r\n const views = this.views\r\n views.right = document.createElement('a-entity')\r\n views.right.setAttribute('id', 'hint-right')\r\n this.el.appendChild(views.right)\r\n\r\n const rows = [[\"mouse-wheel\", \"in-out-arrow\"]]\r\n const rotations = [[0, 0]]\r\n const reflections = [[1, 1]]\r\n\r\n this.addRowsToView(views.right, rows, rotations, reflections, \"below\")\r\n\r\n const cRows = [[\"yaw-arrow\"],\r\n [\"yaw-arrow\"],\r\n [\"yaw-arrow\"],\r\n [\"yaw-arrow\"]]\r\n const cRotations = [[90], [90], [0], [0]]\r\n const cReflections = [[1], [-1], [-1], [1]]\r\n\r\n this.addRowsToView(views.right, cRows, cRotations, cReflections, \"compass\")\r\n },\r\n\r\n createMiddleView() {\r\n\r\n const views = this.views\r\n\r\n views.middle = document.createElement('a-entity')\r\n views.middle.setAttribute('id', 'hint-middle')\r\n this.el.appendChild(views.middle)\r\n\r\n const rows = [[\"roll\"]]\r\n const aRotations = [[0]]\r\n const bRotations = [[180]]\r\n const reflections = [[1]]\r\n\r\n this.addRowsToView(views.middle, rows, aRotations, reflections, \"above\")\r\n this.addRowsToView(views.middle, rows, bRotations, reflections, \"below\")\r\n },\r\n\r\n addRowsToView(view, rows, rotations, reflections, layout) {\r\n\r\n const spacing = 0.15\r\n const imgSize = 0.1\r\n const iconsPath = \"https://cdn.jsdelivr.net/gh/diarmidmackenzie/aframe-components@latest/assets/icons/\"\r\n\r\n var xOffset, yOffset\r\n \r\n xOffset = -((rows[0].length - 1) * spacing / 2)\r\n yOffset = 0.2 + rows.length * spacing / 2 \r\n \r\n if (layout === \"below\") {\r\n yOffset -= 0.5\r\n }\r\n \r\n function createIcon(iconName, xPos, yPos, rotation, reflect) {\r\n\r\n const icon = document.createElement('a-image')\r\n const src = `${iconsPath}${iconName}.svg`\r\n\r\n icon.setAttribute(\"src\", src)\r\n icon.object3D.position.set(xPos, yPos, 0)\r\n icon.object3D.rotation.set(0, 0, THREE.MathUtils.degToRad(rotation))\r\n icon.object3D.scale.set(imgSize * reflect, imgSize, imgSize)\r\n view.appendChild(icon)\r\n }\r\n\r\n function createRow(row, xStart, yPos, rowIndex) {\r\n\r\n row.forEach((iconName, index) => {\r\n createIcon(iconName, xStart + (index * spacing), yPos,\r\n rotations[rowIndex][index],\r\n reflections[rowIndex][index])\r\n })\r\n }\r\n\r\n if ((layout === \"above\") ||\r\n (layout === \"below\"))\r\n {\r\n // lay rows out in a grid above the entity\r\n rows.forEach((row, index) => {\r\n createRow(row, xOffset, yOffset - (index * spacing), index)\r\n })\r\n }\r\n else if (layout === \"compass\") {\r\n // lay rows out at N, S, E & W positions.\r\n console.assert(rows.length == 4)\r\n\r\n const radius = 0.4\r\n \r\n createRow(rows[0], 0, radius, 0) // N\r\n createRow(rows[1], 0, -radius, 1) // S\r\n createRow(rows[2], -radius, 0, 2) // E\r\n createRow(rows[3], radius, 0, 3) // W\r\n\r\n }\r\n },\r\n\r\n update() {\r\n\r\n const show = (x) => { x.object3D.visible = true }\r\n const hide = (x) => { x.object3D.visible = false }\r\n\r\n const views = this.views\r\n\r\n hide(views.hover)\r\n hide(views.left)\r\n hide(views.right)\r\n hide(views.middle)\r\n \r\n const viewToShow = views[this.data.view]\r\n if (viewToShow) {\r\n show(viewToShow)\r\n }\r\n }\r\n})\r\n \r\nAFRAME.registerComponent('mouse-pitch-yaw', {\r\n\r\n schema: {\r\n // whether to only allow rotation on a single axis (whichever moves first)\r\n singleAxis : {type: 'boolean', default: false},\r\n // Number of mouse pixels movement required to lock onto an axis.\r\n threshold : {type: 'number', default: 5}\r\n },\r\n\r\n init: function () {\r\n \r\n this.axis = null\r\n this.cumX = 0\r\n this.cumY = 0\r\n\r\n this.xQuaternion = new THREE.Quaternion();\r\n this.yQuaternion = new THREE.Quaternion();\r\n this.yAxis = new THREE.Vector3(0, 1, 0);\r\n this.xAxis = new THREE.Vector3(1, 0, 0);\r\n \r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n document.addEventListener('mousemove', this.onMouseMove);\r\n },\r\n\r\n\r\n remove() {\r\n document.removeEventListener('mousemove', this.onMouseMove);\r\n },\r\n \r\n onMouseMove: function (evt) {\r\n this.rotateModel(evt);\r\n },\r\n \r\n rotateModel: function (evt) {\r\n\r\n // get normalized vector perpendicular to camera to use as xAxis (to pitch around)\r\n this.xAxis.copy(this.el.object3D.position)\r\n this.xAxis.normalize()\r\n this.xAxis.cross(this.yAxis)\r\n //console.log(\"xAxis: \", this.xAxis)\r\n\r\n var dX = evt.movementX;\r\n var dY = evt.movementY;\r\n\r\n // constrain to single axis if required.\r\n if (this.data.singleAxis) {\r\n\r\n // cumulative movements in X & Y. Used to measure vs. threshold for\r\n // single axis movement.\r\n this.cumX += dX\r\n this.cumY += dY\r\n\r\n if (!this.axis && \r\n ((Math.abs(this.cumX) > this.data.threshold) ||\r\n (Math.abs(this.cumY) > this.data.threshold))) {\r\n this.axis = (Math.abs(this.cumX) > Math.abs(this.cumY)) ? \"x\" : \"y\"\r\n }\r\n\r\n if (this.axis === \"x\") {\r\n dY = 0\r\n }\r\n else if (this.axis === \"y\"){\r\n dX = 0\r\n }\r\n else {\r\n // if not locked onto an axis yet, don't allow amny movement.\r\n dX = 0\r\n dY = 0\r\n }\r\n }\r\n \r\n this.xQuaternion.setFromAxisAngle(this.yAxis, dX / 200)\r\n this.yQuaternion.setFromAxisAngle(this.xAxis, dY / 200)\r\n \r\n this.el.object3D.quaternion.premultiply(this.xQuaternion);\r\n this.el.object3D.quaternion.premultiply(this.yQuaternion);\r\n\r\n // avoid issues that can result from accumulation of small Floating Point inaccuracies.\r\n this.el.object3D.quaternion.normalize()\r\n }\r\n});\r\n\r\nAFRAME.registerComponent('mouse-roll', {\r\n\r\n schema: {\r\n slowdownRadius: {type: 'number', default: 50}\r\n },\r\n\r\n init: function () {\r\n \r\n this.zQuaternion = new THREE.Quaternion();\r\n this.zAxis = new THREE.Vector3(0, 0, 1);\r\n \r\n this.onMouseMove = this.onMouseMove.bind(this);\r\n document.addEventListener('mousemove', this.onMouseMove);\r\n\r\n this.currPointer = new THREE.Vector2()\r\n this.prevPointer = new THREE.Vector2()\r\n\r\n this.el.setAttribute(\"entity-screen-position\", \"\")\r\n\r\n this.modelPos = new THREE.Vector2()\r\n this.el.components['entity-screen-position'].getEntityScreenPosition(this.modelPos)\r\n },\r\n \r\n\r\n remove() {\r\n this.el.removeAttribute(\"entity-screen-position\")\r\n document.removeEventListener('mousemove', this.onMouseMove);\r\n },\r\n \r\n onMouseMove: function (evt) {\r\n this.rotateModel(evt);\r\n },\r\n \r\n rotateModel: function (evt) {\r\n\r\n // get normalized vector away from camera to use as zAxis (to roll around)\r\n this.zAxis.copy(this.el.object3D.position)\r\n this.zAxis.multiplyScalar(-1)\r\n this.zAxis.normalize()\r\n //console.log(\"zAxis: \", this.zAxis)\r\n\r\n this.el.components['entity-screen-position'].getEntityScreenPosition(this.modelPos)\r\n //console.log(\"Model position on screen:\", this.modelPos)\r\n\r\n const dX = evt.movementX;\r\n const dY = evt.movementY;\r\n this.currPointer.set(evt.clientX, evt.clientY)\r\n this.currPointer.sub(this.modelPos)\r\n this.prevPointer.set(evt.clientX - dX, evt.clientY - dY)\r\n this.prevPointer.sub(this.modelPos)\r\n\r\n let angle = this.prevPointer.angle() - this.currPointer.angle()\r\n\r\n // Normalize to rangw PI -> -PI, so that scaling angle down doesn't give unexpected results.\r\n if (angle < (-Math.PI)) angle += (2 * Math.PI)\r\n if (angle > (Math.PI)) angle -= (2 * Math.PI)\r\n \r\n const distanceToCenter = Math.min(this.currPointer.length(), this.prevPointer.length())\r\n if (distanceToCenter < this.data.slowdownRadius) {\r\n const scaleFactor = distanceToCenter / this.data.slowdownRadius\r\n angle *= scaleFactor\r\n }\r\n \r\n this.zQuaternion.setFromAxisAngle(this.zAxis, angle)\r\n this.el.object3D.quaternion.premultiply(this.zQuaternion);\r\n }\r\n});\r\n\r\n// Make available the screen position of an entity\r\nAFRAME.registerComponent('entity-screen-position', {\r\n\r\n init: function () {\r\n \r\n this.vector = new THREE.Vector3()\r\n\r\n // need to keep an up-to-date view of canvs bounds\r\n this.canvasBounds = document.body.getBoundingClientRect();\r\n this.updateCanvasBounds = AFRAME.utils.debounce(() => {\r\n this.canvasBounds = this.el.sceneEl.canvas.getBoundingClientRect()\r\n }, 500);\r\n \r\n window.addEventListener('resize', this.updateCanvasBounds);\r\n window.addEventListener('scroll', this.updateCanvasBounds);\r\n\r\n this.getEntityScreenPosition = this.getEntityScreenPosition.bind(this)\r\n },\r\n \r\n\r\n remove() {\r\n window.removeEventListener('resize', this.updateCanvasBounds);\r\n window.removeEventListener('scroll', this.updateCanvasBounds);\r\n },\r\n\r\n getEntityScreenPosition(vector2) {\r\n\r\n this.el.object3D.getWorldPosition(this.vector)\r\n //console.log(\"World Position:\", this.vector)\r\n this.vector.project(this.el.sceneEl.camera)\r\n\r\n //console.log(\"Projected vector x, y:\", this.vector.x, this.vector.y)\r\n\r\n const bounds = this.canvasBounds;\r\n //console.log(\"Canvas Bounds:\", bounds)\r\n vector2.set((this.vector.x + 1) * bounds.width / 2,\r\n bounds.height - ((this.vector.y + 1) * bounds.height / 2))\r\n //console.log(\"Model position on screen:\", vector2)\r\n\r\n return vector2\r\n }\r\n});\r\n\r\nAFRAME.registerComponent('mouse-dolly', {\r\n\r\n init: function () {\r\n\r\n // 1 - no movement; < 1 = reverse movement.\r\n this.moveSpeed = 1.3\r\n \r\n this.zQuaternion = new THREE.Quaternion();\r\n this.zAxis = new THREE.Vector3(0, 0, 1);\r\n \r\n this.onMouseWheel = this.onMouseWheel.bind(this);\r\n document.addEventListener('mousewheel', this.onMouseWheel);\r\n },\r\n\r\n remove() {\r\n document.removeEventListener('mousewheel', this.onMouseWheel);\r\n },\r\n \r\n onMouseWheel: function (evt) {\r\n this.dollyModel(evt);\r\n },\r\n \r\n dollyModel: function (evt) {\r\n\r\n const dY = evt.deltaY;\r\n\r\n const scalar = Math.pow(this.moveSpeed, -dY/400);\r\n this.el.object3D.position.multiplyScalar(scalar)\r\n }\r\n});\r\n \n\n//# sourceURL=webpack://aframe-mouse-manipulation/./index.js?"); /***/ }), diff --git a/components/mouse-manipulation/dist/mouse-manipulation.min.js b/components/mouse-manipulation/dist/mouse-manipulation.min.js index fa04032..2a02761 100644 --- a/components/mouse-manipulation/dist/mouse-manipulation.min.js +++ b/components/mouse-manipulation/dist/mouse-manipulation.min.js @@ -1 +1 @@ -(()=>{var t={660:()=>{AFRAME.registerComponent("cursor-tracker",{schema:{cursor:{type:"selector",default:"#cursor"}},init(){this.cursor=this.data.cursor,this.raycaster=this.cursor.components.raycaster.raycaster,this.forward=new THREE.Vector3(0,0,-1),this.localRayVector=new THREE.Vector3},tick(){this.el.object3D.getWorldPosition(this.localRayVector),this.localRayVector.add(this.raycaster.ray.direction),this.el.object3D.parent.worldToLocal(this.localRayVector),this.localRayVector.normalize(),this.el.object3D.quaternion.setFromUnitVectors(this.forward,this.localRayVector)}})},711:()=>{AFRAME.registerComponent("label-anchor",{schema:{offsetVector:{type:"vec3"},showLine:{type:"boolean",default:!0},lineColor:{type:"color",default:"white"}},init(){this.label=this.el.querySelector("[label]"),this.cameraWorldPosition=new THREE.Vector3,this.objectWorldPosition=new THREE.Vector3},update(){this.data.showLine?this.el.setAttribute("line__label-anchor",`start: 0 0 0; end: 0 0 0; color: ${this.data.lineColor}`):this.el.removeAttribute("line__label-anchor")},tick(){const t=this.el.sceneEl.camera;var e=1;if(t.isPerspectiveCamera&&(this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.getWorldPosition(this.objectWorldPosition),e=this.objectWorldPosition.distanceTo(this.cameraWorldPosition)),this.label.object3D.position.copy(this.data.offsetVector),this.label.object3D.position.multiplyScalar(e),this.data.showLine){const t=this.label.object3D.position,e=`${t.x} ${t.y} ${t.z}`;this.el.setAttribute("line__label-anchor",`end: ${e}`)}}}),AFRAME.registerComponent("label",{schema:{overwrite:{type:"boolean",default:!1},forceDesktopMode:{type:"boolean",default:!1}},init(){this.enterVR=this.enterVR.bind(this),this.exitVR=this.exitVR.bind(this),this.el.sceneEl.addEventListener("enter-vr",this.enterVR),this.el.sceneEl.addEventListener("exit-vr",this.exitVR)},update(){this.el.sceneEl.is("vr-mode")?this.enterVR():this.exitVR()},enterVR:function(){this.el.setAttribute("face-camera",{fixedSize:this.data.forceDesktopMode,spriteMode:this.data.forceDesktopMode,overwrite:this.data.overwrite})},exitVR:function(){this.el.setAttribute("face-camera",{fixedSize:!0,spriteMode:!0,overwrite:this.data.overwrite})}}),AFRAME.registerComponent("face-camera",{schema:{fixedSize:{type:"boolean",default:!1},spriteMode:{type:"boolean",default:!1},overwrite:{type:"boolean",default:!1}},init:function(){this.cameraWorldPosition=new THREE.Vector3,this.objectWorldPosition=new THREE.Vector3,this.cameraQuaternion=new THREE.Quaternion,this.spriteDistanceVector=new THREE.Vector3,this.cameraDirectionVector=new THREE.Vector3,this.parentInverseQuaternion=new THREE.Quaternion,this.object3DSet=this.object3DSet.bind(this),this.data.overwrite&&this.el.addEventListener("object3dset",this.object3DSet)},object3DSet(t){const e=t.target.getObject3D(t.detail.type);e.material.depthTest=!1,e.material.depthWrite=!1},tick:function(){const t=this.el.sceneEl.camera;if(this.data.spriteMode||t.isOrthographicCamera?(setWorldQuaternion=(t,e)=>{t.updateMatrixWorld(),t.parent.getWorldQuaternion(this.parentInverseQuaternion),this.parentInverseQuaternion.invert(),t.quaternion.copy(e),t.quaternion.premultiply(this.parentInverseQuaternion)},this.cameraQuaternion.setFromRotationMatrix(t.matrixWorld),setWorldQuaternion(this.el.object3D,this.cameraQuaternion)):(this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.lookAt(this.cameraWorldPosition)),this.data.fixedSize)if(t.isPerspectiveCamera)if(this.data.spriteMode){this.cameraDirectionVector.set(0,0,-1),this.cameraDirectionVector.transformDirection(t.matrixWorld),this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.getWorldPosition(this.objectWorldPosition),this.spriteDistanceVector.subVectors(this.objectWorldPosition,this.cameraWorldPosition),this.spriteDistanceVector.projectOnVector(this.cameraDirectionVector);const e=this.spriteDistanceVector.length();this.el.object3D.scale.set(e,e,e)}else{this.el.object3D.getWorldPosition(this.objectWorldPosition);const t=this.objectWorldPosition.distanceTo(this.cameraWorldPosition);this.el.object3D.scale.set(t,t,t)}else this.el.object3D.scale.set(1,1,1)}})},527:()=>{AFRAME.registerComponent("object-parent",{schema:{parent:{type:"selector"}},update(){document.querySelectorAll(`#${parent.id}`).length>1&&console.warn(`object-parent matches duplicate entities for new parent ${parent.id}`);const t=this.data.parent.object3D;this.reparent(t)},remove(){const t=this.el.parentEl;this.reparent(t.object3D)},reparent(t){const e=this.el.object3D,i=e.parent;e.parent!==t&&(objectEl=t=>"Scene"===t.type?this.el.sceneEl:t.el,console.log(`Reparenting ${e.el.id} from ${objectEl(i).id} to ${objectEl(t).id}`),t.attach(e))}})}},e={};function i(o){var s=e[o];if(void 0!==s)return s.exports;var n=e[o]={exports:{}};return t[o](n,n.exports,i),n.exports}AFRAME.components["object-parent"]||i(527),AFRAME.components["cursor-tracker"]||i(660),AFRAME.components.label||i(711),AFRAME.registerComponent("mouse-manipulation",{schema:{debug:{type:"boolean",default:!1},showHints:{type:"boolean",default:!0},grabEvents:{type:"boolean",default:!1},grabEvent:{type:"string",default:"mouseGrab"},releaseEvent:{type:"string",default:"mouseRelease"}},events:{mousedown:function(t){this.mouseDown(t)},mouseup:function(t){this.mouseUp(t)},mouseenter:function(t){this.mouseEnter(t)},mouseleave:function(t){this.mouseLeave(t)}},init(){this.el.id||(this.el.id="cursor-"+THREE.MathUtils.generateUUID()),this.moveSpeed=3,this.grabbedEl=null,this.camera=document.querySelector("[camera]"),this.cursorTracker=document.createElement("a-entity"),this.cursorTracker.setAttribute("cursor-tracker",`cursor:#${this.el.id}`),this.camera.appendChild(this.cursorTracker),this.cursorContactPoint=document.createElement("a-entity"),this.cursorContactPoint.setAttribute("id",`${this.el.id}-cursor-contact-point`),this.data.debug&&(this.cursorContactPoint.setAttribute("geometry","primitive:box; height:0.1; width: 0.1; depth:0.1"),this.cursorContactPoint.setAttribute("material","color: blue")),this.cursorTracker.appendChild(this.cursorContactPoint),this.cameraContactPoint=document.createElement("a-entity"),this.cameraContactPoint.setAttribute("id",`${this.el.id}-camera-contact-point`),this.data.debug&&(this.cameraContactPoint.setAttribute("geometry","primitive:box; height:0.1; width: 0.1; depth:0.1"),this.cameraContactPoint.setAttribute("material","color: red")),this.camera.appendChild(this.cameraContactPoint),this.vector1=new THREE.Vector3,this.vector2=new THREE.Vector3,this.windowMouseUp=this.windowMouseUp.bind(this),this.windowMouseDown=this.windowMouseDown.bind(this),window.addEventListener("mouseup",this.windowMouseUp),window.addEventListener("mousedown",this.windowMouseDown),window.addEventListener("contextmenu",(t=>t.preventDefault())),this.lbDown=!1,this.mbDown=!1,this.rbDown=!1,this.radiansPerMousePixel=.01},update:function(){this.data.showHints?this.createHints():this.removeHints()},remove(){this.removeHints(),this.cursorTracker.parentNode.removeChild(this.cursorTracker),this.cameraContactPoint.parentNode.removeChild(this.cameraContactPoint),window.removeEventListener("mouseup",this.windowMouseUp),window.removeEventListener("mousedown",this.windowMouseDown)},windowMouseDown(t){void 0!==t.buttons&&this.grabbedEl&&(this.data.debug&&console.log("MouseDown:",t),this.recordMouseButtonsState(t),this.updateMouseControls(),this.updateHints(),this.lbDown?this.grabElToContactPoint(this.cursorContactPoint,`#${this.el.id}-cursor-contact-point`):this.grabElToContactPoint(this.cameraContactPoint,`#${this.el.id}-camera-contact-point`))},windowMouseUp(t){void 0!==t.buttons&&this.grabbedEl&&(this.data.debug&&console.log("MouseUp:",t),this.recordMouseButtonsState(t),this.updateMouseControls(),this.updateHints(),this.lbDown?this.data.debug&&console.log("Left button still down"):0===t.buttons?(this.data.debug&&console.log("No buttons down - releasing"),this.releaseEl()):0===t.button&&(this.data.debug&&console.log("Left button released, middle or right still down"),this.grabElToContactPoint(this.cameraContactPoint,`#${this.el.id}-camera-contact-point`)))},recordMouseButtonsState(t){this.lbDown=1&t.buttons,this.mbDown=4&t.buttons,this.rbDown=2&t.buttons,this.data.debug&&(console.log("this.lbDown:",this.lbDown),console.log("this.rbDown:",this.rbDown),console.log("this.mbDown:",this.mbDown))},updateMouseControls(){this.lbDown?this.cursorContactPoint.setAttribute("mouse-dolly",""):this.rbDown?(this.cursorContactPoint.removeAttribute("mouse-dolly"),this.cameraContactPoint.setAttribute("mouse-dolly","")):(this.cursorContactPoint.removeAttribute("mouse-dolly"),this.cameraContactPoint.removeAttribute("mouse-dolly")),this.rbDown?this.cameraContactPoint.setAttribute("mouse-pitch-yaw",""):this.cameraContactPoint.removeAttribute("mouse-pitch-yaw"),this.mbDown?this.cameraContactPoint.setAttribute("mouse-roll",""):this.cameraContactPoint.removeAttribute("mouse-roll")},createHints(){this.data.showHints&&(this.hints=document.createElement("a-entity"),this.hints.setAttribute("label","overwrite: true; forceDesktopMode: true"),this.hints.setAttribute("mouse-manipulation-hints",""),this.el.appendChild(this.hints),this.updateHints())},updateHints(){if(!this.data.showHints)return;const t=t=>{this.hints.setAttribute("mouse-manipulation-hints","view",t)};this.lbDown?t("left"):this.rbDown?t("right"):this.mbDown?t("middle"):this.hoverEl?t("hover"):t("none")},removeHints(){this.hints&&(this.hints.parentNode.removeChild(this.hints),this.hints=null)},mouseDown(t){const e=this.getIntersections(t.target);if(0===e.length)return;const i=e[0];var o=this.getRaycastTarget(i);this.grabbedEl&&this.grabbedEl!==o&&console.warn("Grabbed 2nd element without releasing the first:",o.id,this.grabbedEl.id),this.grabbedEl=o},assureUsableId(t){t.id?document.getElementById(t.id)!==t&&console.error(`Element ID for ${t.id} does not unambiguously identify it. Check for duplicate IDs.`):t.setAttribute("id",Math.random().toString(36).slice(2))},getParentEl(t){const e=t.object3D.parent;return"Scene"===e.type?this.el.sceneEl:e.el},grabElToContactPoint(t,e){this.originalParentEl||(this.originalParentEl=this.getParentEl(this.grabbedEl)),this.assureUsableId(this.originalParentEl);const i=t.object3D.position;this.grabbedEl.object3D.getWorldPosition(i),t.object3D.parent.worldToLocal(i),this.grabbedEl.setAttribute("object-parent","parent",e),this.hints.object3D.position.set(0,0,0),t.object3D.add(this.hints.object3D),this.data.grabEvents&&this.grabbedEl.emit(this.data.grabEvent)},releaseEl(){if(this.grabbedEl.object3D.parent,this.grabbedEl.setAttribute("object-parent","parent",`#${this.originalParentEl.id}`),this.data.grabEvents&&this.grabbedEl.emit(this.data.releaseEvent),this.grabbedEl=null,this.originalParentEl=null,this.el.object3D.add(this.hints.object3D),this.hoverEl){const t=this.hints.object3D.position;this.hoverEl.object3D.getWorldPosition(t),this.hints.object3D.parent.worldToLocal(t)}},mouseUp(){},getRaycastTarget:t=>t.components["raycast-target"]?t.components["raycast-target"].target:t,mouseEnter(t){const e=this.getIntersections(t.target);if(0===e.length)return;const i=e[0];if(this.hoverEl=this.getRaycastTarget(i),this.data.debug&&console.log("HoverEl set:",this.hoverEl),this.grabbedEl)return;this.cursorContactPoint;const o=this.hints.object3D.position;this.hoverEl.object3D.getWorldPosition(o),this.hints.object3D.parent.worldToLocal(o),this.updateHints()},mouseLeave(t){this.hoverEl=null,this.data.debug&&console.log("HoverEl cleared"),this.updateHints()},getIntersections:t=>t.components.raycaster.intersectedEls}),AFRAME.registerComponent("mouse-manipulation-hints",{schema:{view:{type:"string",oneOf:["none","hover","left","middle","right"],default:"none"}},init(){this.views={},this.views,this.createHoverView(),this.createLeftView(),this.createRightView(),this.createMiddleView()},createHoverView(){const t=this.views;t.hover=document.createElement("a-entity"),t.hover.setAttribute("id","hint-hover"),this.el.appendChild(t.hover),this.addRowsToView(t.hover,[["left-mouse","move-arrows","left-mouse","pitch-yaw-arrow"],["mouse-wheel","in-out-arrow","middle-mouse","roll"]],[[0,0,0,0],[0,0,0,0]],[[1,1,-1,1],[1,1,1,1]],"above")},createLeftView(){const t=this.views;t.left=document.createElement("a-entity"),t.left.setAttribute("id","hint-left"),this.el.appendChild(t.left),this.addRowsToView(t.left,[["mouse-wheel","in-out-arrow"]],[[0,0]],[[1,1]],"below"),this.addRowsToView(t.left,[["left-arrow"],["left-arrow"],["left-arrow"],["left-arrow"]],[[270],[90],[0],[180]],[[1],[1],[1],[1]],"compass")},createRightView(){const t=this.views;t.right=document.createElement("a-entity"),t.right.setAttribute("id","hint-right"),this.el.appendChild(t.right),this.addRowsToView(t.right,[["mouse-wheel","in-out-arrow"]],[[0,0]],[[1,1]],"below"),this.addRowsToView(t.right,[["yaw-arrow"],["yaw-arrow"],["yaw-arrow"],["yaw-arrow"]],[[90],[90],[0],[0]],[[1],[-1],[-1],[1]],"compass")},createMiddleView(){const t=this.views;t.middle=document.createElement("a-entity"),t.middle.setAttribute("id","hint-middle"),this.el.appendChild(t.middle);const e=[["roll"]],i=[[1]];this.addRowsToView(t.middle,e,[[0]],i,"above"),this.addRowsToView(t.middle,e,[[180]],i,"below")},addRowsToView(t,e,i,o,s){const n=.15;var r,a;function h(e,s,r,a){e.forEach(((e,h)=>{!function(e,i,o,s,n){const r=document.createElement("a-image"),a=`https://cdn.jsdelivr.net/gh/diarmidmackenzie/aframe-components@latest/assets/icons/${e}.svg`;r.setAttribute("src",a),r.object3D.position.set(i,o,0),r.object3D.rotation.set(0,0,THREE.MathUtils.degToRad(s)),r.object3D.scale.set(.1*n,.1,.1),t.appendChild(r)}(e,s+h*n,r,i[a][h],o[a][h])}))}if(r=-(e[0].length-1)*n/2,a=.2+e.length*n/2,"below"===s&&(a-=.5),"above"===s||"below"===s)e.forEach(((t,e)=>{h(t,r,a-e*n,e)}));else if("compass"===s){console.assert(4==e.length);const t=.4;h(e[0],0,t,0),h(e[1],0,-t,1),h(e[2],-t,0,2),h(e[3],t,0,3)}},update(){const t=t=>{t.object3D.visible=!1},e=this.views;t(e.hover),t(e.left),t(e.right),t(e.middle);const i=e[this.data.view];i&&(i.object3D.visible=!0)}}),AFRAME.registerComponent("mouse-pitch-yaw",{schema:{singleAxis:{type:"boolean",default:!1},threshold:{type:"number",default:5}},init:function(){this.axis=null,this.cumX=0,this.cumY=0,this.xQuaternion=new THREE.Quaternion,this.yQuaternion=new THREE.Quaternion,this.yAxis=new THREE.Vector3(0,1,0),this.xAxis=new THREE.Vector3(1,0,0),this.onMouseMove=this.onMouseMove.bind(this),document.addEventListener("mousemove",this.onMouseMove)},remove(){document.removeEventListener("mousemove",this.onMouseMove)},onMouseMove:function(t){this.rotateModel(t)},rotateModel:function(t){this.xAxis.copy(this.el.object3D.position),this.xAxis.normalize(),this.xAxis.cross(this.yAxis);var e=t.movementX,i=t.movementY;this.data.singleAxis&&(this.cumX+=e,this.cumY+=i,!this.axis&&(Math.abs(this.cumX)>this.data.threshold||Math.abs(this.cumY)>this.data.threshold)&&(this.axis=Math.abs(this.cumX)>Math.abs(this.cumY)?"x":"y"),"x"===this.axis?i=0:"y"===this.axis?e=0:(e=0,i=0)),this.xQuaternion.setFromAxisAngle(this.yAxis,e/200),this.yQuaternion.setFromAxisAngle(this.xAxis,i/200),this.el.object3D.quaternion.premultiply(this.xQuaternion),this.el.object3D.quaternion.premultiply(this.yQuaternion),this.el.object3D.quaternion.normalize()}}),AFRAME.registerComponent("mouse-roll",{schema:{slowdownRadius:{type:"number",default:50}},init:function(){this.zQuaternion=new THREE.Quaternion,this.zAxis=new THREE.Vector3(0,0,1),this.onMouseMove=this.onMouseMove.bind(this),document.addEventListener("mousemove",this.onMouseMove),this.currPointer=new THREE.Vector2,this.prevPointer=new THREE.Vector2,this.el.setAttribute("entity-screen-position",""),this.modelPos=new THREE.Vector2,this.el.components["entity-screen-position"].getEntityScreenPosition(this.modelPos)},remove(){this.el.removeAttribute("entity-screen-position"),document.removeEventListener("mousemove",this.onMouseMove)},onMouseMove:function(t){this.rotateModel(t)},rotateModel:function(t){this.zAxis.copy(this.el.object3D.position),this.zAxis.multiplyScalar(-1),this.zAxis.normalize(),this.el.components["entity-screen-position"].getEntityScreenPosition(this.modelPos);const e=t.movementX,i=t.movementY;this.currPointer.set(t.clientX,t.clientY),this.currPointer.sub(this.modelPos),this.prevPointer.set(t.clientX-e,t.clientY-i),this.prevPointer.sub(this.modelPos);let o=this.prevPointer.angle()-this.currPointer.angle();o<-Math.PI&&(o+=2*Math.PI),o>Math.PI&&(o-=2*Math.PI);const s=Math.min(this.currPointer.length(),this.prevPointer.length());s{this.canvasBounds=this.el.sceneEl.canvas.getBoundingClientRect()}),500),window.addEventListener("resize",this.updateCanvasBounds),window.addEventListener("scroll",this.updateCanvasBounds),this.getEntityScreenPosition=this.getEntityScreenPosition.bind(this)},remove(){window.removeEventListener("resize",this.updateCanvasBounds),window.removeEventListener("scroll",this.updateCanvasBounds)},getEntityScreenPosition(t){this.el.object3D.getWorldPosition(this.vector),this.vector.project(this.el.sceneEl.camera);const e=this.canvasBounds;return t.set((this.vector.x+1)*e.width/2,e.height-(this.vector.y+1)*e.height/2),t}}),AFRAME.registerComponent("mouse-dolly",{init:function(){this.moveSpeed=1.3,this.zQuaternion=new THREE.Quaternion,this.zAxis=new THREE.Vector3(0,0,1),this.onMouseWheel=this.onMouseWheel.bind(this),document.addEventListener("mousewheel",this.onMouseWheel)},remove(){document.removeEventListener("mousewheel",this.onMouseWheel)},onMouseWheel:function(t){this.dollyModel(t)},dollyModel:function(t){const e=t.deltaY,i=Math.pow(this.moveSpeed,-e/400);this.el.object3D.position.multiplyScalar(i)}})})(); \ No newline at end of file +(()=>{var t={660:()=>{AFRAME.registerComponent("cursor-tracker",{schema:{cursor:{type:"selector",default:"#cursor"}},init(){this.cursor=this.data.cursor,this.raycaster=this.cursor.components.raycaster.raycaster,this.forward=new THREE.Vector3(0,0,-1),this.localRayVector=new THREE.Vector3},tick(){this.el.object3D.getWorldPosition(this.localRayVector),this.localRayVector.add(this.raycaster.ray.direction),this.el.object3D.parent.worldToLocal(this.localRayVector),this.localRayVector.normalize(),this.el.object3D.quaternion.setFromUnitVectors(this.forward,this.localRayVector)}})},711:()=>{AFRAME.registerComponent("label-anchor",{schema:{offsetVector:{type:"vec3"},showLine:{type:"boolean",default:!0},lineColor:{type:"color",default:"white"}},init(){this.label=this.el.querySelector("[label]"),this.cameraWorldPosition=new THREE.Vector3,this.objectWorldPosition=new THREE.Vector3},update(){this.data.showLine?this.el.setAttribute("line__label-anchor",`start: 0 0 0; end: 0 0 0; color: ${this.data.lineColor}`):this.el.removeAttribute("line__label-anchor")},tick(){const t=this.el.sceneEl.camera;var e=1;if(t.isPerspectiveCamera&&(this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.getWorldPosition(this.objectWorldPosition),e=this.objectWorldPosition.distanceTo(this.cameraWorldPosition)),this.label.object3D.position.copy(this.data.offsetVector),this.label.object3D.position.multiplyScalar(e),this.data.showLine){const t=this.label.object3D.position,e=`${t.x} ${t.y} ${t.z}`;this.el.setAttribute("line__label-anchor",`end: ${e}`)}}}),AFRAME.registerComponent("label",{schema:{overwrite:{type:"boolean",default:!1},forceDesktopMode:{type:"boolean",default:!1}},init(){this.enterVR=this.enterVR.bind(this),this.exitVR=this.exitVR.bind(this),this.el.sceneEl.addEventListener("enter-vr",this.enterVR),this.el.sceneEl.addEventListener("exit-vr",this.exitVR)},update(){this.el.sceneEl.is("vr-mode")?this.enterVR():this.exitVR()},enterVR:function(){this.el.setAttribute("face-camera",{fixedSize:this.data.forceDesktopMode,spriteMode:this.data.forceDesktopMode,overwrite:this.data.overwrite})},exitVR:function(){this.el.setAttribute("face-camera",{fixedSize:!0,spriteMode:!0,overwrite:this.data.overwrite})}}),AFRAME.registerComponent("face-camera",{schema:{fixedSize:{type:"boolean",default:!1},spriteMode:{type:"boolean",default:!1},overwrite:{type:"boolean",default:!1}},init:function(){this.cameraWorldPosition=new THREE.Vector3,this.objectWorldPosition=new THREE.Vector3,this.cameraQuaternion=new THREE.Quaternion,this.spriteDistanceVector=new THREE.Vector3,this.cameraDirectionVector=new THREE.Vector3,this.parentInverseQuaternion=new THREE.Quaternion,this.object3DSet=this.object3DSet.bind(this),this.data.overwrite&&this.el.addEventListener("object3dset",this.object3DSet)},object3DSet(t){const e=t.target.getObject3D(t.detail.type);e.material.depthTest=!1,e.material.depthWrite=!1},tick:function(){const t=this.el.sceneEl.camera;if(this.data.spriteMode||t.isOrthographicCamera?(setWorldQuaternion=(t,e)=>{t.updateMatrixWorld(),t.parent.getWorldQuaternion(this.parentInverseQuaternion),this.parentInverseQuaternion.invert(),t.quaternion.copy(e),t.quaternion.premultiply(this.parentInverseQuaternion)},this.cameraQuaternion.setFromRotationMatrix(t.matrixWorld),setWorldQuaternion(this.el.object3D,this.cameraQuaternion)):(this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.lookAt(this.cameraWorldPosition)),this.data.fixedSize)if(t.isPerspectiveCamera)if(this.data.spriteMode){this.cameraDirectionVector.set(0,0,-1),this.cameraDirectionVector.transformDirection(t.matrixWorld),this.cameraWorldPosition.setFromMatrixPosition(t.matrixWorld),this.el.object3D.getWorldPosition(this.objectWorldPosition),this.spriteDistanceVector.subVectors(this.objectWorldPosition,this.cameraWorldPosition),this.spriteDistanceVector.projectOnVector(this.cameraDirectionVector);const e=this.spriteDistanceVector.length();this.el.object3D.scale.set(e,e,e)}else{this.el.object3D.getWorldPosition(this.objectWorldPosition);const t=this.objectWorldPosition.distanceTo(this.cameraWorldPosition);this.el.object3D.scale.set(t,t,t)}else this.el.object3D.scale.set(1,1,1)}})},527:()=>{AFRAME.registerComponent("object-parent",{schema:{parent:{type:"selector"}},update(){document.querySelectorAll(`#${parent.id}`).length>1&&console.warn(`object-parent matches duplicate entities for new parent ${parent.id}`);const t=this.data.parent.object3D;this.reparent(t)},remove(){const t=this.el.parentEl;this.reparent(t.object3D)},reparent(t){const e=this.el.object3D,i=e.parent;e.parent!==t&&(objectEl=t=>"Scene"===t.type?this.el.sceneEl:t.el,console.log(`Reparenting ${e.el.id} from ${objectEl(i).id} to ${objectEl(t).id}`),t.attach(e))}})}},e={};function i(o){var s=e[o];if(void 0!==s)return s.exports;var n=e[o]={exports:{}};return t[o](n,n.exports,i),n.exports}AFRAME.components["object-parent"]||i(527),AFRAME.components["cursor-tracker"]||i(660),AFRAME.components.label||i(711),AFRAME.registerComponent("mouse-manipulation",{schema:{debug:{type:"boolean",default:!1},showHints:{type:"boolean",default:!0},grabEvents:{type:"boolean",default:!1},grabEvent:{type:"string",default:"mouseGrab"},releaseEvent:{type:"string",default:"mouseRelease"},controlMethod:{type:"string",default:"parent",oneOf:["parent","transform"]}},events:{mousedown:function(t){this.mouseDown(t)},mouseup:function(t){this.mouseUp(t)},mouseenter:function(t){this.mouseEnter(t)},mouseleave:function(t){this.mouseLeave(t)}},init(){this.el.id||(this.el.id="cursor-"+THREE.MathUtils.generateUUID()),this.moveSpeed=3,this.grabbedEl=null,this.activeContactPoint=null,this.activeControlMethod="",this.camera=document.querySelector("[camera]"),this.cursorTracker=document.createElement("a-entity"),this.cursorTracker.setAttribute("cursor-tracker",`cursor:#${this.el.id}`),this.camera.appendChild(this.cursorTracker),this.cursorContactPoint=document.createElement("a-entity"),this.cursorContactPoint.setAttribute("id",`${this.el.id}-cursor-contact-point`),this.data.debug&&(this.cursorContactPoint.setAttribute("geometry","primitive:box; height:0.1; width: 0.1; depth:0.1"),this.cursorContactPoint.setAttribute("material","color: blue")),this.cursorTracker.appendChild(this.cursorContactPoint),this.cameraContactPoint=document.createElement("a-entity"),this.cameraContactPoint.setAttribute("id",`${this.el.id}-camera-contact-point`),this.data.debug&&(this.cameraContactPoint.setAttribute("geometry","primitive:box; height:0.1; width: 0.1; depth:0.1"),this.cameraContactPoint.setAttribute("material","color: red")),this.camera.appendChild(this.cameraContactPoint),this.vector1=new THREE.Vector3,this.vector2=new THREE.Vector3,this.windowMouseUp=this.windowMouseUp.bind(this),this.windowMouseDown=this.windowMouseDown.bind(this),window.addEventListener("mouseup",this.windowMouseUp),window.addEventListener("mousedown",this.windowMouseDown),window.addEventListener("contextmenu",(t=>t.preventDefault())),this.lbDown=!1,this.mbDown=!1,this.rbDown=!1,this.radiansPerMousePixel=.01,this.lastContactPointTransform=new THREE.Object3D},update:function(){this.data.showHints?this.createHints():this.removeHints()},remove(){this.removeHints(),this.cursorTracker.parentNode.removeChild(this.cursorTracker),this.cameraContactPoint.parentNode.removeChild(this.cameraContactPoint),window.removeEventListener("mouseup",this.windowMouseUp),window.removeEventListener("mousedown",this.windowMouseDown)},windowMouseDown(t){void 0!==t.buttons&&this.grabbedEl&&(this.data.debug&&console.log("MouseDown:",t),this.recordMouseButtonsState(t),this.updateMouseControls(),this.updateHints(),this.lbDown?this.grabElToContactPoint(this.cursorContactPoint,`#${this.el.id}-cursor-contact-point`):this.grabElToContactPoint(this.cameraContactPoint,`#${this.el.id}-camera-contact-point`))},windowMouseUp(t){void 0!==t.buttons&&this.grabbedEl&&(this.data.debug&&console.log("MouseUp:",t),this.recordMouseButtonsState(t),this.updateMouseControls(),this.updateHints(),this.lbDown?this.data.debug&&console.log("Left button still down"):0===t.buttons?(this.data.debug&&console.log("No buttons down - releasing"),this.releaseEl()):0===t.button&&(this.data.debug&&console.log("Left button released, middle or right still down"),this.grabElToContactPoint(this.cameraContactPoint,`#${this.el.id}-camera-contact-point`)))},recordMouseButtonsState(t){this.lbDown=1&t.buttons,this.mbDown=4&t.buttons,this.rbDown=2&t.buttons,this.data.debug&&(console.log("this.lbDown:",this.lbDown),console.log("this.rbDown:",this.rbDown),console.log("this.mbDown:",this.mbDown))},updateMouseControls(){this.lbDown?this.cursorContactPoint.setAttribute("mouse-dolly",""):this.rbDown?(this.cursorContactPoint.removeAttribute("mouse-dolly"),this.cameraContactPoint.setAttribute("mouse-dolly","")):(this.cursorContactPoint.removeAttribute("mouse-dolly"),this.cameraContactPoint.removeAttribute("mouse-dolly")),this.rbDown?this.cameraContactPoint.setAttribute("mouse-pitch-yaw",""):this.cameraContactPoint.removeAttribute("mouse-pitch-yaw"),this.mbDown?this.cameraContactPoint.setAttribute("mouse-roll",""):this.cameraContactPoint.removeAttribute("mouse-roll")},createHints(){this.data.showHints&&(this.hints=document.createElement("a-entity"),this.hints.setAttribute("label","overwrite: true; forceDesktopMode: true"),this.hints.setAttribute("mouse-manipulation-hints",""),this.el.appendChild(this.hints),this.updateHints())},updateHints(){if(!this.data.showHints)return;const t=t=>{this.hints.setAttribute("mouse-manipulation-hints","view",t)};this.lbDown?t("left"):this.rbDown?t("right"):this.mbDown?t("middle"):this.hoverEl?t("hover"):t("none")},removeHints(){this.hints&&(this.hints.parentNode.removeChild(this.hints),this.hints=null)},mouseDown(t){const e=this.getIntersections(t.target);if(0===e.length)return;const i=e[0];var o=this.getRaycastTarget(i);this.grabbedEl&&this.grabbedEl!==o&&console.warn("Grabbed 2nd element without releasing the first:",o.id,this.grabbedEl.id),this.grabbedEl=o},assureUsableId(t){t.id?document.getElementById(t.id)!==t&&console.error(`Element ID for ${t.id} does not unambiguously identify it. Check for duplicate IDs.`):t.setAttribute("id",Math.random().toString(36).slice(2))},getParentEl(t){const e=t.object3D.parent;return"Scene"===e.type?this.el.sceneEl:e.el},grabElToContactPoint(t,e){this.originalParentEl||(this.originalParentEl=this.getParentEl(this.grabbedEl)),this.assureUsableId(this.originalParentEl);const i=t.object3D.position;this.grabbedEl.object3D.getWorldPosition(i),t.object3D.parent.worldToLocal(i),"parent"===this.data.controlMethod?(this.activeControlMethod="parent",this.grabbedEl.setAttribute("object-parent","parent",e)):(this.activeControlMethod="transform",this.saveContactPointTransform(t)),this.hints.object3D.position.set(0,0,0),t.object3D.add(this.hints.object3D),this.data.grabEvents&&this.grabbedEl.emit(this.data.grabEvent)},releaseEl(){if(this.grabbedEl.object3D.parent,"parent"===this.activeControlMethod&&this.grabbedEl.setAttribute("object-parent","parent",`#${this.originalParentEl.id}`),this.data.grabEvents){const t=this.grabbedEl;setTimeout((()=>{t.emit(this.data.releaseEvent)}))}if(this.grabbedEl=null,this.activeControlMethod="",this.originalParentEl=null,this.el.object3D.add(this.hints.object3D),this.hoverEl){const t=this.hints.object3D.position;this.hoverEl.object3D.getWorldPosition(t),this.hints.object3D.parent.worldToLocal(t)}},mouseUp(){},getRaycastTarget:t=>t.components["raycast-target"]?t.components["raycast-target"].target:t,mouseEnter(t){const e=this.getIntersections(t.target);if(0===e.length)return;const i=e[0];if(this.hoverEl=this.getRaycastTarget(i),this.data.debug&&console.log("HoverEl set:",this.hoverEl),this.grabbedEl)return;this.cursorContactPoint;const o=this.hints.object3D.position;this.hoverEl.object3D.getWorldPosition(o),this.hints.object3D.parent.worldToLocal(o),this.updateHints()},mouseLeave(t){this.hoverEl=null,this.data.debug&&console.log("HoverEl cleared"),this.updateHints()},getIntersections:t=>t.components.raycaster.intersectedEls,saveContactPointTransform(t){const e=this.lastContactPointTransform;e.quaternion.identity(),e.position.set(0,0,0),e.scale.set(1,1,1),t.object3D.add(e),this.el.sceneEl.object3D.attach(e),this.activeContactPoint=t},followContactPoint(){const t=this.grabbedEl.object3D;this.lastContactPointTransform.attach(t),this.saveContactPointTransform(this.activeContactPoint),this.originalParentEl.object3D.attach(t)},tick(){"transform"===this.activeControlMethod&&this.followContactPoint()}}),AFRAME.registerComponent("mouse-manipulation-hints",{schema:{view:{type:"string",oneOf:["none","hover","left","middle","right"],default:"none"}},init(){this.views={},this.views,this.createHoverView(),this.createLeftView(),this.createRightView(),this.createMiddleView()},createHoverView(){const t=this.views;t.hover=document.createElement("a-entity"),t.hover.setAttribute("id","hint-hover"),this.el.appendChild(t.hover),this.addRowsToView(t.hover,[["left-mouse","move-arrows","left-mouse","pitch-yaw-arrow"],["mouse-wheel","in-out-arrow","middle-mouse","roll"]],[[0,0,0,0],[0,0,0,0]],[[1,1,-1,1],[1,1,1,1]],"above")},createLeftView(){const t=this.views;t.left=document.createElement("a-entity"),t.left.setAttribute("id","hint-left"),this.el.appendChild(t.left),this.addRowsToView(t.left,[["mouse-wheel","in-out-arrow"]],[[0,0]],[[1,1]],"below"),this.addRowsToView(t.left,[["left-arrow"],["left-arrow"],["left-arrow"],["left-arrow"]],[[270],[90],[0],[180]],[[1],[1],[1],[1]],"compass")},createRightView(){const t=this.views;t.right=document.createElement("a-entity"),t.right.setAttribute("id","hint-right"),this.el.appendChild(t.right),this.addRowsToView(t.right,[["mouse-wheel","in-out-arrow"]],[[0,0]],[[1,1]],"below"),this.addRowsToView(t.right,[["yaw-arrow"],["yaw-arrow"],["yaw-arrow"],["yaw-arrow"]],[[90],[90],[0],[0]],[[1],[-1],[-1],[1]],"compass")},createMiddleView(){const t=this.views;t.middle=document.createElement("a-entity"),t.middle.setAttribute("id","hint-middle"),this.el.appendChild(t.middle);const e=[["roll"]],i=[[1]];this.addRowsToView(t.middle,e,[[0]],i,"above"),this.addRowsToView(t.middle,e,[[180]],i,"below")},addRowsToView(t,e,i,o,s){const n=.15;var r,a;function h(e,s,r,a){e.forEach(((e,h)=>{!function(e,i,o,s,n){const r=document.createElement("a-image"),a=`https://cdn.jsdelivr.net/gh/diarmidmackenzie/aframe-components@latest/assets/icons/${e}.svg`;r.setAttribute("src",a),r.object3D.position.set(i,o,0),r.object3D.rotation.set(0,0,THREE.MathUtils.degToRad(s)),r.object3D.scale.set(.1*n,.1,.1),t.appendChild(r)}(e,s+h*n,r,i[a][h],o[a][h])}))}if(r=-(e[0].length-1)*n/2,a=.2+e.length*n/2,"below"===s&&(a-=.5),"above"===s||"below"===s)e.forEach(((t,e)=>{h(t,r,a-e*n,e)}));else if("compass"===s){console.assert(4==e.length);const t=.4;h(e[0],0,t,0),h(e[1],0,-t,1),h(e[2],-t,0,2),h(e[3],t,0,3)}},update(){const t=t=>{t.object3D.visible=!1},e=this.views;t(e.hover),t(e.left),t(e.right),t(e.middle);const i=e[this.data.view];i&&(i.object3D.visible=!0)}}),AFRAME.registerComponent("mouse-pitch-yaw",{schema:{singleAxis:{type:"boolean",default:!1},threshold:{type:"number",default:5}},init:function(){this.axis=null,this.cumX=0,this.cumY=0,this.xQuaternion=new THREE.Quaternion,this.yQuaternion=new THREE.Quaternion,this.yAxis=new THREE.Vector3(0,1,0),this.xAxis=new THREE.Vector3(1,0,0),this.onMouseMove=this.onMouseMove.bind(this),document.addEventListener("mousemove",this.onMouseMove)},remove(){document.removeEventListener("mousemove",this.onMouseMove)},onMouseMove:function(t){this.rotateModel(t)},rotateModel:function(t){this.xAxis.copy(this.el.object3D.position),this.xAxis.normalize(),this.xAxis.cross(this.yAxis);var e=t.movementX,i=t.movementY;this.data.singleAxis&&(this.cumX+=e,this.cumY+=i,!this.axis&&(Math.abs(this.cumX)>this.data.threshold||Math.abs(this.cumY)>this.data.threshold)&&(this.axis=Math.abs(this.cumX)>Math.abs(this.cumY)?"x":"y"),"x"===this.axis?i=0:"y"===this.axis?e=0:(e=0,i=0)),this.xQuaternion.setFromAxisAngle(this.yAxis,e/200),this.yQuaternion.setFromAxisAngle(this.xAxis,i/200),this.el.object3D.quaternion.premultiply(this.xQuaternion),this.el.object3D.quaternion.premultiply(this.yQuaternion),this.el.object3D.quaternion.normalize()}}),AFRAME.registerComponent("mouse-roll",{schema:{slowdownRadius:{type:"number",default:50}},init:function(){this.zQuaternion=new THREE.Quaternion,this.zAxis=new THREE.Vector3(0,0,1),this.onMouseMove=this.onMouseMove.bind(this),document.addEventListener("mousemove",this.onMouseMove),this.currPointer=new THREE.Vector2,this.prevPointer=new THREE.Vector2,this.el.setAttribute("entity-screen-position",""),this.modelPos=new THREE.Vector2,this.el.components["entity-screen-position"].getEntityScreenPosition(this.modelPos)},remove(){this.el.removeAttribute("entity-screen-position"),document.removeEventListener("mousemove",this.onMouseMove)},onMouseMove:function(t){this.rotateModel(t)},rotateModel:function(t){this.zAxis.copy(this.el.object3D.position),this.zAxis.multiplyScalar(-1),this.zAxis.normalize(),this.el.components["entity-screen-position"].getEntityScreenPosition(this.modelPos);const e=t.movementX,i=t.movementY;this.currPointer.set(t.clientX,t.clientY),this.currPointer.sub(this.modelPos),this.prevPointer.set(t.clientX-e,t.clientY-i),this.prevPointer.sub(this.modelPos);let o=this.prevPointer.angle()-this.currPointer.angle();o<-Math.PI&&(o+=2*Math.PI),o>Math.PI&&(o-=2*Math.PI);const s=Math.min(this.currPointer.length(),this.prevPointer.length());s{this.canvasBounds=this.el.sceneEl.canvas.getBoundingClientRect()}),500),window.addEventListener("resize",this.updateCanvasBounds),window.addEventListener("scroll",this.updateCanvasBounds),this.getEntityScreenPosition=this.getEntityScreenPosition.bind(this)},remove(){window.removeEventListener("resize",this.updateCanvasBounds),window.removeEventListener("scroll",this.updateCanvasBounds)},getEntityScreenPosition(t){this.el.object3D.getWorldPosition(this.vector),this.vector.project(this.el.sceneEl.camera);const e=this.canvasBounds;return t.set((this.vector.x+1)*e.width/2,e.height-(this.vector.y+1)*e.height/2),t}}),AFRAME.registerComponent("mouse-dolly",{init:function(){this.moveSpeed=1.3,this.zQuaternion=new THREE.Quaternion,this.zAxis=new THREE.Vector3(0,0,1),this.onMouseWheel=this.onMouseWheel.bind(this),document.addEventListener("mousewheel",this.onMouseWheel)},remove(){document.removeEventListener("mousewheel",this.onMouseWheel)},onMouseWheel:function(t){this.dollyModel(t)},dollyModel:function(t){const e=t.deltaY,i=Math.pow(this.moveSpeed,-e/400);this.el.object3D.position.multiplyScalar(i)}})})(); \ No newline at end of file diff --git a/components/mouse-manipulation/index.js b/components/mouse-manipulation/index.js index 427cfc2..6a1e540 100644 --- a/components/mouse-manipulation/index.js +++ b/components/mouse-manipulation/index.js @@ -10,7 +10,8 @@ AFRAME.registerComponent('mouse-manipulation', { showHints: {type: 'boolean', default: true}, grabEvents: {type: 'boolean', default: false}, grabEvent: {type: 'string', default: 'mouseGrab'}, - releaseEvent: {type: 'string', default: 'mouseRelease'} + releaseEvent: {type: 'string', default: 'mouseRelease'}, + controlMethod: {type: 'string', default: 'parent', oneOf: ['parent', 'transform']} }, events: { @@ -30,8 +31,10 @@ AFRAME.registerComponent('mouse-manipulation', { // Take a root of this to get a scaling factor. this.moveSpeed = 3; - // variable to track any grabbed element + // variable to track any grabbed element, and active controls state. this.grabbedEl = null; + this.activeContactPoint = null; + this.activeControlMethod = ''; // We create 2 children beneath the camera // - cursorTracker. This is set up to match the orientation of the cursor @@ -83,6 +86,8 @@ AFRAME.registerComponent('mouse-manipulation', { // adjustments to control ratio of mouse pixels to radians for otations. this.radiansPerMousePixel = 0.01 + + this.lastContactPointTransform = new THREE.Object3D() }, update: function() { @@ -315,7 +320,15 @@ AFRAME.registerComponent('mouse-manipulation', { const pos = contactPoint.object3D.position this.grabbedEl.object3D.getWorldPosition(pos) contactPoint.object3D.parent.worldToLocal(pos) - this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector) + + if (this.data.controlMethod === 'parent') { + this.activeControlMethod = 'parent' + this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector) + } + else { + this.activeControlMethod = 'transform' + this.saveContactPointTransform(contactPoint) + } this.hints.object3D.position.set(0, 0 , 0) contactPoint.object3D.add(this.hints.object3D) @@ -327,13 +340,21 @@ AFRAME.registerComponent('mouse-manipulation', { releaseEl() { const contactPoint = this.grabbedEl.object3D.parent - this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`) + + if (this.activeControlMethod === 'parent') { + this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`) + } if (this.data.grabEvents) { - this.grabbedEl.emit(this.data.releaseEvent) + // defer event to next schedule, to allow reparenting to have completed. + const releasedEl = this.grabbedEl + setTimeout(() => { + releasedEl.emit(this.data.releaseEvent) + }) } this.grabbedEl = null + this.activeControlMethod = '' this.originalParentEl = null this.el.object3D.add(this.hints.object3D) @@ -393,8 +414,31 @@ AFRAME.registerComponent('mouse-manipulation', { const els = cursorEl.components.raycaster.intersectedEls return els - } + }, + + saveContactPointTransform(contactPoint) { + const transform = this.lastContactPointTransform + transform.quaternion.identity() + transform.position.set(0, 0, 0) + transform.scale.set(1, 1, 1) + contactPoint.object3D.add(transform) + this.el.sceneEl.object3D.attach(transform) + + this.activeContactPoint = contactPoint + }, + followContactPoint() { + const object = this.grabbedEl.object3D + this.lastContactPointTransform.attach(object) + this.saveContactPointTransform(this.activeContactPoint) + this.originalParentEl.object3D.attach(object) + }, + + tick() { + if (this.activeControlMethod === 'transform') { + this.followContactPoint() + } + } }); AFRAME.registerComponent('mouse-manipulation-hints', { diff --git a/components/mouse-manipulation/package-lock.json b/components/mouse-manipulation/package-lock.json index 7a64be2..e3c143d 100644 --- a/components/mouse-manipulation/package-lock.json +++ b/components/mouse-manipulation/package-lock.json @@ -1,1355 +1,8 @@ { "name": "aframe-mouse-manipulation", - "version": "0.1.0", - "lockfileVersion": 2, + "version": "0.2.1", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "name": "aframe-mouse-manipulation", - "version": "0.1.0", - "license": "MIT", - "dependencies": { - "aframe-cursor-tracker": "^0.1.0", - "aframe-label": "^0.1.0", - "aframe-object-parent": "^0.1.0", - "aframe-raycast-target": "^0.1.0" - }, - "devDependencies": { - "webpack": "^5.75.0", - "webpack-cli": "^5.0.1" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@types/eslint": { - "version": "8.4.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", - "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.11.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", - "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", - "dev": true - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", - "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", - "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", - "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/aframe-cursor-tracker": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/aframe-cursor-tracker/-/aframe-cursor-tracker-0.1.0.tgz", - "integrity": "sha512-DRjiN+M9mPtb8NUBCijNMLUVZMKpNCV234sey3HjzPH4uHcX2Zxse6S6+5BDXJ8dAfLeAWG3ZbU00Yr3RdXw7g==" - }, - "node_modules/aframe-label": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/aframe-label/-/aframe-label-0.1.0.tgz", - "integrity": "sha512-hLt31H5C4Xd/eXyvk5kxQq46aAP5o+6o03MeLYVhOVYL5vk/q3YxAW35IbddPslTizWTpfB3EBNzRAvH2YQbDA==" - }, - "node_modules/aframe-object-parent": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/aframe-object-parent/-/aframe-object-parent-0.1.0.tgz", - "integrity": "sha512-5Pf8eMDT63IL9DskQjZ4l8E+/KFugxCFFZsriMDZeZ6yg0PgBDgxe1U0As+IhZ7VH+3HT7Ujnl70hvwHrF5vJg==" - }, - "node_modules/aframe-raycast-target": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/aframe-raycast-target/-/aframe-raycast-target-0.1.0.tgz", - "integrity": "sha512-pMBfTdvKGRTR45seOJoO8fK+FltRoJa87MQ3dVezXOLsA6OIwXeRj0znImYOnd8jXWcB/Wz27Fzq+T0Rt1sWjw==" - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001445", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001445.tgz", - "integrity": "sha512-8sdQIdMztYmzfTMO6KfLny878Ln9c2M0fc7EH60IjlP4Dc4PiCy7K2Vl3ITmWgOyPgVQKa5x+UP/KqFsxj4mBg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", - "dev": true - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/punycode": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", - "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", - "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.75.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", - "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", - "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.0.1", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.1", - "colorette": "^2.0.14", - "commander": "^9.4.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - } - }, "dependencies": { "@discoveryjs/json-ext": { "version": "0.5.7", @@ -1594,22 +247,19 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/info": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/serve": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", - "dev": true, - "requires": {} + "dev": true }, "@xtuc/ieee754": { "version": "1.2.0", @@ -1633,8 +283,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", - "dev": true, - "requires": {} + "dev": true }, "aframe-cursor-tracker": { "version": "0.1.0", @@ -1651,11 +300,6 @@ "resolved": "https://registry.npmjs.org/aframe-object-parent/-/aframe-object-parent-0.1.0.tgz", "integrity": "sha512-5Pf8eMDT63IL9DskQjZ4l8E+/KFugxCFFZsriMDZeZ6yg0PgBDgxe1U0As+IhZ7VH+3HT7Ujnl70hvwHrF5vJg==" }, - "aframe-raycast-target": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/aframe-raycast-target/-/aframe-raycast-target-0.1.0.tgz", - "integrity": "sha512-pMBfTdvKGRTR45seOJoO8fK+FltRoJa87MQ3dVezXOLsA6OIwXeRj0znImYOnd8jXWcB/Wz27Fzq+T0Rt1sWjw==" - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1672,8 +316,7 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} + "dev": true }, "browserslist": { "version": "4.21.4", diff --git a/components/mouse-manipulation/package.json b/components/mouse-manipulation/package.json index 66619f3..49e90c5 100644 --- a/components/mouse-manipulation/package.json +++ b/components/mouse-manipulation/package.json @@ -1,6 +1,6 @@ { "name": "aframe-mouse-manipulation", - "version": "0.2.1", + "version": "0.3.0", "description": "Enables the user to move objects in 3D space using a mouse on desktop.", "main": "index.js", "scripts": {