a0f94dffc1f385c8685ff00f60d5eb819f5b008a40e081e834fd46c32a5aec94.json 120 KB

1
  1. {"ast":null,"code":"import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager.js\";\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder.js\";\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.js\";\nimport { Ray } from \"../../Culling/ray.js\";\nimport { PickingInfo } from \"../../Collisions/pickingInfo.js\";\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature.js\";\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer.js\";\nimport { BoundingSphere } from \"../../Culling/boundingSphere.js\";\nimport { StandardMaterial } from \"../../Materials/standardMaterial.js\";\nimport { Color3 } from \"../../Maths/math.color.js\";\nimport { NodeMaterial } from \"../../Materials/Node/nodeMaterial.js\";\nimport { Animation } from \"../../Animations/animation.js\";\nimport { QuadraticEase, EasingFunction } from \"../../Animations/easing.js\";\n// side effects\nimport \"../../Meshes/subMesh.project.js\";\nimport { Logger } from \"../../Misc/logger.js\";\n// Tracks the interaction animation state when using a motion controller with a near interaction orb\nvar ControllerOrbAnimationState;\n(function (ControllerOrbAnimationState) {\n /**\n * Orb is invisible\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"DEHYDRATED\"] = 0] = \"DEHYDRATED\";\n /**\n * Orb is visible and inside the hover range\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"HOVER\"] = 1] = \"HOVER\";\n /**\n * Orb is visible and touching a near interaction target\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"TOUCH\"] = 2] = \"TOUCH\";\n})(ControllerOrbAnimationState || (ControllerOrbAnimationState = {}));\n/**\n * Where should the near interaction mesh be attached to when using a motion controller for near interaction\n */\nexport var WebXRNearControllerMode;\n(function (WebXRNearControllerMode) {\n /**\n * Motion controllers will not support near interaction\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"DISABLED\"] = 0] = \"DISABLED\";\n /**\n * The interaction point for motion controllers will be inside of them\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"CENTERED_ON_CONTROLLER\"] = 1] = \"CENTERED_ON_CONTROLLER\";\n /**\n * The interaction point for motion controllers will be in front of the controller\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"CENTERED_IN_FRONT\"] = 2] = \"CENTERED_IN_FRONT\";\n})(WebXRNearControllerMode || (WebXRNearControllerMode = {}));\n/**\n * A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources\n */\nexport class WebXRNearInteraction extends WebXRAbstractFeature {\n /**\n * constructs a new background remover module\n * @param _xrSessionManager the session manager for this module\n * @param _options read-only options to be used in this module\n */\n constructor(_xrSessionManager, _options) {\n super(_xrSessionManager);\n this._options = _options;\n this._tmpRay = new Ray(new Vector3(), new Vector3());\n this._attachController = xrController => {\n if (this._controllers[xrController.uniqueId]) {\n // already attached\n return;\n }\n // get two new meshes\n const {\n touchCollisionMesh,\n touchCollisionMeshFunction,\n hydrateCollisionMeshFunction\n } = this._generateNewTouchPointMesh();\n const selectionMesh = this._generateVisualCue();\n this._controllers[xrController.uniqueId] = {\n xrController,\n meshUnderPointer: null,\n nearInteractionTargetMesh: null,\n pick: null,\n stalePick: null,\n touchCollisionMesh,\n touchCollisionMeshFunction: touchCollisionMeshFunction,\n hydrateCollisionMeshFunction: hydrateCollisionMeshFunction,\n currentAnimationState: ControllerOrbAnimationState.DEHYDRATED,\n grabRay: new Ray(new Vector3(), new Vector3()),\n hoverInteraction: false,\n nearInteraction: false,\n grabInteraction: false,\n downTriggered: false,\n id: WebXRNearInteraction._IdCounter++,\n pickedPointVisualCue: selectionMesh\n };\n this._controllers[xrController.uniqueId]._worldScaleObserver = this._controllers[xrController.uniqueId]._worldScaleObserver || this._xrSessionManager.onWorldScaleFactorChangedObservable.add(values => {\n if (values.newScaleFactor !== values.previousScaleFactor) {\n this._controllers[xrController.uniqueId].touchCollisionMesh.dispose();\n this._controllers[xrController.uniqueId].pickedPointVisualCue.dispose();\n const {\n touchCollisionMesh,\n touchCollisionMeshFunction,\n hydrateCollisionMeshFunction\n } = this._generateNewTouchPointMesh();\n this._controllers[xrController.uniqueId].touchCollisionMesh = touchCollisionMesh;\n this._controllers[xrController.uniqueId].touchCollisionMeshFunction = touchCollisionMeshFunction;\n this._controllers[xrController.uniqueId].hydrateCollisionMeshFunction = hydrateCollisionMeshFunction;\n this._controllers[xrController.uniqueId].pickedPointVisualCue = this._generateVisualCue();\n }\n });\n if (this._attachedController) {\n if (!this._options.enableNearInteractionOnAllControllers && this._options.preferredHandedness && xrController.inputSource.handedness === this._options.preferredHandedness) {\n this._attachedController = xrController.uniqueId;\n }\n } else {\n if (!this._options.enableNearInteractionOnAllControllers) {\n this._attachedController = xrController.uniqueId;\n }\n }\n switch (xrController.inputSource.targetRayMode) {\n case \"tracked-pointer\":\n return this._attachNearInteractionMode(xrController);\n case \"gaze\":\n return null;\n case \"screen\":\n return null;\n }\n };\n this._controllers = {};\n this._farInteractionFeature = null;\n /**\n * default color of the selection ring\n */\n this.selectionMeshDefaultColor = new Color3(0.8, 0.8, 0.8);\n /**\n * This color will be applied to the selection ring when selection is triggered\n */\n this.selectionMeshPickedColor = new Color3(0.3, 0.3, 1.0);\n this._hoverRadius = 0.1;\n this._pickRadius = 0.02;\n this._controllerPickRadius = 0.03; // The radius is slightly larger here to make it easier to manipulate since it's not tied to the hand position\n this._nearGrabLengthScale = 5;\n this._scene = this._xrSessionManager.scene;\n if (this._options.nearInteractionControllerMode === undefined) {\n this._options.nearInteractionControllerMode = 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */;\n }\n if (this._options.farInteractionFeature) {\n this._farInteractionFeature = this._options.farInteractionFeature;\n }\n }\n /**\n * Attach this feature\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n attach() {\n if (!super.attach()) {\n return false;\n }\n this._options.xrInput.controllers.forEach(this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, controller => {\n // REMOVE the controller\n this._detachController(controller.uniqueId);\n });\n this._scene.constantlyUpdateMeshUnderPointer = true;\n return true;\n }\n /**\n * Detach this feature.\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n detach() {\n if (!super.detach()) {\n return false;\n }\n Object.keys(this._controllers).forEach(controllerId => {\n this._detachController(controllerId);\n });\n return true;\n }\n /**\n * Will get the mesh under a specific pointer.\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\n * @param controllerId the controllerId to check\n * @returns The mesh under pointer or null if no mesh is under the pointer\n */\n getMeshUnderPointer(controllerId) {\n if (this._controllers[controllerId]) {\n return this._controllers[controllerId].meshUnderPointer;\n } else {\n return null;\n }\n }\n /**\n * Get the xr controller that correlates to the pointer id in the pointer event\n *\n * @param id the pointer id to search for\n * @returns the controller that correlates to this id or null if not found\n */\n getXRControllerByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].xrController || null;\n }\n }\n return null;\n }\n /**\n * This function sets webXRControllerPointerSelection feature that will be disabled when\n * the hover range is reached for a mesh and will be reattached when not in hover range.\n * This is used to remove the selection rays when moving.\n * @param farInteractionFeature the feature to disable when finger is in hover range for a mesh\n */\n setFarInteractionFeature(farInteractionFeature) {\n this._farInteractionFeature = farInteractionFeature;\n }\n /**\n * Filter used for near interaction pick and hover\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearPickPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearPickable;\n }\n /**\n * Filter used for near interaction grab\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearGrabPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearGrabbable;\n }\n /**\n * Filter used for any near interaction\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearInteractionPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && (mesh.isNearPickable || mesh.isNearGrabbable);\n }\n _controllerAvailablePredicate(mesh, controllerId) {\n let parent = mesh;\n while (parent) {\n if (parent.reservedDataStore && parent.reservedDataStore.nearInteraction && parent.reservedDataStore.nearInteraction.excludedControllerId === controllerId) {\n return false;\n }\n parent = parent.parent;\n }\n return true;\n }\n _handleTransitionAnimation(controllerData, newState) {\n var _controllerData$xrCon;\n if (controllerData.currentAnimationState === newState || this._options.nearInteractionControllerMode !== 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */ || !!((_controllerData$xrCon = controllerData.xrController) !== null && _controllerData$xrCon !== void 0 && _controllerData$xrCon.inputSource.hand)) {\n return;\n }\n // Don't always break to allow for animation fallthrough on rare cases of multi-transitions\n if (newState > controllerData.currentAnimationState) {\n switch (controllerData.currentAnimationState) {\n case ControllerOrbAnimationState.DEHYDRATED:\n {\n controllerData.hydrateCollisionMeshFunction(true);\n if (newState === ControllerOrbAnimationState.HOVER) {\n break;\n }\n }\n // eslint-disable-next-line no-fallthrough\n case ControllerOrbAnimationState.HOVER:\n {\n controllerData.touchCollisionMeshFunction(true);\n if (newState === ControllerOrbAnimationState.TOUCH) {\n break;\n }\n }\n }\n } else {\n switch (controllerData.currentAnimationState) {\n case ControllerOrbAnimationState.TOUCH:\n {\n controllerData.touchCollisionMeshFunction(false);\n if (newState === ControllerOrbAnimationState.HOVER) {\n break;\n }\n }\n // eslint-disable-next-line no-fallthrough\n case ControllerOrbAnimationState.HOVER:\n {\n controllerData.hydrateCollisionMeshFunction(false);\n if (newState === ControllerOrbAnimationState.DEHYDRATED) {\n break;\n }\n }\n }\n }\n controllerData.currentAnimationState = newState;\n }\n _processTouchPoint(id, position, orientation) {\n var _controllerData$xrCon2;\n const controllerData = this._controllers[id];\n // Position and orientation could be temporary values, se we take care of them before calling any functions that use temporary vectors/quaternions\n controllerData.grabRay.origin.copyFrom(position);\n orientation.toEulerAnglesToRef(TmpVectors.Vector3[0]);\n controllerData.grabRay.direction.copyFrom(TmpVectors.Vector3[0]);\n if (this._options.nearInteractionControllerMode === 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */ && !((_controllerData$xrCon2 = controllerData.xrController) !== null && _controllerData$xrCon2 !== void 0 && _controllerData$xrCon2.inputSource.hand)) {\n // offset the touch point in the direction the transform is facing\n controllerData.xrController.getWorldPointerRayToRef(this._tmpRay);\n controllerData.grabRay.origin.addInPlace(this._tmpRay.direction.scale(0.05));\n }\n controllerData.grabRay.length = this._nearGrabLengthScale * this._hoverRadius * this._xrSessionManager.worldScalingFactor;\n controllerData.touchCollisionMesh.position.copyFrom(controllerData.grabRay.origin).scaleInPlace(this._xrSessionManager.worldScalingFactor);\n }\n _onXRFrame(_xrFrame) {\n Object.keys(this._controllers).forEach(id => {\n var _controllerData$xrCon3;\n // only do this for the selected pointer\n const controllerData = this._controllers[id];\n const handData = (_controllerData$xrCon3 = controllerData.xrController) === null || _controllerData$xrCon3 === void 0 ? void 0 : _controllerData$xrCon3.inputSource.hand;\n // If near interaction is not enabled/available for this controller, return early\n if (!this._options.enableNearInteractionOnAllControllers && id !== this._attachedController || !controllerData.xrController || !handData && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad)) {\n controllerData.pick = null;\n return;\n }\n controllerData.hoverInteraction = false;\n controllerData.nearInteraction = false;\n // Every frame check collisions/input\n if (controllerData.xrController) {\n if (handData) {\n const xrIndexTip = handData.get(\"index-finger-tip\");\n if (xrIndexTip) {\n const indexTipPose = _xrFrame.getJointPose(xrIndexTip, this._xrSessionManager.referenceSpace);\n if (indexTipPose && indexTipPose.transform) {\n const axisRHSMultiplier = this._scene.useRightHandedSystem ? 1 : -1;\n TmpVectors.Vector3[0].set(indexTipPose.transform.position.x, indexTipPose.transform.position.y, indexTipPose.transform.position.z * axisRHSMultiplier);\n TmpVectors.Quaternion[0].set(indexTipPose.transform.orientation.x, indexTipPose.transform.orientation.y, indexTipPose.transform.orientation.z * axisRHSMultiplier, indexTipPose.transform.orientation.w * axisRHSMultiplier);\n this._processTouchPoint(id, TmpVectors.Vector3[0], TmpVectors.Quaternion[0]);\n }\n }\n } else if (controllerData.xrController.inputSource.gamepad && this._options.nearInteractionControllerMode !== 0 /* WebXRNearControllerMode.DISABLED */) {\n let controllerPose = controllerData.xrController.pointer;\n if (controllerData.xrController.grip && this._options.nearInteractionControllerMode === 1 /* WebXRNearControllerMode.CENTERED_ON_CONTROLLER */) {\n controllerPose = controllerData.xrController.grip;\n }\n this._processTouchPoint(id, controllerPose.position, controllerPose.rotationQuaternion);\n }\n } else {\n return;\n }\n const accuratePickInfo = (originalScenePick, utilityScenePick) => {\n let pick = null;\n if (!utilityScenePick || !utilityScenePick.hit) {\n // No hit in utility scene\n pick = originalScenePick;\n } else if (!originalScenePick || !originalScenePick.hit) {\n // No hit in original scene\n pick = utilityScenePick;\n } else if (utilityScenePick.distance < originalScenePick.distance) {\n // Hit is closer in utility scene\n pick = utilityScenePick;\n } else {\n // Hit is closer in original scene\n pick = originalScenePick;\n }\n return pick;\n };\n const populateNearInteractionInfo = nearInteractionInfo => {\n let result = new PickingInfo();\n let nearInteractionAtOrigin = false;\n const nearInteraction = nearInteractionInfo && nearInteractionInfo.pickedPoint && nearInteractionInfo.hit;\n if (nearInteractionInfo !== null && nearInteractionInfo !== void 0 && nearInteractionInfo.pickedPoint) {\n nearInteractionAtOrigin = nearInteractionInfo.pickedPoint.x === 0 && nearInteractionInfo.pickedPoint.y === 0 && nearInteractionInfo.pickedPoint.z === 0;\n }\n if (nearInteraction && !nearInteractionAtOrigin) {\n result = nearInteractionInfo;\n }\n return result;\n };\n // Don't perform touch logic while grabbing, to prevent triggering touch interactions while in the middle of a grab interaction\n // Dont update cursor logic either - the cursor should already be visible for the grab to be in range,\n // and in order to maintain its position on the target mesh it is parented for the duration of the grab.\n if (!controllerData.grabInteraction) {\n let pick = null;\n // near interaction hover\n let utilitySceneHoverPick = null;\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\n utilitySceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius * this._xrSessionManager.worldScalingFactor, this._utilityLayerScene, mesh => this._nearInteractionPredicate(mesh));\n }\n const originalSceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius * this._xrSessionManager.worldScalingFactor, this._scene, mesh => this._nearInteractionPredicate(mesh));\n const hoverPickInfo = accuratePickInfo(originalSceneHoverPick, utilitySceneHoverPick);\n if (hoverPickInfo && hoverPickInfo.hit) {\n pick = populateNearInteractionInfo(hoverPickInfo);\n if (pick.hit) {\n controllerData.hoverInteraction = true;\n }\n }\n // near interaction pick\n if (controllerData.hoverInteraction) {\n let utilitySceneNearPick = null;\n const radius = (handData ? this._pickRadius : this._controllerPickRadius) * this._xrSessionManager.worldScalingFactor;\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\n utilitySceneNearPick = this._pickWithSphere(controllerData, radius, this._utilityLayerScene, mesh => this._nearPickPredicate(mesh));\n }\n const originalSceneNearPick = this._pickWithSphere(controllerData, radius, this._scene, mesh => this._nearPickPredicate(mesh));\n const pickInfo = accuratePickInfo(originalSceneNearPick, utilitySceneNearPick);\n const nearPick = populateNearInteractionInfo(pickInfo);\n if (nearPick.hit) {\n // Near pick takes precedence over hover interaction\n pick = nearPick;\n controllerData.nearInteraction = true;\n }\n }\n controllerData.stalePick = controllerData.pick;\n controllerData.pick = pick;\n // Update mesh under pointer\n if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {\n controllerData.meshUnderPointer = controllerData.pick.pickedMesh;\n controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);\n controllerData.pickedPointVisualCue.isVisible = true;\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);\n }\n } else {\n controllerData.meshUnderPointer = null;\n controllerData.pickedPointVisualCue.isVisible = false;\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, false);\n }\n }\n }\n // Update the interaction animation. Only updates if the visible touch mesh is active\n let state = ControllerOrbAnimationState.DEHYDRATED;\n if (controllerData.grabInteraction || controllerData.nearInteraction) {\n state = ControllerOrbAnimationState.TOUCH;\n } else if (controllerData.hoverInteraction) {\n state = ControllerOrbAnimationState.HOVER;\n }\n this._handleTransitionAnimation(controllerData, state);\n });\n }\n get _utilityLayerScene() {\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\n }\n _generateVisualCue() {\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const selectionMesh = CreateSphere(\"nearInteraction\", {\n diameter: 0.0035 * 3 * this._xrSessionManager.worldScalingFactor\n }, sceneToRenderTo);\n selectionMesh.bakeCurrentTransformIntoVertices();\n selectionMesh.isPickable = false;\n selectionMesh.isVisible = false;\n selectionMesh.rotationQuaternion = Quaternion.Identity();\n const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\n targetMat.specularColor = Color3.Black();\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\n targetMat.backFaceCulling = false;\n selectionMesh.material = targetMat;\n return selectionMesh;\n }\n _isControllerReadyForNearInteraction(id) {\n if (this._farInteractionFeature) {\n return this._farInteractionFeature._getPointerSelectionDisabledByPointerId(id);\n }\n return true;\n }\n _attachNearInteractionMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr-near\"\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n if (!this._options.enableNearInteractionOnAllControllers && xrController.uniqueId !== this._attachedController || !controllerData.xrController || !controllerData.xrController.inputSource.hand && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad)) {\n return;\n }\n if (controllerData.pick) {\n controllerData.pick.ray = controllerData.grabRay;\n }\n if (controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n // Near pick pointer event\n if (controllerData.nearInteraction && controllerData.pick && controllerData.pick.hit) {\n if (!controllerData.nearInteractionTargetMesh) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.nearInteractionTargetMesh = controllerData.meshUnderPointer;\n controllerData.downTriggered = true;\n }\n } else if (controllerData.nearInteractionTargetMesh && controllerData.stalePick) {\n this._scene.simulatePointerUp(controllerData.stalePick, pointerEventInit);\n controllerData.downTriggered = false;\n controllerData.nearInteractionTargetMesh = null;\n }\n });\n const grabCheck = pressed => {\n if (this._options.enableNearInteractionOnAllControllers || xrController.uniqueId === this._attachedController && this._isControllerReadyForNearInteraction(controllerData.id)) {\n if (controllerData.pick) {\n controllerData.pick.ray = controllerData.grabRay;\n }\n if (pressed && controllerData.pick && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\n controllerData.grabInteraction = true;\n controllerData.pickedPointVisualCue.isVisible = false;\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = true;\n } else if (!pressed && controllerData.pick && controllerData.grabInteraction) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = false;\n controllerData.grabInteraction = false;\n controllerData.pickedPointVisualCue.isVisible = true;\n }\n } else {\n if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {\n this._attachedController = xrController.uniqueId;\n }\n }\n };\n if (xrController.inputSource.gamepad) {\n const init = motionController => {\n controllerData.squeezeComponent = motionController.getComponent(\"grasp\");\n if (controllerData.squeezeComponent) {\n controllerData.onSqueezeButtonChangedObserver = controllerData.squeezeComponent.onButtonStateChangedObservable.add(component => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n grabCheck(pressed);\n }\n });\n } else {\n controllerData.selectionComponent = motionController.getMainComponent();\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add(component => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n grabCheck(pressed);\n }\n });\n }\n };\n if (xrController.motionController) {\n init(xrController.motionController);\n } else {\n xrController.onMotionControllerInitObservable.add(init);\n }\n } else {\n // use the select and squeeze events\n const selectStartListener = event => {\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id) && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\n controllerData.grabInteraction = true;\n controllerData.pickedPointVisualCue.isVisible = false;\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = true;\n }\n };\n const selectEndListener = event => {\n if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.grabInteraction = false;\n controllerData.pickedPointVisualCue.isVisible = true;\n controllerData.downTriggered = false;\n }\n };\n controllerData.eventListeners = {\n selectend: selectEndListener,\n selectstart: selectStartListener\n };\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\n }\n }\n _detachController(xrControllerUniqueId) {\n const controllerData = this._controllers[xrControllerUniqueId];\n if (!controllerData) {\n return;\n }\n if (controllerData.squeezeComponent) {\n if (controllerData.onSqueezeButtonChangedObserver) {\n controllerData.squeezeComponent.onButtonStateChangedObservable.remove(controllerData.onSqueezeButtonChangedObserver);\n }\n }\n if (controllerData.selectionComponent) {\n if (controllerData.onButtonChangedObserver) {\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\n }\n }\n if (controllerData.onFrameObserver) {\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\n }\n if (controllerData.eventListeners) {\n Object.keys(controllerData.eventListeners).forEach(eventName => {\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName];\n if (func) {\n this._xrSessionManager.session.removeEventListener(eventName, func);\n }\n });\n }\n controllerData.touchCollisionMesh.dispose();\n controllerData.pickedPointVisualCue.dispose();\n this._xrSessionManager.runInXRFrame(() => {\n if (!controllerData.downTriggered) {\n return;\n }\n // Fire a pointerup in case controller was detached before a pointerup event was fired\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr-near\"\n };\n this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);\n });\n // remove world scale observer\n if (controllerData._worldScaleObserver) {\n this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(controllerData._worldScaleObserver);\n }\n // remove from the map\n delete this._controllers[xrControllerUniqueId];\n if (this._attachedController === xrControllerUniqueId) {\n // check for other controllers\n const keys = Object.keys(this._controllers);\n if (keys.length) {\n this._attachedController = keys[0];\n } else {\n this._attachedController = \"\";\n }\n }\n }\n _generateNewTouchPointMesh() {\n const worldScale = this._xrSessionManager.worldScalingFactor;\n // populate information for near hover, pick and pinch\n const meshCreationScene = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const touchCollisionMesh = CreateSphere(\"PickSphere\", {\n diameter: 1 * worldScale\n }, meshCreationScene);\n touchCollisionMesh.isVisible = false;\n // Generate the material for the touch mesh visuals\n if (this._options.motionControllerOrbMaterial) {\n touchCollisionMesh.material = this._options.motionControllerOrbMaterial;\n } else {\n let parsePromise;\n if (this._options.motionControllerTouchMaterialSnippetUrl) {\n parsePromise = NodeMaterial.ParseFromFileAsync(\"motionControllerTouchMaterial\", this._options.motionControllerTouchMaterialSnippetUrl, meshCreationScene);\n } else {\n parsePromise = NodeMaterial.ParseFromSnippetAsync(\"8RUNKL#3\", meshCreationScene);\n }\n parsePromise.then(mat => {\n touchCollisionMesh.material = mat;\n }).catch(err => {\n Logger.Warn(`Error creating touch material in WebXRNearInteraction: ${err}`);\n });\n }\n const easingFunction = new QuadraticEase();\n easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\n // Adjust the visual size based off of the size of the touch collision orb.\n // Having the size perfectly match for hover gives a more accurate tell for when the user will start interacting with the target\n // Sizes for other states are somewhat arbitrary, as they are based on what feels nice during an interaction\n const hoverSizeVec = new Vector3(this._controllerPickRadius, this._controllerPickRadius, this._controllerPickRadius).scaleInPlace(worldScale);\n const touchSize = this._controllerPickRadius * (4 / 3);\n const touchSizeVec = new Vector3(touchSize, touchSize, touchSize).scaleInPlace(worldScale);\n const hydrateTransitionSize = this._controllerPickRadius * (7 / 6);\n const hydrateTransitionSizeVec = new Vector3(hydrateTransitionSize, hydrateTransitionSize, hydrateTransitionSize).scaleInPlace(worldScale);\n const touchHoverTransitionSize = this._controllerPickRadius * (4 / 5);\n const touchHoverTransitionSizeVec = new Vector3(touchHoverTransitionSize, touchHoverTransitionSize, touchHoverTransitionSize).scaleInPlace(worldScale);\n const hoverTouchTransitionSize = this._controllerPickRadius * (3 / 2);\n const hoverTouchTransitionSizeVec = new Vector3(hoverTouchTransitionSize, hoverTouchTransitionSize, hoverTouchTransitionSize).scaleInPlace(worldScale);\n const touchKeys = [{\n frame: 0,\n value: hoverSizeVec\n }, {\n frame: 10,\n value: hoverTouchTransitionSizeVec\n }, {\n frame: 18,\n value: touchSizeVec\n }];\n const releaseKeys = [{\n frame: 0,\n value: touchSizeVec\n }, {\n frame: 10,\n value: touchHoverTransitionSizeVec\n }, {\n frame: 18,\n value: hoverSizeVec\n }];\n const hydrateKeys = [{\n frame: 0,\n value: Vector3.ZeroReadOnly\n }, {\n frame: 12,\n value: hydrateTransitionSizeVec\n }, {\n frame: 15,\n value: hoverSizeVec\n }];\n const dehydrateKeys = [{\n frame: 0,\n value: hoverSizeVec\n }, {\n frame: 10,\n value: Vector3.ZeroReadOnly\n }, {\n frame: 15,\n value: Vector3.ZeroReadOnly\n }];\n const touchAction = new Animation(\"touch\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const releaseAction = new Animation(\"release\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const hydrateAction = new Animation(\"hydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const dehydrateAction = new Animation(\"dehydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n touchAction.setEasingFunction(easingFunction);\n releaseAction.setEasingFunction(easingFunction);\n hydrateAction.setEasingFunction(easingFunction);\n dehydrateAction.setEasingFunction(easingFunction);\n touchAction.setKeys(touchKeys);\n releaseAction.setKeys(releaseKeys);\n hydrateAction.setKeys(hydrateKeys);\n dehydrateAction.setKeys(dehydrateKeys);\n const touchCollisionMeshFunction = isTouch => {\n const action = isTouch ? touchAction : releaseAction;\n meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 18, false, 1);\n };\n const hydrateCollisionMeshFunction = isHydration => {\n const action = isHydration ? hydrateAction : dehydrateAction;\n if (isHydration) {\n touchCollisionMesh.isVisible = true;\n }\n meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 15, false, 1, () => {\n if (!isHydration) {\n touchCollisionMesh.isVisible = false;\n }\n });\n };\n return {\n touchCollisionMesh,\n touchCollisionMeshFunction,\n hydrateCollisionMeshFunction\n };\n }\n _pickWithSphere(controllerData, radius, sceneToUse, predicate) {\n const pickingInfo = new PickingInfo();\n pickingInfo.distance = +Infinity;\n if (controllerData.touchCollisionMesh && controllerData.xrController) {\n const position = controllerData.touchCollisionMesh.position;\n const sphere = BoundingSphere.CreateFromCenterAndRadius(position, radius);\n for (let meshIndex = 0; meshIndex < sceneToUse.meshes.length; meshIndex++) {\n const mesh = sceneToUse.meshes[meshIndex];\n if (!predicate(mesh) || !this._controllerAvailablePredicate(mesh, controllerData.xrController.uniqueId)) {\n continue;\n }\n const result = WebXRNearInteraction.PickMeshWithSphere(mesh, sphere);\n if (result && result.hit && result.distance < pickingInfo.distance) {\n pickingInfo.hit = result.hit;\n pickingInfo.pickedMesh = mesh;\n pickingInfo.pickedPoint = result.pickedPoint;\n pickingInfo.aimTransform = controllerData.xrController.pointer;\n pickingInfo.gripTransform = controllerData.xrController.grip || null;\n pickingInfo.originMesh = controllerData.touchCollisionMesh;\n pickingInfo.distance = result.distance;\n pickingInfo.bu = result.bu;\n pickingInfo.bv = result.bv;\n pickingInfo.faceId = result.faceId;\n pickingInfo.subMeshId = result.subMeshId;\n }\n }\n }\n return pickingInfo;\n }\n /**\n * Picks a mesh with a sphere\n * @param mesh the mesh to pick\n * @param sphere picking sphere in world coordinates\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\n * @returns the picking info\n */\n static PickMeshWithSphere(mesh, sphere, skipBoundingInfo = false) {\n const subMeshes = mesh.subMeshes;\n const pi = new PickingInfo();\n const boundingInfo = mesh.getBoundingInfo();\n if (!mesh._generatePointsArray()) {\n return pi;\n }\n if (!mesh.subMeshes || !boundingInfo) {\n return pi;\n }\n if (!skipBoundingInfo && !BoundingSphere.Intersects(boundingInfo.boundingSphere, sphere)) {\n return pi;\n }\n const result = TmpVectors.Vector3[0];\n const tmpVec = TmpVectors.Vector3[1];\n const tmpRay = new Ray(Vector3.Zero(), Vector3.Zero(), 1);\n let distance = +Infinity;\n let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter, intersectionInfo;\n const center = TmpVectors.Vector3[2];\n const worldToMesh = TmpVectors.Matrix[0];\n worldToMesh.copyFrom(mesh.getWorldMatrix());\n worldToMesh.invert();\n Vector3.TransformCoordinatesToRef(sphere.center, worldToMesh, center);\n for (let index = 0; index < subMeshes.length; index++) {\n const subMesh = subMeshes[index];\n subMesh.projectToRef(center, mesh._positions, mesh.getIndices(), tmpVec);\n Vector3.TransformCoordinatesToRef(tmpVec, mesh.getWorldMatrix(), tmpVec);\n tmp = Vector3.Distance(tmpVec, sphere.center);\n // Check for finger inside of mesh\n tmpDistanceSurfaceToCenter = Vector3.Distance(tmpVec, mesh.getAbsolutePosition());\n tmpDistanceSphereToCenter = Vector3.Distance(sphere.center, mesh.getAbsolutePosition());\n if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {\n tmp = 0;\n tmpVec.copyFrom(sphere.center);\n }\n if (tmp !== -1 && tmp < distance) {\n distance = tmp;\n // ray between the sphere center and the point on the mesh\n Ray.CreateFromToToRef(sphere.center, tmpVec, tmpRay);\n tmpRay.length = distance * 2;\n intersectionInfo = tmpRay.intersectsMesh(mesh);\n result.copyFrom(tmpVec);\n }\n }\n if (distance < sphere.radius) {\n pi.hit = true;\n pi.distance = distance;\n pi.pickedMesh = mesh;\n pi.pickedPoint = result.clone();\n if (intersectionInfo && intersectionInfo.bu !== null && intersectionInfo.bv !== null) {\n pi.faceId = intersectionInfo.faceId;\n pi.subMeshId = intersectionInfo.subMeshId;\n pi.bu = intersectionInfo.bu;\n pi.bv = intersectionInfo.bv;\n }\n }\n return pi;\n }\n}\nWebXRNearInteraction._IdCounter = 200;\n/**\n * The module's name\n */\nWebXRNearInteraction.Name = WebXRFeatureName.NEAR_INTERACTION;\n/**\n * The (Babylon) version of this module.\n * This is an integer representing the implementation version.\n * This number does not correspond to the WebXR specs version\n */\nWebXRNearInteraction.Version = 1;\n//Register the plugin\nWebXRFeaturesManager.AddWebXRFeature(WebXRNearInteraction.Name, (xrSessionManager, options) => {\n return () => new WebXRNearInteraction(xrSessionManager, options);\n}, WebXRNearInteraction.Version, true);","map":{"version":3,"names":["WebXRFeaturesManager","WebXRFeatureName","CreateSphere","Vector3","Quaternion","TmpVectors","Ray","PickingInfo","WebXRAbstractFeature","UtilityLayerRenderer","BoundingSphere","StandardMaterial","Color3","NodeMaterial","Animation","QuadraticEase","EasingFunction","Logger","ControllerOrbAnimationState","WebXRNearControllerMode","WebXRNearInteraction","constructor","_xrSessionManager","_options","_tmpRay","_attachController","xrController","_controllers","uniqueId","touchCollisionMesh","touchCollisionMeshFunction","hydrateCollisionMeshFunction","_generateNewTouchPointMesh","selectionMesh","_generateVisualCue","meshUnderPointer","nearInteractionTargetMesh","pick","stalePick","currentAnimationState","DEHYDRATED","grabRay","hoverInteraction","nearInteraction","grabInteraction","downTriggered","id","_IdCounter","pickedPointVisualCue","_worldScaleObserver","onWorldScaleFactorChangedObservable","add","values","newScaleFactor","previousScaleFactor","dispose","_attachedController","enableNearInteractionOnAllControllers","preferredHandedness","inputSource","handedness","targetRayMode","_attachNearInteractionMode","_farInteractionFeature","selectionMeshDefaultColor","selectionMeshPickedColor","_hoverRadius","_pickRadius","_controllerPickRadius","_nearGrabLengthScale","_scene","scene","nearInteractionControllerMode","undefined","farInteractionFeature","attach","xrInput","controllers","forEach","_addNewAttachObserver","onControllerAddedObservable","onControllerRemovedObservable","controller","_detachController","constantlyUpdateMeshUnderPointer","detach","Object","keys","controllerId","getMeshUnderPointer","getXRControllerByPointerId","i","length","setFarInteractionFeature","_nearPickPredicate","mesh","isEnabled","isVisible","isPickable","isNearPickable","_nearGrabPredicate","isNearGrabbable","_nearInteractionPredicate","_controllerAvailablePredicate","parent","reservedDataStore","excludedControllerId","_handleTransitionAnimation","controllerData","newState","_controllerData$xrCon","hand","HOVER","TOUCH","_processTouchPoint","position","orientation","_controllerData$xrCon2","origin","copyFrom","toEulerAnglesToRef","direction","getWorldPointerRayToRef","addInPlace","scale","worldScalingFactor","scaleInPlace","_onXRFrame","_xrFrame","_controllerData$xrCon3","handData","gamepad","xrIndexTip","get","indexTipPose","getJointPose","referenceSpace","transform","axisRHSMultiplier","useRightHandedSystem","set","x","y","z","w","controllerPose","pointer","grip","rotationQuaternion","accuratePickInfo","originalScenePick","utilityScenePick","hit","distance","populateNearInteractionInfo","nearInteractionInfo","result","nearInteractionAtOrigin","pickedPoint","utilitySceneHoverPick","useUtilityLayer","_utilityLayerScene","_pickWithSphere","originalSceneHoverPick","hoverPickInfo","utilitySceneNearPick","radius","originalSceneNearPick","pickInfo","nearPick","pickedMesh","attached","_setPointerSelectionDisabledByPointerId","state","customUtilityLayerScene","DefaultUtilityLayer","utilityLayerScene","sceneToRenderTo","diameter","bakeCurrentTransformIntoVertices","Identity","targetMat","specularColor","Black","emissiveColor","backFaceCulling","material","_isControllerReadyForNearInteraction","_getPointerSelectionDisabledByPointerId","pointerEventInit","pointerId","pointerType","onFrameObserver","onXRFrameObservable","ray","simulatePointerMove","simulatePointerDown","simulatePointerUp","grabCheck","pressed","disableSwitchOnClick","init","motionController","squeezeComponent","getComponent","onSqueezeButtonChangedObserver","onButtonStateChangedObservable","component","changes","current","selectionComponent","getMainComponent","onButtonChangedObserver","onMotionControllerInitObservable","selectStartListener","event","selectEndListener","eventListeners","selectend","selectstart","session","addEventListener","xrControllerUniqueId","remove","eventName","func","removeEventListener","runInXRFrame","worldScale","meshCreationScene","motionControllerOrbMaterial","parsePromise","motionControllerTouchMaterialSnippetUrl","ParseFromFileAsync","ParseFromSnippetAsync","then","mat","catch","err","Warn","easingFunction","setEasingMode","EASINGMODE_EASEINOUT","hoverSizeVec","touchSize","touchSizeVec","hydrateTransitionSize","hydrateTransitionSizeVec","touchHoverTransitionSize","touchHoverTransitionSizeVec","hoverTouchTransitionSize","hoverTouchTransitionSizeVec","touchKeys","frame","value","releaseKeys","hydrateKeys","ZeroReadOnly","dehydrateKeys","touchAction","ANIMATIONTYPE_VECTOR3","ANIMATIONLOOPMODE_CONSTANT","releaseAction","hydrateAction","dehydrateAction","setEasingFunction","setKeys","isTouch","action","beginDirectAnimation","isHydration","sceneToUse","predicate","pickingInfo","Infinity","sphere","CreateFromCenterAndRadius","meshIndex","meshes","PickMeshWithSphere","aimTransform","gripTransform","originMesh","bu","bv","faceId","subMeshId","skipBoundingInfo","subMeshes","pi","boundingInfo","getBoundingInfo","_generatePointsArray","Intersects","boundingSphere","tmpVec","tmpRay","Zero","tmp","tmpDistanceSphereToCenter","tmpDistanceSurfaceToCenter","intersectionInfo","center","worldToMesh","Matrix","getWorldMatrix","invert","TransformCoordinatesToRef","index","subMesh","projectToRef","_positions","getIndices","Distance","getAbsolutePosition","CreateFromToToRef","intersectsMesh","clone","Name","NEAR_INTERACTION","Version","AddWebXRFeature","xrSessionManager","options"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/XR/features/WebXRNearInteraction.js"],"sourcesContent":["import { WebXRFeaturesManager, WebXRFeatureName } from \"../webXRFeaturesManager.js\";\nimport { CreateSphere } from \"../../Meshes/Builders/sphereBuilder.js\";\nimport { Vector3, Quaternion, TmpVectors } from \"../../Maths/math.vector.js\";\nimport { Ray } from \"../../Culling/ray.js\";\nimport { PickingInfo } from \"../../Collisions/pickingInfo.js\";\nimport { WebXRAbstractFeature } from \"./WebXRAbstractFeature.js\";\nimport { UtilityLayerRenderer } from \"../../Rendering/utilityLayerRenderer.js\";\nimport { BoundingSphere } from \"../../Culling/boundingSphere.js\";\nimport { StandardMaterial } from \"../../Materials/standardMaterial.js\";\nimport { Color3 } from \"../../Maths/math.color.js\";\nimport { NodeMaterial } from \"../../Materials/Node/nodeMaterial.js\";\nimport { Animation } from \"../../Animations/animation.js\";\nimport { QuadraticEase, EasingFunction } from \"../../Animations/easing.js\";\n// side effects\nimport \"../../Meshes/subMesh.project.js\";\nimport { Logger } from \"../../Misc/logger.js\";\n// Tracks the interaction animation state when using a motion controller with a near interaction orb\nvar ControllerOrbAnimationState;\n(function (ControllerOrbAnimationState) {\n /**\n * Orb is invisible\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"DEHYDRATED\"] = 0] = \"DEHYDRATED\";\n /**\n * Orb is visible and inside the hover range\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"HOVER\"] = 1] = \"HOVER\";\n /**\n * Orb is visible and touching a near interaction target\n */\n ControllerOrbAnimationState[ControllerOrbAnimationState[\"TOUCH\"] = 2] = \"TOUCH\";\n})(ControllerOrbAnimationState || (ControllerOrbAnimationState = {}));\n/**\n * Where should the near interaction mesh be attached to when using a motion controller for near interaction\n */\nexport var WebXRNearControllerMode;\n(function (WebXRNearControllerMode) {\n /**\n * Motion controllers will not support near interaction\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"DISABLED\"] = 0] = \"DISABLED\";\n /**\n * The interaction point for motion controllers will be inside of them\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"CENTERED_ON_CONTROLLER\"] = 1] = \"CENTERED_ON_CONTROLLER\";\n /**\n * The interaction point for motion controllers will be in front of the controller\n */\n WebXRNearControllerMode[WebXRNearControllerMode[\"CENTERED_IN_FRONT\"] = 2] = \"CENTERED_IN_FRONT\";\n})(WebXRNearControllerMode || (WebXRNearControllerMode = {}));\n/**\n * A module that will enable near interaction near interaction for hands and motion controllers of XR Input Sources\n */\nexport class WebXRNearInteraction extends WebXRAbstractFeature {\n /**\n * constructs a new background remover module\n * @param _xrSessionManager the session manager for this module\n * @param _options read-only options to be used in this module\n */\n constructor(_xrSessionManager, _options) {\n super(_xrSessionManager);\n this._options = _options;\n this._tmpRay = new Ray(new Vector3(), new Vector3());\n this._attachController = (xrController) => {\n if (this._controllers[xrController.uniqueId]) {\n // already attached\n return;\n }\n // get two new meshes\n const { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction } = this._generateNewTouchPointMesh();\n const selectionMesh = this._generateVisualCue();\n this._controllers[xrController.uniqueId] = {\n xrController,\n meshUnderPointer: null,\n nearInteractionTargetMesh: null,\n pick: null,\n stalePick: null,\n touchCollisionMesh,\n touchCollisionMeshFunction: touchCollisionMeshFunction,\n hydrateCollisionMeshFunction: hydrateCollisionMeshFunction,\n currentAnimationState: ControllerOrbAnimationState.DEHYDRATED,\n grabRay: new Ray(new Vector3(), new Vector3()),\n hoverInteraction: false,\n nearInteraction: false,\n grabInteraction: false,\n downTriggered: false,\n id: WebXRNearInteraction._IdCounter++,\n pickedPointVisualCue: selectionMesh,\n };\n this._controllers[xrController.uniqueId]._worldScaleObserver =\n this._controllers[xrController.uniqueId]._worldScaleObserver ||\n this._xrSessionManager.onWorldScaleFactorChangedObservable.add((values) => {\n if (values.newScaleFactor !== values.previousScaleFactor) {\n this._controllers[xrController.uniqueId].touchCollisionMesh.dispose();\n this._controllers[xrController.uniqueId].pickedPointVisualCue.dispose();\n const { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction } = this._generateNewTouchPointMesh();\n this._controllers[xrController.uniqueId].touchCollisionMesh = touchCollisionMesh;\n this._controllers[xrController.uniqueId].touchCollisionMeshFunction = touchCollisionMeshFunction;\n this._controllers[xrController.uniqueId].hydrateCollisionMeshFunction = hydrateCollisionMeshFunction;\n this._controllers[xrController.uniqueId].pickedPointVisualCue = this._generateVisualCue();\n }\n });\n if (this._attachedController) {\n if (!this._options.enableNearInteractionOnAllControllers &&\n this._options.preferredHandedness &&\n xrController.inputSource.handedness === this._options.preferredHandedness) {\n this._attachedController = xrController.uniqueId;\n }\n }\n else {\n if (!this._options.enableNearInteractionOnAllControllers) {\n this._attachedController = xrController.uniqueId;\n }\n }\n switch (xrController.inputSource.targetRayMode) {\n case \"tracked-pointer\":\n return this._attachNearInteractionMode(xrController);\n case \"gaze\":\n return null;\n case \"screen\":\n return null;\n }\n };\n this._controllers = {};\n this._farInteractionFeature = null;\n /**\n * default color of the selection ring\n */\n this.selectionMeshDefaultColor = new Color3(0.8, 0.8, 0.8);\n /**\n * This color will be applied to the selection ring when selection is triggered\n */\n this.selectionMeshPickedColor = new Color3(0.3, 0.3, 1.0);\n this._hoverRadius = 0.1;\n this._pickRadius = 0.02;\n this._controllerPickRadius = 0.03; // The radius is slightly larger here to make it easier to manipulate since it's not tied to the hand position\n this._nearGrabLengthScale = 5;\n this._scene = this._xrSessionManager.scene;\n if (this._options.nearInteractionControllerMode === undefined) {\n this._options.nearInteractionControllerMode = 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */;\n }\n if (this._options.farInteractionFeature) {\n this._farInteractionFeature = this._options.farInteractionFeature;\n }\n }\n /**\n * Attach this feature\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n attach() {\n if (!super.attach()) {\n return false;\n }\n this._options.xrInput.controllers.forEach(this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);\n this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {\n // REMOVE the controller\n this._detachController(controller.uniqueId);\n });\n this._scene.constantlyUpdateMeshUnderPointer = true;\n return true;\n }\n /**\n * Detach this feature.\n * Will usually be called by the features manager\n *\n * @returns true if successful.\n */\n detach() {\n if (!super.detach()) {\n return false;\n }\n Object.keys(this._controllers).forEach((controllerId) => {\n this._detachController(controllerId);\n });\n return true;\n }\n /**\n * Will get the mesh under a specific pointer.\n * `scene.meshUnderPointer` will only return one mesh - either left or right.\n * @param controllerId the controllerId to check\n * @returns The mesh under pointer or null if no mesh is under the pointer\n */\n getMeshUnderPointer(controllerId) {\n if (this._controllers[controllerId]) {\n return this._controllers[controllerId].meshUnderPointer;\n }\n else {\n return null;\n }\n }\n /**\n * Get the xr controller that correlates to the pointer id in the pointer event\n *\n * @param id the pointer id to search for\n * @returns the controller that correlates to this id or null if not found\n */\n getXRControllerByPointerId(id) {\n const keys = Object.keys(this._controllers);\n for (let i = 0; i < keys.length; ++i) {\n if (this._controllers[keys[i]].id === id) {\n return this._controllers[keys[i]].xrController || null;\n }\n }\n return null;\n }\n /**\n * This function sets webXRControllerPointerSelection feature that will be disabled when\n * the hover range is reached for a mesh and will be reattached when not in hover range.\n * This is used to remove the selection rays when moving.\n * @param farInteractionFeature the feature to disable when finger is in hover range for a mesh\n */\n setFarInteractionFeature(farInteractionFeature) {\n this._farInteractionFeature = farInteractionFeature;\n }\n /**\n * Filter used for near interaction pick and hover\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearPickPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearPickable;\n }\n /**\n * Filter used for near interaction grab\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearGrabPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && mesh.isNearGrabbable;\n }\n /**\n * Filter used for any near interaction\n * @param mesh the mesh candidate to be pick-filtered\n * @returns if the mesh should be included in the list of candidate meshes for near interaction\n */\n _nearInteractionPredicate(mesh) {\n return mesh.isEnabled() && mesh.isVisible && mesh.isPickable && (mesh.isNearPickable || mesh.isNearGrabbable);\n }\n _controllerAvailablePredicate(mesh, controllerId) {\n let parent = mesh;\n while (parent) {\n if (parent.reservedDataStore && parent.reservedDataStore.nearInteraction && parent.reservedDataStore.nearInteraction.excludedControllerId === controllerId) {\n return false;\n }\n parent = parent.parent;\n }\n return true;\n }\n _handleTransitionAnimation(controllerData, newState) {\n if (controllerData.currentAnimationState === newState ||\n this._options.nearInteractionControllerMode !== 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */ ||\n !!controllerData.xrController?.inputSource.hand) {\n return;\n }\n // Don't always break to allow for animation fallthrough on rare cases of multi-transitions\n if (newState > controllerData.currentAnimationState) {\n switch (controllerData.currentAnimationState) {\n case ControllerOrbAnimationState.DEHYDRATED: {\n controllerData.hydrateCollisionMeshFunction(true);\n if (newState === ControllerOrbAnimationState.HOVER) {\n break;\n }\n }\n // eslint-disable-next-line no-fallthrough\n case ControllerOrbAnimationState.HOVER: {\n controllerData.touchCollisionMeshFunction(true);\n if (newState === ControllerOrbAnimationState.TOUCH) {\n break;\n }\n }\n }\n }\n else {\n switch (controllerData.currentAnimationState) {\n case ControllerOrbAnimationState.TOUCH: {\n controllerData.touchCollisionMeshFunction(false);\n if (newState === ControllerOrbAnimationState.HOVER) {\n break;\n }\n }\n // eslint-disable-next-line no-fallthrough\n case ControllerOrbAnimationState.HOVER: {\n controllerData.hydrateCollisionMeshFunction(false);\n if (newState === ControllerOrbAnimationState.DEHYDRATED) {\n break;\n }\n }\n }\n }\n controllerData.currentAnimationState = newState;\n }\n _processTouchPoint(id, position, orientation) {\n const controllerData = this._controllers[id];\n // Position and orientation could be temporary values, se we take care of them before calling any functions that use temporary vectors/quaternions\n controllerData.grabRay.origin.copyFrom(position);\n orientation.toEulerAnglesToRef(TmpVectors.Vector3[0]);\n controllerData.grabRay.direction.copyFrom(TmpVectors.Vector3[0]);\n if (this._options.nearInteractionControllerMode === 2 /* WebXRNearControllerMode.CENTERED_IN_FRONT */ && !controllerData.xrController?.inputSource.hand) {\n // offset the touch point in the direction the transform is facing\n controllerData.xrController.getWorldPointerRayToRef(this._tmpRay);\n controllerData.grabRay.origin.addInPlace(this._tmpRay.direction.scale(0.05));\n }\n controllerData.grabRay.length = this._nearGrabLengthScale * this._hoverRadius * this._xrSessionManager.worldScalingFactor;\n controllerData.touchCollisionMesh.position.copyFrom(controllerData.grabRay.origin).scaleInPlace(this._xrSessionManager.worldScalingFactor);\n }\n _onXRFrame(_xrFrame) {\n Object.keys(this._controllers).forEach((id) => {\n // only do this for the selected pointer\n const controllerData = this._controllers[id];\n const handData = controllerData.xrController?.inputSource.hand;\n // If near interaction is not enabled/available for this controller, return early\n if ((!this._options.enableNearInteractionOnAllControllers && id !== this._attachedController) ||\n !controllerData.xrController ||\n (!handData && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad))) {\n controllerData.pick = null;\n return;\n }\n controllerData.hoverInteraction = false;\n controllerData.nearInteraction = false;\n // Every frame check collisions/input\n if (controllerData.xrController) {\n if (handData) {\n const xrIndexTip = handData.get(\"index-finger-tip\");\n if (xrIndexTip) {\n const indexTipPose = _xrFrame.getJointPose(xrIndexTip, this._xrSessionManager.referenceSpace);\n if (indexTipPose && indexTipPose.transform) {\n const axisRHSMultiplier = this._scene.useRightHandedSystem ? 1 : -1;\n TmpVectors.Vector3[0].set(indexTipPose.transform.position.x, indexTipPose.transform.position.y, indexTipPose.transform.position.z * axisRHSMultiplier);\n TmpVectors.Quaternion[0].set(indexTipPose.transform.orientation.x, indexTipPose.transform.orientation.y, indexTipPose.transform.orientation.z * axisRHSMultiplier, indexTipPose.transform.orientation.w * axisRHSMultiplier);\n this._processTouchPoint(id, TmpVectors.Vector3[0], TmpVectors.Quaternion[0]);\n }\n }\n }\n else if (controllerData.xrController.inputSource.gamepad && this._options.nearInteractionControllerMode !== 0 /* WebXRNearControllerMode.DISABLED */) {\n let controllerPose = controllerData.xrController.pointer;\n if (controllerData.xrController.grip && this._options.nearInteractionControllerMode === 1 /* WebXRNearControllerMode.CENTERED_ON_CONTROLLER */) {\n controllerPose = controllerData.xrController.grip;\n }\n this._processTouchPoint(id, controllerPose.position, controllerPose.rotationQuaternion);\n }\n }\n else {\n return;\n }\n const accuratePickInfo = (originalScenePick, utilityScenePick) => {\n let pick = null;\n if (!utilityScenePick || !utilityScenePick.hit) {\n // No hit in utility scene\n pick = originalScenePick;\n }\n else if (!originalScenePick || !originalScenePick.hit) {\n // No hit in original scene\n pick = utilityScenePick;\n }\n else if (utilityScenePick.distance < originalScenePick.distance) {\n // Hit is closer in utility scene\n pick = utilityScenePick;\n }\n else {\n // Hit is closer in original scene\n pick = originalScenePick;\n }\n return pick;\n };\n const populateNearInteractionInfo = (nearInteractionInfo) => {\n let result = new PickingInfo();\n let nearInteractionAtOrigin = false;\n const nearInteraction = nearInteractionInfo && nearInteractionInfo.pickedPoint && nearInteractionInfo.hit;\n if (nearInteractionInfo?.pickedPoint) {\n nearInteractionAtOrigin = nearInteractionInfo.pickedPoint.x === 0 && nearInteractionInfo.pickedPoint.y === 0 && nearInteractionInfo.pickedPoint.z === 0;\n }\n if (nearInteraction && !nearInteractionAtOrigin) {\n result = nearInteractionInfo;\n }\n return result;\n };\n // Don't perform touch logic while grabbing, to prevent triggering touch interactions while in the middle of a grab interaction\n // Dont update cursor logic either - the cursor should already be visible for the grab to be in range,\n // and in order to maintain its position on the target mesh it is parented for the duration of the grab.\n if (!controllerData.grabInteraction) {\n let pick = null;\n // near interaction hover\n let utilitySceneHoverPick = null;\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\n utilitySceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius * this._xrSessionManager.worldScalingFactor, this._utilityLayerScene, (mesh) => this._nearInteractionPredicate(mesh));\n }\n const originalSceneHoverPick = this._pickWithSphere(controllerData, this._hoverRadius * this._xrSessionManager.worldScalingFactor, this._scene, (mesh) => this._nearInteractionPredicate(mesh));\n const hoverPickInfo = accuratePickInfo(originalSceneHoverPick, utilitySceneHoverPick);\n if (hoverPickInfo && hoverPickInfo.hit) {\n pick = populateNearInteractionInfo(hoverPickInfo);\n if (pick.hit) {\n controllerData.hoverInteraction = true;\n }\n }\n // near interaction pick\n if (controllerData.hoverInteraction) {\n let utilitySceneNearPick = null;\n const radius = (handData ? this._pickRadius : this._controllerPickRadius) * this._xrSessionManager.worldScalingFactor;\n if (this._options.useUtilityLayer && this._utilityLayerScene) {\n utilitySceneNearPick = this._pickWithSphere(controllerData, radius, this._utilityLayerScene, (mesh) => this._nearPickPredicate(mesh));\n }\n const originalSceneNearPick = this._pickWithSphere(controllerData, radius, this._scene, (mesh) => this._nearPickPredicate(mesh));\n const pickInfo = accuratePickInfo(originalSceneNearPick, utilitySceneNearPick);\n const nearPick = populateNearInteractionInfo(pickInfo);\n if (nearPick.hit) {\n // Near pick takes precedence over hover interaction\n pick = nearPick;\n controllerData.nearInteraction = true;\n }\n }\n controllerData.stalePick = controllerData.pick;\n controllerData.pick = pick;\n // Update mesh under pointer\n if (controllerData.pick && controllerData.pick.pickedPoint && controllerData.pick.hit) {\n controllerData.meshUnderPointer = controllerData.pick.pickedMesh;\n controllerData.pickedPointVisualCue.position.copyFrom(controllerData.pick.pickedPoint);\n controllerData.pickedPointVisualCue.isVisible = true;\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, true);\n }\n }\n else {\n controllerData.meshUnderPointer = null;\n controllerData.pickedPointVisualCue.isVisible = false;\n if (this._farInteractionFeature && this._farInteractionFeature.attached) {\n this._farInteractionFeature._setPointerSelectionDisabledByPointerId(controllerData.id, false);\n }\n }\n }\n // Update the interaction animation. Only updates if the visible touch mesh is active\n let state = ControllerOrbAnimationState.DEHYDRATED;\n if (controllerData.grabInteraction || controllerData.nearInteraction) {\n state = ControllerOrbAnimationState.TOUCH;\n }\n else if (controllerData.hoverInteraction) {\n state = ControllerOrbAnimationState.HOVER;\n }\n this._handleTransitionAnimation(controllerData, state);\n });\n }\n get _utilityLayerScene() {\n return this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene;\n }\n _generateVisualCue() {\n const sceneToRenderTo = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const selectionMesh = CreateSphere(\"nearInteraction\", {\n diameter: 0.0035 * 3 * this._xrSessionManager.worldScalingFactor,\n }, sceneToRenderTo);\n selectionMesh.bakeCurrentTransformIntoVertices();\n selectionMesh.isPickable = false;\n selectionMesh.isVisible = false;\n selectionMesh.rotationQuaternion = Quaternion.Identity();\n const targetMat = new StandardMaterial(\"targetMat\", sceneToRenderTo);\n targetMat.specularColor = Color3.Black();\n targetMat.emissiveColor = this.selectionMeshDefaultColor;\n targetMat.backFaceCulling = false;\n selectionMesh.material = targetMat;\n return selectionMesh;\n }\n _isControllerReadyForNearInteraction(id) {\n if (this._farInteractionFeature) {\n return this._farInteractionFeature._getPointerSelectionDisabledByPointerId(id);\n }\n return true;\n }\n _attachNearInteractionMode(xrController) {\n const controllerData = this._controllers[xrController.uniqueId];\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr-near\",\n };\n controllerData.onFrameObserver = this._xrSessionManager.onXRFrameObservable.add(() => {\n if ((!this._options.enableNearInteractionOnAllControllers && xrController.uniqueId !== this._attachedController) ||\n !controllerData.xrController ||\n (!controllerData.xrController.inputSource.hand && (!this._options.nearInteractionControllerMode || !controllerData.xrController.inputSource.gamepad))) {\n return;\n }\n if (controllerData.pick) {\n controllerData.pick.ray = controllerData.grabRay;\n }\n if (controllerData.pick && this._isControllerReadyForNearInteraction(controllerData.id)) {\n this._scene.simulatePointerMove(controllerData.pick, pointerEventInit);\n }\n // Near pick pointer event\n if (controllerData.nearInteraction && controllerData.pick && controllerData.pick.hit) {\n if (!controllerData.nearInteractionTargetMesh) {\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.nearInteractionTargetMesh = controllerData.meshUnderPointer;\n controllerData.downTriggered = true;\n }\n }\n else if (controllerData.nearInteractionTargetMesh && controllerData.stalePick) {\n this._scene.simulatePointerUp(controllerData.stalePick, pointerEventInit);\n controllerData.downTriggered = false;\n controllerData.nearInteractionTargetMesh = null;\n }\n });\n const grabCheck = (pressed) => {\n if (this._options.enableNearInteractionOnAllControllers ||\n (xrController.uniqueId === this._attachedController && this._isControllerReadyForNearInteraction(controllerData.id))) {\n if (controllerData.pick) {\n controllerData.pick.ray = controllerData.grabRay;\n }\n if (pressed && controllerData.pick && controllerData.meshUnderPointer && this._nearGrabPredicate(controllerData.meshUnderPointer)) {\n controllerData.grabInteraction = true;\n controllerData.pickedPointVisualCue.isVisible = false;\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = true;\n }\n else if (!pressed && controllerData.pick && controllerData.grabInteraction) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = false;\n controllerData.grabInteraction = false;\n controllerData.pickedPointVisualCue.isVisible = true;\n }\n }\n else {\n if (pressed && !this._options.enableNearInteractionOnAllControllers && !this._options.disableSwitchOnClick) {\n this._attachedController = xrController.uniqueId;\n }\n }\n };\n if (xrController.inputSource.gamepad) {\n const init = (motionController) => {\n controllerData.squeezeComponent = motionController.getComponent(\"grasp\");\n if (controllerData.squeezeComponent) {\n controllerData.onSqueezeButtonChangedObserver = controllerData.squeezeComponent.onButtonStateChangedObservable.add((component) => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n grabCheck(pressed);\n }\n });\n }\n else {\n controllerData.selectionComponent = motionController.getMainComponent();\n controllerData.onButtonChangedObserver = controllerData.selectionComponent.onButtonStateChangedObservable.add((component) => {\n if (component.changes.pressed) {\n const pressed = component.changes.pressed.current;\n grabCheck(pressed);\n }\n });\n }\n };\n if (xrController.motionController) {\n init(xrController.motionController);\n }\n else {\n xrController.onMotionControllerInitObservable.add(init);\n }\n }\n else {\n // use the select and squeeze events\n const selectStartListener = (event) => {\n if (controllerData.xrController &&\n event.inputSource === controllerData.xrController.inputSource &&\n controllerData.pick &&\n this._isControllerReadyForNearInteraction(controllerData.id) &&\n controllerData.meshUnderPointer &&\n this._nearGrabPredicate(controllerData.meshUnderPointer)) {\n controllerData.grabInteraction = true;\n controllerData.pickedPointVisualCue.isVisible = false;\n this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);\n controllerData.downTriggered = true;\n }\n };\n const selectEndListener = (event) => {\n if (controllerData.xrController &&\n event.inputSource === controllerData.xrController.inputSource &&\n controllerData.pick &&\n this._isControllerReadyForNearInteraction(controllerData.id)) {\n this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);\n controllerData.grabInteraction = false;\n controllerData.pickedPointVisualCue.isVisible = true;\n controllerData.downTriggered = false;\n }\n };\n controllerData.eventListeners = {\n selectend: selectEndListener,\n selectstart: selectStartListener,\n };\n this._xrSessionManager.session.addEventListener(\"selectstart\", selectStartListener);\n this._xrSessionManager.session.addEventListener(\"selectend\", selectEndListener);\n }\n }\n _detachController(xrControllerUniqueId) {\n const controllerData = this._controllers[xrControllerUniqueId];\n if (!controllerData) {\n return;\n }\n if (controllerData.squeezeComponent) {\n if (controllerData.onSqueezeButtonChangedObserver) {\n controllerData.squeezeComponent.onButtonStateChangedObservable.remove(controllerData.onSqueezeButtonChangedObserver);\n }\n }\n if (controllerData.selectionComponent) {\n if (controllerData.onButtonChangedObserver) {\n controllerData.selectionComponent.onButtonStateChangedObservable.remove(controllerData.onButtonChangedObserver);\n }\n }\n if (controllerData.onFrameObserver) {\n this._xrSessionManager.onXRFrameObservable.remove(controllerData.onFrameObserver);\n }\n if (controllerData.eventListeners) {\n Object.keys(controllerData.eventListeners).forEach((eventName) => {\n const func = controllerData.eventListeners && controllerData.eventListeners[eventName];\n if (func) {\n this._xrSessionManager.session.removeEventListener(eventName, func);\n }\n });\n }\n controllerData.touchCollisionMesh.dispose();\n controllerData.pickedPointVisualCue.dispose();\n this._xrSessionManager.runInXRFrame(() => {\n if (!controllerData.downTriggered) {\n return;\n }\n // Fire a pointerup in case controller was detached before a pointerup event was fired\n const pointerEventInit = {\n pointerId: controllerData.id,\n pointerType: \"xr-near\",\n };\n this._scene.simulatePointerUp(new PickingInfo(), pointerEventInit);\n });\n // remove world scale observer\n if (controllerData._worldScaleObserver) {\n this._xrSessionManager.onWorldScaleFactorChangedObservable.remove(controllerData._worldScaleObserver);\n }\n // remove from the map\n delete this._controllers[xrControllerUniqueId];\n if (this._attachedController === xrControllerUniqueId) {\n // check for other controllers\n const keys = Object.keys(this._controllers);\n if (keys.length) {\n this._attachedController = keys[0];\n }\n else {\n this._attachedController = \"\";\n }\n }\n }\n _generateNewTouchPointMesh() {\n const worldScale = this._xrSessionManager.worldScalingFactor;\n // populate information for near hover, pick and pinch\n const meshCreationScene = this._options.useUtilityLayer ? this._options.customUtilityLayerScene || UtilityLayerRenderer.DefaultUtilityLayer.utilityLayerScene : this._scene;\n const touchCollisionMesh = CreateSphere(\"PickSphere\", { diameter: 1 * worldScale }, meshCreationScene);\n touchCollisionMesh.isVisible = false;\n // Generate the material for the touch mesh visuals\n if (this._options.motionControllerOrbMaterial) {\n touchCollisionMesh.material = this._options.motionControllerOrbMaterial;\n }\n else {\n let parsePromise;\n if (this._options.motionControllerTouchMaterialSnippetUrl) {\n parsePromise = NodeMaterial.ParseFromFileAsync(\"motionControllerTouchMaterial\", this._options.motionControllerTouchMaterialSnippetUrl, meshCreationScene);\n }\n else {\n parsePromise = NodeMaterial.ParseFromSnippetAsync(\"8RUNKL#3\", meshCreationScene);\n }\n parsePromise\n .then((mat) => {\n touchCollisionMesh.material = mat;\n })\n .catch((err) => {\n Logger.Warn(`Error creating touch material in WebXRNearInteraction: ${err}`);\n });\n }\n const easingFunction = new QuadraticEase();\n easingFunction.setEasingMode(EasingFunction.EASINGMODE_EASEINOUT);\n // Adjust the visual size based off of the size of the touch collision orb.\n // Having the size perfectly match for hover gives a more accurate tell for when the user will start interacting with the target\n // Sizes for other states are somewhat arbitrary, as they are based on what feels nice during an interaction\n const hoverSizeVec = new Vector3(this._controllerPickRadius, this._controllerPickRadius, this._controllerPickRadius).scaleInPlace(worldScale);\n const touchSize = this._controllerPickRadius * (4 / 3);\n const touchSizeVec = new Vector3(touchSize, touchSize, touchSize).scaleInPlace(worldScale);\n const hydrateTransitionSize = this._controllerPickRadius * (7 / 6);\n const hydrateTransitionSizeVec = new Vector3(hydrateTransitionSize, hydrateTransitionSize, hydrateTransitionSize).scaleInPlace(worldScale);\n const touchHoverTransitionSize = this._controllerPickRadius * (4 / 5);\n const touchHoverTransitionSizeVec = new Vector3(touchHoverTransitionSize, touchHoverTransitionSize, touchHoverTransitionSize).scaleInPlace(worldScale);\n const hoverTouchTransitionSize = this._controllerPickRadius * (3 / 2);\n const hoverTouchTransitionSizeVec = new Vector3(hoverTouchTransitionSize, hoverTouchTransitionSize, hoverTouchTransitionSize).scaleInPlace(worldScale);\n const touchKeys = [\n { frame: 0, value: hoverSizeVec },\n { frame: 10, value: hoverTouchTransitionSizeVec },\n { frame: 18, value: touchSizeVec },\n ];\n const releaseKeys = [\n { frame: 0, value: touchSizeVec },\n { frame: 10, value: touchHoverTransitionSizeVec },\n { frame: 18, value: hoverSizeVec },\n ];\n const hydrateKeys = [\n { frame: 0, value: Vector3.ZeroReadOnly },\n { frame: 12, value: hydrateTransitionSizeVec },\n { frame: 15, value: hoverSizeVec },\n ];\n const dehydrateKeys = [\n { frame: 0, value: hoverSizeVec },\n { frame: 10, value: Vector3.ZeroReadOnly },\n { frame: 15, value: Vector3.ZeroReadOnly },\n ];\n const touchAction = new Animation(\"touch\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const releaseAction = new Animation(\"release\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const hydrateAction = new Animation(\"hydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n const dehydrateAction = new Animation(\"dehydrate\", \"scaling\", 60, Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CONSTANT);\n touchAction.setEasingFunction(easingFunction);\n releaseAction.setEasingFunction(easingFunction);\n hydrateAction.setEasingFunction(easingFunction);\n dehydrateAction.setEasingFunction(easingFunction);\n touchAction.setKeys(touchKeys);\n releaseAction.setKeys(releaseKeys);\n hydrateAction.setKeys(hydrateKeys);\n dehydrateAction.setKeys(dehydrateKeys);\n const touchCollisionMeshFunction = (isTouch) => {\n const action = isTouch ? touchAction : releaseAction;\n meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 18, false, 1);\n };\n const hydrateCollisionMeshFunction = (isHydration) => {\n const action = isHydration ? hydrateAction : dehydrateAction;\n if (isHydration) {\n touchCollisionMesh.isVisible = true;\n }\n meshCreationScene.beginDirectAnimation(touchCollisionMesh, [action], 0, 15, false, 1, () => {\n if (!isHydration) {\n touchCollisionMesh.isVisible = false;\n }\n });\n };\n return { touchCollisionMesh, touchCollisionMeshFunction, hydrateCollisionMeshFunction };\n }\n _pickWithSphere(controllerData, radius, sceneToUse, predicate) {\n const pickingInfo = new PickingInfo();\n pickingInfo.distance = +Infinity;\n if (controllerData.touchCollisionMesh && controllerData.xrController) {\n const position = controllerData.touchCollisionMesh.position;\n const sphere = BoundingSphere.CreateFromCenterAndRadius(position, radius);\n for (let meshIndex = 0; meshIndex < sceneToUse.meshes.length; meshIndex++) {\n const mesh = sceneToUse.meshes[meshIndex];\n if (!predicate(mesh) || !this._controllerAvailablePredicate(mesh, controllerData.xrController.uniqueId)) {\n continue;\n }\n const result = WebXRNearInteraction.PickMeshWithSphere(mesh, sphere);\n if (result && result.hit && result.distance < pickingInfo.distance) {\n pickingInfo.hit = result.hit;\n pickingInfo.pickedMesh = mesh;\n pickingInfo.pickedPoint = result.pickedPoint;\n pickingInfo.aimTransform = controllerData.xrController.pointer;\n pickingInfo.gripTransform = controllerData.xrController.grip || null;\n pickingInfo.originMesh = controllerData.touchCollisionMesh;\n pickingInfo.distance = result.distance;\n pickingInfo.bu = result.bu;\n pickingInfo.bv = result.bv;\n pickingInfo.faceId = result.faceId;\n pickingInfo.subMeshId = result.subMeshId;\n }\n }\n }\n return pickingInfo;\n }\n /**\n * Picks a mesh with a sphere\n * @param mesh the mesh to pick\n * @param sphere picking sphere in world coordinates\n * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check\n * @returns the picking info\n */\n static PickMeshWithSphere(mesh, sphere, skipBoundingInfo = false) {\n const subMeshes = mesh.subMeshes;\n const pi = new PickingInfo();\n const boundingInfo = mesh.getBoundingInfo();\n if (!mesh._generatePointsArray()) {\n return pi;\n }\n if (!mesh.subMeshes || !boundingInfo) {\n return pi;\n }\n if (!skipBoundingInfo && !BoundingSphere.Intersects(boundingInfo.boundingSphere, sphere)) {\n return pi;\n }\n const result = TmpVectors.Vector3[0];\n const tmpVec = TmpVectors.Vector3[1];\n const tmpRay = new Ray(Vector3.Zero(), Vector3.Zero(), 1);\n let distance = +Infinity;\n let tmp, tmpDistanceSphereToCenter, tmpDistanceSurfaceToCenter, intersectionInfo;\n const center = TmpVectors.Vector3[2];\n const worldToMesh = TmpVectors.Matrix[0];\n worldToMesh.copyFrom(mesh.getWorldMatrix());\n worldToMesh.invert();\n Vector3.TransformCoordinatesToRef(sphere.center, worldToMesh, center);\n for (let index = 0; index < subMeshes.length; index++) {\n const subMesh = subMeshes[index];\n subMesh.projectToRef(center, mesh._positions, mesh.getIndices(), tmpVec);\n Vector3.TransformCoordinatesToRef(tmpVec, mesh.getWorldMatrix(), tmpVec);\n tmp = Vector3.Distance(tmpVec, sphere.center);\n // Check for finger inside of mesh\n tmpDistanceSurfaceToCenter = Vector3.Distance(tmpVec, mesh.getAbsolutePosition());\n tmpDistanceSphereToCenter = Vector3.Distance(sphere.center, mesh.getAbsolutePosition());\n if (tmpDistanceSphereToCenter !== -1 && tmpDistanceSurfaceToCenter !== -1 && tmpDistanceSurfaceToCenter > tmpDistanceSphereToCenter) {\n tmp = 0;\n tmpVec.copyFrom(sphere.center);\n }\n if (tmp !== -1 && tmp < distance) {\n distance = tmp;\n // ray between the sphere center and the point on the mesh\n Ray.CreateFromToToRef(sphere.center, tmpVec, tmpRay);\n tmpRay.length = distance * 2;\n intersectionInfo = tmpRay.intersectsMesh(mesh);\n result.copyFrom(tmpVec);\n }\n }\n if (distance < sphere.radius) {\n pi.hit = true;\n pi.distance = distance;\n pi.pickedMesh = mesh;\n pi.pickedPoint = result.clone();\n if (intersectionInfo && intersectionInfo.bu !== null && intersectionInfo.bv !== null) {\n pi.faceId = intersectionInfo.faceId;\n pi.subMeshId = intersectionInfo.subMeshId;\n pi.bu = intersectionInfo.bu;\n pi.bv = intersectionInfo.bv;\n }\n }\n return pi;\n }\n}\nWebXRNearInteraction._IdCounter = 200;\n/**\n * The module's name\n */\nWebXRNearInteraction.Name = WebXRFeatureName.NEAR_INTERACTION;\n/**\n * The (Babylon) version of this module.\n * This is an integer representing the implementation version.\n * This number does not correspond to the WebXR specs version\n */\nWebXRNearInteraction.Version = 1;\n//Register the plugin\nWebXRFeaturesManager.AddWebXRFeature(WebXRNearInteraction.Name, (xrSessionManager, options) => {\n return () => new WebXRNearInteraction(xrSessionManager, options);\n}, WebXRNearInteraction.Version, true);\n"],"mappings":"AAAA,SAASA,oBAAoB,EAAEC,gBAAgB,QAAQ,4BAA4B;AACnF,SAASC,YAAY,QAAQ,wCAAwC;AACrE,SAASC,OAAO,EAAEC,UAAU,EAAEC,UAAU,QAAQ,4BAA4B;AAC5E,SAASC,GAAG,QAAQ,sBAAsB;AAC1C,SAASC,WAAW,QAAQ,iCAAiC;AAC7D,SAASC,oBAAoB,QAAQ,2BAA2B;AAChE,SAASC,oBAAoB,QAAQ,yCAAyC;AAC9E,SAASC,cAAc,QAAQ,iCAAiC;AAChE,SAASC,gBAAgB,QAAQ,qCAAqC;AACtE,SAASC,MAAM,QAAQ,2BAA2B;AAClD,SAASC,YAAY,QAAQ,sCAAsC;AACnE,SAASC,SAAS,QAAQ,+BAA+B;AACzD,SAASC,aAAa,EAAEC,cAAc,QAAQ,4BAA4B;AAC1E;AACA,OAAO,iCAAiC;AACxC,SAASC,MAAM,QAAQ,sBAAsB;AAC7C;AACA,IAAIC,2BAA2B;AAC/B,CAAC,UAAUA,2BAA2B,EAAE;EACpC;AACJ;AACA;EACIA,2BAA2B,CAACA,2BAA2B,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY;EACzF;AACJ;AACA;EACIA,2BAA2B,CAACA,2BAA2B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO;EAC/E;AACJ;AACA;EACIA,2BAA2B,CAACA,2BAA2B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO;AACnF,CAAC,EAAEA,2BAA2B,KAAKA,2BAA2B,GAAG,CAAC,CAAC,CAAC,CAAC;AACrE;AACA;AACA;AACA,OAAO,IAAIC,uBAAuB;AAClC,CAAC,UAAUA,uBAAuB,EAAE;EAChC;AACJ;AACA;EACIA,uBAAuB,CAACA,uBAAuB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU;EAC7E;AACJ;AACA;EACIA,uBAAuB,CAACA,uBAAuB,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,GAAG,wBAAwB;EACzG;AACJ;AACA;EACIA,uBAAuB,CAACA,uBAAuB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,GAAG,mBAAmB;AACnG,CAAC,EAAEA,uBAAuB,KAAKA,uBAAuB,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7D;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,SAASZ,oBAAoB,CAAC;EAC3D;AACJ;AACA;AACA;AACA;EACIa,WAAWA,CAACC,iBAAiB,EAAEC,QAAQ,EAAE;IACrC,KAAK,CAACD,iBAAiB,CAAC;IACxB,IAAI,CAACC,QAAQ,GAAGA,QAAQ;IACxB,IAAI,CAACC,OAAO,GAAG,IAAIlB,GAAG,CAAC,IAAIH,OAAO,CAAC,CAAC,EAAE,IAAIA,OAAO,CAAC,CAAC,CAAC;IACpD,IAAI,CAACsB,iBAAiB,GAAIC,YAAY,IAAK;MACvC,IAAI,IAAI,CAACC,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,EAAE;QAC1C;QACA;MACJ;MACA;MACA,MAAM;QAAEC,kBAAkB;QAAEC,0BAA0B;QAAEC;MAA6B,CAAC,GAAG,IAAI,CAACC,0BAA0B,CAAC,CAAC;MAC1H,MAAMC,aAAa,GAAG,IAAI,CAACC,kBAAkB,CAAC,CAAC;MAC/C,IAAI,CAACP,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,GAAG;QACvCF,YAAY;QACZS,gBAAgB,EAAE,IAAI;QACtBC,yBAAyB,EAAE,IAAI;QAC/BC,IAAI,EAAE,IAAI;QACVC,SAAS,EAAE,IAAI;QACfT,kBAAkB;QAClBC,0BAA0B,EAAEA,0BAA0B;QACtDC,4BAA4B,EAAEA,4BAA4B;QAC1DQ,qBAAqB,EAAErB,2BAA2B,CAACsB,UAAU;QAC7DC,OAAO,EAAE,IAAInC,GAAG,CAAC,IAAIH,OAAO,CAAC,CAAC,EAAE,IAAIA,OAAO,CAAC,CAAC,CAAC;QAC9CuC,gBAAgB,EAAE,KAAK;QACvBC,eAAe,EAAE,KAAK;QACtBC,eAAe,EAAE,KAAK;QACtBC,aAAa,EAAE,KAAK;QACpBC,EAAE,EAAE1B,oBAAoB,CAAC2B,UAAU,EAAE;QACrCC,oBAAoB,EAAEf;MAC1B,CAAC;MACD,IAAI,CAACN,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACqB,mBAAmB,GACxD,IAAI,CAACtB,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACqB,mBAAmB,IACxD,IAAI,CAAC3B,iBAAiB,CAAC4B,mCAAmC,CAACC,GAAG,CAAEC,MAAM,IAAK;QACvE,IAAIA,MAAM,CAACC,cAAc,KAAKD,MAAM,CAACE,mBAAmB,EAAE;UACtD,IAAI,CAAC3B,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACC,kBAAkB,CAAC0B,OAAO,CAAC,CAAC;UACrE,IAAI,CAAC5B,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACoB,oBAAoB,CAACO,OAAO,CAAC,CAAC;UACvE,MAAM;YAAE1B,kBAAkB;YAAEC,0BAA0B;YAAEC;UAA6B,CAAC,GAAG,IAAI,CAACC,0BAA0B,CAAC,CAAC;UAC1H,IAAI,CAACL,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACC,kBAAkB,GAAGA,kBAAkB;UAChF,IAAI,CAACF,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACE,0BAA0B,GAAGA,0BAA0B;UAChG,IAAI,CAACH,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACG,4BAA4B,GAAGA,4BAA4B;UACpG,IAAI,CAACJ,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC,CAACoB,oBAAoB,GAAG,IAAI,CAACd,kBAAkB,CAAC,CAAC;QAC7F;MACJ,CAAC,CAAC;MACV,IAAI,IAAI,CAACsB,mBAAmB,EAAE;QAC1B,IAAI,CAAC,IAAI,CAACjC,QAAQ,CAACkC,qCAAqC,IACpD,IAAI,CAAClC,QAAQ,CAACmC,mBAAmB,IACjChC,YAAY,CAACiC,WAAW,CAACC,UAAU,KAAK,IAAI,CAACrC,QAAQ,CAACmC,mBAAmB,EAAE;UAC3E,IAAI,CAACF,mBAAmB,GAAG9B,YAAY,CAACE,QAAQ;QACpD;MACJ,CAAC,MACI;QACD,IAAI,CAAC,IAAI,CAACL,QAAQ,CAACkC,qCAAqC,EAAE;UACtD,IAAI,CAACD,mBAAmB,GAAG9B,YAAY,CAACE,QAAQ;QACpD;MACJ;MACA,QAAQF,YAAY,CAACiC,WAAW,CAACE,aAAa;QAC1C,KAAK,iBAAiB;UAClB,OAAO,IAAI,CAACC,0BAA0B,CAACpC,YAAY,CAAC;QACxD,KAAK,MAAM;UACP,OAAO,IAAI;QACf,KAAK,QAAQ;UACT,OAAO,IAAI;MACnB;IACJ,CAAC;IACD,IAAI,CAACC,YAAY,GAAG,CAAC,CAAC;IACtB,IAAI,CAACoC,sBAAsB,GAAG,IAAI;IAClC;AACR;AACA;IACQ,IAAI,CAACC,yBAAyB,GAAG,IAAIpD,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IAC1D;AACR;AACA;IACQ,IAAI,CAACqD,wBAAwB,GAAG,IAAIrD,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;IACzD,IAAI,CAACsD,YAAY,GAAG,GAAG;IACvB,IAAI,CAACC,WAAW,GAAG,IAAI;IACvB,IAAI,CAACC,qBAAqB,GAAG,IAAI,CAAC,CAAC;IACnC,IAAI,CAACC,oBAAoB,GAAG,CAAC;IAC7B,IAAI,CAACC,MAAM,GAAG,IAAI,CAAChD,iBAAiB,CAACiD,KAAK;IAC1C,IAAI,IAAI,CAAChD,QAAQ,CAACiD,6BAA6B,KAAKC,SAAS,EAAE;MAC3D,IAAI,CAAClD,QAAQ,CAACiD,6BAA6B,GAAG,CAAC,CAAC;IACpD;IACA,IAAI,IAAI,CAACjD,QAAQ,CAACmD,qBAAqB,EAAE;MACrC,IAAI,CAACX,sBAAsB,GAAG,IAAI,CAACxC,QAAQ,CAACmD,qBAAqB;IACrE;EACJ;EACA;AACJ;AACA;AACA;AACA;AACA;EACIC,MAAMA,CAAA,EAAG;IACL,IAAI,CAAC,KAAK,CAACA,MAAM,CAAC,CAAC,EAAE;MACjB,OAAO,KAAK;IAChB;IACA,IAAI,CAACpD,QAAQ,CAACqD,OAAO,CAACC,WAAW,CAACC,OAAO,CAAC,IAAI,CAACrD,iBAAiB,CAAC;IACjE,IAAI,CAACsD,qBAAqB,CAAC,IAAI,CAACxD,QAAQ,CAACqD,OAAO,CAACI,2BAA2B,EAAE,IAAI,CAACvD,iBAAiB,CAAC;IACrG,IAAI,CAACsD,qBAAqB,CAAC,IAAI,CAACxD,QAAQ,CAACqD,OAAO,CAACK,6BAA6B,EAAGC,UAAU,IAAK;MAC5F;MACA,IAAI,CAACC,iBAAiB,CAACD,UAAU,CAACtD,QAAQ,CAAC;IAC/C,CAAC,CAAC;IACF,IAAI,CAAC0C,MAAM,CAACc,gCAAgC,GAAG,IAAI;IACnD,OAAO,IAAI;EACf;EACA;AACJ;AACA;AACA;AACA;AACA;EACIC,MAAMA,CAAA,EAAG;IACL,IAAI,CAAC,KAAK,CAACA,MAAM,CAAC,CAAC,EAAE;MACjB,OAAO,KAAK;IAChB;IACAC,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC5D,YAAY,CAAC,CAACmD,OAAO,CAAEU,YAAY,IAAK;MACrD,IAAI,CAACL,iBAAiB,CAACK,YAAY,CAAC;IACxC,CAAC,CAAC;IACF,OAAO,IAAI;EACf;EACA;AACJ;AACA;AACA;AACA;AACA;EACIC,mBAAmBA,CAACD,YAAY,EAAE;IAC9B,IAAI,IAAI,CAAC7D,YAAY,CAAC6D,YAAY,CAAC,EAAE;MACjC,OAAO,IAAI,CAAC7D,YAAY,CAAC6D,YAAY,CAAC,CAACrD,gBAAgB;IAC3D,CAAC,MACI;MACD,OAAO,IAAI;IACf;EACJ;EACA;AACJ;AACA;AACA;AACA;AACA;EACIuD,0BAA0BA,CAAC5C,EAAE,EAAE;IAC3B,MAAMyC,IAAI,GAAGD,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC5D,YAAY,CAAC;IAC3C,KAAK,IAAIgE,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,IAAI,CAACK,MAAM,EAAE,EAAED,CAAC,EAAE;MAClC,IAAI,IAAI,CAAChE,YAAY,CAAC4D,IAAI,CAACI,CAAC,CAAC,CAAC,CAAC7C,EAAE,KAAKA,EAAE,EAAE;QACtC,OAAO,IAAI,CAACnB,YAAY,CAAC4D,IAAI,CAACI,CAAC,CAAC,CAAC,CAACjE,YAAY,IAAI,IAAI;MAC1D;IACJ;IACA,OAAO,IAAI;EACf;EACA;AACJ;AACA;AACA;AACA;AACA;EACImE,wBAAwBA,CAACnB,qBAAqB,EAAE;IAC5C,IAAI,CAACX,sBAAsB,GAAGW,qBAAqB;EACvD;EACA;AACJ;AACA;AACA;AACA;EACIoB,kBAAkBA,CAACC,IAAI,EAAE;IACrB,OAAOA,IAAI,CAACC,SAAS,CAAC,CAAC,IAAID,IAAI,CAACE,SAAS,IAAIF,IAAI,CAACG,UAAU,IAAIH,IAAI,CAACI,cAAc;EACvF;EACA;AACJ;AACA;AACA;AACA;EACIC,kBAAkBA,CAACL,IAAI,EAAE;IACrB,OAAOA,IAAI,CAACC,SAAS,CAAC,CAAC,IAAID,IAAI,CAACE,SAAS,IAAIF,IAAI,CAACG,UAAU,IAAIH,IAAI,CAACM,eAAe;EACxF;EACA;AACJ;AACA;AACA;AACA;EACIC,yBAAyBA,CAACP,IAAI,EAAE;IAC5B,OAAOA,IAAI,CAACC,SAAS,CAAC,CAAC,IAAID,IAAI,CAACE,SAAS,IAAIF,IAAI,CAACG,UAAU,KAAKH,IAAI,CAACI,cAAc,IAAIJ,IAAI,CAACM,eAAe,CAAC;EACjH;EACAE,6BAA6BA,CAACR,IAAI,EAAEP,YAAY,EAAE;IAC9C,IAAIgB,MAAM,GAAGT,IAAI;IACjB,OAAOS,MAAM,EAAE;MACX,IAAIA,MAAM,CAACC,iBAAiB,IAAID,MAAM,CAACC,iBAAiB,CAAC9D,eAAe,IAAI6D,MAAM,CAACC,iBAAiB,CAAC9D,eAAe,CAAC+D,oBAAoB,KAAKlB,YAAY,EAAE;QACxJ,OAAO,KAAK;MAChB;MACAgB,MAAM,GAAGA,MAAM,CAACA,MAAM;IAC1B;IACA,OAAO,IAAI;EACf;EACAG,0BAA0BA,CAACC,cAAc,EAAEC,QAAQ,EAAE;IAAA,IAAAC,qBAAA;IACjD,IAAIF,cAAc,CAACrE,qBAAqB,KAAKsE,QAAQ,IACjD,IAAI,CAACtF,QAAQ,CAACiD,6BAA6B,KAAK,CAAC,CAAC,mDAClD,CAAC,GAAAsC,qBAAA,GAACF,cAAc,CAAClF,YAAY,cAAAoF,qBAAA,eAA3BA,qBAAA,CAA6BnD,WAAW,CAACoD,IAAI,GAAE;MACjD;IACJ;IACA;IACA,IAAIF,QAAQ,GAAGD,cAAc,CAACrE,qBAAqB,EAAE;MACjD,QAAQqE,cAAc,CAACrE,qBAAqB;QACxC,KAAKrB,2BAA2B,CAACsB,UAAU;UAAE;YACzCoE,cAAc,CAAC7E,4BAA4B,CAAC,IAAI,CAAC;YACjD,IAAI8E,QAAQ,KAAK3F,2BAA2B,CAAC8F,KAAK,EAAE;cAChD;YACJ;UACJ;QACA;QACA,KAAK9F,2BAA2B,CAAC8F,KAAK;UAAE;YACpCJ,cAAc,CAAC9E,0BAA0B,CAAC,IAAI,CAAC;YAC/C,IAAI+E,QAAQ,KAAK3F,2BAA2B,CAAC+F,KAAK,EAAE;cAChD;YACJ;UACJ;MACJ;IACJ,CAAC,MACI;MACD,QAAQL,cAAc,CAACrE,qBAAqB;QACxC,KAAKrB,2BAA2B,CAAC+F,KAAK;UAAE;YACpCL,cAAc,CAAC9E,0BAA0B,CAAC,KAAK,CAAC;YAChD,IAAI+E,QAAQ,KAAK3F,2BAA2B,CAAC8F,KAAK,EAAE;cAChD;YACJ;UACJ;QACA;QACA,KAAK9F,2BAA2B,CAAC8F,KAAK;UAAE;YACpCJ,cAAc,CAAC7E,4BAA4B,CAAC,KAAK,CAAC;YAClD,IAAI8E,QAAQ,KAAK3F,2BAA2B,CAACsB,UAAU,EAAE;cACrD;YACJ;UACJ;MACJ;IACJ;IACAoE,cAAc,CAACrE,qBAAqB,GAAGsE,QAAQ;EACnD;EACAK,kBAAkBA,CAACpE,EAAE,EAAEqE,QAAQ,EAAEC,WAAW,EAAE;IAAA,IAAAC,sBAAA;IAC1C,MAAMT,cAAc,GAAG,IAAI,CAACjF,YAAY,CAACmB,EAAE,CAAC;IAC5C;IACA8D,cAAc,CAACnE,OAAO,CAAC6E,MAAM,CAACC,QAAQ,CAACJ,QAAQ,CAAC;IAChDC,WAAW,CAACI,kBAAkB,CAACnH,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC,CAAC;IACrDyG,cAAc,CAACnE,OAAO,CAACgF,SAAS,CAACF,QAAQ,CAAClH,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,IAAI,CAACoB,QAAQ,CAACiD,6BAA6B,KAAK,CAAC,CAAC,mDAAmD,GAAA6C,sBAAA,GAACT,cAAc,CAAClF,YAAY,cAAA2F,sBAAA,eAA3BA,sBAAA,CAA6B1D,WAAW,CAACoD,IAAI,GAAE;MACrJ;MACAH,cAAc,CAAClF,YAAY,CAACgG,uBAAuB,CAAC,IAAI,CAAClG,OAAO,CAAC;MACjEoF,cAAc,CAACnE,OAAO,CAAC6E,MAAM,CAACK,UAAU,CAAC,IAAI,CAACnG,OAAO,CAACiG,SAAS,CAACG,KAAK,CAAC,IAAI,CAAC,CAAC;IAChF;IACAhB,cAAc,CAACnE,OAAO,CAACmD,MAAM,GAAG,IAAI,CAACvB,oBAAoB,GAAG,IAAI,CAACH,YAAY,GAAG,IAAI,CAAC5C,iBAAiB,CAACuG,kBAAkB;IACzHjB,cAAc,CAAC/E,kBAAkB,CAACsF,QAAQ,CAACI,QAAQ,CAACX,cAAc,CAACnE,OAAO,CAAC6E,MAAM,CAAC,CAACQ,YAAY,CAAC,IAAI,CAACxG,iBAAiB,CAACuG,kBAAkB,CAAC;EAC9I;EACAE,UAAUA,CAACC,QAAQ,EAAE;IACjB1C,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC5D,YAAY,CAAC,CAACmD,OAAO,CAAEhC,EAAE,IAAK;MAAA,IAAAmF,sBAAA;MAC3C;MACA,MAAMrB,cAAc,GAAG,IAAI,CAACjF,YAAY,CAACmB,EAAE,CAAC;MAC5C,MAAMoF,QAAQ,IAAAD,sBAAA,GAAGrB,cAAc,CAAClF,YAAY,cAAAuG,sBAAA,uBAA3BA,sBAAA,CAA6BtE,WAAW,CAACoD,IAAI;MAC9D;MACA,IAAK,CAAC,IAAI,CAACxF,QAAQ,CAACkC,qCAAqC,IAAIX,EAAE,KAAK,IAAI,CAACU,mBAAmB,IACxF,CAACoD,cAAc,CAAClF,YAAY,IAC3B,CAACwG,QAAQ,KAAK,CAAC,IAAI,CAAC3G,QAAQ,CAACiD,6BAA6B,IAAI,CAACoC,cAAc,CAAClF,YAAY,CAACiC,WAAW,CAACwE,OAAO,CAAE,EAAE;QACnHvB,cAAc,CAACvE,IAAI,GAAG,IAAI;QAC1B;MACJ;MACAuE,cAAc,CAAClE,gBAAgB,GAAG,KAAK;MACvCkE,cAAc,CAACjE,eAAe,GAAG,KAAK;MACtC;MACA,IAAIiE,cAAc,CAAClF,YAAY,EAAE;QAC7B,IAAIwG,QAAQ,EAAE;UACV,MAAME,UAAU,GAAGF,QAAQ,CAACG,GAAG,CAAC,kBAAkB,CAAC;UACnD,IAAID,UAAU,EAAE;YACZ,MAAME,YAAY,GAAGN,QAAQ,CAACO,YAAY,CAACH,UAAU,EAAE,IAAI,CAAC9G,iBAAiB,CAACkH,cAAc,CAAC;YAC7F,IAAIF,YAAY,IAAIA,YAAY,CAACG,SAAS,EAAE;cACxC,MAAMC,iBAAiB,GAAG,IAAI,CAACpE,MAAM,CAACqE,oBAAoB,GAAG,CAAC,GAAG,CAAC,CAAC;cACnEtI,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC,CAACyI,GAAG,CAACN,YAAY,CAACG,SAAS,CAACtB,QAAQ,CAAC0B,CAAC,EAAEP,YAAY,CAACG,SAAS,CAACtB,QAAQ,CAAC2B,CAAC,EAAER,YAAY,CAACG,SAAS,CAACtB,QAAQ,CAAC4B,CAAC,GAAGL,iBAAiB,CAAC;cACtJrI,UAAU,CAACD,UAAU,CAAC,CAAC,CAAC,CAACwI,GAAG,CAACN,YAAY,CAACG,SAAS,CAACrB,WAAW,CAACyB,CAAC,EAAEP,YAAY,CAACG,SAAS,CAACrB,WAAW,CAAC0B,CAAC,EAAER,YAAY,CAACG,SAAS,CAACrB,WAAW,CAAC2B,CAAC,GAAGL,iBAAiB,EAAEJ,YAAY,CAACG,SAAS,CAACrB,WAAW,CAAC4B,CAAC,GAAGN,iBAAiB,CAAC;cAC5N,IAAI,CAACxB,kBAAkB,CAACpE,EAAE,EAAEzC,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC,EAAEE,UAAU,CAACD,UAAU,CAAC,CAAC,CAAC,CAAC;YAChF;UACJ;QACJ,CAAC,MACI,IAAIwG,cAAc,CAAClF,YAAY,CAACiC,WAAW,CAACwE,OAAO,IAAI,IAAI,CAAC5G,QAAQ,CAACiD,6BAA6B,KAAK,CAAC,CAAC,wCAAwC;UAClJ,IAAIyE,cAAc,GAAGrC,cAAc,CAAClF,YAAY,CAACwH,OAAO;UACxD,IAAItC,cAAc,CAAClF,YAAY,CAACyH,IAAI,IAAI,IAAI,CAAC5H,QAAQ,CAACiD,6BAA6B,KAAK,CAAC,CAAC,sDAAsD;YAC5IyE,cAAc,GAAGrC,cAAc,CAAClF,YAAY,CAACyH,IAAI;UACrD;UACA,IAAI,CAACjC,kBAAkB,CAACpE,EAAE,EAAEmG,cAAc,CAAC9B,QAAQ,EAAE8B,cAAc,CAACG,kBAAkB,CAAC;QAC3F;MACJ,CAAC,MACI;QACD;MACJ;MACA,MAAMC,gBAAgB,GAAGA,CAACC,iBAAiB,EAAEC,gBAAgB,KAAK;QAC9D,IAAIlH,IAAI,GAAG,IAAI;QACf,IAAI,CAACkH,gBAAgB,IAAI,CAACA,gBAAgB,CAACC,GAAG,EAAE;UAC5C;UACAnH,IAAI,GAAGiH,iBAAiB;QAC5B,CAAC,MACI,IAAI,CAACA,iBAAiB,IAAI,CAACA,iBAAiB,CAACE,GAAG,EAAE;UACnD;UACAnH,IAAI,GAAGkH,gBAAgB;QAC3B,CAAC,MACI,IAAIA,gBAAgB,CAACE,QAAQ,GAAGH,iBAAiB,CAACG,QAAQ,EAAE;UAC7D;UACApH,IAAI,GAAGkH,gBAAgB;QAC3B,CAAC,MACI;UACD;UACAlH,IAAI,GAAGiH,iBAAiB;QAC5B;QACA,OAAOjH,IAAI;MACf,CAAC;MACD,MAAMqH,2BAA2B,GAAIC,mBAAmB,IAAK;QACzD,IAAIC,MAAM,GAAG,IAAIrJ,WAAW,CAAC,CAAC;QAC9B,IAAIsJ,uBAAuB,GAAG,KAAK;QACnC,MAAMlH,eAAe,GAAGgH,mBAAmB,IAAIA,mBAAmB,CAACG,WAAW,IAAIH,mBAAmB,CAACH,GAAG;QACzG,IAAIG,mBAAmB,aAAnBA,mBAAmB,eAAnBA,mBAAmB,CAAEG,WAAW,EAAE;UAClCD,uBAAuB,GAAGF,mBAAmB,CAACG,WAAW,CAACjB,CAAC,KAAK,CAAC,IAAIc,mBAAmB,CAACG,WAAW,CAAChB,CAAC,KAAK,CAAC,IAAIa,mBAAmB,CAACG,WAAW,CAACf,CAAC,KAAK,CAAC;QAC3J;QACA,IAAIpG,eAAe,IAAI,CAACkH,uBAAuB,EAAE;UAC7CD,MAAM,GAAGD,mBAAmB;QAChC;QACA,OAAOC,MAAM;MACjB,CAAC;MACD;MACA;MACA;MACA,IAAI,CAAChD,cAAc,CAAChE,eAAe,EAAE;QACjC,IAAIP,IAAI,GAAG,IAAI;QACf;QACA,IAAI0H,qBAAqB,GAAG,IAAI;QAChC,IAAI,IAAI,CAACxI,QAAQ,CAACyI,eAAe,IAAI,IAAI,CAACC,kBAAkB,EAAE;UAC1DF,qBAAqB,GAAG,IAAI,CAACG,eAAe,CAACtD,cAAc,EAAE,IAAI,CAAC1C,YAAY,GAAG,IAAI,CAAC5C,iBAAiB,CAACuG,kBAAkB,EAAE,IAAI,CAACoC,kBAAkB,EAAGlE,IAAI,IAAK,IAAI,CAACO,yBAAyB,CAACP,IAAI,CAAC,CAAC;QACxM;QACA,MAAMoE,sBAAsB,GAAG,IAAI,CAACD,eAAe,CAACtD,cAAc,EAAE,IAAI,CAAC1C,YAAY,GAAG,IAAI,CAAC5C,iBAAiB,CAACuG,kBAAkB,EAAE,IAAI,CAACvD,MAAM,EAAGyB,IAAI,IAAK,IAAI,CAACO,yBAAyB,CAACP,IAAI,CAAC,CAAC;QAC/L,MAAMqE,aAAa,GAAGf,gBAAgB,CAACc,sBAAsB,EAAEJ,qBAAqB,CAAC;QACrF,IAAIK,aAAa,IAAIA,aAAa,CAACZ,GAAG,EAAE;UACpCnH,IAAI,GAAGqH,2BAA2B,CAACU,aAAa,CAAC;UACjD,IAAI/H,IAAI,CAACmH,GAAG,EAAE;YACV5C,cAAc,CAAClE,gBAAgB,GAAG,IAAI;UAC1C;QACJ;QACA;QACA,IAAIkE,cAAc,CAAClE,gBAAgB,EAAE;UACjC,IAAI2H,oBAAoB,GAAG,IAAI;UAC/B,MAAMC,MAAM,GAAG,CAACpC,QAAQ,GAAG,IAAI,CAAC/D,WAAW,GAAG,IAAI,CAACC,qBAAqB,IAAI,IAAI,CAAC9C,iBAAiB,CAACuG,kBAAkB;UACrH,IAAI,IAAI,CAACtG,QAAQ,CAACyI,eAAe,IAAI,IAAI,CAACC,kBAAkB,EAAE;YAC1DI,oBAAoB,GAAG,IAAI,CAACH,eAAe,CAACtD,cAAc,EAAE0D,MAAM,EAAE,IAAI,CAACL,kBAAkB,EAAGlE,IAAI,IAAK,IAAI,CAACD,kBAAkB,CAACC,IAAI,CAAC,CAAC;UACzI;UACA,MAAMwE,qBAAqB,GAAG,IAAI,CAACL,eAAe,CAACtD,cAAc,EAAE0D,MAAM,EAAE,IAAI,CAAChG,MAAM,EAAGyB,IAAI,IAAK,IAAI,CAACD,kBAAkB,CAACC,IAAI,CAAC,CAAC;UAChI,MAAMyE,QAAQ,GAAGnB,gBAAgB,CAACkB,qBAAqB,EAAEF,oBAAoB,CAAC;UAC9E,MAAMI,QAAQ,GAAGf,2BAA2B,CAACc,QAAQ,CAAC;UACtD,IAAIC,QAAQ,CAACjB,GAAG,EAAE;YACd;YACAnH,IAAI,GAAGoI,QAAQ;YACf7D,cAAc,CAACjE,eAAe,GAAG,IAAI;UACzC;QACJ;QACAiE,cAAc,CAACtE,SAAS,GAAGsE,cAAc,CAACvE,IAAI;QAC9CuE,cAAc,CAACvE,IAAI,GAAGA,IAAI;QAC1B;QACA,IAAIuE,cAAc,CAACvE,IAAI,IAAIuE,cAAc,CAACvE,IAAI,CAACyH,WAAW,IAAIlD,cAAc,CAACvE,IAAI,CAACmH,GAAG,EAAE;UACnF5C,cAAc,CAACzE,gBAAgB,GAAGyE,cAAc,CAACvE,IAAI,CAACqI,UAAU;UAChE9D,cAAc,CAAC5D,oBAAoB,CAACmE,QAAQ,CAACI,QAAQ,CAACX,cAAc,CAACvE,IAAI,CAACyH,WAAW,CAAC;UACtFlD,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,IAAI;UACpD,IAAI,IAAI,CAAClC,sBAAsB,IAAI,IAAI,CAACA,sBAAsB,CAAC4G,QAAQ,EAAE;YACrE,IAAI,CAAC5G,sBAAsB,CAAC6G,uCAAuC,CAAChE,cAAc,CAAC9D,EAAE,EAAE,IAAI,CAAC;UAChG;QACJ,CAAC,MACI;UACD8D,cAAc,CAACzE,gBAAgB,GAAG,IAAI;UACtCyE,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,KAAK;UACrD,IAAI,IAAI,CAAClC,sBAAsB,IAAI,IAAI,CAACA,sBAAsB,CAAC4G,QAAQ,EAAE;YACrE,IAAI,CAAC5G,sBAAsB,CAAC6G,uCAAuC,CAAChE,cAAc,CAAC9D,EAAE,EAAE,KAAK,CAAC;UACjG;QACJ;MACJ;MACA;MACA,IAAI+H,KAAK,GAAG3J,2BAA2B,CAACsB,UAAU;MAClD,IAAIoE,cAAc,CAAChE,eAAe,IAAIgE,cAAc,CAACjE,eAAe,EAAE;QAClEkI,KAAK,GAAG3J,2BAA2B,CAAC+F,KAAK;MAC7C,CAAC,MACI,IAAIL,cAAc,CAAClE,gBAAgB,EAAE;QACtCmI,KAAK,GAAG3J,2BAA2B,CAAC8F,KAAK;MAC7C;MACA,IAAI,CAACL,0BAA0B,CAACC,cAAc,EAAEiE,KAAK,CAAC;IAC1D,CAAC,CAAC;EACN;EACA,IAAIZ,kBAAkBA,CAAA,EAAG;IACrB,OAAO,IAAI,CAAC1I,QAAQ,CAACuJ,uBAAuB,IAAIrK,oBAAoB,CAACsK,mBAAmB,CAACC,iBAAiB;EAC9G;EACA9I,kBAAkBA,CAAA,EAAG;IACjB,MAAM+I,eAAe,GAAG,IAAI,CAAC1J,QAAQ,CAACyI,eAAe,GAAG,IAAI,CAACzI,QAAQ,CAACuJ,uBAAuB,IAAIrK,oBAAoB,CAACsK,mBAAmB,CAACC,iBAAiB,GAAG,IAAI,CAAC1G,MAAM;IACzK,MAAMrC,aAAa,GAAG/B,YAAY,CAAC,iBAAiB,EAAE;MAClDgL,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC5J,iBAAiB,CAACuG;IAClD,CAAC,EAAEoD,eAAe,CAAC;IACnBhJ,aAAa,CAACkJ,gCAAgC,CAAC,CAAC;IAChDlJ,aAAa,CAACiE,UAAU,GAAG,KAAK;IAChCjE,aAAa,CAACgE,SAAS,GAAG,KAAK;IAC/BhE,aAAa,CAACmH,kBAAkB,GAAGhJ,UAAU,CAACgL,QAAQ,CAAC,CAAC;IACxD,MAAMC,SAAS,GAAG,IAAI1K,gBAAgB,CAAC,WAAW,EAAEsK,eAAe,CAAC;IACpEI,SAAS,CAACC,aAAa,GAAG1K,MAAM,CAAC2K,KAAK,CAAC,CAAC;IACxCF,SAAS,CAACG,aAAa,GAAG,IAAI,CAACxH,yBAAyB;IACxDqH,SAAS,CAACI,eAAe,GAAG,KAAK;IACjCxJ,aAAa,CAACyJ,QAAQ,GAAGL,SAAS;IAClC,OAAOpJ,aAAa;EACxB;EACA0J,oCAAoCA,CAAC7I,EAAE,EAAE;IACrC,IAAI,IAAI,CAACiB,sBAAsB,EAAE;MAC7B,OAAO,IAAI,CAACA,sBAAsB,CAAC6H,uCAAuC,CAAC9I,EAAE,CAAC;IAClF;IACA,OAAO,IAAI;EACf;EACAgB,0BAA0BA,CAACpC,YAAY,EAAE;IACrC,MAAMkF,cAAc,GAAG,IAAI,CAACjF,YAAY,CAACD,YAAY,CAACE,QAAQ,CAAC;IAC/D,MAAMiK,gBAAgB,GAAG;MACrBC,SAAS,EAAElF,cAAc,CAAC9D,EAAE;MAC5BiJ,WAAW,EAAE;IACjB,CAAC;IACDnF,cAAc,CAACoF,eAAe,GAAG,IAAI,CAAC1K,iBAAiB,CAAC2K,mBAAmB,CAAC9I,GAAG,CAAC,MAAM;MAClF,IAAK,CAAC,IAAI,CAAC5B,QAAQ,CAACkC,qCAAqC,IAAI/B,YAAY,CAACE,QAAQ,KAAK,IAAI,CAAC4B,mBAAmB,IAC3G,CAACoD,cAAc,CAAClF,YAAY,IAC3B,CAACkF,cAAc,CAAClF,YAAY,CAACiC,WAAW,CAACoD,IAAI,KAAK,CAAC,IAAI,CAACxF,QAAQ,CAACiD,6BAA6B,IAAI,CAACoC,cAAc,CAAClF,YAAY,CAACiC,WAAW,CAACwE,OAAO,CAAE,EAAE;QACvJ;MACJ;MACA,IAAIvB,cAAc,CAACvE,IAAI,EAAE;QACrBuE,cAAc,CAACvE,IAAI,CAAC6J,GAAG,GAAGtF,cAAc,CAACnE,OAAO;MACpD;MACA,IAAImE,cAAc,CAACvE,IAAI,IAAI,IAAI,CAACsJ,oCAAoC,CAAC/E,cAAc,CAAC9D,EAAE,CAAC,EAAE;QACrF,IAAI,CAACwB,MAAM,CAAC6H,mBAAmB,CAACvF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;MAC1E;MACA;MACA,IAAIjF,cAAc,CAACjE,eAAe,IAAIiE,cAAc,CAACvE,IAAI,IAAIuE,cAAc,CAACvE,IAAI,CAACmH,GAAG,EAAE;QAClF,IAAI,CAAC5C,cAAc,CAACxE,yBAAyB,EAAE;UAC3C,IAAI,CAACkC,MAAM,CAAC8H,mBAAmB,CAACxF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;UACtEjF,cAAc,CAACxE,yBAAyB,GAAGwE,cAAc,CAACzE,gBAAgB;UAC1EyE,cAAc,CAAC/D,aAAa,GAAG,IAAI;QACvC;MACJ,CAAC,MACI,IAAI+D,cAAc,CAACxE,yBAAyB,IAAIwE,cAAc,CAACtE,SAAS,EAAE;QAC3E,IAAI,CAACgC,MAAM,CAAC+H,iBAAiB,CAACzF,cAAc,CAACtE,SAAS,EAAEuJ,gBAAgB,CAAC;QACzEjF,cAAc,CAAC/D,aAAa,GAAG,KAAK;QACpC+D,cAAc,CAACxE,yBAAyB,GAAG,IAAI;MACnD;IACJ,CAAC,CAAC;IACF,MAAMkK,SAAS,GAAIC,OAAO,IAAK;MAC3B,IAAI,IAAI,CAAChL,QAAQ,CAACkC,qCAAqC,IAClD/B,YAAY,CAACE,QAAQ,KAAK,IAAI,CAAC4B,mBAAmB,IAAI,IAAI,CAACmI,oCAAoC,CAAC/E,cAAc,CAAC9D,EAAE,CAAE,EAAE;QACtH,IAAI8D,cAAc,CAACvE,IAAI,EAAE;UACrBuE,cAAc,CAACvE,IAAI,CAAC6J,GAAG,GAAGtF,cAAc,CAACnE,OAAO;QACpD;QACA,IAAI8J,OAAO,IAAI3F,cAAc,CAACvE,IAAI,IAAIuE,cAAc,CAACzE,gBAAgB,IAAI,IAAI,CAACiE,kBAAkB,CAACQ,cAAc,CAACzE,gBAAgB,CAAC,EAAE;UAC/HyE,cAAc,CAAChE,eAAe,GAAG,IAAI;UACrCgE,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,KAAK;UACrD,IAAI,CAAC3B,MAAM,CAAC8H,mBAAmB,CAACxF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;UACtEjF,cAAc,CAAC/D,aAAa,GAAG,IAAI;QACvC,CAAC,MACI,IAAI,CAAC0J,OAAO,IAAI3F,cAAc,CAACvE,IAAI,IAAIuE,cAAc,CAAChE,eAAe,EAAE;UACxE,IAAI,CAAC0B,MAAM,CAAC+H,iBAAiB,CAACzF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;UACpEjF,cAAc,CAAC/D,aAAa,GAAG,KAAK;UACpC+D,cAAc,CAAChE,eAAe,GAAG,KAAK;UACtCgE,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,IAAI;QACxD;MACJ,CAAC,MACI;QACD,IAAIsG,OAAO,IAAI,CAAC,IAAI,CAAChL,QAAQ,CAACkC,qCAAqC,IAAI,CAAC,IAAI,CAAClC,QAAQ,CAACiL,oBAAoB,EAAE;UACxG,IAAI,CAAChJ,mBAAmB,GAAG9B,YAAY,CAACE,QAAQ;QACpD;MACJ;IACJ,CAAC;IACD,IAAIF,YAAY,CAACiC,WAAW,CAACwE,OAAO,EAAE;MAClC,MAAMsE,IAAI,GAAIC,gBAAgB,IAAK;QAC/B9F,cAAc,CAAC+F,gBAAgB,GAAGD,gBAAgB,CAACE,YAAY,CAAC,OAAO,CAAC;QACxE,IAAIhG,cAAc,CAAC+F,gBAAgB,EAAE;UACjC/F,cAAc,CAACiG,8BAA8B,GAAGjG,cAAc,CAAC+F,gBAAgB,CAACG,8BAA8B,CAAC3J,GAAG,CAAE4J,SAAS,IAAK;YAC9H,IAAIA,SAAS,CAACC,OAAO,CAACT,OAAO,EAAE;cAC3B,MAAMA,OAAO,GAAGQ,SAAS,CAACC,OAAO,CAACT,OAAO,CAACU,OAAO;cACjDX,SAAS,CAACC,OAAO,CAAC;YACtB;UACJ,CAAC,CAAC;QACN,CAAC,MACI;UACD3F,cAAc,CAACsG,kBAAkB,GAAGR,gBAAgB,CAACS,gBAAgB,CAAC,CAAC;UACvEvG,cAAc,CAACwG,uBAAuB,GAAGxG,cAAc,CAACsG,kBAAkB,CAACJ,8BAA8B,CAAC3J,GAAG,CAAE4J,SAAS,IAAK;YACzH,IAAIA,SAAS,CAACC,OAAO,CAACT,OAAO,EAAE;cAC3B,MAAMA,OAAO,GAAGQ,SAAS,CAACC,OAAO,CAACT,OAAO,CAACU,OAAO;cACjDX,SAAS,CAACC,OAAO,CAAC;YACtB;UACJ,CAAC,CAAC;QACN;MACJ,CAAC;MACD,IAAI7K,YAAY,CAACgL,gBAAgB,EAAE;QAC/BD,IAAI,CAAC/K,YAAY,CAACgL,gBAAgB,CAAC;MACvC,CAAC,MACI;QACDhL,YAAY,CAAC2L,gCAAgC,CAAClK,GAAG,CAACsJ,IAAI,CAAC;MAC3D;IACJ,CAAC,MACI;MACD;MACA,MAAMa,mBAAmB,GAAIC,KAAK,IAAK;QACnC,IAAI3G,cAAc,CAAClF,YAAY,IAC3B6L,KAAK,CAAC5J,WAAW,KAAKiD,cAAc,CAAClF,YAAY,CAACiC,WAAW,IAC7DiD,cAAc,CAACvE,IAAI,IACnB,IAAI,CAACsJ,oCAAoC,CAAC/E,cAAc,CAAC9D,EAAE,CAAC,IAC5D8D,cAAc,CAACzE,gBAAgB,IAC/B,IAAI,CAACiE,kBAAkB,CAACQ,cAAc,CAACzE,gBAAgB,CAAC,EAAE;UAC1DyE,cAAc,CAAChE,eAAe,GAAG,IAAI;UACrCgE,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,KAAK;UACrD,IAAI,CAAC3B,MAAM,CAAC8H,mBAAmB,CAACxF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;UACtEjF,cAAc,CAAC/D,aAAa,GAAG,IAAI;QACvC;MACJ,CAAC;MACD,MAAM2K,iBAAiB,GAAID,KAAK,IAAK;QACjC,IAAI3G,cAAc,CAAClF,YAAY,IAC3B6L,KAAK,CAAC5J,WAAW,KAAKiD,cAAc,CAAClF,YAAY,CAACiC,WAAW,IAC7DiD,cAAc,CAACvE,IAAI,IACnB,IAAI,CAACsJ,oCAAoC,CAAC/E,cAAc,CAAC9D,EAAE,CAAC,EAAE;UAC9D,IAAI,CAACwB,MAAM,CAAC+H,iBAAiB,CAACzF,cAAc,CAACvE,IAAI,EAAEwJ,gBAAgB,CAAC;UACpEjF,cAAc,CAAChE,eAAe,GAAG,KAAK;UACtCgE,cAAc,CAAC5D,oBAAoB,CAACiD,SAAS,GAAG,IAAI;UACpDW,cAAc,CAAC/D,aAAa,GAAG,KAAK;QACxC;MACJ,CAAC;MACD+D,cAAc,CAAC6G,cAAc,GAAG;QAC5BC,SAAS,EAAEF,iBAAiB;QAC5BG,WAAW,EAAEL;MACjB,CAAC;MACD,IAAI,CAAChM,iBAAiB,CAACsM,OAAO,CAACC,gBAAgB,CAAC,aAAa,EAAEP,mBAAmB,CAAC;MACnF,IAAI,CAAChM,iBAAiB,CAACsM,OAAO,CAACC,gBAAgB,CAAC,WAAW,EAAEL,iBAAiB,CAAC;IACnF;EACJ;EACArI,iBAAiBA,CAAC2I,oBAAoB,EAAE;IACpC,MAAMlH,cAAc,GAAG,IAAI,CAACjF,YAAY,CAACmM,oBAAoB,CAAC;IAC9D,IAAI,CAAClH,cAAc,EAAE;MACjB;IACJ;IACA,IAAIA,cAAc,CAAC+F,gBAAgB,EAAE;MACjC,IAAI/F,cAAc,CAACiG,8BAA8B,EAAE;QAC/CjG,cAAc,CAAC+F,gBAAgB,CAACG,8BAA8B,CAACiB,MAAM,CAACnH,cAAc,CAACiG,8BAA8B,CAAC;MACxH;IACJ;IACA,IAAIjG,cAAc,CAACsG,kBAAkB,EAAE;MACnC,IAAItG,cAAc,CAACwG,uBAAuB,EAAE;QACxCxG,cAAc,CAACsG,kBAAkB,CAACJ,8BAA8B,CAACiB,MAAM,CAACnH,cAAc,CAACwG,uBAAuB,CAAC;MACnH;IACJ;IACA,IAAIxG,cAAc,CAACoF,eAAe,EAAE;MAChC,IAAI,CAAC1K,iBAAiB,CAAC2K,mBAAmB,CAAC8B,MAAM,CAACnH,cAAc,CAACoF,eAAe,CAAC;IACrF;IACA,IAAIpF,cAAc,CAAC6G,cAAc,EAAE;MAC/BnI,MAAM,CAACC,IAAI,CAACqB,cAAc,CAAC6G,cAAc,CAAC,CAAC3I,OAAO,CAAEkJ,SAAS,IAAK;QAC9D,MAAMC,IAAI,GAAGrH,cAAc,CAAC6G,cAAc,IAAI7G,cAAc,CAAC6G,cAAc,CAACO,SAAS,CAAC;QACtF,IAAIC,IAAI,EAAE;UACN,IAAI,CAAC3M,iBAAiB,CAACsM,OAAO,CAACM,mBAAmB,CAACF,SAAS,EAAEC,IAAI,CAAC;QACvE;MACJ,CAAC,CAAC;IACN;IACArH,cAAc,CAAC/E,kBAAkB,CAAC0B,OAAO,CAAC,CAAC;IAC3CqD,cAAc,CAAC5D,oBAAoB,CAACO,OAAO,CAAC,CAAC;IAC7C,IAAI,CAACjC,iBAAiB,CAAC6M,YAAY,CAAC,MAAM;MACtC,IAAI,CAACvH,cAAc,CAAC/D,aAAa,EAAE;QAC/B;MACJ;MACA;MACA,MAAMgJ,gBAAgB,GAAG;QACrBC,SAAS,EAAElF,cAAc,CAAC9D,EAAE;QAC5BiJ,WAAW,EAAE;MACjB,CAAC;MACD,IAAI,CAACzH,MAAM,CAAC+H,iBAAiB,CAAC,IAAI9L,WAAW,CAAC,CAAC,EAAEsL,gBAAgB,CAAC;IACtE,CAAC,CAAC;IACF;IACA,IAAIjF,cAAc,CAAC3D,mBAAmB,EAAE;MACpC,IAAI,CAAC3B,iBAAiB,CAAC4B,mCAAmC,CAAC6K,MAAM,CAACnH,cAAc,CAAC3D,mBAAmB,CAAC;IACzG;IACA;IACA,OAAO,IAAI,CAACtB,YAAY,CAACmM,oBAAoB,CAAC;IAC9C,IAAI,IAAI,CAACtK,mBAAmB,KAAKsK,oBAAoB,EAAE;MACnD;MACA,MAAMvI,IAAI,GAAGD,MAAM,CAACC,IAAI,CAAC,IAAI,CAAC5D,YAAY,CAAC;MAC3C,IAAI4D,IAAI,CAACK,MAAM,EAAE;QACb,IAAI,CAACpC,mBAAmB,GAAG+B,IAAI,CAAC,CAAC,CAAC;MACtC,CAAC,MACI;QACD,IAAI,CAAC/B,mBAAmB,GAAG,EAAE;MACjC;IACJ;EACJ;EACAxB,0BAA0BA,CAAA,EAAG;IACzB,MAAMoM,UAAU,GAAG,IAAI,CAAC9M,iBAAiB,CAACuG,kBAAkB;IAC5D;IACA,MAAMwG,iBAAiB,GAAG,IAAI,CAAC9M,QAAQ,CAACyI,eAAe,GAAG,IAAI,CAACzI,QAAQ,CAACuJ,uBAAuB,IAAIrK,oBAAoB,CAACsK,mBAAmB,CAACC,iBAAiB,GAAG,IAAI,CAAC1G,MAAM;IAC3K,MAAMzC,kBAAkB,GAAG3B,YAAY,CAAC,YAAY,EAAE;MAAEgL,QAAQ,EAAE,CAAC,GAAGkD;IAAW,CAAC,EAAEC,iBAAiB,CAAC;IACtGxM,kBAAkB,CAACoE,SAAS,GAAG,KAAK;IACpC;IACA,IAAI,IAAI,CAAC1E,QAAQ,CAAC+M,2BAA2B,EAAE;MAC3CzM,kBAAkB,CAAC6J,QAAQ,GAAG,IAAI,CAACnK,QAAQ,CAAC+M,2BAA2B;IAC3E,CAAC,MACI;MACD,IAAIC,YAAY;MAChB,IAAI,IAAI,CAAChN,QAAQ,CAACiN,uCAAuC,EAAE;QACvDD,YAAY,GAAG1N,YAAY,CAAC4N,kBAAkB,CAAC,+BAA+B,EAAE,IAAI,CAAClN,QAAQ,CAACiN,uCAAuC,EAAEH,iBAAiB,CAAC;MAC7J,CAAC,MACI;QACDE,YAAY,GAAG1N,YAAY,CAAC6N,qBAAqB,CAAC,UAAU,EAAEL,iBAAiB,CAAC;MACpF;MACAE,YAAY,CACPI,IAAI,CAAEC,GAAG,IAAK;QACf/M,kBAAkB,CAAC6J,QAAQ,GAAGkD,GAAG;MACrC,CAAC,CAAC,CACGC,KAAK,CAAEC,GAAG,IAAK;QAChB7N,MAAM,CAAC8N,IAAI,CAAC,0DAA0DD,GAAG,EAAE,CAAC;MAChF,CAAC,CAAC;IACN;IACA,MAAME,cAAc,GAAG,IAAIjO,aAAa,CAAC,CAAC;IAC1CiO,cAAc,CAACC,aAAa,CAACjO,cAAc,CAACkO,oBAAoB,CAAC;IACjE;IACA;IACA;IACA,MAAMC,YAAY,GAAG,IAAIhP,OAAO,CAAC,IAAI,CAACiE,qBAAqB,EAAE,IAAI,CAACA,qBAAqB,EAAE,IAAI,CAACA,qBAAqB,CAAC,CAAC0D,YAAY,CAACsG,UAAU,CAAC;IAC7I,MAAMgB,SAAS,GAAG,IAAI,CAAChL,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,MAAMiL,YAAY,GAAG,IAAIlP,OAAO,CAACiP,SAAS,EAAEA,SAAS,EAAEA,SAAS,CAAC,CAACtH,YAAY,CAACsG,UAAU,CAAC;IAC1F,MAAMkB,qBAAqB,GAAG,IAAI,CAAClL,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,MAAMmL,wBAAwB,GAAG,IAAIpP,OAAO,CAACmP,qBAAqB,EAAEA,qBAAqB,EAAEA,qBAAqB,CAAC,CAACxH,YAAY,CAACsG,UAAU,CAAC;IAC1I,MAAMoB,wBAAwB,GAAG,IAAI,CAACpL,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,MAAMqL,2BAA2B,GAAG,IAAItP,OAAO,CAACqP,wBAAwB,EAAEA,wBAAwB,EAAEA,wBAAwB,CAAC,CAAC1H,YAAY,CAACsG,UAAU,CAAC;IACtJ,MAAMsB,wBAAwB,GAAG,IAAI,CAACtL,qBAAqB,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,MAAMuL,2BAA2B,GAAG,IAAIxP,OAAO,CAACuP,wBAAwB,EAAEA,wBAAwB,EAAEA,wBAAwB,CAAC,CAAC5H,YAAY,CAACsG,UAAU,CAAC;IACtJ,MAAMwB,SAAS,GAAG,CACd;MAAEC,KAAK,EAAE,CAAC;MAAEC,KAAK,EAAEX;IAAa,CAAC,EACjC;MAAEU,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAEH;IAA4B,CAAC,EACjD;MAAEE,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAET;IAAa,CAAC,CACrC;IACD,MAAMU,WAAW,GAAG,CAChB;MAAEF,KAAK,EAAE,CAAC;MAAEC,KAAK,EAAET;IAAa,CAAC,EACjC;MAAEQ,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAEL;IAA4B,CAAC,EACjD;MAAEI,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAEX;IAAa,CAAC,CACrC;IACD,MAAMa,WAAW,GAAG,CAChB;MAAEH,KAAK,EAAE,CAAC;MAAEC,KAAK,EAAE3P,OAAO,CAAC8P;IAAa,CAAC,EACzC;MAAEJ,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAEP;IAAyB,CAAC,EAC9C;MAAEM,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAEX;IAAa,CAAC,CACrC;IACD,MAAMe,aAAa,GAAG,CAClB;MAAEL,KAAK,EAAE,CAAC;MAAEC,KAAK,EAAEX;IAAa,CAAC,EACjC;MAAEU,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAE3P,OAAO,CAAC8P;IAAa,CAAC,EAC1C;MAAEJ,KAAK,EAAE,EAAE;MAAEC,KAAK,EAAE3P,OAAO,CAAC8P;IAAa,CAAC,CAC7C;IACD,MAAME,WAAW,GAAG,IAAIrP,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAEA,SAAS,CAACsP,qBAAqB,EAAEtP,SAAS,CAACuP,0BAA0B,CAAC;IAChI,MAAMC,aAAa,GAAG,IAAIxP,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,EAAEA,SAAS,CAACsP,qBAAqB,EAAEtP,SAAS,CAACuP,0BAA0B,CAAC;IACpI,MAAME,aAAa,GAAG,IAAIzP,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,EAAEA,SAAS,CAACsP,qBAAqB,EAAEtP,SAAS,CAACuP,0BAA0B,CAAC;IACpI,MAAMG,eAAe,GAAG,IAAI1P,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,EAAEA,SAAS,CAACsP,qBAAqB,EAAEtP,SAAS,CAACuP,0BAA0B,CAAC;IACxIF,WAAW,CAACM,iBAAiB,CAACzB,cAAc,CAAC;IAC7CsB,aAAa,CAACG,iBAAiB,CAACzB,cAAc,CAAC;IAC/CuB,aAAa,CAACE,iBAAiB,CAACzB,cAAc,CAAC;IAC/CwB,eAAe,CAACC,iBAAiB,CAACzB,cAAc,CAAC;IACjDmB,WAAW,CAACO,OAAO,CAACd,SAAS,CAAC;IAC9BU,aAAa,CAACI,OAAO,CAACX,WAAW,CAAC;IAClCQ,aAAa,CAACG,OAAO,CAACV,WAAW,CAAC;IAClCQ,eAAe,CAACE,OAAO,CAACR,aAAa,CAAC;IACtC,MAAMpO,0BAA0B,GAAI6O,OAAO,IAAK;MAC5C,MAAMC,MAAM,GAAGD,OAAO,GAAGR,WAAW,GAAGG,aAAa;MACpDjC,iBAAiB,CAACwC,oBAAoB,CAAChP,kBAAkB,EAAE,CAAC+O,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM7O,4BAA4B,GAAI+O,WAAW,IAAK;MAClD,MAAMF,MAAM,GAAGE,WAAW,GAAGP,aAAa,GAAGC,eAAe;MAC5D,IAAIM,WAAW,EAAE;QACbjP,kBAAkB,CAACoE,SAAS,GAAG,IAAI;MACvC;MACAoI,iBAAiB,CAACwC,oBAAoB,CAAChP,kBAAkB,EAAE,CAAC+O,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM;QACxF,IAAI,CAACE,WAAW,EAAE;UACdjP,kBAAkB,CAACoE,SAAS,GAAG,KAAK;QACxC;MACJ,CAAC,CAAC;IACN,CAAC;IACD,OAAO;MAAEpE,kBAAkB;MAAEC,0BAA0B;MAAEC;IAA6B,CAAC;EAC3F;EACAmI,eAAeA,CAACtD,cAAc,EAAE0D,MAAM,EAAEyG,UAAU,EAAEC,SAAS,EAAE;IAC3D,MAAMC,WAAW,GAAG,IAAI1Q,WAAW,CAAC,CAAC;IACrC0Q,WAAW,CAACxH,QAAQ,GAAG,CAACyH,QAAQ;IAChC,IAAItK,cAAc,CAAC/E,kBAAkB,IAAI+E,cAAc,CAAClF,YAAY,EAAE;MAClE,MAAMyF,QAAQ,GAAGP,cAAc,CAAC/E,kBAAkB,CAACsF,QAAQ;MAC3D,MAAMgK,MAAM,GAAGzQ,cAAc,CAAC0Q,yBAAyB,CAACjK,QAAQ,EAAEmD,MAAM,CAAC;MACzE,KAAK,IAAI+G,SAAS,GAAG,CAAC,EAAEA,SAAS,GAAGN,UAAU,CAACO,MAAM,CAAC1L,MAAM,EAAEyL,SAAS,EAAE,EAAE;QACvE,MAAMtL,IAAI,GAAGgL,UAAU,CAACO,MAAM,CAACD,SAAS,CAAC;QACzC,IAAI,CAACL,SAAS,CAACjL,IAAI,CAAC,IAAI,CAAC,IAAI,CAACQ,6BAA6B,CAACR,IAAI,EAAEa,cAAc,CAAClF,YAAY,CAACE,QAAQ,CAAC,EAAE;UACrG;QACJ;QACA,MAAMgI,MAAM,GAAGxI,oBAAoB,CAACmQ,kBAAkB,CAACxL,IAAI,EAAEoL,MAAM,CAAC;QACpE,IAAIvH,MAAM,IAAIA,MAAM,CAACJ,GAAG,IAAII,MAAM,CAACH,QAAQ,GAAGwH,WAAW,CAACxH,QAAQ,EAAE;UAChEwH,WAAW,CAACzH,GAAG,GAAGI,MAAM,CAACJ,GAAG;UAC5ByH,WAAW,CAACvG,UAAU,GAAG3E,IAAI;UAC7BkL,WAAW,CAACnH,WAAW,GAAGF,MAAM,CAACE,WAAW;UAC5CmH,WAAW,CAACO,YAAY,GAAG5K,cAAc,CAAClF,YAAY,CAACwH,OAAO;UAC9D+H,WAAW,CAACQ,aAAa,GAAG7K,cAAc,CAAClF,YAAY,CAACyH,IAAI,IAAI,IAAI;UACpE8H,WAAW,CAACS,UAAU,GAAG9K,cAAc,CAAC/E,kBAAkB;UAC1DoP,WAAW,CAACxH,QAAQ,GAAGG,MAAM,CAACH,QAAQ;UACtCwH,WAAW,CAACU,EAAE,GAAG/H,MAAM,CAAC+H,EAAE;UAC1BV,WAAW,CAACW,EAAE,GAAGhI,MAAM,CAACgI,EAAE;UAC1BX,WAAW,CAACY,MAAM,GAAGjI,MAAM,CAACiI,MAAM;UAClCZ,WAAW,CAACa,SAAS,GAAGlI,MAAM,CAACkI,SAAS;QAC5C;MACJ;IACJ;IACA,OAAOb,WAAW;EACtB;EACA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,OAAOM,kBAAkBA,CAACxL,IAAI,EAAEoL,MAAM,EAAEY,gBAAgB,GAAG,KAAK,EAAE;IAC9D,MAAMC,SAAS,GAAGjM,IAAI,CAACiM,SAAS;IAChC,MAAMC,EAAE,GAAG,IAAI1R,WAAW,CAAC,CAAC;IAC5B,MAAM2R,YAAY,GAAGnM,IAAI,CAACoM,eAAe,CAAC,CAAC;IAC3C,IAAI,CAACpM,IAAI,CAACqM,oBAAoB,CAAC,CAAC,EAAE;MAC9B,OAAOH,EAAE;IACb;IACA,IAAI,CAAClM,IAAI,CAACiM,SAAS,IAAI,CAACE,YAAY,EAAE;MAClC,OAAOD,EAAE;IACb;IACA,IAAI,CAACF,gBAAgB,IAAI,CAACrR,cAAc,CAAC2R,UAAU,CAACH,YAAY,CAACI,cAAc,EAAEnB,MAAM,CAAC,EAAE;MACtF,OAAOc,EAAE;IACb;IACA,MAAMrI,MAAM,GAAGvJ,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC;IACpC,MAAMoS,MAAM,GAAGlS,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC;IACpC,MAAMqS,MAAM,GAAG,IAAIlS,GAAG,CAACH,OAAO,CAACsS,IAAI,CAAC,CAAC,EAAEtS,OAAO,CAACsS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IACzD,IAAIhJ,QAAQ,GAAG,CAACyH,QAAQ;IACxB,IAAIwB,GAAG,EAAEC,yBAAyB,EAAEC,0BAA0B,EAAEC,gBAAgB;IAChF,MAAMC,MAAM,GAAGzS,UAAU,CAACF,OAAO,CAAC,CAAC,CAAC;IACpC,MAAM4S,WAAW,GAAG1S,UAAU,CAAC2S,MAAM,CAAC,CAAC,CAAC;IACxCD,WAAW,CAACxL,QAAQ,CAACxB,IAAI,CAACkN,cAAc,CAAC,CAAC,CAAC;IAC3CF,WAAW,CAACG,MAAM,CAAC,CAAC;IACpB/S,OAAO,CAACgT,yBAAyB,CAAChC,MAAM,CAAC2B,MAAM,EAAEC,WAAW,EAAED,MAAM,CAAC;IACrE,KAAK,IAAIM,KAAK,GAAG,CAAC,EAAEA,KAAK,GAAGpB,SAAS,CAACpM,MAAM,EAAEwN,KAAK,EAAE,EAAE;MACnD,MAAMC,OAAO,GAAGrB,SAAS,CAACoB,KAAK,CAAC;MAChCC,OAAO,CAACC,YAAY,CAACR,MAAM,EAAE/M,IAAI,CAACwN,UAAU,EAAExN,IAAI,CAACyN,UAAU,CAAC,CAAC,EAAEjB,MAAM,CAAC;MACxEpS,OAAO,CAACgT,yBAAyB,CAACZ,MAAM,EAAExM,IAAI,CAACkN,cAAc,CAAC,CAAC,EAAEV,MAAM,CAAC;MACxEG,GAAG,GAAGvS,OAAO,CAACsT,QAAQ,CAAClB,MAAM,EAAEpB,MAAM,CAAC2B,MAAM,CAAC;MAC7C;MACAF,0BAA0B,GAAGzS,OAAO,CAACsT,QAAQ,CAAClB,MAAM,EAAExM,IAAI,CAAC2N,mBAAmB,CAAC,CAAC,CAAC;MACjFf,yBAAyB,GAAGxS,OAAO,CAACsT,QAAQ,CAACtC,MAAM,CAAC2B,MAAM,EAAE/M,IAAI,CAAC2N,mBAAmB,CAAC,CAAC,CAAC;MACvF,IAAIf,yBAAyB,KAAK,CAAC,CAAC,IAAIC,0BAA0B,KAAK,CAAC,CAAC,IAAIA,0BAA0B,GAAGD,yBAAyB,EAAE;QACjID,GAAG,GAAG,CAAC;QACPH,MAAM,CAAChL,QAAQ,CAAC4J,MAAM,CAAC2B,MAAM,CAAC;MAClC;MACA,IAAIJ,GAAG,KAAK,CAAC,CAAC,IAAIA,GAAG,GAAGjJ,QAAQ,EAAE;QAC9BA,QAAQ,GAAGiJ,GAAG;QACd;QACApS,GAAG,CAACqT,iBAAiB,CAACxC,MAAM,CAAC2B,MAAM,EAAEP,MAAM,EAAEC,MAAM,CAAC;QACpDA,MAAM,CAAC5M,MAAM,GAAG6D,QAAQ,GAAG,CAAC;QAC5BoJ,gBAAgB,GAAGL,MAAM,CAACoB,cAAc,CAAC7N,IAAI,CAAC;QAC9C6D,MAAM,CAACrC,QAAQ,CAACgL,MAAM,CAAC;MAC3B;IACJ;IACA,IAAI9I,QAAQ,GAAG0H,MAAM,CAAC7G,MAAM,EAAE;MAC1B2H,EAAE,CAACzI,GAAG,GAAG,IAAI;MACbyI,EAAE,CAACxI,QAAQ,GAAGA,QAAQ;MACtBwI,EAAE,CAACvH,UAAU,GAAG3E,IAAI;MACpBkM,EAAE,CAACnI,WAAW,GAAGF,MAAM,CAACiK,KAAK,CAAC,CAAC;MAC/B,IAAIhB,gBAAgB,IAAIA,gBAAgB,CAAClB,EAAE,KAAK,IAAI,IAAIkB,gBAAgB,CAACjB,EAAE,KAAK,IAAI,EAAE;QAClFK,EAAE,CAACJ,MAAM,GAAGgB,gBAAgB,CAAChB,MAAM;QACnCI,EAAE,CAACH,SAAS,GAAGe,gBAAgB,CAACf,SAAS;QACzCG,EAAE,CAACN,EAAE,GAAGkB,gBAAgB,CAAClB,EAAE;QAC3BM,EAAE,CAACL,EAAE,GAAGiB,gBAAgB,CAACjB,EAAE;MAC/B;IACJ;IACA,OAAOK,EAAE;EACb;AACJ;AACA7Q,oBAAoB,CAAC2B,UAAU,GAAG,GAAG;AACrC;AACA;AACA;AACA3B,oBAAoB,CAAC0S,IAAI,GAAG7T,gBAAgB,CAAC8T,gBAAgB;AAC7D;AACA;AACA;AACA;AACA;AACA3S,oBAAoB,CAAC4S,OAAO,GAAG,CAAC;AAChC;AACAhU,oBAAoB,CAACiU,eAAe,CAAC7S,oBAAoB,CAAC0S,IAAI,EAAE,CAACI,gBAAgB,EAAEC,OAAO,KAAK;EAC3F,OAAO,MAAM,IAAI/S,oBAAoB,CAAC8S,gBAAgB,EAAEC,OAAO,CAAC;AACpE,CAAC,EAAE/S,oBAAoB,CAAC4S,OAAO,EAAE,IAAI,CAAC","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}