@zeainc/zea-ux
Version:
1 lines • 137 kB
JavaScript
import{ZeaMouseEvent as e,ZeaTouchEvent as t,XRControllerEvent as i,Ray as a,TreeItem as s,ColorParameter as n,Color as o,XRPoseEvent as r,EventEmitter as l,Registry as h,Parameter as c,Material as d,MaterialColorParam as m,NumberParameter as g,GLShader as u,Xfo as p,Operator as f,Cylinder as v,Cone as P,GeomItem as I,Torus as w,MathFunctions as C,Cuboid as b,Vec3 as y,EulerAngles as x,NumberOperatorInput as S,XfoOperatorOutput as X,XfoOperatorInput as M,KinematicGroup as T,SelectionSet as A,MultiChoiceParameter as D,BaseItem as R,BaseTool as O,Rect as k,ScreenSpaceMaterial as V,Vec2 as _,Lines as E,LinesMaterial as G,VRViewport as z,FlatSurfaceMaterial as B,Plane as U,DataImage as N,Quat as F,CADAsset as H,LinesSphere as L,Circle as J,Cross as K,FatLinesMaterial as Z,SimpleSurfaceMaterial as j,Sphere as W,XfoParameter as Y,Label as $,BillboardItem as q,BillboardAlignment as Q,CADBody as ee,CompoundGeom as te,LinesCuboid as ie,Scene as ae,GLRenderer as se,CameraManipulator as ne,libsRegistry as oe}from"@zeainc/zea-engine";var re={name:"@zeainc/zea-ux",version:"4.9.0",description:"Zea UX",homepage:"https://github.com/ZeaInc/zea-ux#readme",author:"Zea Inc.",license:"MIT",repository:{type:"git",url:"git+ssh://git@github.com/ZeaInc/zea-ux.git"},bugs:{url:"https://github.com/ZeaInc/zea-ux/issues"},main:"dist/index.cjs.js",module:"dist/index.esm.js",browser:"dist/index.umd.js",umd:"dist/index.umd.js",exports:{".":{import:"./dist/index.esm.js",require:"./dist/index.cjs.js",types:"./dist/zea-ux.d.ts"}},types:"dist/zea-ux.d.ts",files:["dist/"],keywords:["Zea","UX"],scripts:{"build:tsc":"npx tsc","build:tsc:watch":"npx tsc --watch","clean:build":"rm -Rf dist/ buildcache","build:rollup":"rollup -c","build:rollup:watch":"rollup -w -c",build:"npm-run-all clean:build build:rollup",dev:"npm-run-all --parallel build:rollup:watch start:watch",start:"es-dev-server --app-index testing-e2e/index.html --open","start:watch":"es-dev-server --app-index testing-e2e/index.html --open --watch",release:"standard-version",dist:"yarn publish --access=public",docs:"adg --config adg.config.json","docs-w":"adg -w --config=adg.config.json","docs:serve":"docsify serve docs/",lint:"eslint src/",prepare:"yarn run build",test:"jest",generate:"plop","test:coverage":"jest --coverage","test:debug":"node --inspect ./node_modules/jest/bin/jest.js --runInBand --watch","test:watch":"jest --watch","test:e2e":"percy exec cypress run --browser chrome --headless","test:e2e:watch":"percy exec cypress open","to-cleanup":"rm -Rf dist/ node_modules/ yarn.lock","to-link-packages":"yarn link @zeainc/zea-engine"},devDependencies:{"@babel/preset-env":"^7.12.7","@percy/cypress":"^2.3.1","@rollup/plugin-commonjs":"^21.0.1","@rollup/plugin-json":"^4.1.0","@rollup/plugin-node-resolve":"^13.0.6","@rollup/plugin-terser":"0.4.4","@rollup/plugin-typescript":"^12.1.1","@zeainc/zea-collab":"^6.3.4","@zeainc/zea-engine":"4.17.0",canvas:"^2.6.1",copyfiles:"^2.4.1",cypress:"^5.6.0","docsify-cli":"^4.4.2",documentation:"^13.1.0","es-dev-server":"^1.60.1",eslint:"^7.14.0","eslint-config-google":"^0.14.0","eslint-config-prettier":"^6.15.0","eslint-plugin-prettier":"^3.2.0",husky:"^4.3.0","husky-run":"^0.0.0",jest:"^26.6.3","npm-run-all":"^4.1.5",plop:"^2.7.4",prettier:"^2.2.1",rollup:"^2.34.1","rollup-plugin-dts":"^4.2.3","standard-version":"^9.0.0","ts-node":"^10.4.0",tslib:"^2.3.1",typedoc:"^0.23.21","typedoc-plugin-markdown":"^3.13.6",typescript:"^5.6.3"},dependencies:{"dom-to-image":"^2.6.0",global:"^4.4.0","license-checker":"^25.0.1"},husky:{hooks:{"disabled=pre-commit":"npm test","disabled=pre-push":"npm test"}}};function le(s){return s instanceof e||t?s.pointerRay:s instanceof i?s.controller.pointerRay:(console.warn("unhandled pointer event"),new a)}class he extends s{gizmoRay;activeController;captured=!1;colorParam=new n("Color",new o);highlightColorParam=new n("HighlightColor",new o(1,1,1));grabPos;holdPos;holdDist;value;delta;releasePos;constructor(e){super(e),this.addParameter(this.colorParam),this.addParameter(this.highlightColorParam)}highlight(){this.emit("highlight")}unhighlight(){this.emit("unhighlight")}getManipulationPlane(){const e=this.globalXfoParam.value;return new a(e.tr,e.ori.getZaxis())}onPointerEnter(e){this.highlight()}onPointerLeave(e){this.unhighlight()}onPointerDown(a){a.setCapture(this),a.stopPropagation(),this.captured=!0,a instanceof t&&this.highlight(),a instanceof e||a instanceof t?this.handlePointerDown(a):a instanceof i&&this.onXRControllerButtonDown(a)}onPointerMove(i){this.captured&&(i.stopPropagation(),i instanceof e||i instanceof t?this.handlePointerMove(i):i instanceof r&&this.onXRPoseChanged(i)),i.preventDefault()}onPointerUp(a){a.stopPropagation(),this.captured&&(a.releaseCapture(),this.captured=!1,a instanceof t&&this.unhighlight(),a instanceof e||a instanceof t?this.handlePointerUp(a):a instanceof i&&this.onVRControllerButtonUp(a))}onPointerClick(e){e.stopPropagation()}onPointerDoubleClick(e){e.stopPropagation()}onWheel(e){}handlePointerDown(e){this.gizmoRay=this.getManipulationPlane();const t=le(e),i=t.intersectRayPlane(this.gizmoRay);this.grabPos=t.pointAtDist(i),this.onDragStart(e)}handlePointerMove(e){const t=le(e),i=t.intersectRayPlane(this.gizmoRay);this.holdPos=t.pointAtDist(i),this.onDrag(e)}handlePointerUp(e){const t=e.pointerRay;if(t){const e=t.intersectRayPlane(this.gizmoRay);this.releasePos=t.pointAtDist(e)}this.onDragEnd(e)}onXRControllerButtonDown(e){this.activeController=e.controller;const t=this.activeController.getTipXfo().clone(),i=this.getManipulationPlane(),a=t.tr.subtract(i.start),s=t.tr.subtract(i.dir.scale(a.dot(i.dir)));this.grabPos=s,this.onDragStart(e)}onXRPoseChanged(e){if(this.activeController){const t=this.activeController.getTipXfo(),i=this.getManipulationPlane(),a=t.tr.subtract(i.start),s=t.tr.subtract(i.dir.scale(a.dot(i.dir)));this.holdPos=s,this.onDrag(e)}}onVRControllerButtonUp(e){this.activeController==e.controller&&(this.activeController.getTipXfo(),this.onDragEnd(e),this.activeController=void 0)}onDragStart(e){console.warn("@Handle#onDragStart - Implement me!",e)}onDrag(e){console.warn("@Handle#onDrag - Implement me!",e)}onDragEnd(e){console.warn("@Handle#onDragEnd - Implement me!",e)}setTargetParam(e){console.warn("setTargetParam not implemented")}}class ce extends he{grabDist;constructor(e){super(e)}handlePointerDown(e){this.gizmoRay=this.getManipulationPlane();const t=le(e).intersectRayVector(this.gizmoRay);this.grabDist=Array.isArray(t)?t[1]:t;const i=this.gizmoRay.pointAtDist(this.grabDist);this.grabPos=i,this.onDragStart(e)}handlePointerMove(e){const t=le(e).intersectRayVector(this.gizmoRay),i=Array.isArray(t)?t[1]:t;this.holdPos=this.gizmoRay.pointAtDist(i),this.holdDist=i,this.value=i,this.delta=i-this.grabDist,this.onDrag(e)}handlePointerUp(e){const t=le(e);if(t){const e=t.intersectRayVector(this.gizmoRay),i=Array.isArray(e)?e[1]:e,a=this.gizmoRay.pointAtDist(i);this.releasePos=a}this.onDragEnd(e)}onXRControllerButtonDown(e){this.gizmoRay=this.getManipulationPlane(),this.activeController=e.controller;const t=this.activeController.getTipXfo();this.grabDist=t.tr.subtract(this.gizmoRay.start).dot(this.gizmoRay.dir),this.grabPos=this.gizmoRay.start.add(this.gizmoRay.dir.scale(this.grabDist)),this.onDragStart(e)}onXRPoseChanged(e){const t=this.activeController.getTipXfo().tr.subtract(this.gizmoRay.start).dot(this.gizmoRay.dir);this.holdPos=this.gizmoRay.start.add(this.gizmoRay.dir.scale(t)),this.value=t,this.delta=t-this.grabDist,this.onDrag(e)}onVRControllerButtonUp(e){this.activeController==e.controller&&(this.onDragEnd(),this.activeController=void 0)}}const de=e=>{e.undo();for(let t=e.secondaryChanges.length-1;t>=0;t--)de(e.secondaryChanges[t])},me=e=>{e.redo();for(let t=0;t<e.secondaryChanges.length;t++)me(e.secondaryChanges[t])};class ge extends l{__undoStack=[];__redoStack=[];__currChange=null;constructor(){super(),this.currChangeUpdated=this.currChangeUpdated.bind(this)}flush(){for(const e of this.__undoStack)e.destroy();this.__undoStack=[];for(const e of this.__redoStack)e.destroy();this.__redoStack=[],this.__currChange&&(this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null)}addChange(e){this.__currChange&&this.__currChange.off&&this.__currChange.off("updated",this.currChangeUpdated),this.__undoStack.push(e),this.__currChange=e,this.__currChange.on&&this.__currChange.on("updated",this.currChangeUpdated);for(const e of this.__redoStack)e.destroy();this.__redoStack=[],this.emit("changeAdded",{change:e})}getCurrentChange(){return this.__currChange}currChangeUpdated(e){this.emit("changeUpdated",e)}undo(e=!0){if(this.__undoStack.length>0){this.__currChange&&(this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null);const t=this.__undoStack.pop();de(t),e&&(this.__redoStack.push(t),this.emit("changeUndone",{change:t}))}}cancel(){if(this.__currChange){this.__currChange.off("updated",this.currChangeUpdated),this.__currChange=null;const e=this.__undoStack.pop();de(e)}}redo(){if(this.__redoStack.length>0){const e=this.__redoStack.pop();me(e),this.__undoStack.push(e),this.emit("changeRedone",{change:e})}}constructChange(e){return h.constructClass(e)}static isChangeClassRegistered(e){try{h.getClassName(Object.getPrototypeOf(e).constructor);return!0}catch(e){return!1}}static getChangeClassName(e){return h.getClassName(Object.getPrototypeOf(e).constructor)}static registerChange(e,t){h.register(e,t)}static getInstance(){return ue||(ue=new ge),ue}}let ue;class pe extends l{name;secondaryChanges=[];suppressPrimaryChange=!1;closed=!1;constructor(e){super(),this.name=e||ge.getChangeClassName(this)}addSecondaryChange(e){const t=this.secondaryChanges.length;return this.secondaryChanges.push(e),e.setPrimaryChange(this),t}setPrimaryChange(e){}undo(){}redo(){}update(e){throw new Error("Implement me")}toJSON(e){return{name:this.name,className:this.getClassName(),secondaryChanges:this.secondaryChanges.map((t=>t.toJSON(e)))}}fromJSON(e,t){this.name=e.name,e.secondaryChanges.forEach((e=>{const i=ge.getInstance().constructChange(e.className);i.fromJSON(e,t),this.addSecondaryChange(i)}))}destroy(){}}ge.registerChange("Change",pe);class fe extends pe{param;nextValue;prevValue;supressed=!1;constructor(e,t){super(e?e.getName()+" Changed":"ParameterValueChange"),e&&(this.prevValue=e.value,this.param=e,null!=t&&(this.nextValue=t,this.param.value=this.nextValue))}undo(){this.param&&!this.suppressPrimaryChange&&(this.param.value=this.prevValue)}redo(){this.param&&!this.suppressPrimaryChange&&(this.param.value=this.nextValue)}update(e){this.param&&(this.nextValue=e.value,this.supressed||(this.param.value=this.nextValue),this.emit("updated",e))}toJSON(e){const t=super.toJSON(e);return t.paramPath=this.param.getPath(),null!=this.nextValue&&(this.nextValue.toJSON?t.value=this.nextValue.toJSON():t.value=this.nextValue),t}fromJSON(e,t){super.fromJSON(e,t);const i=t.appData.scene.getRoot().resolvePath(e.paramPath,1);i&&i instanceof c?(this.param=i,this.prevValue=this.param.value,this.prevValue.clone?this.nextValue=this.prevValue.clone():this.nextValue=this.prevValue,null!=e.value&&(this.nextValue.fromJSON?this.nextValue.fromJSON(e.value):this.nextValue=e.value),this.supressed||(this.param.value=this.nextValue)):console.warn("resolvePath is unable to resolve",e.paramPath)}}ge.registerChange("ParameterValueChange",fe);class ve extends d{baseColorParam=new m("BaseColor",new o(1,1,.5));maintainScreenSizeParam=new g("MaintainScreenSize",0);overlayParam=new g("Overlay",0,[0,1]);constructor(e){super(e),this.__shaderName="HandleShader",this.addParameter(this.baseColorParam),this.addParameter(this.maintainScreenSizeParam),this.addParameter(this.overlayParam)}}h.register("HandleMaterial",ve);const Pe=new ve("HandleShader_template");h.register("HandleShader",class extends u{constructor(e){super(e),this.setShaderStage("VERTEX_SHADER",'\nprecision highp float;\n\nattribute vec3 positions;\n#ifdef ENABLE_TEXTURES\nattribute vec2 texCoords;\n#endif\n\n<%include file="GLSLUtils.glsl"/>\n<%include file="stack-gl/transpose.glsl"/>\n<%include file="drawItemId.glsl"/>\n<%include file="drawItemTexture.glsl"/>\n<%include file="modelMatrix.glsl"/>\n<%include file="materialparams.glsl"/>\n\nuniform mat4 viewMatrix;\nuniform mat4 projectionMatrix;\nuniform lowp int isOrthographic;\nuniform vec4 viewportFrustum;\n\n\n/* VS Outputs */\nvarying float v_drawItemId;\nvarying vec4 v_geomItemData;\nvarying vec3 v_viewPos;\n#ifdef ENABLE_TEXTURES\nvarying vec2 v_textureCoord;\n#endif\n\nvoid main(void) {\n int drawItemId = getDrawItemId();\n v_drawItemId = float(drawItemId);\n v_geomItemData = getInstanceData(drawItemId);\n\n //////////////////////////////////////////////\n // Material\n vec2 materialCoords = v_geomItemData.zw;\n vec4 materialValue1 = getMaterialValue(materialCoords, 1);\n int maintainScreenSize = int(materialValue1.x + 0.5);\n float overlay = materialValue1.y;\n\n //////////////////////////////////////////////\n // Matrix\n \n mat4 modelMatrix = getModelMatrix(drawItemId);\n if (maintainScreenSize != 0) {\n // Remove the scale from the model matrix.\n vec3 row0 = normalize(vec3(modelMatrix[0][0], modelMatrix[0][1], modelMatrix[0][2]));\n vec3 row1 = normalize(vec3(modelMatrix[1][0], modelMatrix[1][1], modelMatrix[1][2]));\n vec3 row2 = normalize(vec3(modelMatrix[2][0], modelMatrix[2][1], modelMatrix[2][2]));\n modelMatrix = mat4(\n row0.x, row0.y, row0.z, 0.0,\n row1.x, row1.y, row1.z, 0.0,\n row2.x, row2.y, row2.z, 0.0,\n modelMatrix[3][0], modelMatrix[3][1], modelMatrix[3][2], 1.0\n );\n }\n mat4 modelViewMatrix = viewMatrix * modelMatrix;\n if (maintainScreenSize != 0) {\n if (isOrthographic > 0){\n // At a distance of 1, we should match the orthographic and perspective sizes.\n // Calculate the size of the handle in perpective projection at 1 meter.\n // With a 24mm camera, the Fov is 46.4 degrees, or 0.8098327729253689 radians.\n // (0.81 / 2.0) * focalDist * 2.0\n // The frustum height at 1m is 0.81.\n float sc = viewportFrustum.y / 0.8098327;\n mat4 scmat = mat4(\n sc, 0.0, 0.0, 0.0,\n 0.0, sc, 0.0, 0.0,\n 0.0, 0.0, sc, 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n modelViewMatrix = modelViewMatrix * scmat;\n } else {\n float dist = modelViewMatrix[3][2];\n float sc = abs(dist); // Note: items in front of the camera will have a negative value here.\n mat4 scmat = mat4(\n sc, 0.0, 0.0, 0.0,\n 0.0, sc, 0.0, 0.0,\n 0.0, 0.0, sc, 0.0,\n 0.0, 0.0, 0.0, 1.0\n );\n modelViewMatrix = modelViewMatrix * scmat;\n }\n }\n\n vec4 viewPos = modelViewMatrix * vec4(positions, 1.0);\n gl_Position = projectionMatrix * viewPos;\n\n if(overlay > 0.0){\n gl_Position.z = mix(gl_Position.z, -gl_Position.w, overlay);\n }\n\n v_viewPos = viewPos.xyz;\n v_textureCoord = texCoords;\n v_textureCoord.y = 1.0 - v_textureCoord.y;// Flip y\n}\n'),this.setShaderStage("FRAGMENT_SHADER",'\nprecision highp float;\n\n<%include file="GLSLUtils.glsl"/>\n<%include file="math/constants.glsl"/>\n<%include file="drawItemTexture.glsl"/>\n<%include file="stack-gl/gamma.glsl"/>\n<%include file="materialparams.glsl"/>\n\n\n#if defined(DRAW_COLOR)\n\nuniform color BaseColor;\n\n#ifdef ENABLE_TEXTURES\nuniform sampler2D BaseColorTex;\nuniform int BaseColorTexType;\n#endif\n\n#elif defined(DRAW_GEOMDATA)\n\nuniform lowp int isOrthographic;\nimport \'surfaceGeomData.glsl\'\n\n#elif defined(DRAW_HIGHLIGHT)\n\n#ifdef ENABLE_FLOAT_TEXTURES\nvec4 getHighlightColor(int id) {\n return fetchTexel(instancesTexture, instancesTextureSize, (id * pixelsPerItem) + 4);\n}\n#else // ENABLE_FLOAT_TEXTURES\n\nuniform vec4 highlightColor;\n\nvec4 getHighlightColor() {\n return highlightColor;\n}\n\n#endif // ENABLE_FLOAT_TEXTURES\n\n#endif // DRAW_HIGHLIGHT\n\n/* VS Outputs */\nvarying float v_drawItemId;\nvarying vec4 v_geomItemData;\nvarying vec3 v_viewPos;\n#ifdef ENABLE_TEXTURES\nvarying vec2 v_textureCoord;\n#endif\n\n\n#ifdef ENABLE_ES3\n out vec4 fragColor;\n#endif\nvoid main(void) {\n#ifndef ENABLE_ES3\n vec4 fragColor;\n#endif\n\n int drawItemId = int(v_drawItemId + 0.5);\n\n //////////////////////////////////////////////\n // Color\n#if defined(DRAW_COLOR)\n\n vec2 materialCoords = v_geomItemData.zw;\n vec4 baseColor = toLinear(getMaterialValue(materialCoords, 0));\n\n fragColor = baseColor;\n\n#ifdef ENABLE_INLINE_GAMMACORRECTION\n fragColor.rgb = toGamma(fragColor.rgb);\n#endif\n\n //////////////////////////////////////////////\n // GeomData\n#elif defined(DRAW_GEOMDATA)\n\n fragColor = setFragColor_geomData(v_viewPos, floatGeomBuffer, passId, v_drawItemId, isOrthographic);\n //////////////////////////////////////////////\n // Highlight\n#elif defined(DRAW_HIGHLIGHT)\n \n fragColor = getHighlightColor(drawItemId);\n\n#endif // DRAW_HIGHLIGHT\n\n\n#ifndef ENABLE_ES3\n gl_FragColor = fragColor;\n#endif\n}\n')}static getPackedMaterialData(e){const t=new Float32Array(8),i=e.getParameter("BaseColor").value;return t[0]=i.r,t[1]=i.g,t[2]=i.b,t[3]=i.a,t[4]=e.getParameter("MaintainScreenSize").value,t[5]=e.getParameter("Overlay").value,t}static isOverlay(){return!0}static getMaterialTemplate(){return Pe}});const Ie=(e,t)=>{e.update();const i=e.positions;for(let e=0;e<i.getCount();e++){const a=i.getValue(e),s=t.transformVec3(a);i.setValue(e,s)}};class we extends pe{supressed=!1;treeItems=[];baseXfo;localXfos=[];prevValues=[];newValues=[];constructor(e,t){if(super("SelectionXfoChange"),!e||!t)return;this.treeItems=e,this.baseXfo=t;const i=t.inverse();this.treeItems.forEach((e=>{this.localXfos.push(i.multiply(e.globalXfoParam.value)),this.prevValues.push(e.globalXfoParam.value),this.newValues.push(e.globalXfoParam.value)}))}setDeltaXfo(e){const t=this.baseXfo.clone();t.tr=e.tr.add(t.tr),t.ori=e.ori.multiply(t.ori),t.sc=e.sc.multiply(t.sc),this.prevValues.forEach(((e,i)=>{const a=t.multiply(this.localXfos[i]);this.newValues[i]=a,this.treeItems[i].globalXfoParam.value=this.newValues[i].clone()})),this.emit("updated",{newValues:[...this.newValues]})}setDone(){this.emit("done")}undo(){this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.prevValues[t]}))}redo(){this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.newValues[t]}))}update(e){this.newValues=e.newValues,this.supressed||this.treeItems.forEach(((e,t)=>{e.globalXfoParam.value=this.newValues[t]})),this.emit("updated",e)}toJSON(e){const t=super.toJSON(e);return t.treeItems=[],t.prevValues=[],t.newValues=[],t.baseXfo=this.baseXfo.toJSON(),t.supressed=this.supressed,this.treeItems.forEach(((e,i)=>{t.treeItems[i]=this.treeItems[i].getPath(),t.prevValues[i]=this.prevValues[i].toJSON(),t.newValues[i]=this.newValues[i].toJSON()})),t}fromJSON(e,t){super.fromJSON(e,t),this.baseXfo||(this.baseXfo=new p),this.baseXfo.fromJSON(e.baseXfo);const i=this.baseXfo.inverse();e.treeItems.forEach(((a,s)=>{this.treeItems[s]=t.appData.scene.getRoot().resolvePath(a),this.localXfos.push(i.multiply(this.treeItems[s].globalXfoParam.value)),this.prevValues[s]||(this.prevValues[s]=new p),this.prevValues[s].fromJSON(e.prevValues[s]),this.newValues[s]||(this.newValues[s]=new p),this.newValues[s].fromJSON(e.newValues[s])}))}}ge.registerChange("SelectionXfoChange",we);class Ce extends pe{__selectionManager;__prevSelection;__newSelection;constructor(e,t,i){super("SelectionChange"),e&&t&&i&&(this.__selectionManager=e,this.__prevSelection=t,this.__newSelection=i)}undo(){this.__selectionManager.setSelection(this.__prevSelection,!1)}redo(){this.__selectionManager.setSelection(this.__newSelection,!1)}toJSON(e){const t=super.toJSON(e),i=[];for(const e of this.__newSelection)i.push(e.getPath());return t.itemPaths=i,t}fromJSON(e,t){super.fromJSON(e,t),this.__selectionManager=t.appData.selectionManager,this.__prevSelection=new Set(this.__selectionManager.getSelection());const i=t.appData.scene.getRoot(),a=new Set;for(const t of e.itemPaths)a.add(i.resolvePath(t,1));this.__newSelection=a,this.__selectionManager.setSelection(this.__newSelection,!1)}}ge.registerChange("SelectionChange",Ce);class be extends pe{selection;state;constructor(e,t){super("Selection Visibility Change"),e&&"boolean"==typeof t&&(this.selection=e,this.state=t,this._changeItemsVisibility(this.state))}undo(){this._changeItemsVisibility(!this.state)}redo(){this._changeItemsVisibility(this.state)}_changeItemsVisibility(e){for(const t of this.selection)t.getParameter("Visible").value=e}}ge.registerChange("ToggleSelectionVisibility",be);class ye extends pe{treeItem;owner;prevSelection;selectionManager;treeItemIndex;constructor(e,t,i){e?(super(e.getName()+" Added"),this.treeItem=e,this.owner=t,this.selectionManager=i,this.prevSelection=new Set(this.selectionManager.getSelection()),this.treeItemIndex=this.owner.getChildIndex(this.owner.addChild(this.treeItem)),this.selectionManager.setSelection(new Set([this.treeItem]),!1)):super()}undo(){if(this.treeItem instanceof f){this.treeItem.detach()}else this.treeItem instanceof s&&this.treeItem.traverse((e=>{if(e instanceof f){e.detach()}}),!1);this.owner.removeChild(this.treeItemIndex),this.selectionManager&&this.selectionManager.setSelection(this.prevSelection,!1)}redo(){if(this.treeItem instanceof f){this.treeItem.reattach()}else this.treeItem instanceof s&&this.treeItem.traverse((e=>{if(e instanceof f){e.reattach()}}),!1);this.owner.addChild(this.treeItem),this.selectionManager&&this.selectionManager.setSelection(new Set([this.treeItem]),!1)}toJSON(e){const t=super.toJSON(e);return t.treeItem=this.treeItem.toJSON(e),t.treeItemPath=this.treeItem.getPath(),t.treeItemIndex=this.treeItemIndex,t}fromJSON(e,t){super.fromJSON(e,t);const i=h.constructClass(e.treeItem.type);i?(this.name=e.name,this.treeItem=i,this.treeItem.fromJSON(e.treeItem,t),this.treeItemIndex=this.owner.getChildIndex(this.owner.addChild(this.treeItem))):console.warn("resolvePath is unable to construct",e.treeItem)}destroy(){}}ge.registerChange("TreeItemAddChange",ye);class xe extends pe{treeItem;oldOwner;oldOwnerIndex;newOwner;constructor(e,t){e?(super(e.getName()+" Moved"),this.treeItem=e,this.oldOwner=this.treeItem.getOwner(),this.oldOwnerIndex=this.oldOwner.getChildIndex(this.treeItem),this.newOwner=t,this.newOwner.addChild(this.treeItem,!0)):super()}undo(){this.oldOwner.insertChild(this.treeItem,this.oldOwnerIndex,!0)}redo(){this.newOwner.addChild(this.treeItem,!0)}toJSON(e){const t=super.toJSON(e);return t.treeItemPath=this.treeItem.getPath(),t.newOwnerPath=this.newOwner.getPath(),t}fromJSON(e,t){if(!t||!t.scene)return;super.fromJSON(e,t);const i=t.scene.getRoot().resolvePath(e.treeItemPath,1);if(!i)return void console.warn("resolvePath is unable to resolve",e.treeItemPath);const a=t.scene.getRoot().resolvePath(e.newOwnerPath,1);a?(this.name=e.name,this.treeItem=i,this.newOwner=a,this.oldOwner=this.treeItem.getOwner(),this.oldOwnerIndex=this.oldOwner.getChildIndex(this.treeItem),this.newOwner.addChild(this.treeItem,!0)):console.warn("resolvePath is unable to resolve",e.newOwnerPath)}}ge.registerChange("TreeItemMoveChange",xe);class Se extends pe{items=[];itemOwners=[];itemPaths=[];itemIndices=[];constructor(e,t){if(super(),e){this.items=e;const i=new Set(t?.selectionManager?.getSelection()),a=[];this.items.forEach((e=>{const t=e.getOwner(),s=t.getChildIndex(e);a.push(e.getName()),this.itemOwners.push(t),this.itemPaths.push(e.getPath()),this.itemIndices.push(s),i.has(e)&&i.delete(e),e.traverse((e=>{i.has(e)&&i.delete(e)}),!1),t.removeChild(s)})),t?.selectionManager&&t.selectionManager.setSelection(i,!0,this),this.name=a+" Deleted"}}undo(){this.items.forEach(((e,t)=>{this.itemOwners[t].insertChild(e,this.itemIndices[t],!1,!1)}))}redo(){this.items.forEach(((e,t)=>{this.itemOwners[t].removeChild(this.itemIndices[t])}))}toJSON(e){const t=super.toJSON(e);return t.itemPaths=this.itemPaths,t.itemIndices=this.itemIndices,t}fromJSON(e,t){super.fromJSON(e,t);const i=t.appData.scene.getRoot();e.itemPaths.forEach((e=>{const t=i.resolvePath(e,1);if(!t)return void console.warn("resolvePath is unable to resolve",e);const a=t.getOwner(),s=a.getChildIndex(t);this.itemOwners.push(a),this.itemPaths.push(t.getPath()),this.itemIndices.push(s),a.removeChild(s)}))}}ge.registerChange("TreeItemsRemoveChange",Se);class Xe extends ce{handleMat;baseXfo;change;param;selectionGroup;constructor(e,t=.1,i=.003,a=new o){super(e),this.colorParam.value=a,this.handleMat=new ve("handle"),this.handleMat.baseColorParam.value=a,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const s=new v(i,t,64);s.baseZAtZeroParam.value=!0;const n=new P(8*i,16*i,64,!0),r=new I("handle",s,this.handleMat),l=new I("tip",n,this.handleMat),h=new p;h.tr.set(0,0,t),Ie(n,h),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(r),this.addChild(l)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){const t=this.getTargetParam();if(this.baseXfo=t.value,this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new we(Array.from(e),this.globalXfoParam.value),ge.getInstance().addChange(this.change)}else this.change=new fe(t),ge.getInstance().addChange(this.change)}onDrag(e){const t=this.holdPos.subtract(this.grabPos);if(this.change instanceof we){const e=new p(t);this.change.setDeltaXfo(e)}else{const e=this.baseXfo.clone();e.tr.addInPlace(t),this.change.update({value:e})}}onDragEnd(e){this.change instanceof we&&this.change.setDone(),this.change=null}}class Me extends he{param;radiusParam;baseXfo;handleXfo;snapIncrementAngle=22.5;enableAngleSnapping=!1;handleToTargetXfo;vec0;change;handleMat;handle;selectionGroup;constructor(e,t,i,a=.5*Math.PI,s=new o(1,1,0)){super(e),this.radiusParam=new g("Radius",t),this.colorParam.value=s,this.addParameter(this.radiusParam),this.handleMat=new ve("handle"),this.handleMat.baseColorParam.value=s,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const n=new w(i,t,64,a);this.handle=new I("handle",n,this.handleMat),this.radiusParam.on("valueChanged",(()=>{t=this.radiusParam.value,n.outerRadiusParam.value=t,n.innerRadiusParam.value=.02*t})),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(this.handle)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){if(this.highlight(),this.baseXfo=this.globalXfoParam.value.clone(),this.vec0=this.grabPos.subtract(this.baseXfo.tr),this.vec0.normalizeInPlace(),this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new we(Array.from(e),this.baseXfo),ge.getInstance().addChange(this.change)}else{const e=this.baseXfo.inverse(),t=this.getTargetParam();this.handleToTargetXfo=e.multiply(t.value),this.change=new fe(t),ge.getInstance().addChange(this.change)}}onDrag(t){const i=this.holdPos.subtract(this.baseXfo.tr);i.normalizeInPlace();let a=this.vec0.angleTo(i);if(this.vec0.cross(i).dot(this.baseXfo.ori.getZaxis())<0&&(a=-a),t instanceof e&&t.shiftKey||this.enableAngleSnapping){const e=C.degToRad(this.snapIncrementAngle);a=Math.floor(a/e)*e}const s=new p;if(s.ori.setFromAxisAndAngle(this.baseXfo.ori.getZaxis(),a),this.change instanceof we)this.change.setDeltaXfo(s);else{const e=this.baseXfo.clone();e.ori=s.ori.multiply(e.ori);const t=e.multiply(this.handleToTargetXfo);this.change.update({value:t})}}onDragEnd(e){this.change instanceof we&&this.change.setDone(),this.change=null}}class Te extends he{param;fullXfoManipulationInVR;grabOffset;baseXfo;change;selectionGroup;constructor(e){super(e),this.fullXfoManipulationInVR=!0}setSelectionGroup(e){this.selectionGroup=e}setTargetParam(e){this.param=e}getTargetParam(){return this.param?this.param:this.globalXfoParam}onDragStart(e){this.grabPos=this.grabPos;const t=this.getTargetParam();if(this.baseXfo=t.value,this.selectionGroup){const e=this.selectionGroup.getItems();this.change=new we(Array.from(e),this.globalXfoParam.value),ge.getInstance().addChange(this.change)}else this.change=new fe(t),ge.getInstance().addChange(this.change)}onDrag(e){const t=this.holdPos.subtract(this.grabPos);if(this.change instanceof we){const e=new p(t);this.change.setDeltaXfo(e)}else{const e=this.baseXfo.clone();e.tr.addInPlace(t),this.change.update({value:e})}}onDragEnd(e){this.change instanceof we&&this.change.setDone(),this.change=null}onXRControllerButtonDown(e){if(this.fullXfoManipulationInVR){this.activeController=e.controller;const t=this.activeController.getTipXfo(),i=this.globalXfoParam.value;this.grabOffset=t.inverse().multiply(i)}else super.onXRControllerButtonDown(e)}onXRPoseChanged(e){if(this.fullXfoManipulationInVR){const e=this.activeController.getTipXfo().multiply(this.grabOffset);if(this.change)this.change.update({value:e});else{this.getTargetParam().value=e}}else super.onXRPoseChanged(e)}onVRControllerButtonUp(e){this.fullXfoManipulationInVR?this.change=null:super.onVRControllerButtonUp(e)}}class Ae extends Te{sizeParam;handle;handleMat;constructor(e,t,i,a=new o){super(e),this.sizeParam=new g("Size",t),this.addParameter(this.sizeParam),this.colorParam.value=a,this.handleMat=new ve("handle"),this.handleMat.baseColorParam.value=a,this.handleMat.maintainScreenSizeParam.value=1,this.handleMat.overlayParam.value=.9;const s=new b(t,t,.02*t),n=new p;n.tr=i,Ie(s,n),this.handle=new I("handle",s,this.handleMat),this.sizeParam.on("valueChanged",(()=>{t=this.sizeParam.value,s.sizeXParam.value=t,s.sizeYParam.value=t,s.sizeZParam.value=.02*t})),this.colorParam.on("valueChanged",(()=>{this.handleMat.baseColorParam.value=this.colorParam.value})),this.addChild(this.handle)}highlight(){super.highlight(),this.handleMat.baseColorParam.value=this.highlightColorParam.value}unhighlight(){super.unhighlight(),this.handleMat.baseColorParam.value=this.colorParam.value}}class De extends s{param;highlightColorParam=new n("HighlightColor",new o(1,1,1));constructor(e=.1,t=.001){super("XfoHandle"),this.highlightColorParam.on("valueChanged",(()=>{const e=this.highlightColorParam.value;this.traverse((t=>{t instanceof he&&(t.highlightColorParam.value=e)}))})),this.addParameter(this.highlightColorParam);const i=new s("Translate");this.addChild(i);const a=new o(1,.1,.1),n=new o("#32CD32"),r=new o("#1E90FF");a.a=1,n.a=1,r.a=1;{const s=new Xe("linearX",e,t,a),n=new p;n.ori.setFromAxisAndAngle(new y(0,1,0),.5*Math.PI),s.localXfoParam.value=n,i.addChild(s)}{const a=new Xe("linearY",e,t,n),s=new p;s.ori.setFromAxisAndAngle(new y(1,0,0),-.5*Math.PI),a.localXfoParam.value=s,i.addChild(a)}{const a=new Xe("linearZ",e,t,r);i.addChild(a)}const l=.25*e;{const e=new Ae("planarXY",l,new y(.85*l,.85*l,0),r),t=new p;e.localXfoParam.value=t,i.addChild(e)}{const e=new Ae("planarYZ",l,new y(-.85*l,.85*l,0),a),t=new p;t.ori.setFromAxisAndAngle(new y(0,1,0),.5*Math.PI),e.localXfoParam.value=t,i.addChild(e)}{const e=new Ae("planarXZ",l,new y(.85*l,.85*l,0),n),t=new p;t.ori.setFromAxisAndAngle(new y(1,0,0),.5*Math.PI),e.localXfoParam.value=t,i.addChild(e)}const h=new s("Rotate");this.addChild(h);{const i=new Me("rotationX",.75*e,t,.5*Math.PI,a),s=new p;s.ori.setFromEulerAngles(new x(-.5*Math.PI,-.5*Math.PI,0)),i.localXfoParam.value=s,h.addChild(i)}{const i=new Me("rotationY",.75*e,t,.5*Math.PI,n),a=new p;a.ori.setFromAxisAndAngle(new y(1,0,0),-.5*Math.PI),i.localXfoParam.value=a,h.addChild(i)}{const i=new Me("rotationZ",.75*e,t,.5*Math.PI,r),a=new p;a.ori.setFromAxisAndAngle(new y(0,0,1),.5*Math.PI),i.localXfoParam.value=a,h.addChild(i)}}showHandles(e){e?this.setVisible(!0):this.setVisible(!1)}setTargetParam(e){this.param=e,this.traverse((t=>{(t instanceof Xe||t instanceof Ae||t instanceof Me)&&t.setTargetParam(e)}))}setSelectionGroup(e){this.traverse((t=>{(t instanceof Xe||t instanceof Ae||t instanceof Me)&&t.setSelectionGroup(e)}))}}class Re extends f{currGroupXfo;xfoModeInput=new S("InitialXfoMode");xfoOutput=new X("GroupGlobalXfo");constructor(e,t){super(),this.addInput(this.xfoModeInput).setParam(e),this.addOutput(this.xfoOutput).setParam(t),this.currGroupXfo=new p}addItem(e){const t=new M("MemberGlobalXfo"+this.getNumInputs());t.setParam(e.globalXfoParam),this.addInput(t),this.setDirty()}removeItem(e){const t=e.globalXfoParam;for(let e=1;e<this.getNumInputs();e++){const i=this.getInputByIndex(e);if(i.getParam()==t)return this.removeInput(i),void this.setDirty()}throw new Error("Item not found in SelectionGroupXfoOperator")}backPropagateValue(e){const t=this.currGroupXfo.inverse(),i=e.multiply(t);i.ori.normalizeInPlace(),this.currGroupXfo=i.multiply(this.currGroupXfo);for(let e=1;e<this.getNumInputs();e++){const t=this.getInputByIndex(e),a=t.getValue(),s=i.multiply(a);t.setValue(s)}}evaluate(){if(this.currGroupXfo=new p,1==this.getNumInputs())return void this.xfoOutput.setClean(this.currGroupXfo);const e=this.xfoModeInput.param.value;if(e!=T.INITIAL_XFO_MODES.manual){if(e==T.INITIAL_XFO_MODES.first){const e=this.getInputByIndex(1).getValue();this.currGroupXfo.tr=e.tr.clone(),this.currGroupXfo.ori=e.ori.clone()}else if(e==T.INITIAL_XFO_MODES.average){this.currGroupXfo.ori.set(0,0,0,0);let e=0;for(let t=1;t<this.getNumInputs();t++){const i=this.getInputByIndex(t).getValue();this.currGroupXfo.tr.addInPlace(i.tr),0==e&&this.currGroupXfo.ori.addInPlace(i.ori),e++}this.currGroupXfo.tr.scaleInPlace(1/e)}else{if(e!=T.INITIAL_XFO_MODES.globalOri)throw new Error("Invalid KinematicGroup.INITIAL_XFO_MODES.");{let e=0;for(let t=1;t<this.getNumInputs();t++){const i=this.getInputByIndex(t).getValue();this.currGroupXfo.tr.addInPlace(i.tr),e++}this.currGroupXfo.tr.scaleInPlace(1/e)}}this.currGroupXfo.ori.normalizeInPlace(),this.xfoOutput.setClean(this.currGroupXfo)}else this.currGroupXfo=this.xfoOutput.getParam().value.clone()}}const Oe={disabled:0,manual:1,first:2,average:3,globalOri:4};class ke extends A{initialXfoModeParam=new D("InitialXfoMode",Oe.average,["manual","first","average","global"]);selectionGroupXfoOp;constructor(e){super();const t=e.selectionOutlineColor?e.selectionOutlineColor:new o(3/255,227/255,172/255,.1);this.highlightColorParam.value=t,this.itemsParam.setFilterFn((e=>e instanceof R)),this.addParameter(this.initialXfoModeParam),this.selectionGroupXfoOp=new Re(this.initialXfoModeParam,this.globalXfoParam)}static get INITIAL_XFO_MODES(){return Oe}clone(e){const t=new ke;return t.copyFrom(this,e),t}bindItem(e,t){const i=this.highlightColorParam.value;i.a=this.highlightFillParam.value,e.addHighlight("selected"+this.getId(),i,!0),this.selectionGroupXfoOp.addItem(e)}unbindItem(e,t){e.removeHighlight("selected"+this.getId(),!0),this.selectionGroupXfoOp.removeItem(e)}}class Ve extends l{appData;leadSelection=void 0;selectionGroup;xfoHandle;xfoHandleVisible;renderer;pickFilter;pickCB;constructor(e,t={}){super(),this.appData=e,this.selectionGroup=new ke(t),!0===t.enableXfoHandles&&(this.xfoHandle=new De,this.xfoHandle.setSelectionGroup(this.selectionGroup),this.xfoHandle.setVisible(!1),this.xfoHandle.highlightColorParam.value=new o(1,1,0),this.xfoHandleVisible=!0,this.selectionGroup.addChild(this.xfoHandle)),this.appData.renderer&&this.setRenderer(this.appData.renderer)}setRenderer(e){this.renderer!=e?(this.renderer=e,this.renderer.addTreeItem(this.selectionGroup)):console.warn("Renderer already set on SelectionManager")}setXfoMode(e){this.xfoHandle&&(this.selectionGroup.initialXfoModeParam.value=e)}showHandles(e){this.xfoHandleVisible=e}updateHandleVisibility(){if(!this.xfoHandle)return;const e=this.selectionGroup.getItems(),t=Array.from(e).length>0;this.xfoHandle.setVisible(t&&this.xfoHandleVisible),this.renderer.requestRedraw()}getSelection(){return this.selectionGroup.getItems()}setSelection(e,t=!0,i){const a=new Set(this.selectionGroup.getItems()),s=new Set(a);for(const t of e)a.has(t)||(t.setSelected(!0),a.add(t));for(const t of a)e.has(t)||(t.setSelected(!1),a.delete(t));if(this.selectionGroup.setItems(a),a.size>0?this.setLeadSelection(a.values().next().value):this.setLeadSelection(),this.updateHandleVisibility(),t){const e=new Ce(this,s,a);i?i.addSecondaryChange(e):ge.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:s,selection:a})}setLeadSelection(e){this.leadSelection!=e&&(this.leadSelection=e,this.emit("leadSelectionChanged",{treeItem:e}))}toggleItemSelection(e,t=!0,i=!0,a){const s=new Set(this.selectionGroup.getItems()),n=new Set(s);if(t&&(1!=s.size||!s.has(e))){let t=!0;if(s.has(e)){let i=1;e.traverse((e=>{s.has(e)&&i++})),t=i!=s.size}t&&(Array.from(s).forEach((e=>{e.setSelected(!1)})),s.clear())}let o;if(s.has(e)?(e.setSelected(!1),s.delete(e),o=!1):(e.setSelected(!0),s.add(e),o=!0),this.selectionGroup.setItems(s),o&&1===s.size?this.setLeadSelection(e):o||(1===s.size?this.setLeadSelection(s.values().next().value):0===s.size&&this.setLeadSelection()),i){const e=new Ce(this,n,s);a?a.addSecondaryChange(e):ge.getInstance().addChange(e)}this.updateHandleVisibility(),this.emit("selectionChanged",{prevSelection:n,selection:s})}clearSelection(e=!0,t){const i=new Set(this.selectionGroup.getItems());if(0==i.size)return;let a;e&&(a=new Set(i));for(const e of i)e.setSelected(!1);if(i.clear(),this.selectionGroup.setItems(i),this.setLeadSelection(),this.updateHandleVisibility(),e){const e=new Ce(this,a,i);t?t.addSecondaryChange(e):ge.getInstance().addChange(e)}this.emit("selectionChanged",{selection:i,prevSelection:a})}selectItems(e,t=!0,i=!0,a){const s=new Set(this.selectionGroup.getItems()),n=new Set(s);t&&s.clear();for(const t of e)s.has(t)||(t.setSelected(!0),s.add(t));if(this.selectionGroup.setItems(s),1===s.size?this.setLeadSelection(s.values().next().value):0===s.size&&this.setLeadSelection(),this.updateHandleVisibility(),i){const e=new Ce(this,n,s);a?a.addSecondaryChange(e):ge.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:n,selection:s})}deselectItems(e,t=!0,i){const a=new Set(this.selectionGroup.getItems()),s=new Set(a);for(const t of e)a.has(t)&&(t.setSelected(!1),a.delete(t));if(this.selectionGroup.setItems(a),1===a.size?this.setLeadSelection(a.values().next().value):0===a.size&&this.setLeadSelection(),this.updateHandleVisibility(),t){const e=new Ce(this,s,a);i?i.addSecondaryChange(e):ge.getInstance().addChange(e)}this.emit("selectionChanged",{prevSelection:s,selection:a})}startPickingMode(e,t){this.pickCB=e,this.pickFilter=t}pickingModeActive(){return!!this.pickCB&&!!this.pickFilter}endPickingMode(){this.pickCB=void 0}pick(e){if(this.pickCB)if(Array.isArray(e))e.forEach((e=>{const t=this.pickFilter?this.pickFilter(e):e;t&&this.pickCB(t)}));else{const t=this.pickFilter?this.pickFilter(e):e;t&&this.pickCB(t)}}}class _e extends O{appData;dragging;selectionManager;selectionRectXfo;rectItem;pointerDownPos;selectionRect;selectionRectMat;selectionFilterFn=null;constructor(e){super(),e||console.error("App data not provided to tool"),this.appData=e,this.dragging=!1,e.selectionManager||console.error("`SelectionTool` requires `SelectionManager` to be provided in the `appData` object"),this.selectionManager=e.selectionManager,this.selectionRect=new k(1,1),this.selectionRectMat=new V("marker"),this.selectionRectMat.baseColorParam.value=new o("#03E3AC"),this.selectionRectXfo=new p,this.selectionRectXfo.sc.set(0,0,0),this.rectItem=new I("selectionRect",this.selectionRect,this.selectionRectMat),this.rectItem.visibleParam.value=!1,this.rectItem.pickableParam.value=!1,this.appData.renderer.addTreeItem(this.rectItem)}activateTool(){super.activateTool()}deactivateTool(){super.deactivateTool(),this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo,this.rectItem.visibleParam.value=!1}setSelectionManager(e){this.selectionManager=e}setSelectionFilter(e){this.selectionFilterFn=e}resizeRect(e,t){const i=e.getWidth(),a=e.getHeight(),s=new _(1/i*2,1/a*2),n=t.multiply(s);this.selectionRectXfo.sc.set(Math.abs(n.x),Math.abs(n.y),1);const o=this.pointerDownPos.subtract(t.scale(.5)).multiply(s).subtract(new _(1,1));this.selectionRectXfo.tr.x=o.x,this.selectionRectXfo.tr.y=-o.y,this.rectItem.globalXfoParam.value=this.selectionRectXfo}onPointerDoublePress(e){}onPointerDown(i){this.dragging?(this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo,this.rectItem.visibleParam.value=!1,this.pointerDownPos=void 0,this.dragging=!1,i.stopPropagation()):(i instanceof t||i instanceof e&&0==i.button)&&(this.pointerDownPos=i.pointerPos.scale(window.devicePixelRatio),this.dragging=!1,i.stopPropagation())}onPointerMove(i){if(i instanceof e||i instanceof t)if(this.pointerDownPos){const e=i.pointerPos.scale(window.devicePixelRatio),t=this.pointerDownPos.subtract(e);t.length()>4&&(this.dragging=!0,this.rectItem.visibleParam.value=!0,this.resizeRect(i.viewport,t)),i.stopPropagation()}else this.selectionManager.pickingModeActive()&&(i.intersectionData?this.selectionManager.pickFilter(i.intersectionData.geomItem):this.selectionManager.pickFilter(null));else console.warn("not handling VR")}onPointerUp(i){if((i instanceof e||i instanceof t)&&this.pointerDownPos){if(this.dragging){this.dragging=!1,this.rectItem.visibleParam.value=!1;const e=i.pointerPos.scale(window.devicePixelRatio),t=new _(Math.min(this.pointerDownPos.x,e.x),Math.min(this.pointerDownPos.y,e.y)),a=new _(Math.max(this.pointerDownPos.x,e.x),Math.max(this.pointerDownPos.y,e.y)),s=i.viewport;let n=Array.from(s.getGeomItemsInRect(t,a));if(n=n.filter((e=>e!=this.rectItem&&!(e.parent instanceof he))),this.selectionFilterFn){const e=[];n.forEach((t=>{const i=this.selectionFilterFn(t);i&&e.push(i)})),n=e}if(!this.selectionManager)throw"Please set the Selection Manager on the Selection Tool before using it.";if(this.selectionManager.pickingModeActive())this.selectionManager.pick(n);else{const e=new Set(n);i.shiftKey?this.selectionManager.deselectItems(e):this.selectionManager.selectItems(e,!i.ctrlKey),this.selectionRectXfo.sc.set(0,0,0),this.rectItem.globalXfoParam.value=this.selectionRectXfo}}else{const e=i.viewport,t=i.pointerPos,a=e.getGeomDataAtPos(t,void 0);if(null==a||a.geomItem.getOwner()instanceof he)this.selectionManager.clearSelection();else{let e=a.geomItem;if(this.selectionFilterFn&&(e=this.selectionFilterFn(e)),e)if(this.selectionManager.pickingModeActive())this.selectionManager.pick(e);else if(i.shiftKey){const t=new Set;t.add(e),this.selectionManager.deselectItems(t)}else this.selectionManager.toggleItemSelection(e,!i.ctrlKey)}}this.pointerDownPos=void 0,i.stopPropagation()}}onXRControllerButtonDown(e){if(1==e.button){if(!this.selectionManager)throw"Please set the Selection Manager on the Selection Tool before using it.";const t=e.controller.getGeomItemAtTip();null==t||t.geomItem.getOwner()instanceof he||(this.selectionManager.toggleItemSelection(t.geomItem),e.stopPropagation())}}}const Ee=new E;Ee.setNumVertices(2),Ee.setNumSegments(1),Ee.setSegmentVertexIndices(0,0,1);const Ge=Ee.getVertexAttribute("positions");Ge.setValue(0,new y(0,0,0)),Ge.setValue(1,new y(0,0,1)),Ee.setBoundingBoxDirty();const ze=new G("line");ze.baseColorParam.value=new o(.2,1,.2);class Be extends O{appData;vrViewport;prevCursor;pointerController;pointerThickness=.002;pointerColor=new o(1,.2,.2);geom;material;defaultRaycastDist=0;raycastDist=20;bindControllerId;pointerGeomItems=[];constructor(e){super(),this.appData=e,this.appData.renderer.getXRViewport().then((e=>{e instanceof z&&(this.vrViewport=e)}))}activateTool(){super.activateTool(),this.displayPointers()}deactivateTool(){super.deactivateTool(),this.removePointers()}displayPointers(){this.appData&&this.appData.renderer&&(this.prevCursor=this.appData.renderer.getGLCanvas().style.cursor,this.appData.renderer.getGLCanvas().style.cursor="crosshair"),this.pointerThickness>0?(!this.geom||this.geom instanceof v)&&(this.geom=new v(this.pointerThickness,1,6,2,!0,!0),this.material=new B("line"),this.material.overlayParam.value=.5):(this.geom=Ee,this.material=new G("line"),this.material.overlayParam.value=.5),this.material.baseColorParam.value=this.pointerColor;const e=e=>{if(this.pointerGeomItems[e.id])return;this.defaultRaycastDist=e.raycastDist,e.raycastDist=this.raycastDist;const t=new I("PointerRay",this.geom,this.material);t.pickableParam.value=!1;const i=new p;i.sc.set(1,1,this.raycastDist/e.getTipXfo().sc.z),t.localXfoParam.value=i,e.tipItem.addChild(t,!1),this.pointerGeomItems[e.id]=t,this.appData.session&&this.appData.session.pub("poseChanged",{interfaceType:"VR",showPointer:{controllerId:e.id,thickness:this.pointerThickness,xfo:i,color:this.pointerColor}})};if(this.pointerController)e(this.pointerController);else if(this.vrViewport){for(const t of this.vrViewport.controllers)e(t);this.bindControllerId=this.vrViewport.on("controllerAdded",(t=>e(t.controller)))}}removePointers(){this.appData&&this.appData.renderer&&(this.appData.renderer.getGLCanvas().style.cursor=this.prevCursor);const e=e=>{this.pointerGeomItems[e.id]&&(e.tipItem.removeChildByHandle(this.pointerGeomItems[e.id]),e.raycastDist=this.defaultRaycastDist,this.pointerGeomItems[e.id]=null)};if(this.pointerController)e(this.pointerController);else if(this.vrViewport){for(const t of this.vrViewport.controllers)e(t);this.vrViewport.removeListenerById("controllerAdded",this.bindControllerId)}}setPointerLength(e,t){const i=this.pointerGeomItems[t.id];if(i){const a=i.localXfoParam.value;a.sc.set(1,1,e/t.getTipXfo().sc.z),i.localXfoParam.value=a,this.appData.session&&this.appData.session.pub("poseChanged",{interfaceType:"VR",updatePointer:{controllerId:t.id,xfo:a}})}}checkPointerIntersection(e){const t=e.getGeomItemAtTip();t?this.setPointerLength(t.dist,e):this.setPointerLength(this.raycastDist,e)}onPointerMove(e){e instanceof r&&(this.pointerController?this.checkPointerIntersection(this.pointerController):e.controllers.forEach((e=>{this.pointerGeomItems[e.id]&&this.checkPointerIntersection(e)})),e.stopPropagation())}}const Ue=function(){return{escape:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},parseExtension:e,mimeType:function(t){const i=e(t).toLowerCase();return function(){const e="application/font-woff",t="image/jpeg";return{woff:e,woff2:e,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:t,jpeg:t,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}()[i]||""},dataAsUrl:function(e,t){return"data:"+t+";base64,"+e},isDataUrl:function(e){return-1!==e.search(/^(data:)/)},canvasToBlob:function(e){return e.toBlob?new Promise((function(t){e.toBlob(t)})):function(e){return new Promise((function(t){const i=window.atob(e.toDataURL().split(",")[1]),a=i.length,s=new Uint8Array(a);for(let e=0;e<a;e++)s[e]=i.charCodeAt(e);t(new Blob([s],{type:"image/png"}))}))}(e)},resolveUrl:function(e,t){const i=document.implementation.createHTMLDocument(),a=i.createElement("base");i.head.appendChild(a);const s=i.createElement("a");return i.body.appendChild(s),a.href=t,s.href=e,s.href},getAndEncode:function(e){const t=3e4;Je.impl.options.cacheBust&&(e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());return new Promise((function(i){const a=new XMLHttpRequest;let s;if(a.onreadystatechange=n,a.ontimeout=o,a.responseType="blob",a.timeout=t,a.open("GET",e,!0),a.send(),Je.impl.options.imagePlaceholder){const e=Je.impl.options.imagePlaceholder.split(/,/);e&&e[1]&&(s=e[1])}function n(){if(4!==a.readyState)return;if(200!==a.status)return void(s?i(s):r("cannot fetch resource: "+e+", status: "+a.status));const t=new FileReader;t.onloadend=function(){if("string"==typeof t.result){const e=t.result.split(/,/)[1];i(e)}else console.warn("encoder.result is not of string type")},t.readAsDataURL(a.response)}function o(){s?i(s):r("timeout of "+t+"ms occured while fetching resource: "+e)}function r(e){console.error(e),i("")}}))},uid:function(){let e=0;return function(){return"u"+t()+e++;function t(){return("0000"+(Math.random()*Math.pow(36,4)|0).toString(36)).slice(-4)}}}(),delay:function(e){return function(t){return new Promise((function(i){setTimeout((function(){i(t)}),e)}))}},asArray:function(e){const t=[],i=e.length;for(let a=0;a<i;a++)t.push(e[a]);return t},escapeXhtml:function(e){return e.replace(/#/g,"%23").replace(/\n/g,"%0A")},makeImage:function(e){return new Promise((function(t,i){const a=new Image;a.onload=function(){t(a)},a.onerror=i,a.src=e}))},width:function(e){const i=t(e,"border-left-width"),a=t(e,"border-right-width");return e.scrollWidth+i+a},height:function(e){const i=t(e,"border-top-width"),a=t(e,"border-bottom-width");return e.scrollHeight+i+a}};function e(e){const t=/\.([^\.\/]*?)$/g.exec(e);return t?t[1]:""}function t(e,t){const i=window.getComputedStyle(e).getPropertyValue(t);return parseFloat(i.replace("px",""))}}(),Ne=function(){const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:function(e,s,n){return o()?Promise.resolve(e):Promise.resolve(e).then(i).then((function(t){let i=Promise.resolve(e);return t.forEach((function(e){i=i.then((function(t){return a(t,e,s,n)}))})),i}));function o(){return!t(e)}},shouldProcess:t,impl:{readUrls:i,inline:a}};function t(t){return-1!==t.search(e)}function i(t){const i=[];let a;for(;null!==(a=e.exec(t));)i.push(a[1]);return i.filter((function(e){return!Ue.isDataUrl(e)}))}function a(e,t,i,a){return Promise.resolve(t).then((function(e){return i?Ue.resolveUrl(e,i):e})).then(a||Ue.getAndEncode).then((function(e){return Ue.dataAsUrl(e,Ue.mimeType(t))})).then((function(i){return e.replace(function(e){return new RegExp("(url\\(['\"]?)("+Ue.escape(e)+")(['\"]?\\))","g")}(t),"$1"+i+"$3")}))}}(),Fe=function(){return{