drone-camera 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +157 -2
- package/index.d.ts +51 -0
- package/index.d.ts.map +1 -0
- package/index.js +20474 -0
- package/index.js.map +1 -0
- package/index.umd.cjs +1361 -0
- package/index.umd.cjs.map +1 -0
- package/lib/drone-capture-manifest.d.ts +169 -0
- package/lib/drone-capture-manifest.d.ts.map +1 -0
- package/lib/drone-capture-panel.d.ts +135 -0
- package/lib/drone-capture-panel.d.ts.map +1 -0
- package/lib/drone-capture.d.ts +380 -0
- package/lib/drone-capture.d.ts.map +1 -0
- package/lib/drone-cesium-mission.d.ts +120 -0
- package/lib/drone-cesium-mission.d.ts.map +1 -0
- package/lib/drone-cesium-rig.d.ts +50 -0
- package/lib/drone-cesium-rig.d.ts.map +1 -0
- package/lib/drone-cesium.d.ts +519 -0
- package/lib/drone-cesium.d.ts.map +1 -0
- package/lib/drone-control.d.ts +188 -0
- package/lib/drone-control.d.ts.map +1 -0
- package/lib/drone-engine.d.ts +70 -0
- package/lib/drone-engine.d.ts.map +1 -0
- package/lib/drone-exif.d.ts +64 -0
- package/lib/drone-exif.d.ts.map +1 -0
- package/lib/drone-fly.d.ts +545 -0
- package/lib/drone-fly.d.ts.map +1 -0
- package/lib/drone-gallery.d.ts +146 -0
- package/lib/drone-gallery.d.ts.map +1 -0
- package/lib/drone-husky-model.d.ts +22 -0
- package/lib/drone-husky-model.d.ts.map +1 -0
- package/lib/drone-image-utils.d.ts +67 -0
- package/lib/drone-image-utils.d.ts.map +1 -0
- package/lib/drone-image-viewer.d.ts +97 -0
- package/lib/drone-image-viewer.d.ts.map +1 -0
- package/lib/drone-lights.d.ts +194 -0
- package/lib/drone-lights.d.ts.map +1 -0
- package/lib/drone-minimap.d.ts +155 -0
- package/lib/drone-minimap.d.ts.map +1 -0
- package/lib/drone-panel.d.ts +265 -0
- package/lib/drone-panel.d.ts.map +1 -0
- package/lib/drone-panorama-viewer.d.ts +162 -0
- package/lib/drone-panorama-viewer.d.ts.map +1 -0
- package/lib/drone-panorama.d.ts +242 -0
- package/lib/drone-panorama.d.ts.map +1 -0
- package/lib/drone-photogrammetry.d.ts +207 -0
- package/lib/drone-photogrammetry.d.ts.map +1 -0
- package/lib/drone-radar.d.ts +136 -0
- package/lib/drone-radar.d.ts.map +1 -0
- package/lib/drone-reconstruction-preview.d.ts +84 -0
- package/lib/drone-reconstruction-preview.d.ts.map +1 -0
- package/lib/drone-rig.d.ts +385 -0
- package/lib/drone-rig.d.ts.map +1 -0
- package/lib/drone-sim.d.ts +883 -0
- package/lib/drone-sim.d.ts.map +1 -0
- package/lib/drone-stitch.d.ts +84 -0
- package/lib/drone-stitch.d.ts.map +1 -0
- package/lib/drone-world.d.ts +194 -0
- package/lib/drone-world.d.ts.map +1 -0
- package/lib/mission-editor.d.ts +116 -0
- package/lib/mission-editor.d.ts.map +1 -0
- package/lib/mission-panel.d.ts +173 -0
- package/lib/mission-panel.d.ts.map +1 -0
- package/package.json +61 -4
package/index.umd.cjs
ADDED
|
@@ -0,0 +1,1361 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.DroneControl={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){"@babel/helpers - typeof";return t=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},t(e)}function n(e,n){if(t(e)!=`object`||!e)return e;var r=e[Symbol.toPrimitive];if(r!==void 0){var i=r.call(e,n||`default`);if(t(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(e)}function r(e){var r=n(e,`string`);return t(r)==`symbol`?r:r+``}function i(e,t,n){return(t=r(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var a={name:`DJI Mini 4 Pro`,weightKg:.249,batteryWh:18.96,batteryNominalVoltage:7.32,batteryFullVoltage:8.4,batteryEmptyVoltage:6.9,batteryInternalResistance:.09,maxWindResistance:10.7,hoverPowerWatts:33,idlePowerWatts:1.6,climbWattsPerMps:3.6,levelSpeedPowerGain:.55,maxFlightTimeMin:34,takeoffAltitude:1.2,rthAltitudeDefault:20,landingSlowAltitude:2,gimbalPitchMin:-90,gimbalPitchMax:60,gimbalYawRange:5},o={cine:{label:`平稳挡 C`,horizontalSpeed:5,climbSpeed:3,descendSpeed:1.5,maxTiltDeg:20,accel:2,brakeAccel:3,yawRateDeg:60},normal:{label:`普通挡 N`,horizontalSpeed:12,climbSpeed:5,descendSpeed:3,maxTiltDeg:30,accel:3.5,brakeAccel:6,yawRateDeg:100},sport:{label:`运动挡 S`,horizontalSpeed:16,climbSpeed:5,descendSpeed:5,maxTiltDeg:35,accel:5,brakeAccel:8,yawRateDeg:150}},s=Object.keys(o).map(e=>({key:e,label:o[e].label})),c=0,l=1e3,u=1,d=90,f=.5,p={powerOff:`未上电`,selfCheck:`开机自检`,warmingUp:`传感器预热`,standby:`地面待机`,motorsOn:`电机已启动`,takingOff:`自动起飞`,flying:`飞行中`,waypoint:`航线执行`,rth:`智能返航`,landing:`自动降落`,emergency:`动力丧失 · 坠落`,stopped:`已停桨`},m={gps:`GNSS 卫星定位`,vision:`视觉定位`,atti:`姿态模式(无定位)`},h={throttle:0,yaw:0,pitch:0,roll:0},g=[`FrontLeft`,`FrontRight`,`RearLeft`,`RearRight`],_={gnssLost:!1,compassError:!1,imuError:!1,motorFailure:!1,rcLost:!1,visionLost:!1,obstacleAvoidanceOff:!1},v={maxAltitude:120,maxDistance:500,unlimitedFlight:!1,rthAltitude:20,windSpeed:0,windDirection:0,lowBatteryPercent:20,criticalBatteryPercent:10,rcFailsafe:`rth`,timeScale:1,speedScale:1,selfCheckSeconds:.3,warmupSeconds:.28,gnssAcquireRate:30},y={idle:`未执行`,running:`执行中`,paused:`已暂停`},b={idle:`待执行`,"depart-climb":`垂直调整到首航点高度`,"depart-cruise":`水平飞向首个航点`,"depart-settle":`调整到航点高度`,"depart-align":`对准航线方向`,goto:`飞向航点`,hover:`航点悬停`};function x(e){return e.startsWith(`depart-`)}var S={autoSpeed:6,headingMode:`auto`,pathMode:`straight`,finishAction:`hover`,loop:!1},C=[{x:0,z:-32,altitude:35,speed:6,hoverSeconds:2,gimbalPitch:-40,action:`photo`},{x:32,z:-32,altitude:40,speed:6,hoverSeconds:0,gimbalPitch:null,action:`none`},{x:32,z:18,altitude:40,speed:6,hoverSeconds:0,gimbalPitch:null,action:`none`},{x:0,z:18,altitude:30,speed:6,hoverSeconds:3,gimbalPitch:-60,action:`photo`},{x:-28,z:0,altitude:35,speed:6,hoverSeconds:0,gimbalPitch:null,action:`none`}],w=500;function T(e,t=500){let n=(e,t)=>typeof e==`number`&&Number.isFinite(e)?e:t,r=e.gimbalPitch;return{x:n(e.x,0),z:n(e.z,0),altitude:I(n(e.altitude,30),1,t),speed:I(n(e.speed,0),0,16),hoverSeconds:I(n(e.hoverSeconds,0),0,60),gimbalPitch:typeof r==`number`&&Number.isFinite(r)?I(r,a.gimbalPitchMin,a.gimbalPitchMax):null,action:e.action===`photo`?`photo`:`none`}}function E(e,t,n){let r=Math.max(.5,t.autoSpeed),i=0,a=0,o=n.x,s=n.z,c=0,l=1/0,u=(e.length,0);for(let t of e){let e=Math.hypot(t.x-o,t.z-s,t.altitude-c);i+=e,a+=e/Math.max(.5,t.speed>0?t.speed:r)+t.hoverSeconds,l=Math.min(l,t.altitude),u=Math.max(u,t.altitude),o=t.x,s=t.z,c=t.altitude}return{format:`drone-camera/mission`,version:1,exportedAt:new Date().toISOString(),frame:{origin:`返航点(起飞点)`,unit:`m`,x:`东向偏移(向东为正)`,z:`南向偏移(向南为正,负值表示偏北)`,altitude:`相对起飞点的高度(AGL)`},home:{x:n.x,z:n.z},config:t,summary:{points:e.length,distance:Number(i.toFixed(2)),duration:Number(a.toFixed(1)),altitudeMin:e.length?l:0,altitudeMax:u},waypoints:e}}function D(e){let t=e=>{let t=String(e);return/[",\r\n]/.test(t)?`"${t.replace(/"/g,`""`)}"`:t};return`${[[`序号`,`X(东向,m)`,`Z(南向,m)`,`高度(m)`,`速度(m/s,空=巡航)`,`悬停(s)`,`云台俯仰(度)`,`动作`],...e.map((e,t)=>[t+1,e.x,e.z,e.altitude,e.speed>0?e.speed:``,e.hoverSeconds,e.gimbalPitch??``,e.action===`photo`?`拍照`:`无动作`])].map(e=>e.map(t).join(`,`)).join(`\r
|
|
2
|
+
`)}\r\n`}function O(e,t=`json`){return t===`csv`?D(e.waypoints):`${JSON.stringify(e,null,2)}\n`}function k(e,t,n,r,i){let a=(e,t,n,r)=>Math.hypot(n-e,r-t),o=0,s=1/0;for(let c=0;c<=e.length;c+=1){let l=c===0?null:e[c-1],u=e[c]??null,d=l?l.x:r,f=l?l.z:i,p=u?a(d,f,t,n)+a(t,n,u.x,u.z)-a(d,f,u.x,u.z):a(d,f,t,n);p<s-1e-6&&(s=p,o=c)}return o}var A=9.81,j=3,M=10,N=12,P=12,ee=45,F=1,te=1,ne=.3,re=.9,ie=.8,ae=3,oe=60,se=90,ce=.25,le=.3,ue=.15,de=2.5,I=(e,t,n)=>Math.min(n,Math.max(t,e)),L=(e,t,n)=>e+(t-e)*n,fe=e=>e*Math.PI/180,pe=e=>e*180/Math.PI;function me(e){return(e%360+360)%360}function he(e){return`${Number.isInteger(e)?String(e):e.toFixed(2).replace(/\.?0+$/,``)}×`}function ge(e){let t=fe(e);return{x:Math.sin(t),z:-Math.cos(t)}}var _e=class{constructor(){i(this,`config`,{...v}),i(this,`faults`,{..._}),i(this,`obstacles`,[]),i(this,`phase`,`powerOff`),i(this,`mode`,`normal`),i(this,`position`,{x:0,y:0,z:0}),i(this,`velocity`,{x:0,y:0,z:0}),i(this,`heading`,0),i(this,`tiltPitch`,0),i(this,`tiltRoll`,0),i(this,`motorLoad`,0),i(this,`motorSpeeds`,{FrontLeft:0,FrontRight:0,RearLeft:0,RearRight:0}),i(this,`armFold`,0),i(this,`damaged`,!1),i(this,`stick`,{...h}),i(this,`externalChecks`,[]),i(this,`recording`,!1),i(this,`recordSeconds`,0),i(this,`photoCount`,0),i(this,`cameraZoom`,1),i(this,`gimbalPitch`,-10),i(this,`gimbalRoll`,0),i(this,`gimbalYaw`,0),i(this,`mission`,C.map(e=>({...e}))),i(this,`missionConfig`,{...S}),i(this,`missionStatus`,`idle`),i(this,`missionIndex`,-1),i(this,`missionStage`,`idle`),i(this,`events`,[]),i(this,`time`,0),i(this,`phaseTime`,0),i(this,`flightTime`,0),i(this,`accelX`,0),i(this,`accelZ`,0),i(this,`tiltPitchTarget`,0),i(this,`tiltRollTarget`,0),i(this,`yawRateCurrent`,0),i(this,`spinHeading`,null),i(this,`spinRateDeg`,90),i(this,`batteryUsedWh`,0),i(this,`batteryTemp`,25),i(this,`satellites`,0),i(this,`visionAvailable`,!1),i(this,`rcLinkQuality`,1),i(this,`rcLostTimer`,0),i(this,`lowBatteryCountdown`,0),i(this,`rthStage`,`ascend`),i(this,`rthReason`,``),i(this,`rthStickGrace`,0),i(this,`home`,{x:0,z:0}),i(this,`homeRecorded`,!1),i(this,`altitudeMax`,0),i(this,`altitudeLimitReached`,!1),i(this,`distanceLimitReached`,!1),i(this,`obstacleReport`,{forward:null,backward:null,left:null,right:null,up:null,down:null,braking:!1,brakingDirection:null}),i(this,`eventId`,0),i(this,`warnedAt`,new Map),i(this,`landingTimer`,0),i(this,`landingStage`,`approach`),i(this,`landingHoldTimer`,0),i(this,`missionPending`,!1),i(this,`missionStartHeading`,0),i(this,`missionStickGrace`,0),i(this,`missionHoverTimer`,0),i(this,`missionWaypointTimer`,0),i(this,`missionElapsed`,0),i(this,`missionPasses`,0),i(this,`missionPauseReason`,``),i(this,`missionPausedStage`,`idle`),i(this,`missionTotalDistance`,0),i(this,`scaledSpec`,null)}get phaseLabel(){if(this.phase===`landing`){if(this.landingStage===`hold`)return`降落 · ${F} 米悬停确认`;if(this.landingStage===`settle`)return`降落 · 缓慢触地`;if(this.landingStage===`approach`)return`降落 · 下降至悬停位`}return p[this.phase]}get airborne(){return this.position.y>.05&&this.phase!==`powerOff`}get motorsOn(){return this.motorLoad>.02}get altitudeCeiling(){return this.config.unlimitedFlight?1/0:this.config.maxAltitude}get distanceCeiling(){return this.config.unlimitedFlight?1/0:this.config.maxDistance}setConfig(e){let t=this.config.unlimitedFlight;this.config={...this.config,...e},e.unlimitedFlight!==void 0&&e.unlimitedFlight!==t&&this.pushEvent(`info`,e.unlimitedFlight?`已取消高度 / 距离限制(演示模式)`:`已恢复限高 ${this.config.maxAltitude} m、限距 ${this.config.maxDistance} m`)}get speedScale(){let e=this.config.speedScale;return Number.isFinite(e)?I(e,0,l):1}setSpeedScale(e){let t=Number.isFinite(e)?I(e,0,l):1,n=this.speedScale;this.config.speedScale=t,!(Math.abs(t-n)<1e-9)&&this.pushEvent(`info`,`飞行速度倍率调整为 ${he(t)}`)}specFor(e){let t=this.speedScale,n=this.scaledSpec;if(n&&n.mode===e&&n.scale===t)return n.spec;let r=o[e],i=t===1?r:{...r,horizontalSpeed:r.horizontalSpeed*t,climbSpeed:r.climbSpeed*t,descendSpeed:r.descendSpeed*t,accel:r.accel*t,brakeAccel:r.brakeAccel*t,yawRateDeg:r.yawRateDeg*t};return this.scaledSpec={mode:e,scale:t,spec:i},i}get modeSpec(){return this.specFor(this.mode)}get batteryPercent(){return I(100-this.batteryUsedWh/a.batteryWh*100,0,100)}get openCircuitVoltage(){let e=this.batteryPercent/100;return a.batteryEmptyVoltage+(a.batteryFullVoltage-a.batteryEmptyVoltage)*e**.55}get batteryCurrent(){return this.currentPowerWatts/Math.max(6.4,this.openCircuitVoltage)}get batteryVoltage(){return Math.max(6,this.openCircuitVoltage-this.batteryCurrent*a.batteryInternalResistance)}get positionSource(){return this.faults.gnssLost?this.visionAvailable?`vision`:`atti`:this.satellites>=6&&!this.faults.compassError?`gps`:this.visionAvailable?`vision`:`atti`}get currentPowerWatts(){if(this.phase===`powerOff`)return 0;let e=I(Math.hypot(this.velocity.x,this.velocity.z)/16,0,1.2),t=this.motorLoad>.02,n=a.idlePowerWatts+a.hoverPowerWatts*(t?1:.05)*(1+a.levelSpeedPowerGain*e*e);n+=Math.max(0,this.velocity.y)*a.climbWattsPerMps,t&&(n=Math.max(n,12));let r=1+I(this.config.windSpeed/30,0,1)*.35;return n*r}get remainingMinutes(){let e=Math.max(this.currentPowerWatts,12);return this.batteryPercent/100*a.batteryWh*60/e}powerOn(){(this.phase===`powerOff`||this.phase===`stopped`)&&(this.damaged?this.pushEvent(`error`,`飞行器受损,需重新上电复位后再次自检`):(this.phase=`selfCheck`,this.phaseTime=0,this.heading=0,this.position={x:0,y:0,z:0},this.velocity={x:0,y:0,z:0},this.batteryUsedWh=0,this.batteryTemp=25,this.satellites=+!this.faults.gnssLost,this.flightTime=0,this.altitudeMax=0,this.damaged=!1,this.pushEvent(`info`,`飞行器上电,开始系统自检`)))}powerOff(){this.airborne||this.phase===`powerOff`||(this.phase=`powerOff`,this.motorLoad=0,this.missionPending&&(this.missionPending=!1,this.missionStatus=`idle`,this.missionIndex=-1),this.recording&&this.stopRecording(),this.pushEvent(`info`,`飞行器已关机`))}setMode(e){this.mode!==e&&(this.mode=e,this.pushEvent(`info`,`切换至${o[e].label}`))}setStick(e){this.stick={...this.stick,...e}}startMotors(){if(this.phase!==`standby`)return!1;let e=this.checklist.filter(e=>e.blocking&&!e.ok);return e.length>0?(this.pushEvent(`error`,`起飞前检查未通过:${e.map(e=>e.label).join(`、`)}`),!1):(this.phase=`motorsOn`,this.phaseTime=0,this.pushEvent(`success`,`电机已启动(内八掰杆),桨叶开始怠速旋转`),!0)}stopMotors(){return this.phase===`motorsOn`&&(this.phase=`standby`,this.pushEvent(`info`,`电机已停止`),!0)}takeOff(){return this.phase===`motorsOn`&&(this.phase=`takingOff`,this.phaseTime=0,this.home={x:this.position.x,z:this.position.z},this.homeRecorded=!0,this.damageCheck(),this.pushEvent(`success`,`起飞:自动上升至 1.2 米`),!0)}autoTakeOff(){return this.phase===`standby`&&!this.startMotors()?!1:this.takeOff()}startLanding(){return!this.airborne&&this.phase!==`takingOff`||this.phase===`landing`||this.phase===`emergency`?!1:(this.abortMission(`触发自动降落`),this.spinHeading=null,this.phase=`landing`,this.phaseTime=0,this.landingTimer=0,this.beginLandingDescent(),this.pushEvent(`info`,`开始自动降落`),!0)}startRth(e){return!this.airborne||this.phase===`rth`?!1:(this.abortMission(`触发返航`),this.spinHeading=null,this.phase=`rth`,this.phaseTime=0,this.rthStage=this.position.y<this.config.rthAltitude-.5?`ascend`:`cruise`,this.rthReason=e,this.rthStickGrace=1.2,this.pushEvent(`warn`,`触发智能返航(${e}),返航高度 ${this.config.rthAltitude} 米`),!0)}cancelRth(e=`用户取消`){this.phase===`rth`&&(this.phase=`flying`,this.pushEvent(`info`,`返航已中止(${e})`))}emergencyStop(){return this.airborne?(this.pushEvent(`warn`,`飞行器尚未落地(离地 ${this.position.y.toFixed(1)} 米),已拒绝紧急停桨,请先降落`),!1):this.stopMotors()}reset(){this.phase=`powerOff`,this.position={x:0,y:0,z:0},this.velocity={x:0,y:0,z:0},this.tiltPitch=0,this.tiltRoll=0,this.heading=0,this.spinHeading=null,this.yawRateCurrent=0,this.motorLoad=0,this.damaged=!1,this.batteryUsedWh=0,this.flightTime=0,this.altitudeMax=0,this.stick={...h},this.recording=!1,this.recordSeconds=0,this.rthReason=``,this.missionStatus=`idle`,this.missionIndex=-1,this.missionStage=`idle`,this.missionPending=!1,this.missionHoverTimer=0,this.missionWaypointTimer=0,this.missionElapsed=0,this.missionPasses=0,this.missionPauseReason=``,this.pushEvent(`info`,`沙盒已重置`)}step(e){let t=I(e,0,.1);t<=0||(this.time+=t,this.phaseTime+=t,this.recording&&(this.recordSeconds+=t),this.phase===`powerOff`?(this.motorLoad=L(this.motorLoad,0,Math.min(1,t*6)),this.updateBattery(t)):(this.updatePhaseMachine(t),this.updateGnss(t),this.updateFlight(t),this.updateCamera(t),this.updateBattery(t),this.updateFailsafe(t)))}updatePhaseMachine(e){switch(this.phase){case`selfCheck`:this.motorLoad=L(this.motorLoad,0,Math.min(1,e*4)),this.phaseTime>=this.config.selfCheckSeconds&&(this.phase=`warmingUp`,this.phaseTime=0,this.pushEvent(`info`,`自检通过,开始 IMU / 传感器预热`));break;case`warmingUp`:this.phaseTime>=this.config.warmupSeconds&&(this.phase=`standby`,this.phaseTime=0,this.home={x:this.position.x,z:this.position.z},this.homeRecorded=!0,this.pushEvent(`success`,`预热完成,已记录返航点,等待起飞指令`));break;case`motorsOn`:this.motorLoad=L(this.motorLoad,.32,Math.min(1,e*3));break;case`takingOff`:{this.motorLoad=L(this.motorLoad,.62,Math.min(1,e*3));let t=1.5*this.speedScale;this.position.y=Math.min(a.takeoffAltitude,this.position.y+t*e),this.velocity.y=t,this.settleHorizontal(e),this.position.y>=a.takeoffAltitude-.01&&(this.position.y=a.takeoffAltitude,this.velocity.y=0,this.missionPending?this.beginMissionPath():(this.phase=`flying`,this.pushEvent(`success`,`已到达 1.2 米,进入悬停`)));break}case`landing`:this.updateLanding(e);break;case`emergency`:this.applyGravityFall(e);break;case`stopped`:case`standby`:this.motorLoad=L(this.motorLoad,0,Math.min(1,e*3)),this.settleHorizontal(e)}}beginLandingDescent(){this.landingHoldTimer=0,this.landingStage=this.position.y>1.05?`approach`:`settle`}updateLanding(e){if(this.motorLoad=L(this.motorLoad,.55,Math.min(1,e*3)),this.settleHorizontal(e),this.landingStage===`approach`){let t=this.position.y<=a.landingSlowAltitude?.6*this.speedScale:this.modeSpec.descendSpeed;this.velocity.y=-t,this.position.y-=t*e,this.position.y<=F&&(this.position.y=F,this.velocity.y=0,this.enterLandingHold());return}if(this.landingStage===`hold`){this.position.y=F,this.velocity.y=0,this.landingHoldTimer+=e,this.landingHoldTimer>=te&&(this.landingStage=`settle`,this.pushEvent(`info`,`悬停确认完成,开始缓慢降落`));return}let t=ne*this.speedScale;this.velocity.y=-t,this.position.y-=t*e,this.position.y<=.02?(this.position.y=0,this.velocity.y=0,this.landingTimer+=e,this.landingTimer>=1.2&&this.finishLanding()):this.landingTimer=0}enterLandingHold(){this.landingStage=`hold`,this.landingHoldTimer=0,this.pushEvent(`info`,`已到达 ${F} 米悬停位,确认后缓降`)}finishLanding(){this.phase=`standby`,this.landingTimer=0,this.landingHoldTimer=0,this.landingStage=`settle`,this.motorLoad=0,this.velocity={x:0,y:0,z:0},this.recording&&this.stopRecording(),this.pushEvent(`success`,`已安全降落,本次飞行 ${this.formatDuration(this.flightTime)}`),this.batteryPercent<=this.config.criticalBatteryPercent&&this.pushEvent(`warn`,`严重低电量,建议更换电池后再起飞`)}applyGravityFall(e){this.velocity.y-=A*e,this.velocity.x*=1-Math.min(1,e*.4),this.velocity.z*=1-Math.min(1,e*.4),this.position.x+=this.velocity.x*e,this.position.y+=this.velocity.y*e,this.position.z+=this.velocity.z*e,this.tiltPitch=L(this.tiltPitch,25,Math.min(1,e*2)),this.position.y<=0&&(this.position.y=0,this.velocity={x:0,y:0,z:0},this.damaged=!0,this.phase=`stopped`,this.pushEvent(`error`,`飞行器坠地受损,请重新上电复位`))}settleHorizontal(e){if(this.positionSource===`atti`){let t=this.windVector();this.velocity.x=L(this.velocity.x,t.x,Math.min(1,e*.8)),this.velocity.z=L(this.velocity.z,t.z,Math.min(1,e*.8))}else{let t=Math.min(1,e*4);this.velocity.x=L(this.velocity.x,0,t),this.velocity.z=L(this.velocity.z,0,t)}this.position.x+=this.velocity.x*e,this.position.z+=this.velocity.z*e}updateFlight(e){let t=this.velocity.x,n=this.velocity.z;(this.phase===`flying`||this.phase===`rth`||this.phase===`waypoint`)&&(this.phase===`waypoint`?this.updateMission(e):this.updateGnssPositionFlight(e),this.updateMotorLoad(e)),this.accelX=(this.velocity.x-t)/e,this.accelZ=(this.velocity.z-n)/e,this.updateTilt(e),this.updateMotorSpeeds(e),this.applyObstacleBrake(),this.altitudeMax=Math.max(this.altitudeMax,this.position.y)}updateGnssPositionFlight(e){let t=this.modeSpec,n=this.positionSource,r={pitch:this.stick.pitch,roll:this.stick.roll},i=Math.hypot(r.pitch,r.roll);if(this.phase===`rth`){this.updateRth(e);return}n===`atti`&&!this.faults.gnssLost&&(this.heading+=Math.sin(this.time*.7)*8*e);let a=i>1?1/i:1,o=r.pitch*t.horizontalSpeed*a,s=r.roll*t.horizontalSpeed*a,c=ge(this.heading),l={x:-c.z,z:c.x},u=c.x*o+l.x*s,d=c.z*o+l.z*s,f=this.windVector();n!==`atti`&&(u-=f.x,d-=f.z);let p=Math.hypot(u,d),m=n===`atti`?t.horizontalSpeed:t.horizontalSpeed+.01;if(p>m){let e=m/p;u*=e,d*=e}let h=u+f.x,g=d+f.z,_=(i>.06?t.accel:t.brakeAccel)*e;this.velocity.x+=I(h-this.velocity.x,-_,_),this.velocity.z+=I(g-this.velocity.z,-_,_);let v=this.stick.throttle;if(Math.abs(v)>.06){let n=v>0?v*t.climbSpeed:v*t.descendSpeed,r=3*this.speedScale*e;this.velocity.y+=I(n-this.velocity.y,-r,r)}else{let t=n===`atti`?-.35*this.speedScale:0,r=2*this.speedScale*e;this.velocity.y+=I(t-this.velocity.y,-r,r)}this.integratePosition(e),this.applyYaw(e)}integratePosition(e){this.position.x+=this.velocity.x*e,this.position.z+=this.velocity.z*e,this.position.y+=this.velocity.y*e,this.altitudeLimitReached=!1;let t=this.altitudeCeiling;Number.isFinite(t)&&this.position.y>=t&&(this.position.y=t,this.velocity.y>0&&(this.velocity.y=0),this.altitudeLimitReached=!0,this.warnOnce(`altitude`,`已达最大飞行高度限制`)),this.position.y<0&&(this.position.y=0,this.velocity.y<0&&(this.velocity.y=0));let n=this.distanceToHome;this.distanceLimitReached=!1;let r=this.distanceCeiling;if(Number.isFinite(r)&&n>r){let e=r/n;this.position.x=this.home.x+(this.position.x-this.home.x)*e,this.position.z=this.home.z+(this.position.z-this.home.z)*e,this.velocity.x=0,this.velocity.z=0,this.distanceLimitReached=!0,this.warnOnce(`distance`,`已达最大飞行距离限制`)}}applyYaw(e){let t=this.spinHeading;if(t!==null){this.yawRateCurrent=L(this.yawRateCurrent,0,Math.min(1,e*7)),this.heading=this.turnToward(this.heading,t,this.spinRateDeg*this.speedScale*e);return}let n=this.stick.yaw*this.modeSpec.yawRateDeg*(this.faults.motorFailure?.7:1);this.yawRateCurrent=L(this.yawRateCurrent,n,Math.min(1,e*7)),this.heading=(this.heading+this.yawRateCurrent*e+360)%360,this.faults.motorFailure&&(this.heading=(this.heading+22*e+360)%360)}updateTilt(e){let t=this.modeSpec,n=this.windVector(),r=this.velocity.x-n.x,i=this.velocity.z-n.z,a=ge(this.heading),o={x:-a.z,z:a.x},s=r*a.x+i*a.z,c=r*o.x+i*o.z,l=Math.max(t.horizontalSpeed,.1),u=Math.tan(fe(t.maxTiltDeg))/(l*l),d=(this.accelX*a.x+this.accelZ*a.z)/A,f=(this.accelX*o.x+this.accelZ*o.z)/A,p=-pe(Math.atan(u*s*Math.abs(s)+I(d,-1.2,1.2))),m=pe(Math.atan(u*c*Math.abs(c)+I(f,-1.2,1.2)));p=I(p,-t.maxTiltDeg,t.maxTiltDeg),m=I(m,-t.maxTiltDeg,t.maxTiltDeg),this.positionSource===`atti`&&this.airborne&&(p+=Math.sin(this.time*2.1)*1.6,m+=Math.cos(this.time*1.7)*2.2);let h=this.phase===`standby`?8:3.2;this.tiltPitchTarget=p,this.tiltRollTarget=m,this.tiltPitch=L(this.tiltPitch,p,Math.min(1,e*h)),this.tiltRoll=L(this.tiltRoll,m,Math.min(1,e*h))}updateMotorSpeeds(e){let t=this.motorSpeeds;if(this.motorLoad<=.02){for(let e of g)t[e]=0;return}let n=this.modeSpec,r=Math.max(n.maxTiltDeg,1),i=I((this.tiltPitchTarget-this.tiltPitch)/r,-1,1),a=I((this.tiltRollTarget-this.tiltRoll)/r,-1,1),o=I(this.yawRateCurrent/Math.max(n.yawRateDeg,1),-1,1),s=i*.55,c=a*.55,l=o*.3,u=.15,d=-this.tiltPitch/r*u,f=this.tiltRoll/r*u,p=Math.min(fe(Math.hypot(this.tiltPitch,this.tiltRoll)),fe(80)),m=Math.sqrt(1/Math.max(Math.cos(p),.15));for(let e of g){let n=e===`FrontLeft`||e===`FrontRight`,r=e===`FrontRight`||e===`RearRight`,i=(n?1:-1)*s+(n?-1:1)*d,a=(r?-1:1)*c+(r?-1:1)*f,o=(e===`FrontRight`||e===`RearLeft`?1:-1)*l,u=1+i+a+o;t[e]=I(this.motorLoad*m*u,0,1.15)}}updateMotorLoad(e){if(this.phase===`emergency`||this.phase===`powerOff`){this.motorLoad=L(this.motorLoad,0,Math.min(1,e*8));return}let t=I(this.velocity.y/5,-.3,1),n=I(Math.hypot(this.velocity.x,this.velocity.z)/16,0,1),r=I(.42+t*.45+n*.28,.2,1),i=this.phase!==`standby`&&this.phase!==`stopped`;this.motorLoad=L(this.motorLoad,i?r:0,Math.min(1,e*4))}updateRth(e){let t=this.specFor(`normal`),n=ee*this.speedScale;this.rthStickGrace=Math.max(0,this.rthStickGrace-e);let r=Math.hypot(this.stick.pitch,this.stick.roll,this.stick.throttle);if(this.rthStickGrace<=0&&r>.15){this.cancelRth(`检测到摇杆操作`);return}let i=Math.max(this.config.rthAltitude,2);if(this.rthStage===`ascend`){let n=i-this.position.y;this.velocity.x=L(this.velocity.x,0,Math.min(1,e*2)),this.velocity.z=L(this.velocity.z,0,Math.min(1,e*2)),this.velocity.y=I(n,-t.climbSpeed,t.climbSpeed),Math.abs(n)<.3&&(this.velocity.y=0,this.rthStage=`cruise`,this.pushEvent(`info`,`已升至返航高度 ${i} 米,开始返航`))}else if(this.rthStage===`cruise`){let r=this.home.x-this.position.x,i=this.home.z-this.position.z,a=Math.hypot(r,i);if(a<.8)this.velocity.x=0,this.velocity.z=0,this.rthStage=`descend`,this.pushEvent(`info`,`已到达返航点上方,开始下降`);else{let o=r/a,s=i/a,c=pe(Math.atan2(o,-s)),l=Math.abs((c-this.heading+540)%360-180);if(this.velocity.y=L(this.velocity.y,0,Math.min(1,e*2)),l>P)this.velocity.x=L(this.velocity.x,0,Math.min(1,e*8)),this.velocity.z=L(this.velocity.z,0,Math.min(1,e*8)),this.heading=this.turnToward(this.heading,c,n*e);else{let r=Math.min(t.horizontalSpeed,Math.max(2*this.speedScale,a*.5));this.velocity.x=L(this.velocity.x,o*r,Math.min(1,e*1.6)),this.velocity.z=L(this.velocity.z,s*r,Math.min(1,e*1.6)),this.heading=this.turnToward(this.heading,c,n*e)}}}else if(this.rthStage===`descend`){this.velocity.x=L(this.velocity.x,0,Math.min(1,e*3)),this.velocity.z=L(this.velocity.z,0,Math.min(1,e*3)),this.velocity.y=-t.descendSpeed,this.integratePosition(e),this.position.y<=F&&(this.rthStage=`landing`,this.phase=`landing`,this.landingTimer=0,this.position.y=F,this.velocity.y=0,this.enterLandingHold());return}else{this.phase=`landing`;return}this.integratePosition(e)}turnToward(e,t,n){let r=(t-e+540)%360-180;return r=I(r,-n,n),(e+r+360)%360}normalizeWaypoint(e){return T(e,this.config.unlimitedFlight?1/0:500)}setMission(e){return this.missionStatus!==`idle`||this.missionPending?(this.pushEvent(`warn`,`航线执行中无法修改航点列表,请先停止任务`),!1):(this.mission=e.map(e=>this.normalizeWaypoint(e)),this.missionIndex=-1,this.missionStage=`idle`,!0)}updateMissionWaypoint(e,t){if(this.missionStatus!==`idle`||this.missionPending)return null;let n=this.mission[e];if(!n)return null;let r=this.normalizeWaypoint({...n,...t});return this.constrainMissionWaypoint(r),this.mission[e]=r,r}addMissionWaypoint(e,t=this.mission.length){if(this.missionStatus!==`idle`||this.missionPending)return this.pushEvent(`warn`,`航线执行中无法新增航点,请先停止任务`),-1;let n=I(Math.round(t),0,this.mission.length),r=this.normalizeWaypoint(e);this.constrainMissionWaypoint(r);let i=this.mission.slice();return i.splice(n,0,r),this.mission=i,n}removeMissionWaypoint(e){if(this.missionStatus!==`idle`||this.missionPending)return this.pushEvent(`warn`,`航线执行中无法删除航点,请先停止任务`),!1;if(e<0||e>=this.mission.length)return!1;let t=this.mission.slice();return t.splice(e,1),this.mission=t,!0}constrainMissionWaypoint(e){let t=this.altitudeCeiling;e.altitude=Number.isFinite(t)?I(e.altitude,1,t):Math.max(1,e.altitude);let n=e.x-this.home.x,r=e.z-this.home.z,i=Math.hypot(n,r),a=this.distanceCeiling;if(!Number.isFinite(a)||i<=a)return;let o=a/i;e.x=this.home.x+n*o,e.z=this.home.z+r*o}setMissionConfig(e){this.missionConfig={...this.missionConfig,...e}}resetMissionToDefault(){this.setMission(C.map(e=>({...e})))}startMission(){if(this.missionStatus!==`idle`||this.missionPending)return!1;if(this.mission.length===0)return this.pushEvent(`error`,`航线任务启动失败:航点列表为空`),!1;let e=this.validateMission();if(e)return this.pushEvent(`error`,`航线任务启动失败:${e}`),!1;if(this.positionSource===`atti`)return this.pushEvent(`error`,`航线任务启动失败:当前无定位(姿态模式),航点任务需要 GNSS 定位`),!1;if(this.phase===`standby`||this.phase===`motorsOn`||this.phase===`takingOff`){let e=this.phase!==`takingOff`;return this.missionPending=!0,e&&!this.autoTakeOff()?(this.missionPending=!1,!1):(this.pushEvent(`info`,`航线已下发(${this.mission.length} 个航点),起飞到位后自动开始执行`),!0)}return this.phase===`landing`||this.phase===`emergency`||this.phase===`stopped`||this.phase===`powerOff`?(this.pushEvent(`error`,`航线任务启动失败:当前阶段(${p[this.phase]})无法执行`),!1):(this.phase===`rth`&&this.cancelRth(`执行航线任务`),this.beginMissionPath(),!0)}beginMissionPath(){this.missionPending=!1,this.missionStatus=`running`,this.missionIndex=0,this.missionStage=`depart-climb`,this.missionHoverTimer=0,this.missionWaypointTimer=0,this.missionElapsed=0,this.missionPasses=0,this.missionStickGrace=1,this.missionPauseReason=``,this.missionStartHeading=this.heading,this.missionTotalDistance=this.computeMissionDistanceLeft(),this.phase=`waypoint`,this.phaseTime=0;let e=this.mission[0];this.pushEvent(`success`,`开始执行航线任务(${this.mission.length} 个航点 · 巡航 ${this.missionConfig.autoSpeed} m/s)${e?` · 先垂直调整到 ${e.altitude} 米`:``}`)}pauseMission(e=`用户暂停`){return this.missionStatus===`running`&&(this.missionStatus=`paused`,this.missionPauseReason=e,this.missionPausedStage=this.missionStage,this.velocity={x:0,y:0,z:0},this.phase===`waypoint`&&(this.phase=`flying`),this.pushEvent(`warn`,`航线任务已暂停(${e}),可手动接管;点「继续」回到当前航点`),!0)}resumeMission(){return this.missionStatus===`paused`&&(this.missionStatus=`running`,this.missionPauseReason=``,this.missionStickGrace=1,this.missionWaypointTimer=0,this.missionStage=x(this.missionPausedStage)?this.resolveMissionDepartStage():`goto`,this.airborne&&(this.phase=`waypoint`),this.pushEvent(`info`,`航线任务继续执行(航点 ${this.missionIndex+1}/${this.mission.length})`),!0)}stopMission(e=`用户停止`){return this.missionStatus===`idle`&&!this.missionPending?!1:(this.missionPending=!1,this.abortMission(e),this.phase===`waypoint`&&(this.phase=`flying`,this.velocity={x:0,y:0,z:0}),!0)}abortMission(e){(this.missionStatus!==`idle`||this.missionPending)&&(this.missionStatus=`idle`,this.missionIndex=-1,this.missionStage=`idle`,this.missionPending=!1,this.missionHoverTimer=0,this.missionWaypointTimer=0,this.missionPauseReason=``,this.pushEvent(`warn`,`航线任务已中止(${e})`))}validateMission(){let e=this.altitudeCeiling,t=this.distanceCeiling;if(!Number.isFinite(e)&&!Number.isFinite(t))return null;for(let n=0;n<this.mission.length;n+=1){let r=this.mission[n];if(!r)continue;if(Number.isFinite(e)&&r.altitude>e)return`航点 ${n+1} 高度 ${r.altitude} m 超过限高 ${e} m`;let i=Math.hypot(r.x-this.home.x,r.z-this.home.z);if(Number.isFinite(t)&&i>t)return`航点 ${n+1} 距返航点 ${i.toFixed(0)} m,超过限距 ${t} m`}return null}updateMission(e){this.missionStickGrace=Math.max(0,this.missionStickGrace-e);let t=Math.hypot(this.stick.pitch,this.stick.roll,this.stick.throttle,this.stick.yaw);if(this.missionStickGrace<=0&&t>.15){this.pauseMission(`检测到摇杆操作`);return}if(this.positionSource===`atti`){this.pauseMission(`GNSS 失锁,进入姿态模式`);return}this.missionElapsed+=e;let n=this.mission[this.missionIndex];if(!n){this.finishMission();return}if(x(this.missionStage)){this.updateMissionDepart(e);return}let r=this.modeSpec,i=n.x-this.position.x,a=n.z-this.position.z,o=Math.hypot(i,a),s=n.altitude-this.position.y,c=this.missionConfig.pathMode===`curved`;if(this.missionStage===`hover`){if(this.position.y=n.altitude,this.velocity.x=L(this.velocity.x,0,Math.min(1,e*4)),this.velocity.z=L(this.velocity.z,0,Math.min(1,e*4)),this.velocity.y=L(this.velocity.y,0,Math.min(1,e*2)),this.missionHoverTimer+=e,this.missionHoverTimer>=n.hoverSeconds&&this.advanceMission(),this.phase!==`waypoint`)return;this.integratePosition(e);return}let l=this.speedScale,u=o>.4?pe(Math.atan2(i,-a)):this.heading,d=this.missionConfig.headingMode===`auto`?u:this.missionStartHeading;this.heading=this.turnToward(this.heading,d,oe*l*e);let f=Math.abs((d-this.heading+540)%360-180),p=I(s,-r.descendSpeed,r.climbSpeed);this.velocity.y=L(this.velocity.y,p,Math.min(1,e*2));let m=I(n.speed>0?n.speed:this.missionConfig.autoSpeed,.5,Math.max(.5,this.missionConfig.autoSpeed))*l,h=this.missionConfig.headingMode!==`auto`||f<=P,g=m*m/(2*r.brakeAccel)+.6*l,_=0;h&&(_=!c&&o<g?Math.max(.6*l,o/g*m):m);let v=o>.001?i/o:0,y=o>.001?a/o:0,b=Math.min(1,e*(c?2.6:1.8));if(this.velocity.x=L(this.velocity.x,v*_,b),this.velocity.z=L(this.velocity.z,y*_,b),c?o<=ae:o<=re&&Math.abs(s)<=ie){if(this.arriveWaypoint(),this.phase!==`waypoint`)return;this.integratePosition(e)}else this.missionWaypointTimer+=e,!(this.missionWaypointTimer>se&&(this.pushEvent(`warn`,`航点 ${this.missionIndex+1} 长时间未到达,已跳过`),this.advanceMission(),this.phase!==`waypoint`))&&this.integratePosition(e)}updateMissionDepart(e){let t=this.mission[0];if(!t){this.finishMission();return}let n=this.modeSpec,r=this.speedScale,i=t.x-this.position.x,a=t.z-this.position.z,o=Math.hypot(i,a),s=t.altitude-this.position.y;if(this.missionWaypointTimer+=e,this.missionWaypointTimer>se){this.pushEvent(`warn`,`首航点长时间未到达,跳过启航段直接执行航线`),this.missionWaypointTimer=0,this.missionStage=`goto`,this.integratePosition(e);return}if(this.missionStage===`depart-climb`){this.velocity.x=L(this.velocity.x,0,Math.min(1,e*3)),this.velocity.z=L(this.velocity.z,0,Math.min(1,e*3)),this.velocity.y=I(s,-n.descendSpeed,n.climbSpeed),Math.abs(s)<=le&&(this.position.y=t.altitude,this.velocity.y=0,this.missionStage=`depart-cruise`,this.pushEvent(`info`,`已垂直调整到 ${t.altitude} 米(首航点高度),水平飞向航点 1`)),this.integratePosition(e);return}if(this.missionStage===`depart-cruise`){this.velocity.y=I(s,-n.descendSpeed,n.climbSpeed);let c=I(t.speed>0?t.speed:this.missionConfig.autoSpeed,.5,Math.max(.5,this.missionConfig.autoSpeed))*r,l=c*c/(2*n.brakeAccel)+.6*r,u=o<l?Math.max(.4*r,o/l*c):c,d=o>.001?i/o:0,f=o>.001?a/o:0,p=this.missionConfig.headingMode===`auto`&&o>.4?pe(Math.atan2(i,-a)):this.missionStartHeading;this.heading=this.turnToward(this.heading,p,oe*r*e);let m=Math.min(1,e*2.2);this.velocity.x=L(this.velocity.x,d*u,m),this.velocity.z=L(this.velocity.z,f*u,m),o<=ce&&(this.velocity.x=0,this.velocity.z=0,this.missionStage=`depart-settle`),this.integratePosition(e);return}if(this.velocity.x=0,this.velocity.z=0,this.missionStage===`depart-settle`){this.velocity.y=I(s,-n.descendSpeed,n.climbSpeed),Math.abs(s)<=ue&&(this.position.y=t.altitude,this.velocity.y=0,this.missionStage=`depart-align`),this.integratePosition(e);return}this.velocity.y=L(this.velocity.y,0,Math.min(1,e*4));let c=this.missionRouteHeading(0),l=this.missionConfig.headingMode===`auto`?c:this.missionStartHeading;this.heading=this.turnToward(this.heading,l,oe*r*e),Math.abs((l-this.heading+540)%360-180)<=de&&(this.position.x=t.x,this.position.z=t.z,this.position.y=t.altitude,this.velocity={x:0,y:0,z:0},this.missionStage=`goto`,this.missionWaypointTimer=0,this.pushEvent(`success`,`机头已对准航线方向(${l.toFixed(0)}°),开始执行航线`),this.arriveWaypoint()),this.integratePosition(e)}resolveMissionDepartStage(){let e=this.mission[0];if(!e)return`goto`;let t=Math.hypot(e.x-this.position.x,e.z-this.position.z),n=Math.abs(e.altitude-this.position.y);return n>le?`depart-climb`:t>re?`depart-cruise`:n>ue?`depart-settle`:`depart-align`}missionRouteHeading(e){let t=this.mission[e];if(!t)return this.heading;let n=this.mission[e+1];if(n)return this.bearingBetween(t,n);let r=this.mission[e-1];return r?this.bearingBetween(r,t):this.bearingBetween({x:this.home.x,z:this.home.z},t)}bearingBetween(e,t){let n=t.x-e.x,r=t.z-e.z;return Math.hypot(n,r)<.01?this.heading:pe(Math.atan2(n,-r))}arriveWaypoint(){let e=this.mission[this.missionIndex];if(!e)return;let t=`航点 ${this.missionIndex+1}/${this.mission.length}`;this.missionWaypointTimer=0,e.gimbalPitch!==null&&this.setGimbalPitch(e.gimbalPitch),e.action===`photo`&&this.takePhoto();let n=this.missionConfig.pathMode!==`curved`&&e.hoverSeconds>0,r=[];e.gimbalPitch!==null&&r.push(`云台俯仰 ${e.gimbalPitch}°`),n&&r.push(`悬停 ${e.hoverSeconds} 秒`),this.pushEvent(`success`,`到达${t}${r.length?` · 执行:${r.join(` · `)}`:``}`),n?(this.missionStage=`hover`,this.missionHoverTimer=0,this.position.y=e.altitude,this.velocity={x:0,y:0,z:0}):this.advanceMission()}advanceMission(){this.missionStage=`goto`,this.missionHoverTimer=0,this.missionWaypointTimer=0;let e=this.missionIndex+1;e<this.mission.length?this.missionIndex=e:this.missionConfig.loop?(this.missionIndex=0,this.missionPasses+=1,this.pushEvent(`info`,`航线完成第 ${this.missionPasses} 圈,循环执行`)):this.finishMission()}finishMission(){let e=this.mission.length,t=this.missionPasses+1,n=this.missionElapsed;switch(this.missionStatus=`idle`,this.missionIndex=-1,this.missionStage=`idle`,this.missionHoverTimer=0,this.missionWaypointTimer=0,this.missionPauseReason=``,this.pushEvent(`success`,`航线任务完成(共 ${e} 个航点 · ${t} 圈 · 用时 ${this.formatDuration(n)})`),this.missionConfig.finishAction){case`rth`:this.startRth(`航线任务完成`);break;case`land`:this.startLanding();break;default:this.phase=`flying`,this.velocity={x:0,y:0,z:0}}}get missionPendingStart(){return this.missionPending}get missionDistanceLeft(){return this.missionStatus===`idle`||this.missionIndex<0?0:this.computeMissionDistanceLeft()}computeMissionDistanceLeft(){let e=0,t=this.position.x,n=this.position.y,r=this.position.z;for(let i=Math.max(0,this.missionIndex);i<this.mission.length;i+=1){let a=this.mission[i];a&&(e+=Math.hypot(a.x-t,a.z-r,a.altitude-n),t=a.x,n=a.altitude,r=a.z)}return e}get missionProgress(){return this.missionStatus===`idle`||this.missionTotalDistance<=0?0:I(1-this.computeMissionDistanceLeft()/this.missionTotalDistance,0,1)}get missionEtaSeconds(){if(this.missionStatus===`idle`||this.missionIndex<0)return 0;let e=Math.max(.5,this.missionConfig.autoSpeed)*Math.max(this.speedScale,.001),t=0;for(let e=this.missionIndex;e<this.mission.length;e+=1){let n=this.mission[e];n&&(t+=n.hoverSeconds)}return this.missionDistanceLeft/e+t}updateGnss(e){let t=this.phase!==`powerOff`,n=0;t&&!this.faults.gnssLost&&(n=this.faults.compassError?12:18,this.position.y>60&&--n),this.satellites<n?this.satellites=Math.min(n,this.satellites+this.config.gnssAcquireRate*e):this.satellites>n&&(this.satellites=Math.max(n,this.satellites-this.config.gnssAcquireRate*2.5*e));let r=!this.faults.visionLost&&!this.faults.imuError&&this.position.y<N;if(this.visionAvailable=r&&this.phase!==`powerOff`,this.faults.rcLost)this.rcLinkQuality=Math.max(0,this.rcLinkQuality-e*1.6);else{let e=I(this.distanceToHome/2e3,0,.6);this.rcLinkQuality=I(1-e,.35,1)}}get hdop(){return this.satellites<=0?99:I(1.6-this.satellites*.06+(this.faults.gnssLost?4:0),.5,5)}get gpsBars(){return this.satellites<=0||this.faults.gnssLost?0:this.satellites>=14?5:this.satellites>=11?4:this.satellites>=8?3:this.satellites>=6?2:1}get rcBars(){return Math.round(I(this.rcLinkQuality,0,1)*5)}get distanceToHome(){return Math.hypot(this.position.x-this.home.x,this.position.z-this.home.z)}get homePosition(){return{...this.home}}get homeReady(){return this.homeRecorded}forceBatteryLevel(e){let t=I(e,0,100);this.batteryUsedWh=(100-t)/100*a.batteryWh}updateBattery(e){if(this.phase===`powerOff`){this.batteryTemp=L(this.batteryTemp,24,Math.min(1,e*.02));return}let t=this.currentPowerWatts;this.batteryUsedWh+=t*e/3600;let n=I(t/60,0,1),r=this.airborne?28+n*22:24+n*6;this.batteryTemp=L(this.batteryTemp,r,Math.min(1,e*.02)),this.airborne&&(this.flightTime+=e)}get lowBattery(){return this.batteryPercent<=this.config.lowBatteryPercent}get criticalBattery(){return this.batteryPercent<=this.config.criticalBatteryPercent}updateFailsafe(e){this.faults.rcLost?(this.rcLostTimer+=e,this.rcLostTimer>j&&this.airborne&&this.phase!==`rth`&&(this.config.rcFailsafe===`rth`?(this.startRth(`遥控信号丢失`),this.pushEvent(`warn`,`遥控器失联超过 3 秒,已自动执行返航`)):this.config.rcFailsafe===`land`?(this.startLanding(),this.pushEvent(`warn`,`遥控器失联,原地降落`)):this.pushEvent(`warn`,`遥控器失联,保持悬停等待信号恢复`))):this.rcLostTimer=0,this.airborne&&this.lowBattery&&!this.criticalBattery&&this.phase===`flying`?this.lowBatteryCountdown<=0?(this.lowBatteryCountdown=M,this.pushEvent(`warn`,`电量低于 ${this.config.lowBatteryPercent}%,${M} 秒后自动返航`),this.warnOnce(`lowBattery`,`低电量:请尽快返航`)):(this.lowBatteryCountdown-=e,this.lowBatteryCountdown<=0&&(this.lowBatteryCountdown=0,this.startRth(`低电量返航`)||this.pushEvent(`error`,`无法触发返航`))):this.lowBattery||(this.lowBatteryCountdown=0),this.airborne&&this.criticalBattery&&this.phase!==`landing`&&this.phase!==`emergency`&&(this.warnOnce(`criticalBattery`,`严重低电量:强制降落`),this.startLanding(),this.pushEvent(`error`,`严重低电量,已强制降落`)),this.batteryPercent<=0&&this.airborne&&(this.phase=`emergency`,this.pushEvent(`error`,`电池耗尽,动力失效`))}applyObstacleBrake(){if(this.obstacleReport={forward:null,backward:null,left:null,right:null,up:null,down:null,braking:!1,brakingDirection:null},this.obstacleReport.down=this.position.y,this.faults.obstacleAvoidanceOff||this.obstacles.length===0)return;let e=this.position,t=ge(this.heading),n={x:-t.z,z:t.x},r=[{key:`forward`,x:t.x,y:0,z:t.z},{key:`backward`,x:-t.x,y:0,z:-t.z},{key:`right`,x:n.x,y:0,z:n.z},{key:`left`,x:-n.x,y:0,z:-n.z},{key:`up`,x:0,y:1,z:0},{key:`down`,x:0,y:-1,z:0}];for(let t of r){let n=null;for(let r of this.obstacles){let i=ve(e,t,r,1.6);i!==null&&(n===null||i<n)&&(n=i)}this.obstacleReport[t.key]=n}for(let e of[`forward`,`backward`,`left`,`right`]){let t=this.obstacleReport[e];if(t===null)continue;let n=r.find(t=>t.key===e);if(!n)continue;let i=this.velocity.x*n.x+this.velocity.z*n.z;i<=.15||t<=i*i/(2*this.modeSpec.brakeAccel)+.6&&(this.velocity.x-=n.x*i,this.velocity.z-=n.z*i,this.obstacleReport.braking=!0,this.obstacleReport.brakingDirection=e,this.warnOnce(`obstacle`,`避障刹停:前方障碍物过近`))}}spinTo(e,t=90){this.spinHeading=e===null?null:me(e),this.spinRateDeg=t}get spinTarget(){return this.spinHeading}get spinning(){return this.spinHeading!==null}get spinAligned(){let e=this.spinHeading;return e===null||Math.abs((e-this.heading+540)%360-180)<=f}nudgeGimbal(e,t=0){this.gimbalPitch=I(this.gimbalPitch+e,a.gimbalPitchMin,a.gimbalPitchMax),this.gimbalYaw=I(this.gimbalYaw+t,-a.gimbalYawRange,a.gimbalYawRange)}setGimbalPitch(e){this.gimbalPitch=I(e,a.gimbalPitchMin,a.gimbalPitchMax)}updateCamera(e){this.gimbalYaw=L(this.gimbalYaw,0,Math.min(1,e*1.2))}toggleRecording(){this.setRecordingState(!this.recording)}setRecordingState(e){e!==this.recording&&(e?(this.recording=!0,this.recordSeconds=0,this.pushEvent(`info`,`开始录像`)):(this.recording=!1,this.pushEvent(`info`,`录像结束,时长 ${this.formatDuration(this.recordSeconds)}`)))}stopRecording(){this.setRecordingState(!1)}takePhoto(){this.photoCount+=1,this.pushEvent(`info`,`拍照(第 ${this.photoCount} 张)`)}setZoom(e){this.cameraZoom=I(e,1,4)}get checklist(){let e=[];for(let t of this.externalChecks)e.push(t);e.push({id:`imu`,label:`IMU 惯性测量单元`,ok:!this.faults.imuError,detail:this.faults.imuError?`IMU 异常,禁止起飞`:`正常`,blocking:!0}),e.push({id:`compass`,label:`指南针`,ok:!this.faults.compassError,detail:this.faults.compassError?`受磁干扰,请重新校准`:`正常`,blocking:!0});let t=this.satellites>=6;e.push({id:`gnss`,label:`定位系统`,ok:t||this.visionAvailable,detail:t?`GNSS ${Math.round(this.satellites)} 星 · HDOP ${this.hdop.toFixed(1)}`:this.visionAvailable?`仅视觉定位(建议等待搜星完成)`:`无 GNSS 无视觉定位`,blocking:!t&&!this.visionAvailable}),e.push({id:`home`,label:`返航点`,ok:this.homeRecorded,detail:this.homeRecorded?`已记录`:`等待记录`,blocking:!0}),e.push({id:`battery`,label:`电池电量`,ok:this.batteryPercent>this.config.criticalBatteryPercent+3,detail:`${this.batteryPercent.toFixed(0)}% · ${this.batteryVoltage.toFixed(1)} V · ${this.batteryTemp.toFixed(0)} ℃`,blocking:this.batteryPercent<=this.config.criticalBatteryPercent}),e.push({id:`wind`,label:`风速`,ok:this.config.windSpeed<=a.maxWindResistance,detail:`${this.config.windSpeed.toFixed(1)} m/s(抗风上限 ${a.maxWindResistance} m/s)`,blocking:!1});let n=this.phase===`standby`||this.phase===`motorsOn`;return e.push({id:`phase`,label:`飞行器状态`,ok:n,detail:p[this.phase],blocking:!n}),e}get canTakeOff(){return(this.phase===`standby`||this.phase===`motorsOn`)&&this.checklist.every(e=>!e.blocking||e.ok)}get warnings(){let e=[];return this.faults.imuError&&e.push(`IMU 异常`),this.faults.compassError&&e.push(`指南针受扰`),this.faults.gnssLost&&e.push(`GNSS 失锁`),this.faults.rcLost&&e.push(`遥控信号丢失`),this.faults.visionLost&&e.push(`下视视觉失效`),this.faults.motorFailure&&e.push(`电机异常`),this.faults.obstacleAvoidanceOff&&e.push(`避障已关闭`),this.positionSource===`atti`?e.push(`姿态模式 · 无定位`):this.positionSource===`vision`&&e.push(`视觉定位`),this.config.windSpeed>a.maxWindResistance&&e.push(`风速超过抗风上限`),this.altitudeLimitReached&&e.push(`已达限高`),this.distanceLimitReached&&e.push(`已达限距`),this.obstacleReport.braking&&e.push(`避障刹停`),this.lowBattery&&!this.criticalBattery&&e.push(`低电量`),this.criticalBattery&&e.push(`严重低电量`),e}warnOnce(e,t){let n=this.warnedAt.get(e)??-1/0;this.time-n<6||(this.warnedAt.set(e,this.time),this.pushEventInternal(`warn`,t))}damageCheck(){this.config.windSpeed>a.maxWindResistance&&this.pushEvent(`warn`,`风速超过最大抗风能力,谨慎飞行`)}pushEvent(e,t){this.pushEventInternal(e,t)}pushEventInternal(e,t){this.eventId+=1,this.events.unshift({id:this.eventId,time:this.time,level:e,text:t}),this.events.length>200&&this.events.pop()}formatDuration(e){let t=Math.max(0,Math.round(e)),n=Math.floor(t/60),r=t%60;return`${n} 分 ${String(r).padStart(2,`0`)} 秒`}windVector(){let e=this.config.windSpeed;if(e<=0)return{x:0,z:0};let t=ge(this.config.windDirection);return{x:t.x*e,z:t.z*e}}get windRelative(){if(this.config.windSpeed<.3)return`静风`;let e=(this.config.windDirection+180-this.heading+540)%360-180,t=Math.abs(e),n=e>=0?`右`:`左`;return t<20?`正逆风`:t>160?`正顺风`:t<=60?`逆风偏${n} ${Math.round(t)}°`:t>=120?`顺风偏${n} ${Math.round(180-t)}°`:`侧风偏${n} ${Math.round(t)}°`}snapshot(){return{phase:this.phase,phaseLabel:this.phaseLabel,mode:this.mode,modeLabel:this.modeSpec.label,speedScale:this.speedScale,positionSource:this.positionSource,positionSourceLabel:m[this.positionSource],airborne:this.airborne,motorsOn:this.motorLoad>.02,damaged:this.damaged,batteryPercent:this.batteryPercent,batteryVoltage:this.batteryVoltage,batteryCurrent:this.batteryCurrent,batteryTemp:this.batteryTemp,batteryWhLeft:this.batteryPercent/100*a.batteryWh,batteryModeText:this.criticalBattery?`严重低电量`:this.lowBattery?`低电量`:`正常`,altitude:this.position.y,altitudeMax:this.altitudeMax,positionX:this.position.x,positionZ:this.position.z,horizontalSpeed:Math.hypot(this.velocity.x,this.velocity.z),verticalSpeed:this.velocity.y,heading:this.heading,tiltPitch:this.tiltPitch,tiltRoll:this.tiltRoll,distanceToHome:this.distanceToHome,homeRecorded:this.homeRecorded,altitudeLimitReached:this.altitudeLimitReached,distanceLimitReached:this.distanceLimitReached,satellites:this.satellites,hdop:this.hdop,gpsBars:this.gpsBars,rcBars:this.rcBars,visionAvailable:this.visionAvailable,gimbalPitch:this.gimbalPitch,gimbalRoll:this.gimbalRoll,gimbalYaw:this.gimbalYaw,motorLoad:this.motorLoad,motorSpeeds:{...this.motorSpeeds},armFold:this.armFold,stick:{...this.stick},windSpeed:this.config.windSpeed,windDirection:this.config.windDirection,windRelative:this.windRelative,flightTime:this.flightTime,totalTime:this.time,remainingMinutes:this.remainingMinutes,lowBattery:this.lowBattery,criticalBattery:this.criticalBattery,lowBatteryCountdown:this.lowBatteryCountdown,rthStage:this.phase===`rth`?this.rthStage:``,landingStage:this.phase===`landing`?this.landingStage:``,rthReason:this.rthReason,warnings:this.warnings,events:this.events.slice(0,12),checklist:this.checklist,obstacle:{...this.obstacleReport},recording:this.recording,recordSeconds:this.recordSeconds,photoCount:this.photoCount,cameraZoom:this.cameraZoom,mission:{status:this.missionStatus,statusLabel:y[this.missionStatus],stage:this.missionStage,stageLabel:b[this.missionStage],index:this.missionIndex,total:this.mission.length,passes:this.missionPasses,elapsed:this.missionElapsed,distanceLeft:this.missionDistanceLeft,progress:this.missionProgress,etaSeconds:this.missionEtaSeconds,pauseReason:this.missionPauseReason,active:this.mission[this.missionIndex]?{...this.mission[this.missionIndex]}:null,waypoints:this.mission.map(e=>({...e})),config:{...this.missionConfig}}}}get elapsed(){return this.time}};function ve(e,t,n,r){let i=n.minX-r,a=n.maxX+r,o=n.minY-r,s=n.maxY+r,c=n.minZ-r,l=n.maxZ+r,u=0,d=1/0,f=[[e.x,t.x,i,a],[e.y,t.y,o,s],[e.z,t.z,c,l]];for(let[e,t,n,r]of f){if(Math.abs(t)<1e-6){if(e<n||e>r)return null;continue}let i=(n-e)/t,a=(r-e)/t;if(i>a&&([i,a]=[a,i]),u=Math.max(u,i),d=Math.min(d,a),u>d)return null}return u>=0?u:null}var ye,be,xe,Se,Ce,we,Te,Ee,De,Oe=`attached`,ke=1e3,Ae=1001,je=1002,Me=1003,Ne=1004,Pe=1005,Fe=1006,Ie=1007,Le=1008,Re=1009,ze=1015,Be=1023,Ve=1028,He=2300,Ue=2301,We=2302,Ge=2303,Ke=2400,qe=2401,Je=2402,Ye=2500,Xe=`srgb`,Ze=`srgb-linear`,Qe=`linear`,$e=`srgb`,et=7680,tt=35044,nt=2e3;function rt(e){for(let t=e.length-1;t>=0;--t)if(e[t]>=65535)return!0;return!1}function it(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function at(e){return document.createElementNS(`http://www.w3.org/1999/xhtml`,e)}var ot={};function st(...e){let t=`THREE.`+e.shift();console.log(t,...e)}function ct(e){let t=e[0];if(typeof t==`string`&&t.startsWith(`TSL:`)){let t=e[1];t&&t.isStackTrace?e[0]+=` `+t.getLocation():e[1]=`Stack trace not available. Enable "THREE.Node.captureStackTrace" to capture stack traces.`}return e}function R(...e){e=ct(e);let t=`THREE.`+e.shift();{let n=e[0];n&&n.isStackTrace?console.warn(n.getError(t)):console.warn(t,...e)}}function z(...e){e=ct(e);let t=`THREE.`+e.shift();{let n=e[0];n&&n.isStackTrace?console.error(n.getError(t)):console.error(t,...e)}}function lt(...e){let t=e.join(` `);t in ot||(ot[t]=!0,R(...e))}var ut=class{addEventListener(e,t){this._listeners===void 0&&(this._listeners={});let n=this._listeners;n[e]===void 0&&(n[e]=[]),n[e].indexOf(t)===-1&&n[e].push(t)}hasEventListener(e,t){let n=this._listeners;return n!==void 0&&n[e]!==void 0&&n[e].indexOf(t)!==-1}removeEventListener(e,t){let n=this._listeners;if(n===void 0)return;let r=n[e];if(r!==void 0){let e=r.indexOf(t);e!==-1&&r.splice(e,1)}}dispatchEvent(e){let t=this._listeners;if(t===void 0)return;let n=t[e.type];if(n!==void 0){e.target=this;let t=n.slice(0);for(let n=0,r=t.length;n<r;n++)t[n].call(this,e);e.target=null}}},dt=`00.01.02.03.04.05.06.07.08.09.0a.0b.0c.0d.0e.0f.10.11.12.13.14.15.16.17.18.19.1a.1b.1c.1d.1e.1f.20.21.22.23.24.25.26.27.28.29.2a.2b.2c.2d.2e.2f.30.31.32.33.34.35.36.37.38.39.3a.3b.3c.3d.3e.3f.40.41.42.43.44.45.46.47.48.49.4a.4b.4c.4d.4e.4f.50.51.52.53.54.55.56.57.58.59.5a.5b.5c.5d.5e.5f.60.61.62.63.64.65.66.67.68.69.6a.6b.6c.6d.6e.6f.70.71.72.73.74.75.76.77.78.79.7a.7b.7c.7d.7e.7f.80.81.82.83.84.85.86.87.88.89.8a.8b.8c.8d.8e.8f.90.91.92.93.94.95.96.97.98.99.9a.9b.9c.9d.9e.9f.a0.a1.a2.a3.a4.a5.a6.a7.a8.a9.aa.ab.ac.ad.ae.af.b0.b1.b2.b3.b4.b5.b6.b7.b8.b9.ba.bb.bc.bd.be.bf.c0.c1.c2.c3.c4.c5.c6.c7.c8.c9.ca.cb.cc.cd.ce.cf.d0.d1.d2.d3.d4.d5.d6.d7.d8.d9.da.db.dc.dd.de.df.e0.e1.e2.e3.e4.e5.e6.e7.e8.e9.ea.eb.ec.ed.ee.ef.f0.f1.f2.f3.f4.f5.f6.f7.f8.f9.fa.fb.fc.fd.fe.ff`.split(`.`),ft=1234567,pt=Math.PI/180,mt=180/Math.PI;function ht(){let e=Math.random()*4294967295|0,t=Math.random()*4294967295|0,n=Math.random()*4294967295|0,r=Math.random()*4294967295|0;return(dt[e&255]+dt[e>>8&255]+dt[e>>16&255]+dt[e>>24&255]+`-`+dt[t&255]+dt[t>>8&255]+`-`+dt[t>>16&15|64]+dt[t>>24&255]+`-`+dt[n&63|128]+dt[n>>8&255]+`-`+dt[n>>16&255]+dt[n>>24&255]+dt[r&255]+dt[r>>8&255]+dt[r>>16&255]+dt[r>>24&255]).toLowerCase()}function B(e,t,n){return Math.max(t,Math.min(n,e))}function gt(e,t){return(e%t+t)%t}function _t(e,t,n,r,i){return r+(e-t)*(i-r)/(n-t)}function vt(e,t,n){return e===t?0:(n-e)/(t-e)}function yt(e,t,n){return(1-n)*e+n*t}function bt(e,t,n,r){return yt(e,t,1-Math.exp(-n*r))}function xt(e,t=1){return t-Math.abs(gt(e,t*2)-t)}function St(e,t,n){return e<=t?0:e>=n?1:(e=(e-t)/(n-t),e*e*(3-2*e))}function Ct(e,t,n){return e<=t?0:e>=n?1:(e=(e-t)/(n-t),e*e*e*(e*(e*6-15)+10))}function wt(e,t){return e+Math.floor(Math.random()*(t-e+1))}function Tt(e,t){return e+Math.random()*(t-e)}function Et(e){return e*(.5-Math.random())}function Dt(e){e!==void 0&&(ft=e);let t=ft+=1831565813;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}function Ot(e){return e*pt}function kt(e){return e*mt}function At(e){return e>0&&Number.isInteger(e)&&2**Math.round(Math.log2(e))===e}function jt(e){return 2**Math.ceil(Math.log(e)/Math.LN2)}function Mt(e){return 2**Math.floor(Math.log(e)/Math.LN2)}function Nt(e,t,n,r,i){let a=Math.cos,o=Math.sin,s=a(n/2),c=o(n/2),l=a((t+r)/2),u=o((t+r)/2),d=a((t-r)/2),f=o((t-r)/2),p=a((r-t)/2),m=o((r-t)/2);switch(i){case`XYX`:e.set(s*u,c*d,c*f,s*l);break;case`YZY`:e.set(c*f,s*u,c*d,s*l);break;case`ZXZ`:e.set(c*d,c*f,s*u,s*l);break;case`XZX`:e.set(s*u,c*m,c*p,s*l);break;case`YXY`:e.set(c*p,s*u,c*m,s*l);break;case`ZYZ`:e.set(c*m,c*p,s*u,s*l);break;default:R(`MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: `+i)}}function Pt(e,t){switch(t.constructor){case Float32Array:return e;case Uint32Array:return e/4294967295;case Uint16Array:return e/65535;case Uint8Array:case Uint8ClampedArray:return e/255;case Int32Array:return Math.max(e/2147483647,-1);case Int16Array:return Math.max(e/32767,-1);case Int8Array:return Math.max(e/127,-1);default:throw Error(`THREE.MathUtils: Invalid component type.`)}}function V(e,t){switch(t.constructor){case Float32Array:return e;case Uint32Array:return Math.round(e*4294967295);case Uint16Array:return Math.round(e*65535);case Uint8Array:case Uint8ClampedArray:return Math.round(e*255);case Int32Array:return Math.round(e*2147483647);case Int16Array:return Math.round(e*32767);case Int8Array:return Math.round(e*127);default:throw Error(`THREE.MathUtils: Invalid component type.`)}}var Ft={DEG2RAD:pt,RAD2DEG:mt,generateUUID:ht,clamp:B,euclideanModulo:gt,mapLinear:_t,inverseLerp:vt,lerp:yt,damp:bt,pingpong:xt,smoothstep:St,smootherstep:Ct,randInt:wt,randFloat:Tt,randFloatSpread:Et,seededRandom:Dt,degToRad:Ot,radToDeg:kt,isPowerOfTwo:At,ceilPowerOfTwo:jt,floorPowerOfTwo:Mt,setQuaternionFromProperEuler:Nt,normalize:V,denormalize:Pt};Te=Symbol.iterator;var H=class{constructor(e=0,t=0){this.x=e,this.y=t}get width(){return this.x}set width(e){this.x=e}get height(){return this.y}set height(e){this.y=e}set(e,t){return this.x=e,this.y=t,this}setScalar(e){return this.x=e,this.y=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;default:throw Error(`THREE.Vector2: index is out of range: `+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;default:throw Error(`THREE.Vector2: index is out of range: `+e)}}clone(){return new this.constructor(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e){return this.x+=e.x,this.y+=e.y,this}addScalar(e){return this.x+=e,this.y+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this}subScalar(e){return this.x-=e,this.y-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this}multiply(e){return this.x*=e.x,this.y*=e.y,this}multiplyScalar(e){return this.x*=e,this.y*=e,this}divide(e){return this.x/=e.x,this.y/=e.y,this}divideScalar(e){return this.multiplyScalar(1/e)}applyMatrix3(e){let t=this.x,n=this.y,r=e.elements;return this.x=r[0]*t+r[3]*n+r[6],this.y=r[1]*t+r[4]*n+r[7],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this}clamp(e,t){return this.x=B(this.x,e.x,t.x),this.y=B(this.y,e.y,t.y),this}clampScalar(e,t){return this.x=B(this.x,e,t),this.y=B(this.y,e,t),this}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(B(n,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(e){let t=Math.sqrt(this.lengthSq()*e.lengthSq());if(t===0)return Math.PI/2;let n=this.dot(e)/t;return Math.acos(B(n,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let t=this.x-e.x,n=this.y-e.y;return t*t+n*n}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this}lerpVectors(e,t,n){return this.x=e.x+(t.x-e.x)*n,this.y=e.y+(t.y-e.y)*n,this}equals(e){return e.x===this.x&&e.y===this.y}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this}rotateAround(e,t){let n=Math.cos(t),r=Math.sin(t),i=this.x-e.x,a=this.y-e.y;return this.x=i*n-a*r+e.x,this.y=i*r+a*n+e.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Te](){yield this.x,yield this.y}};ye=H,ye.prototype.isVector2=!0;var It=class{constructor(e=0,t=0,n=0,r=1){this.isQuaternion=!0,this._x=e,this._y=t,this._z=n,this._w=r}static slerpFlat(e,t,n,r,i,a,o){let s=n[r+0],c=n[r+1],l=n[r+2],u=n[r+3],d=i[a+0],f=i[a+1],p=i[a+2],m=i[a+3];if(u!==m||s!==d||c!==f||l!==p){let e=s*d+c*f+l*p+u*m;e<0&&(d=-d,f=-f,p=-p,m=-m,e=-e);let t=1-o;if(e<.9995){let n=Math.acos(e),r=Math.sin(n);t=Math.sin(t*n)/r,o=Math.sin(o*n)/r,s=s*t+d*o,c=c*t+f*o,l=l*t+p*o,u=u*t+m*o}else{s=s*t+d*o,c=c*t+f*o,l=l*t+p*o,u=u*t+m*o;let e=1/Math.sqrt(s*s+c*c+l*l+u*u);s*=e,c*=e,l*=e,u*=e}}e[t]=s,e[t+1]=c,e[t+2]=l,e[t+3]=u}static multiplyQuaternionsFlat(e,t,n,r,i,a){let o=n[r],s=n[r+1],c=n[r+2],l=n[r+3],u=i[a],d=i[a+1],f=i[a+2],p=i[a+3];return e[t]=o*p+l*u+s*f-c*d,e[t+1]=s*p+l*d+c*u-o*f,e[t+2]=c*p+l*f+o*d-s*u,e[t+3]=l*p-o*u-s*d-c*f,e}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get w(){return this._w}set w(e){this._w=e,this._onChangeCallback()}set(e,t,n,r){return this._x=e,this._y=t,this._z=n,this._w=r,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(e){return this._x=e.x,this._y=e.y,this._z=e.z,this._w=e.w,this._onChangeCallback(),this}setFromEuler(e,t=!0){let n=e._x,r=e._y,i=e._z,a=e._order,o=Math.cos,s=Math.sin,c=o(n/2),l=o(r/2),u=o(i/2),d=s(n/2),f=s(r/2),p=s(i/2);switch(a){case`XYZ`:this._x=d*l*u+c*f*p,this._y=c*f*u-d*l*p,this._z=c*l*p+d*f*u,this._w=c*l*u-d*f*p;break;case`YXZ`:this._x=d*l*u+c*f*p,this._y=c*f*u-d*l*p,this._z=c*l*p-d*f*u,this._w=c*l*u+d*f*p;break;case`ZXY`:this._x=d*l*u-c*f*p,this._y=c*f*u+d*l*p,this._z=c*l*p+d*f*u,this._w=c*l*u-d*f*p;break;case`ZYX`:this._x=d*l*u-c*f*p,this._y=c*f*u+d*l*p,this._z=c*l*p-d*f*u,this._w=c*l*u+d*f*p;break;case`YZX`:this._x=d*l*u+c*f*p,this._y=c*f*u+d*l*p,this._z=c*l*p-d*f*u,this._w=c*l*u-d*f*p;break;case`XZY`:this._x=d*l*u-c*f*p,this._y=c*f*u-d*l*p,this._z=c*l*p+d*f*u,this._w=c*l*u+d*f*p;break;default:R(`Quaternion: .setFromEuler() encountered an unknown order: `+a)}return t===!0&&this._onChangeCallback(),this}setFromAxisAngle(e,t){let n=t/2,r=Math.sin(n);return this._x=e.x*r,this._y=e.y*r,this._z=e.z*r,this._w=Math.cos(n),this._onChangeCallback(),this}setFromRotationMatrix(e){let t=e.elements,n=t[0],r=t[4],i=t[8],a=t[1],o=t[5],s=t[9],c=t[2],l=t[6],u=t[10],d=n+o+u;if(d>0){let e=.5/Math.sqrt(d+1);this._w=.25/e,this._x=(l-s)*e,this._y=(i-c)*e,this._z=(a-r)*e}else if(n>o&&n>u){let e=2*Math.sqrt(1+n-o-u);this._w=(l-s)/e,this._x=.25*e,this._y=(r+a)/e,this._z=(i+c)/e}else if(o>u){let e=2*Math.sqrt(1+o-n-u);this._w=(i-c)/e,this._x=(r+a)/e,this._y=.25*e,this._z=(s+l)/e}else{let e=2*Math.sqrt(1+u-n-o);this._w=(a-r)/e,this._x=(i+c)/e,this._y=(s+l)/e,this._z=.25*e}return this._onChangeCallback(),this}setFromUnitVectors(e,t){let n=e.dot(t)+1;return n<1e-8?(n=0,Math.abs(e.x)>Math.abs(e.z)?(this._x=-e.y,this._y=e.x,this._z=0,this._w=n):(this._x=0,this._y=-e.z,this._z=e.y,this._w=n)):(this._x=e.y*t.z-e.z*t.y,this._y=e.z*t.x-e.x*t.z,this._z=e.x*t.y-e.y*t.x,this._w=n),this.normalize()}angleTo(e){return 2*Math.acos(Math.abs(B(this.dot(e),-1,1)))}rotateTowards(e,t){let n=this.angleTo(e);if(n===0)return this;let r=Math.min(1,t/n);return this.slerp(e,r),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(e){return this._x*e._x+this._y*e._y+this._z*e._z+this._w*e._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let e=this.length();return e===0?(this._x=0,this._y=0,this._z=0,this._w=1):(e=1/e,this._x*=e,this._y*=e,this._z*=e,this._w*=e),this._onChangeCallback(),this}multiply(e){return this.multiplyQuaternions(this,e)}premultiply(e){return this.multiplyQuaternions(e,this)}multiplyQuaternions(e,t){let n=e._x,r=e._y,i=e._z,a=e._w,o=t._x,s=t._y,c=t._z,l=t._w;return this._x=n*l+a*o+r*c-i*s,this._y=r*l+a*s+i*o-n*c,this._z=i*l+a*c+n*s-r*o,this._w=a*l-n*o-r*s-i*c,this._onChangeCallback(),this}slerp(e,t){let n=e._x,r=e._y,i=e._z,a=e._w,o=this.dot(e);o<0&&(n=-n,r=-r,i=-i,a=-a,o=-o);let s=1-t;if(o<.9995){let e=Math.acos(o),c=Math.sin(e);s=Math.sin(s*e)/c,t=Math.sin(t*e)/c,this._x=this._x*s+n*t,this._y=this._y*s+r*t,this._z=this._z*s+i*t,this._w=this._w*s+a*t,this._onChangeCallback()}else this._x=this._x*s+n*t,this._y=this._y*s+r*t,this._z=this._z*s+i*t,this._w=this._w*s+a*t,this.normalize();return this}slerpQuaternions(e,t,n){return this.copy(e).slerp(t,n)}random(){let e=2*Math.PI*Math.random(),t=2*Math.PI*Math.random(),n=Math.random(),r=Math.sqrt(1-n),i=Math.sqrt(n);return this.set(r*Math.sin(e),r*Math.cos(e),i*Math.sin(t),i*Math.cos(t))}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._w===this._w}fromArray(e,t=0){return this._x=e[t],this._y=e[t+1],this._z=e[t+2],this._w=e[t+3],this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._w,e}fromBufferAttribute(e,t){return this._x=e.getX(t),this._y=e.getY(t),this._z=e.getZ(t),this._w=e.getW(t),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}};Ee=Symbol.iterator;var U=class{constructor(e=0,t=0,n=0){this.x=e,this.y=t,this.z=n}set(e,t,n){return n===void 0&&(n=this.z),this.x=e,this.y=t,this.z=n,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;default:throw Error(`THREE.Vector3: index is out of range: `+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error(`THREE.Vector3: index is out of range: `+e)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this}multiplyVectors(e,t){return this.x=e.x*t.x,this.y=e.y*t.y,this.z=e.z*t.z,this}applyEuler(e){return this.applyQuaternion(Rt.setFromEuler(e))}applyAxisAngle(e,t){return this.applyQuaternion(Rt.setFromAxisAngle(e,t))}applyMatrix3(e){let t=this.x,n=this.y,r=this.z,i=e.elements;return this.x=i[0]*t+i[3]*n+i[6]*r,this.y=i[1]*t+i[4]*n+i[7]*r,this.z=i[2]*t+i[5]*n+i[8]*r,this}applyNormalMatrix(e){return this.applyMatrix3(e).normalize()}applyMatrix4(e){let t=this.x,n=this.y,r=this.z,i=e.elements,a=1/(i[3]*t+i[7]*n+i[11]*r+i[15]);return this.x=(i[0]*t+i[4]*n+i[8]*r+i[12])*a,this.y=(i[1]*t+i[5]*n+i[9]*r+i[13])*a,this.z=(i[2]*t+i[6]*n+i[10]*r+i[14])*a,this}applyQuaternion(e){let t=this.x,n=this.y,r=this.z,i=e.x,a=e.y,o=e.z,s=e.w,c=2*(a*r-o*n),l=2*(o*t-i*r),u=2*(i*n-a*t);return this.x=t+s*c+a*u-o*l,this.y=n+s*l+o*c-i*u,this.z=r+s*u+i*l-a*c,this}project(e){return this.applyMatrix4(e.matrixWorldInverse).applyMatrix4(e.projectionMatrix)}unproject(e){return this.applyMatrix4(e.projectionMatrixInverse).applyMatrix4(e.matrixWorld)}transformDirection(e){let t=this.x,n=this.y,r=this.z,i=e.elements;return this.x=i[0]*t+i[4]*n+i[8]*r,this.y=i[1]*t+i[5]*n+i[9]*r,this.z=i[2]*t+i[6]*n+i[10]*r,this.normalize()}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this}divideScalar(e){return this.multiplyScalar(1/e)}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this}clamp(e,t){return this.x=B(this.x,e.x,t.x),this.y=B(this.y,e.y,t.y),this.z=B(this.z,e.z,t.z),this}clampScalar(e,t){return this.x=B(this.x,e,t),this.y=B(this.y,e,t),this.z=B(this.z,e,t),this}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(B(n,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this.z+=(e.z-this.z)*t,this}lerpVectors(e,t,n){return this.x=e.x+(t.x-e.x)*n,this.y=e.y+(t.y-e.y)*n,this.z=e.z+(t.z-e.z)*n,this}cross(e){return this.crossVectors(this,e)}crossVectors(e,t){let n=e.x,r=e.y,i=e.z,a=t.x,o=t.y,s=t.z;return this.x=r*s-i*o,this.y=i*a-n*s,this.z=n*o-r*a,this}projectOnVector(e){let t=e.lengthSq();if(t===0)return this.set(0,0,0);let n=e.dot(this)/t;return this.copy(e).multiplyScalar(n)}projectOnPlane(e){return Lt.copy(this).projectOnVector(e),this.sub(Lt)}reflect(e){return this.sub(Lt.copy(e).multiplyScalar(2*this.dot(e)))}angleTo(e){let t=Math.sqrt(this.lengthSq()*e.lengthSq());if(t===0)return Math.PI/2;let n=this.dot(e)/t;return Math.acos(B(n,-1,1))}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let t=this.x-e.x,n=this.y-e.y,r=this.z-e.z;return t*t+n*n+r*r}manhattanDistanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)+Math.abs(this.z-e.z)}setFromSpherical(e){return this.setFromSphericalCoords(e.radius,e.phi,e.theta)}setFromSphericalCoords(e,t,n){let r=Math.sin(t)*e;return this.x=r*Math.sin(n),this.y=Math.cos(t)*e,this.z=r*Math.cos(n),this}setFromCylindrical(e){return this.setFromCylindricalCoords(e.radius,e.theta,e.y)}setFromCylindricalCoords(e,t,n){return this.x=e*Math.sin(t),this.y=n,this.z=e*Math.cos(t),this}setFromMatrixPosition(e){let t=e.elements;return this.x=t[12],this.y=t[13],this.z=t[14],this}setFromMatrixScale(e){let t=this.setFromMatrixColumn(e,0).length(),n=this.setFromMatrixColumn(e,1).length(),r=this.setFromMatrixColumn(e,2).length();return this.x=t,this.y=n,this.z=r,this}setFromMatrixColumn(e,t){return this.fromArray(e.elements,t*4)}setFromMatrix3Column(e,t){return this.fromArray(e.elements,t*3)}setFromEuler(e){return this.x=e._x,this.y=e._y,this.z=e._z,this}setFromColor(e){return this.x=e.r,this.y=e.g,this.z=e.b,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this.z=e[t+2],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this.z=e.getZ(t),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){let e=Math.random()*Math.PI*2,t=Math.random()*2-1,n=Math.sqrt(1-t*t);return this.x=n*Math.cos(e),this.y=t,this.z=n*Math.sin(e),this}*[Ee](){yield this.x,yield this.y,yield this.z}};be=U,be.prototype.isVector3=!0;var Lt=new U,Rt=new It,zt=class{constructor(e,t,n,r,i,a,o,s,c){this.elements=[1,0,0,0,1,0,0,0,1],e!==void 0&&this.set(e,t,n,r,i,a,o,s,c)}set(e,t,n,r,i,a,o,s,c){let l=this.elements;return l[0]=e,l[1]=r,l[2]=o,l[3]=t,l[4]=i,l[5]=s,l[6]=n,l[7]=a,l[8]=c,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(e){let t=this.elements,n=e.elements;return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],this}extractBasis(e,t,n){return e.setFromMatrix3Column(this,0),t.setFromMatrix3Column(this,1),n.setFromMatrix3Column(this,2),this}setFromMatrix4(e){let t=e.elements;return this.set(t[0],t[4],t[8],t[1],t[5],t[9],t[2],t[6],t[10]),this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){let n=e.elements,r=t.elements,i=this.elements,a=n[0],o=n[3],s=n[6],c=n[1],l=n[4],u=n[7],d=n[2],f=n[5],p=n[8],m=r[0],h=r[3],g=r[6],_=r[1],v=r[4],y=r[7],b=r[2],x=r[5],S=r[8];return i[0]=a*m+o*_+s*b,i[3]=a*h+o*v+s*x,i[6]=a*g+o*y+s*S,i[1]=c*m+l*_+u*b,i[4]=c*h+l*v+u*x,i[7]=c*g+l*y+u*S,i[2]=d*m+f*_+p*b,i[5]=d*h+f*v+p*x,i[8]=d*g+f*y+p*S,this}multiplyScalar(e){let t=this.elements;return t[0]*=e,t[3]*=e,t[6]*=e,t[1]*=e,t[4]*=e,t[7]*=e,t[2]*=e,t[5]*=e,t[8]*=e,this}determinant(){let e=this.elements,t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],c=e[7],l=e[8];return t*a*l-t*o*c-n*i*l+n*o*s+r*i*c-r*a*s}invert(){let e=this.elements,t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],c=e[7],l=e[8],u=l*a-o*c,d=o*s-l*i,f=c*i-a*s,p=t*u+n*d+r*f;if(p===0)return this.set(0,0,0,0,0,0,0,0,0);let m=1/p;return e[0]=u*m,e[1]=(r*c-l*n)*m,e[2]=(o*n-r*a)*m,e[3]=d*m,e[4]=(l*t-r*s)*m,e[5]=(r*i-o*t)*m,e[6]=f*m,e[7]=(n*s-c*t)*m,e[8]=(a*t-n*i)*m,this}transpose(){let e,t=this.elements;return e=t[1],t[1]=t[3],t[3]=e,e=t[2],t[2]=t[6],t[6]=e,e=t[5],t[5]=t[7],t[7]=e,this}getNormalMatrix(e){return this.setFromMatrix4(e).invert().transpose()}transposeIntoArray(e){let t=this.elements;return e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8],this}setUvTransform(e,t,n,r,i,a,o){let s=Math.cos(i),c=Math.sin(i);return this.set(n*s,n*c,-n*(s*a+c*o)+a+e,-r*c,r*s,-r*(-c*a+s*o)+o+t,0,0,1),this}scale(e,t){return lt(`Matrix3: .scale() is deprecated. Use .makeScale() instead.`),this.premultiply(Bt.makeScale(e,t)),this}rotate(e){return lt(`Matrix3: .rotate() is deprecated. Use .makeRotation() instead.`),this.premultiply(Bt.makeRotation(-e)),this}translate(e,t){return lt(`Matrix3: .translate() is deprecated. Use .makeTranslation() instead.`),this.premultiply(Bt.makeTranslation(e,t)),this}makeTranslation(e,t){return e.isVector2?this.set(1,0,e.x,0,1,e.y,0,0,1):this.set(1,0,e,0,1,t,0,0,1),this}makeRotation(e){let t=Math.cos(e),n=Math.sin(e);return this.set(t,-n,0,n,t,0,0,0,1),this}makeScale(e,t){return this.set(e,0,0,0,t,0,0,0,1),this}equals(e){let t=this.elements,n=e.elements;for(let e=0;e<9;e++)if(t[e]!==n[e])return!1;return!0}fromArray(e,t=0){for(let n=0;n<9;n++)this.elements[n]=e[n+t];return this}toArray(e=[],t=0){let n=this.elements;return e[t]=n[0],e[t+1]=n[1],e[t+2]=n[2],e[t+3]=n[3],e[t+4]=n[4],e[t+5]=n[5],e[t+6]=n[6],e[t+7]=n[7],e[t+8]=n[8],e}clone(){return new this.constructor().fromArray(this.elements)}};xe=zt,xe.prototype.isMatrix3=!0;var Bt=new zt,Vt=new zt().set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),Ht=new zt().set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function Ut(){let e={enabled:!0,workingColorSpace:Ze,spaces:{},convert:function(e,t,n){return this.enabled===!1||t===n||!t||!n||(this.spaces[t].transfer===`srgb`&&(e.r=Gt(e.r),e.g=Gt(e.g),e.b=Gt(e.b)),this.spaces[t].primaries!==this.spaces[n].primaries&&(e.applyMatrix3(this.spaces[t].toXYZ),e.applyMatrix3(this.spaces[n].fromXYZ)),this.spaces[n].transfer===`srgb`&&(e.r=Kt(e.r),e.g=Kt(e.g),e.b=Kt(e.b))),e},workingToColorSpace:function(e,t){return this.convert(e,this.workingColorSpace,t)},colorSpaceToWorking:function(e,t){return this.convert(e,t,this.workingColorSpace)},getPrimaries:function(e){return this.spaces[e].primaries},getTransfer:function(e){return e===``?Qe:this.spaces[e].transfer},getToneMappingMode:function(e){return this.spaces[e].outputColorSpaceConfig.toneMappingMode||`standard`},getLuminanceCoefficients:function(e,t=this.workingColorSpace){return e.fromArray(this.spaces[t].luminanceCoefficients)},define:function(e){Object.assign(this.spaces,e)},_getMatrix:function(e,t,n){return e.copy(this.spaces[t].toXYZ).multiply(this.spaces[n].fromXYZ)},_getDrawingBufferColorSpace:function(e){return this.spaces[e].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(e=this.workingColorSpace){return this.spaces[e].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(t,n){return lt(`ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace().`),e.workingToColorSpace(t,n)},toWorkingColorSpace:function(t,n){return lt(`ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking().`),e.colorSpaceToWorking(t,n)}},t=[.64,.33,.3,.6,.15,.06],n=[.2126,.7152,.0722],r=[.3127,.329];return e.define({[Ze]:{primaries:t,whitePoint:r,transfer:Qe,toXYZ:Vt,fromXYZ:Ht,luminanceCoefficients:n,workingColorSpaceConfig:{unpackColorSpace:Xe},outputColorSpaceConfig:{drawingBufferColorSpace:Xe}},[Xe]:{primaries:t,whitePoint:r,transfer:$e,toXYZ:Vt,fromXYZ:Ht,luminanceCoefficients:n,outputColorSpaceConfig:{drawingBufferColorSpace:Xe}}}),e}var Wt=Ut();function Gt(e){return e<.04045?e*.0773993808:(e*.9478672986+.0521327014)**2.4}function Kt(e){return e<.0031308?e*12.92:1.055*e**.41666-.055}var qt,Jt=class{static getDataURL(e,t=`image/png`){if(/^data:/i.test(e.src)||typeof HTMLCanvasElement>`u`)return e.src;let n;if(e instanceof HTMLCanvasElement)n=e;else{qt===void 0&&(qt=at(`canvas`)),qt.width=e.width,qt.height=e.height;let t=qt.getContext(`2d`);e instanceof ImageData?t.putImageData(e,0,0):t.drawImage(e,0,0,e.width,e.height),n=qt}return n.toDataURL(t)}static sRGBToLinear(e){if(typeof HTMLImageElement<`u`&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement||typeof ImageBitmap<`u`&&e instanceof ImageBitmap){let t=at(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);n.drawImage(e,0,0,e.width,e.height);let r=n.getImageData(0,0,e.width,e.height),i=r.data;for(let e=0;e<i.length;e++)i[e]=Gt(i[e]/255)*255;return n.putImageData(r,0,0),t}if(e.data){let t=e.data.slice(0);for(let e=0;e<t.length;e++)t instanceof Uint8Array||t instanceof Uint8ClampedArray?t[e]=Math.floor(Gt(t[e]/255)*255):t[e]=Gt(t[e]);return{data:t,width:e.width,height:e.height}}return R(`ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.`),e}},Yt=0,Xt=class{constructor(e=null){this.isTextureSource=!0,Object.defineProperty(this,"id",{value:Yt++}),this.uuid=ht(),this.data=e,this.dataReady=!0,this.version=0}getSize(e){let t=this.data;return typeof HTMLVideoElement<`u`&&t instanceof HTMLVideoElement?e.set(t.videoWidth,t.videoHeight,0):typeof VideoFrame<`u`&&t instanceof VideoFrame?e.set(t.displayWidth,t.displayHeight,0):t===null?e.set(0,0,0):e.set(t.width,t.height,t.depth||0),e}set needsUpdate(e){e===!0&&this.version++}toJSON(e){let t=e===void 0||typeof e==`string`;if(!t&&e.images[this.uuid]!==void 0)return e.images[this.uuid];let n={uuid:this.uuid,url:``},r=this.data;if(r!==null){let e;if(Array.isArray(r)){e=[];for(let t=0,n=r.length;t<n;t++)r[t].isDataTexture?e.push(Zt(r[t].image)):e.push(Zt(r[t]))}else e=Zt(r);n.url=e}return t||(e.images[this.uuid]=n),n}};function Zt(e){return typeof HTMLImageElement<`u`&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement||typeof ImageBitmap<`u`&&e instanceof ImageBitmap?Jt.getDataURL(e):e.data?{data:Array.from(e.data),width:e.width,height:e.height,type:e.data.constructor.name}:(R(`Texture: Unable to serialize Texture.`),{})}var Qt=0,$t=new U,en=class e extends ut{constructor(t=e.DEFAULT_IMAGE,n=e.DEFAULT_MAPPING,r=Ae,i=Ae,a=Fe,o=Le,s=Be,c=Re,l=e.DEFAULT_ANISOTROPY,u=``){super(),this.isTexture=!0,Object.defineProperty(this,"id",{value:Qt++}),this.uuid=ht(),this.name=``,this.source=new Xt(t),this.mipmaps=[],this.mapping=n,this.channel=0,this.wrapS=r,this.wrapT=i,this.magFilter=a,this.minFilter=o,this.anisotropy=l,this.format=s,this.internalFormat=null,this.type=c,this.offset=new H(0,0),this.repeat=new H(1,1),this.center=new H(0,0),this.rotation=0,this.matrixAutoUpdate=!0,this.matrix=new zt,this.generateMipmaps=!0,this.premultiplyAlpha=!1,this.flipY=!0,this.unpackAlignment=4,this.colorSpace=u,this.userData={},this.updateRanges=[],this.version=0,this.onUpdate=null,this.renderTarget=null,this.isRenderTargetTexture=!1,this.isArrayTexture=!!(t&&t.depth&&t.depth>1),this.pmremVersion=0,this.normalized=!1}get width(){return this.source.getSize($t).x}get height(){return this.source.getSize($t).y}get depth(){return this.source.getSize($t).z}get image(){return this.source.data}set image(e){this.source.data=e}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return new this.constructor().copy(this)}copy(e){return this.name=e.name,this.source=e.source,this.mipmaps=e.mipmaps.slice(0),this.mapping=e.mapping,this.channel=e.channel,this.wrapS=e.wrapS,this.wrapT=e.wrapT,this.magFilter=e.magFilter,this.minFilter=e.minFilter,this.anisotropy=e.anisotropy,this.format=e.format,this.internalFormat=e.internalFormat,this.type=e.type,this.normalized=e.normalized,this.offset.copy(e.offset),this.repeat.copy(e.repeat),this.center.copy(e.center),this.rotation=e.rotation,this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrix.copy(e.matrix),this.generateMipmaps=e.generateMipmaps,this.premultiplyAlpha=e.premultiplyAlpha,this.flipY=e.flipY,this.unpackAlignment=e.unpackAlignment,this.colorSpace=e.colorSpace,this.renderTarget=e.renderTarget,this.isRenderTargetTexture=e.isRenderTargetTexture,this.isArrayTexture=e.isArrayTexture,this.userData=JSON.parse(JSON.stringify(e.userData)),this.needsUpdate=!0,this}setValues(e){for(let t in e){let n=e[t];if(n===void 0){R(`Texture.setValues(): parameter '${t}' has value of undefined.`);continue}let r=this[t];r===void 0?R(`Texture.setValues(): property '${t}' does not exist.`):r&&n&&r.isVector2&&n.isVector2||r&&n&&r.isVector3&&n.isVector3||r&&n&&r.isMatrix3&&n.isMatrix3?r.copy(n):this[t]=n}}toJSON(e){let t=e===void 0||typeof e==`string`;if(!t&&e.textures[this.uuid]!==void 0)return e.textures[this.uuid];let n={metadata:{version:4.7,type:`Texture`,generator:`Texture.toJSON`},uuid:this.uuid,name:this.name,image:this.source.toJSON(e).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,normalized:this.normalized,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(n.userData=this.userData),t||(e.textures[this.uuid]=n),n}dispose(){this.dispatchEvent({type:`dispose`})}transformUv(e){if(this.mapping!==300)return e;if(e.applyMatrix3(this.matrix),e.x<0||e.x>1)switch(this.wrapS){case ke:e.x-=Math.floor(e.x);break;case Ae:e.x=e.x<0?0:1;break;case je:Math.abs(Math.floor(e.x)%2)===1?e.x=Math.ceil(e.x)-e.x:e.x-=Math.floor(e.x)}if(e.y<0||e.y>1)switch(this.wrapT){case ke:e.y-=Math.floor(e.y);break;case Ae:e.y=e.y<0?0:1;break;case je:Math.abs(Math.floor(e.y)%2)===1?e.y=Math.ceil(e.y)-e.y:e.y-=Math.floor(e.y)}return this.flipY&&(e.y=1-e.y),e}set needsUpdate(e){e===!0&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(e){e===!0&&this.pmremVersion++}};en.DEFAULT_IMAGE=null,en.DEFAULT_MAPPING=300,en.DEFAULT_ANISOTROPY=1,De=Symbol.iterator;var tn=class{constructor(e=0,t=0,n=0,r=1){this.x=e,this.y=t,this.z=n,this.w=r}get width(){return this.z}set width(e){this.z=e}get height(){return this.w}set height(e){this.w=e}set(e,t,n,r){return this.x=e,this.y=t,this.z=n,this.w=r,this}setScalar(e){return this.x=e,this.y=e,this.z=e,this.w=e,this}setX(e){return this.x=e,this}setY(e){return this.y=e,this}setZ(e){return this.z=e,this}setW(e){return this.w=e,this}setComponent(e,t){switch(e){case 0:this.x=t;break;case 1:this.y=t;break;case 2:this.z=t;break;case 3:this.w=t;break;default:throw Error(`THREE.Vector4: index is out of range: `+e)}return this}getComponent(e){switch(e){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error(`THREE.Vector4: index is out of range: `+e)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.w=e.w===void 0?1:e.w,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.w+=e,this}addVectors(e,t){return this.x=e.x+t.x,this.y=e.y+t.y,this.z=e.z+t.z,this.w=e.w+t.w,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this.w+=e.w*t,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.w-=e,this}subVectors(e,t){return this.x=e.x-t.x,this.y=e.y-t.y,this.z=e.z-t.z,this.w=e.w-t.w,this}multiply(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this}applyMatrix4(e){let t=this.x,n=this.y,r=this.z,i=this.w,a=e.elements;return this.x=a[0]*t+a[4]*n+a[8]*r+a[12]*i,this.y=a[1]*t+a[5]*n+a[9]*r+a[13]*i,this.z=a[2]*t+a[6]*n+a[10]*r+a[14]*i,this.w=a[3]*t+a[7]*n+a[11]*r+a[15]*i,this}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.w/=e.w,this}divideScalar(e){return this.multiplyScalar(1/e)}setAxisAngleFromQuaternion(e){this.w=2*Math.acos(e.w);let t=Math.sqrt(1-e.w*e.w);return t<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=e.x/t,this.y=e.y/t,this.z=e.z/t),this}setAxisAngleFromRotationMatrix(e){let t,n,r,i,a=.01,o=.1,s=e.elements,c=s[0],l=s[4],u=s[8],d=s[1],f=s[5],p=s[9],m=s[2],h=s[6],g=s[10];if(Math.abs(l-d)<a&&Math.abs(u-m)<a&&Math.abs(p-h)<a){if(Math.abs(l+d)<o&&Math.abs(u+m)<o&&Math.abs(p+h)<o&&Math.abs(c+f+g-3)<o)return this.set(1,0,0,0),this;t=Math.PI;let e=(c+1)/2,s=(f+1)/2,_=(g+1)/2,v=(l+d)/4,y=(u+m)/4,b=(p+h)/4;return e>s&&e>_?e<a?(n=0,r=.707106781,i=.707106781):(n=Math.sqrt(e),r=v/n,i=y/n):s>_?s<a?(n=.707106781,r=0,i=.707106781):(r=Math.sqrt(s),n=v/r,i=b/r):_<a?(n=.707106781,r=.707106781,i=0):(i=Math.sqrt(_),n=y/i,r=b/i),this.set(n,r,i,t),this}let _=Math.sqrt((h-p)*(h-p)+(u-m)*(u-m)+(d-l)*(d-l));return Math.abs(_)<.001&&(_=1),this.x=(h-p)/_,this.y=(u-m)/_,this.z=(d-l)/_,this.w=Math.acos((c+f+g-1)/2),this}setFromMatrixPosition(e){let t=e.elements;return this.x=t[12],this.y=t[13],this.z=t[14],this.w=t[15],this}min(e){return this.x=Math.min(this.x,e.x),this.y=Math.min(this.y,e.y),this.z=Math.min(this.z,e.z),this.w=Math.min(this.w,e.w),this}max(e){return this.x=Math.max(this.x,e.x),this.y=Math.max(this.y,e.y),this.z=Math.max(this.z,e.z),this.w=Math.max(this.w,e.w),this}clamp(e,t){return this.x=B(this.x,e.x,t.x),this.y=B(this.y,e.y,t.y),this.z=B(this.z,e.z,t.z),this.w=B(this.w,e.w,t.w),this}clampScalar(e,t){return this.x=B(this.x,e,t),this.y=B(this.y,e,t),this.z=B(this.z,e,t),this.w=B(this.w,e,t),this}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(B(n,e,t))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.w=Math.floor(this.w),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.w=Math.ceil(this.w),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.w=Math.round(this.w),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this.w=Math.trunc(this.w),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this.w=-this.w,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)}normalize(){return this.divideScalar(this.length()||1)}setLength(e){return this.normalize().multiplyScalar(e)}lerp(e,t){return this.x+=(e.x-this.x)*t,this.y+=(e.y-this.y)*t,this.z+=(e.z-this.z)*t,this.w+=(e.w-this.w)*t,this}lerpVectors(e,t,n){return this.x=e.x+(t.x-e.x)*n,this.y=e.y+(t.y-e.y)*n,this.z=e.z+(t.z-e.z)*n,this.w=e.w+(t.w-e.w)*n,this}equals(e){return e.x===this.x&&e.y===this.y&&e.z===this.z&&e.w===this.w}fromArray(e,t=0){return this.x=e[t],this.y=e[t+1],this.z=e[t+2],this.w=e[t+3],this}toArray(e=[],t=0){return e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e[t+3]=this.w,e}fromBufferAttribute(e,t){return this.x=e.getX(t),this.y=e.getY(t),this.z=e.getZ(t),this.w=e.getW(t),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this.w=Math.random(),this}*[De](){yield this.x,yield this.y,yield this.z,yield this.w}};Se=tn,Se.prototype.isVector4=!0;var W=class e{constructor(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],e!==void 0&&this.set(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h)}set(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h){let g=this.elements;return g[0]=e,g[4]=t,g[8]=n,g[12]=r,g[1]=i,g[5]=a,g[9]=o,g[13]=s,g[2]=c,g[6]=l,g[10]=u,g[14]=d,g[3]=f,g[7]=p,g[11]=m,g[15]=h,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return new e().fromArray(this.elements)}copy(e){let t=this.elements,n=e.elements;return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],this}copyPosition(e){let t=this.elements,n=e.elements;return t[12]=n[12],t[13]=n[13],t[14]=n[14],this}setFromMatrix3(e){let t=e.elements;return this.set(t[0],t[3],t[6],0,t[1],t[4],t[7],0,t[2],t[5],t[8],0,0,0,0,1),this}extractBasis(e,t,n){return this.determinantAffine()===0?(e.set(1,0,0),t.set(0,1,0),n.set(0,0,1),this):(e.setFromMatrixColumn(this,0),t.setFromMatrixColumn(this,1),n.setFromMatrixColumn(this,2),this)}makeBasis(e,t,n){return this.set(e.x,t.x,n.x,0,e.y,t.y,n.y,0,e.z,t.z,n.z,0,0,0,0,1),this}extractRotation(e){if(e.determinantAffine()===0)return this.identity();let t=this.elements,n=e.elements,r=1/nn.setFromMatrixColumn(e,0).length(),i=1/nn.setFromMatrixColumn(e,1).length(),a=1/nn.setFromMatrixColumn(e,2).length();return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=0,t[4]=n[4]*i,t[5]=n[5]*i,t[6]=n[6]*i,t[7]=0,t[8]=n[8]*a,t[9]=n[9]*a,t[10]=n[10]*a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromEuler(e){let t=this.elements,n=e.x,r=e.y,i=e.z,a=Math.cos(n),o=Math.sin(n),s=Math.cos(r),c=Math.sin(r),l=Math.cos(i),u=Math.sin(i);if(e.order===`XYZ`){let e=a*l,n=a*u,r=o*l,i=o*u;t[0]=s*l,t[4]=-s*u,t[8]=c,t[1]=n+r*c,t[5]=e-i*c,t[9]=-o*s,t[2]=i-e*c,t[6]=r+n*c,t[10]=a*s}else if(e.order===`YXZ`){let e=s*l,n=s*u,r=c*l,i=c*u;t[0]=e+i*o,t[4]=r*o-n,t[8]=a*c,t[1]=a*u,t[5]=a*l,t[9]=-o,t[2]=n*o-r,t[6]=i+e*o,t[10]=a*s}else if(e.order===`ZXY`){let e=s*l,n=s*u,r=c*l,i=c*u;t[0]=e-i*o,t[4]=-a*u,t[8]=r+n*o,t[1]=n+r*o,t[5]=a*l,t[9]=i-e*o,t[2]=-a*c,t[6]=o,t[10]=a*s}else if(e.order===`ZYX`){let e=a*l,n=a*u,r=o*l,i=o*u;t[0]=s*l,t[4]=r*c-n,t[8]=e*c+i,t[1]=s*u,t[5]=i*c+e,t[9]=n*c-r,t[2]=-c,t[6]=o*s,t[10]=a*s}else if(e.order===`YZX`){let e=a*s,n=a*c,r=o*s,i=o*c;t[0]=s*l,t[4]=i-e*u,t[8]=r*u+n,t[1]=u,t[5]=a*l,t[9]=-o*l,t[2]=-c*l,t[6]=n*u+r,t[10]=e-i*u}else if(e.order===`XZY`){let e=a*s,n=a*c,r=o*s,i=o*c;t[0]=s*l,t[4]=-u,t[8]=c*l,t[1]=e*u+i,t[5]=a*l,t[9]=n*u-r,t[2]=r*u-n,t[6]=o*l,t[10]=i*u+e}return t[3]=0,t[7]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,this}makeRotationFromQuaternion(e){return this.compose(an,e,on)}lookAt(e,t,n){let r=this.elements;return ln.subVectors(e,t),ln.lengthSq()===0&&(ln.z=1),ln.normalize(),sn.crossVectors(n,ln),sn.lengthSq()===0&&(Math.abs(n.z)===1?ln.x+=1e-4:ln.z+=1e-4,ln.normalize(),sn.crossVectors(n,ln)),sn.normalize(),cn.crossVectors(ln,sn),r[0]=sn.x,r[4]=cn.x,r[8]=ln.x,r[1]=sn.y,r[5]=cn.y,r[9]=ln.y,r[2]=sn.z,r[6]=cn.z,r[10]=ln.z,this}multiply(e){return this.multiplyMatrices(this,e)}premultiply(e){return this.multiplyMatrices(e,this)}multiplyMatrices(e,t){let n=e.elements,r=t.elements,i=this.elements,a=n[0],o=n[4],s=n[8],c=n[12],l=n[1],u=n[5],d=n[9],f=n[13],p=n[2],m=n[6],h=n[10],g=n[14],_=n[3],v=n[7],y=n[11],b=n[15],x=r[0],S=r[4],C=r[8],w=r[12],T=r[1],E=r[5],D=r[9],O=r[13],k=r[2],A=r[6],j=r[10],M=r[14],N=r[3],P=r[7],ee=r[11],F=r[15];return i[0]=a*x+o*T+s*k+c*N,i[4]=a*S+o*E+s*A+c*P,i[8]=a*C+o*D+s*j+c*ee,i[12]=a*w+o*O+s*M+c*F,i[1]=l*x+u*T+d*k+f*N,i[5]=l*S+u*E+d*A+f*P,i[9]=l*C+u*D+d*j+f*ee,i[13]=l*w+u*O+d*M+f*F,i[2]=p*x+m*T+h*k+g*N,i[6]=p*S+m*E+h*A+g*P,i[10]=p*C+m*D+h*j+g*ee,i[14]=p*w+m*O+h*M+g*F,i[3]=_*x+v*T+y*k+b*N,i[7]=_*S+v*E+y*A+b*P,i[11]=_*C+v*D+y*j+b*ee,i[15]=_*w+v*O+y*M+b*F,this}multiplyScalar(e){let t=this.elements;return t[0]*=e,t[4]*=e,t[8]*=e,t[12]*=e,t[1]*=e,t[5]*=e,t[9]*=e,t[13]*=e,t[2]*=e,t[6]*=e,t[10]*=e,t[14]*=e,t[3]*=e,t[7]*=e,t[11]*=e,t[15]*=e,this}determinant(){let e=this.elements,t=e[0],n=e[4],r=e[8],i=e[12],a=e[1],o=e[5],s=e[9],c=e[13],l=e[2],u=e[6],d=e[10],f=e[14],p=e[3],m=e[7],h=e[11],g=e[15],_=s*f-c*d,v=o*f-c*u,y=o*d-s*u,b=a*f-c*l,x=a*d-s*l,S=a*u-o*l;return t*(m*_-h*v+g*y)-n*(p*_-h*b+g*x)+r*(p*v-m*b+g*S)-i*(p*y-m*x+h*S)}determinantAffine(){let e=this.elements,t=e[0],n=e[4],r=e[8],i=e[1],a=e[5],o=e[9],s=e[2],c=e[6],l=e[10];return t*(a*l-o*c)-n*(i*l-o*s)+r*(i*c-a*s)}transpose(){let e=this.elements,t;return t=e[1],e[1]=e[4],e[4]=t,t=e[2],e[2]=e[8],e[8]=t,t=e[6],e[6]=e[9],e[9]=t,t=e[3],e[3]=e[12],e[12]=t,t=e[7],e[7]=e[13],e[13]=t,t=e[11],e[11]=e[14],e[14]=t,this}setPosition(e,t,n){let r=this.elements;return e.isVector3?(r[12]=e.x,r[13]=e.y,r[14]=e.z):(r[12]=e,r[13]=t,r[14]=n),this}invert(){let e=this.elements,t=e[0],n=e[1],r=e[2],i=e[3],a=e[4],o=e[5],s=e[6],c=e[7],l=e[8],u=e[9],d=e[10],f=e[11],p=e[12],m=e[13],h=e[14],g=e[15],_=t*o-n*a,v=t*s-r*a,y=t*c-i*a,b=n*s-r*o,x=n*c-i*o,S=r*c-i*s,C=l*m-u*p,w=l*h-d*p,T=l*g-f*p,E=u*h-d*m,D=u*g-f*m,O=d*g-f*h,k=_*O-v*D+y*E+b*T-x*w+S*C;if(k===0)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);let A=1/k;return e[0]=(o*O-s*D+c*E)*A,e[1]=(r*D-n*O-i*E)*A,e[2]=(m*S-h*x+g*b)*A,e[3]=(d*x-u*S-f*b)*A,e[4]=(s*T-a*O-c*w)*A,e[5]=(t*O-r*T+i*w)*A,e[6]=(h*y-p*S-g*v)*A,e[7]=(l*S-d*y+f*v)*A,e[8]=(a*D-o*T+c*C)*A,e[9]=(n*T-t*D-i*C)*A,e[10]=(p*x-m*y+g*_)*A,e[11]=(u*y-l*x-f*_)*A,e[12]=(o*w-a*E-s*C)*A,e[13]=(t*E-n*w+r*C)*A,e[14]=(m*v-p*b-h*_)*A,e[15]=(l*b-u*v+d*_)*A,this}scale(e){let t=this.elements,n=e.x,r=e.y,i=e.z;return t[0]*=n,t[4]*=r,t[8]*=i,t[1]*=n,t[5]*=r,t[9]*=i,t[2]*=n,t[6]*=r,t[10]*=i,t[3]*=n,t[7]*=r,t[11]*=i,this}getMaxScaleOnAxis(){let e=this.elements,t=e[0]*e[0]+e[1]*e[1]+e[2]*e[2],n=e[4]*e[4]+e[5]*e[5]+e[6]*e[6],r=e[8]*e[8]+e[9]*e[9]+e[10]*e[10];return Math.sqrt(Math.max(t,n,r))}makeTranslation(e,t,n){return e.isVector3?this.set(1,0,0,e.x,0,1,0,e.y,0,0,1,e.z,0,0,0,1):this.set(1,0,0,e,0,1,0,t,0,0,1,n,0,0,0,1),this}makeRotationX(e){let t=Math.cos(e),n=Math.sin(e);return this.set(1,0,0,0,0,t,-n,0,0,n,t,0,0,0,0,1),this}makeRotationY(e){let t=Math.cos(e),n=Math.sin(e);return this.set(t,0,n,0,0,1,0,0,-n,0,t,0,0,0,0,1),this}makeRotationZ(e){let t=Math.cos(e),n=Math.sin(e);return this.set(t,-n,0,0,n,t,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(e,t){let n=Math.cos(t),r=Math.sin(t),i=1-n,a=e.x,o=e.y,s=e.z,c=i*a,l=i*o;return this.set(c*a+n,c*o-r*s,c*s+r*o,0,c*o+r*s,l*o+n,l*s-r*a,0,c*s-r*o,l*s+r*a,i*s*s+n,0,0,0,0,1),this}makeScale(e,t,n){return this.set(e,0,0,0,0,t,0,0,0,0,n,0,0,0,0,1),this}makeShear(e,t,n,r,i,a){return this.set(1,n,i,0,e,1,a,0,t,r,1,0,0,0,0,1),this}compose(e,t,n){let r=this.elements,i=t._x,a=t._y,o=t._z,s=t._w,c=i+i,l=a+a,u=o+o,d=i*c,f=i*l,p=i*u,m=a*l,h=a*u,g=o*u,_=s*c,v=s*l,y=s*u,b=n.x,x=n.y,S=n.z;return r[0]=(1-(m+g))*b,r[1]=(f+y)*b,r[2]=(p-v)*b,r[3]=0,r[4]=(f-y)*x,r[5]=(1-(d+g))*x,r[6]=(h+_)*x,r[7]=0,r[8]=(p+v)*S,r[9]=(h-_)*S,r[10]=(1-(d+m))*S,r[11]=0,r[12]=e.x,r[13]=e.y,r[14]=e.z,r[15]=1,this}decompose(e,t,n){let r=this.elements;e.x=r[12],e.y=r[13],e.z=r[14];let i=this.determinantAffine();if(i===0)return n.set(1,1,1),t.identity(),this;let a=nn.set(r[0],r[1],r[2]).length(),o=nn.set(r[4],r[5],r[6]).length(),s=nn.set(r[8],r[9],r[10]).length();i<0&&(a=-a),rn.copy(this);let c=1/a,l=1/o,u=1/s;return rn.elements[0]*=c,rn.elements[1]*=c,rn.elements[2]*=c,rn.elements[4]*=l,rn.elements[5]*=l,rn.elements[6]*=l,rn.elements[8]*=u,rn.elements[9]*=u,rn.elements[10]*=u,t.setFromRotationMatrix(rn),n.x=a,n.y=o,n.z=s,this}makePerspective(e,t,n,r,i,a,o=nt,s=!1){let c=this.elements,l=2*i/(t-e),u=2*i/(n-r),d=(t+e)/(t-e),f=(n+r)/(n-r),p,m;if(s)p=i/(a-i),m=a*i/(a-i);else if(o===2e3)p=-(a+i)/(a-i),m=-2*a*i/(a-i);else if(o===2001)p=-a/(a-i),m=-a*i/(a-i);else throw Error(`THREE.Matrix4.makePerspective(): Invalid coordinate system: `+o);return c[0]=l,c[4]=0,c[8]=d,c[12]=0,c[1]=0,c[5]=u,c[9]=f,c[13]=0,c[2]=0,c[6]=0,c[10]=p,c[14]=m,c[3]=0,c[7]=0,c[11]=-1,c[15]=0,this}makeOrthographic(e,t,n,r,i,a,o=nt,s=!1){let c=this.elements,l=2/(t-e),u=2/(n-r),d=-(t+e)/(t-e),f=-(n+r)/(n-r),p,m;if(s)p=1/(a-i),m=a/(a-i);else if(o===2e3)p=-2/(a-i),m=-(a+i)/(a-i);else if(o===2001)p=-1/(a-i),m=-i/(a-i);else throw Error(`THREE.Matrix4.makeOrthographic(): Invalid coordinate system: `+o);return c[0]=l,c[4]=0,c[8]=0,c[12]=d,c[1]=0,c[5]=u,c[9]=0,c[13]=f,c[2]=0,c[6]=0,c[10]=p,c[14]=m,c[3]=0,c[7]=0,c[11]=0,c[15]=1,this}equals(e){let t=this.elements,n=e.elements;for(let e=0;e<16;e++)if(t[e]!==n[e])return!1;return!0}fromArray(e,t=0){for(let n=0;n<16;n++)this.elements[n]=e[n+t];return this}toArray(e=[],t=0){let n=this.elements;return e[t]=n[0],e[t+1]=n[1],e[t+2]=n[2],e[t+3]=n[3],e[t+4]=n[4],e[t+5]=n[5],e[t+6]=n[6],e[t+7]=n[7],e[t+8]=n[8],e[t+9]=n[9],e[t+10]=n[10],e[t+11]=n[11],e[t+12]=n[12],e[t+13]=n[13],e[t+14]=n[14],e[t+15]=n[15],e}};Ce=W,Ce.prototype.isMatrix4=!0;var nn=new U,rn=new W,an=new U(0,0,0),on=new U(1,1,1),sn=new U,cn=new U,ln=new U,un=new W,dn=new It,fn=class e{constructor(t=0,n=0,r=0,i=e.DEFAULT_ORDER){this.isEuler=!0,this._x=t,this._y=n,this._z=r,this._order=i}get x(){return this._x}set x(e){this._x=e,this._onChangeCallback()}get y(){return this._y}set y(e){this._y=e,this._onChangeCallback()}get z(){return this._z}set z(e){this._z=e,this._onChangeCallback()}get order(){return this._order}set order(e){this._order=e,this._onChangeCallback()}set(e,t,n,r=this._order){return this._x=e,this._y=t,this._z=n,this._order=r,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(e){return this._x=e._x,this._y=e._y,this._z=e._z,this._order=e._order,this._onChangeCallback(),this}setFromRotationMatrix(e,t=this._order,n=!0){let r=e.elements,i=r[0],a=r[4],o=r[8],s=r[1],c=r[5],l=r[9],u=r[2],d=r[6],f=r[10];switch(t){case`XYZ`:this._y=Math.asin(B(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-l,f),this._z=Math.atan2(-a,i)):(this._x=Math.atan2(d,c),this._z=0);break;case`YXZ`:this._x=Math.asin(-B(l,-1,1)),Math.abs(l)<.9999999?(this._y=Math.atan2(o,f),this._z=Math.atan2(s,c)):(this._y=Math.atan2(-u,i),this._z=0);break;case`ZXY`:this._x=Math.asin(B(d,-1,1)),Math.abs(d)<.9999999?(this._y=Math.atan2(-u,f),this._z=Math.atan2(-a,c)):(this._y=0,this._z=Math.atan2(s,i));break;case`ZYX`:this._y=Math.asin(-B(u,-1,1)),Math.abs(u)<.9999999?(this._x=Math.atan2(d,f),this._z=Math.atan2(s,i)):(this._x=0,this._z=Math.atan2(-a,c));break;case`YZX`:this._z=Math.asin(B(s,-1,1)),Math.abs(s)<.9999999?(this._x=Math.atan2(-l,c),this._y=Math.atan2(-u,i)):(this._x=0,this._y=Math.atan2(o,f));break;case`XZY`:this._z=Math.asin(-B(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(d,c),this._y=Math.atan2(o,i)):(this._x=Math.atan2(-l,f),this._y=0);break;default:R(`Euler: .setFromRotationMatrix() encountered an unknown order: `+t)}return this._order=t,n===!0&&this._onChangeCallback(),this}setFromQuaternion(e,t,n){return un.makeRotationFromQuaternion(e),this.setFromRotationMatrix(un,t,n)}setFromVector3(e,t=this._order){return this.set(e.x,e.y,e.z,t)}reorder(e){return dn.setFromEuler(this),this.setFromQuaternion(dn,e)}equals(e){return e._x===this._x&&e._y===this._y&&e._z===this._z&&e._order===this._order}fromArray(e){return this._x=e[0],this._y=e[1],this._z=e[2],e[3]!==void 0&&(this._order=e[3]),this._onChangeCallback(),this}toArray(e=[],t=0){return e[t]=this._x,e[t+1]=this._y,e[t+2]=this._z,e[t+3]=this._order,e}_onChange(e){return this._onChangeCallback=e,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}};fn.DEFAULT_ORDER=`XYZ`;var pn=class{constructor(){this.mask=1}set(e){this.mask=1<<e>>>0}enable(e){this.mask|=1<<e}enableAll(){this.mask=-1}toggle(e){this.mask^=1<<e}disable(e){this.mask&=~(1<<e)}disableAll(){this.mask=0}test(e){return(this.mask&e.mask)!==0}isEnabled(e){return!!(this.mask&1<<e)}},mn=0,hn=new U,gn=new It,_n=new W,vn=new U,yn=new U,bn=new U,xn=new It,Sn=new U(1,0,0),Cn=new U(0,1,0),wn=new U(0,0,1),Tn={type:`added`},En={type:`removed`},Dn={type:`childadded`,child:null},On={type:`childremoved`,child:null},G=class e extends ut{constructor(){super(),this.isObject3D=!0,Object.defineProperty(this,"id",{value:mn++}),this.uuid=ht(),this.name=``,this.type=`Object3D`,this.parent=null,this.children=[],this.up=e.DEFAULT_UP.clone();let t=new U,n=new fn,r=new It,i=new U(1,1,1);function a(){r.setFromEuler(n,!1)}function o(){n.setFromQuaternion(r,void 0,!1)}n._onChange(a),r._onChange(o),Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:t},rotation:{configurable:!0,enumerable:!0,value:n},quaternion:{configurable:!0,enumerable:!0,value:r},scale:{configurable:!0,enumerable:!0,value:i},modelViewMatrix:{value:new W},normalMatrix:{value:new zt}}),this.matrix=new W,this.matrixWorld=new W,this.matrixAutoUpdate=e.DEFAULT_MATRIX_AUTO_UPDATE,this.matrixWorldAutoUpdate=e.DEFAULT_MATRIX_WORLD_AUTO_UPDATE,this.matrixWorldNeedsUpdate=!1,this.layers=new pn,this.visible=!0,this.castShadow=!1,this.receiveShadow=!1,this.frustumCulled=!0,this.renderOrder=0,this.animations=[],this.customDepthMaterial=void 0,this.customDistanceMaterial=void 0,this.static=!1,this.userData={},this.pivot=null}onBeforeShadow(){}onAfterShadow(){}onBeforeRender(){}onAfterRender(){}applyMatrix4(e){this.matrixAutoUpdate&&this.updateMatrix(),this.matrix.premultiply(e),this.matrix.decompose(this.position,this.quaternion,this.scale)}applyQuaternion(e){return this.quaternion.premultiply(e),this}setRotationFromAxisAngle(e,t){this.quaternion.setFromAxisAngle(e,t)}setRotationFromEuler(e){this.quaternion.setFromEuler(e,!0)}setRotationFromMatrix(e){this.quaternion.setFromRotationMatrix(e)}setRotationFromQuaternion(e){this.quaternion.copy(e)}rotateOnAxis(e,t){return gn.setFromAxisAngle(e,t),this.quaternion.multiply(gn),this}rotateOnWorldAxis(e,t){return gn.setFromAxisAngle(e,t),this.quaternion.premultiply(gn),this}rotateX(e){return this.rotateOnAxis(Sn,e)}rotateY(e){return this.rotateOnAxis(Cn,e)}rotateZ(e){return this.rotateOnAxis(wn,e)}translateOnAxis(e,t){return hn.copy(e).applyQuaternion(this.quaternion),this.position.add(hn.multiplyScalar(t)),this}translateX(e){return this.translateOnAxis(Sn,e)}translateY(e){return this.translateOnAxis(Cn,e)}translateZ(e){return this.translateOnAxis(wn,e)}localToWorld(e){return this.updateWorldMatrix(!0,!1),e.applyMatrix4(this.matrixWorld)}worldToLocal(e){return this.updateWorldMatrix(!0,!1),e.applyMatrix4(_n.copy(this.matrixWorld).invert())}lookAt(e,t,n){e.isVector3?vn.copy(e):vn.set(e,t,n);let r=this.parent;this.updateWorldMatrix(!0,!1),yn.setFromMatrixPosition(this.matrixWorld),this.isCamera||this.isLight?_n.lookAt(yn,vn,this.up):_n.lookAt(vn,yn,this.up),this.quaternion.setFromRotationMatrix(_n),r&&(_n.extractRotation(r.matrixWorld),gn.setFromRotationMatrix(_n),this.quaternion.premultiply(gn.invert()))}add(e){if(arguments.length>1){for(let e=0;e<arguments.length;e++)this.add(arguments[e]);return this}return e===this?(z(`Object3D.add: object can't be added as a child of itself.`,e),this):(e&&e.isObject3D?(e.removeFromParent(),e.parent=this,this.children.push(e),e.dispatchEvent(Tn),Dn.child=e,this.dispatchEvent(Dn),Dn.child=null):z(`Object3D.add: object not an instance of THREE.Object3D.`,e),this)}remove(e){if(arguments.length>1){for(let e=0;e<arguments.length;e++)this.remove(arguments[e]);return this}let t=this.children.indexOf(e);return t!==-1&&(e.parent=null,this.children.splice(t,1),e.dispatchEvent(En),On.child=e,this.dispatchEvent(On),On.child=null),this}removeFromParent(){let e=this.parent;return e!==null&&e.remove(this),this}clear(){return this.remove(...this.children)}attach(e){return this.updateWorldMatrix(!0,!1),_n.copy(this.matrixWorld).invert(),e.parent!==null&&(e.parent.updateWorldMatrix(!0,!1),_n.multiply(e.parent.matrixWorld)),e.applyMatrix4(_n),e.removeFromParent(),e.parent=this,this.children.push(e),e.updateWorldMatrix(!1,!0),e.dispatchEvent(Tn),Dn.child=e,this.dispatchEvent(Dn),Dn.child=null,this}getObjectById(e){return this.getObjectByProperty(`id`,e)}getObjectByName(e){return this.getObjectByProperty(`name`,e)}getObjectByProperty(e,t){if(this[e]===t)return this;for(let n=0,r=this.children.length;n<r;n++){let r=this.children[n].getObjectByProperty(e,t);if(r!==void 0)return r}}getObjectsByProperty(e,t,n=[]){this[e]===t&&n.push(this);let r=this.children;for(let i=0,a=r.length;i<a;i++)r[i].getObjectsByProperty(e,t,n);return n}getWorldPosition(e){return this.updateWorldMatrix(!0,!1),e.setFromMatrixPosition(this.matrixWorld)}getWorldQuaternion(e){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(yn,e,bn),e}getWorldScale(e){return this.updateWorldMatrix(!0,!1),this.matrixWorld.decompose(yn,xn,e),e}getWorldDirection(e){this.updateWorldMatrix(!0,!1);let t=this.matrixWorld.elements;return e.set(t[8],t[9],t[10]).normalize()}raycast(){}intersectsFrustum(){}traverse(e){e(this);let t=this.children;for(let n=0,r=t.length;n<r;n++)t[n].traverse(e)}traverseVisible(e){if(this.visible===!1)return;e(this);let t=this.children;for(let n=0,r=t.length;n<r;n++)t[n].traverseVisible(e)}traverseAncestors(e){let t=this.parent;t!==null&&(e(t),t.traverseAncestors(e))}updateMatrix(){this.matrix.compose(this.position,this.quaternion,this.scale);let e=this.pivot;if(e!==null){let t=e.x,n=e.y,r=e.z,i=this.matrix.elements;i[12]+=t-i[0]*t-i[4]*n-i[8]*r,i[13]+=n-i[1]*t-i[5]*n-i[9]*r,i[14]+=r-i[2]*t-i[6]*n-i[10]*r}this.matrixWorldNeedsUpdate=!0}updateMatrixWorld(e){this.matrixAutoUpdate&&this.updateMatrix(),(this.matrixWorldNeedsUpdate||e)&&(this.matrixWorldAutoUpdate===!0&&(this.parent===null?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix)),this.matrixWorldNeedsUpdate=!1,e=!0);let t=this.children;for(let n=0,r=t.length;n<r;n++)t[n].updateMatrixWorld(e)}updateWorldMatrix(e,t,n=!1){let r=this.parent;if(e===!0&&r!==null&&r.updateWorldMatrix(!0,!1),this.matrixAutoUpdate&&this.updateMatrix(),(this.matrixWorldNeedsUpdate||n)&&(this.matrixWorldAutoUpdate===!0&&(this.parent===null?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix)),this.matrixWorldNeedsUpdate=!1,n=!0),t===!0){let e=this.children;for(let t=0,r=e.length;t<r;t++)e[t].updateWorldMatrix(!1,!0,n)}}toJSON(e){let t=e===void 0||typeof e==`string`,n={};t&&(e={geometries:{},materials:{},textures:{},images:{},shapes:{},skeletons:{},animations:{},nodes:{}},n.metadata={version:4.7,type:`Object`,generator:`Object3D.toJSON`});let r={};r.uuid=this.uuid,r.type=this.type,r.name=this.name,r.castShadow=this.castShadow,r.receiveShadow=this.receiveShadow,r.visible=this.visible,r.frustumCulled=this.frustumCulled,r.renderOrder=this.renderOrder,r.static=this.static,r.matrixAutoUpdate=this.matrixAutoUpdate,Object.keys(this.userData).length>0&&(r.userData=this.userData),r.layers=this.layers.mask,r.matrix=this.matrix.toArray(),r.up=this.up.toArray(),this.pivot!==null&&(r.pivot=this.pivot.toArray()),this.morphTargetDictionary!==void 0&&(r.morphTargetDictionary=Object.assign({},this.morphTargetDictionary)),this.morphTargetInfluences!==void 0&&(r.morphTargetInfluences=this.morphTargetInfluences.slice()),this.isInstancedMesh&&(r.type=`InstancedMesh`,r.count=this.count,r.instanceMatrix=this.instanceMatrix.toJSON(),this.instanceColor!==null&&(r.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(r.type=`BatchedMesh`,r.perObjectFrustumCulled=this.perObjectFrustumCulled,r.sortObjects=this.sortObjects,r.drawRanges=this._drawRanges,r.reservedRanges=this._reservedRanges,r.geometryInfo=this._geometryInfo.map(e=>({...e,boundingBox:e.boundingBox?e.boundingBox.toJSON():void 0,boundingSphere:e.boundingSphere?e.boundingSphere.toJSON():void 0})),r.instanceInfo=this._instanceInfo.map(e=>({...e})),r.availableInstanceIds=this._availableInstanceIds.slice(),r.availableGeometryIds=this._availableGeometryIds.slice(),r.nextIndexStart=this._nextIndexStart,r.nextVertexStart=this._nextVertexStart,r.geometryCount=this._geometryCount,r.maxInstanceCount=this._maxInstanceCount,r.maxVertexCount=this._maxVertexCount,r.maxIndexCount=this._maxIndexCount,r.geometryInitialized=this._geometryInitialized,r.matricesTexture=this._matricesTexture.toJSON(e),r.indirectTexture=this._indirectTexture.toJSON(e),this._colorsTexture!==null&&(r.colorsTexture=this._colorsTexture.toJSON(e)),this.boundingSphere!==null&&(r.boundingSphere=this.boundingSphere.toJSON()),this.boundingBox!==null&&(r.boundingBox=this.boundingBox.toJSON()));function i(t,n){return t[n.uuid]===void 0&&(t[n.uuid]=n.toJSON(e)),n.uuid}if(this.isScene)this.background&&(this.background.isColor?r.background=this.background.toJSON():this.background.isTexture&&(r.background=this.background.toJSON(e).uuid)),this.environment&&this.environment.isTexture&&this.environment.isRenderTargetTexture!==!0&&(r.environment=this.environment.toJSON(e).uuid);else if(this.isMesh||this.isLine||this.isPoints){r.geometry=i(e.geometries,this.geometry);let t=this.geometry.parameters;if(t!==void 0&&t.shapes!==void 0){let n=t.shapes;if(Array.isArray(n))for(let t=0,r=n.length;t<r;t++){let r=n[t];i(e.shapes,r)}else i(e.shapes,n)}}if(this.isSkinnedMesh&&(r.bindMode=this.bindMode,r.bindMatrix=this.bindMatrix.toArray(),this.skeleton!==void 0&&(i(e.skeletons,this.skeleton),r.skeleton=this.skeleton.uuid)),this.material!==void 0){if(Array.isArray(this.material)){let t=[];for(let n=0,r=this.material.length;n<r;n++)t.push(i(e.materials,this.material[n]));r.material=t}else r.material=i(e.materials,this.material)}if(this.children.length>0){r.children=[];for(let t=0;t<this.children.length;t++)r.children.push(this.children[t].toJSON(e).object)}if(this.animations.length>0){r.animations=[];for(let t=0;t<this.animations.length;t++){let n=this.animations[t];r.animations.push(i(e.animations,n))}}if(t){let t=a(e.geometries),r=a(e.materials),i=a(e.textures),o=a(e.images),s=a(e.shapes),c=a(e.skeletons),l=a(e.animations),u=a(e.nodes);t.length>0&&(n.geometries=t),r.length>0&&(n.materials=r),i.length>0&&(n.textures=i),o.length>0&&(n.images=o),s.length>0&&(n.shapes=s),c.length>0&&(n.skeletons=c),l.length>0&&(n.animations=l),u.length>0&&(n.nodes=u)}return n.object=r,n;function a(e){let t=[];for(let n in e){let r=e[n];delete r.metadata,t.push(r)}return t}}clone(e){return new this.constructor().copy(this,e)}copy(e,t=!0){if(this.name=e.name,this.up.copy(e.up),this.position.copy(e.position),this.rotation.order=e.rotation.order,this.quaternion.copy(e.quaternion),this.scale.copy(e.scale),this.pivot=e.pivot===null?null:e.pivot.clone(),this.matrix.copy(e.matrix),this.matrixWorld.copy(e.matrixWorld),this.matrixAutoUpdate=e.matrixAutoUpdate,this.matrixWorldAutoUpdate=e.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=e.matrixWorldNeedsUpdate,this.layers.mask=e.layers.mask,this.visible=e.visible,this.castShadow=e.castShadow,this.receiveShadow=e.receiveShadow,this.frustumCulled=e.frustumCulled,this.renderOrder=e.renderOrder,this.static=e.static,this.animations=e.animations.slice(),this.userData=JSON.parse(JSON.stringify(e.userData)),t===!0)for(let t=0;t<e.children.length;t++){let n=e.children[t];this.add(n.clone())}return this}dispose(){this.dispatchEvent({type:`dispose`})}};G.DEFAULT_UP=new U(0,1,0),G.DEFAULT_MATRIX_AUTO_UPDATE=!0,G.DEFAULT_MATRIX_WORLD_AUTO_UPDATE=!0;var kn=class extends G{constructor(){super(),this.isGroup=!0,this.type=`Group`}},An={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},jn={h:0,s:0,l:0},Mn={h:0,s:0,l:0};function Nn(e,t,n){return n<0&&(n+=1),n>1&&--n,n<1/6?e+(t-e)*6*n:n<1/2?t:n<2/3?e+(t-e)*6*(2/3-n):e}var K=class{constructor(e,t,n){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(e,t,n)}set(e,t,n){if(t===void 0&&n===void 0){let t=e;t&&t.isColor?this.copy(t):typeof t==`number`?this.setHex(t):typeof t==`string`&&this.setStyle(t)}else this.setRGB(e,t,n);return this}setScalar(e){return this.r=e,this.g=e,this.b=e,this}setHex(e,t=Xe){return e=Math.floor(e),this.r=(e>>16&255)/255,this.g=(e>>8&255)/255,this.b=(e&255)/255,Wt.colorSpaceToWorking(this,t),this}setRGB(e,t,n,r=Wt.workingColorSpace){return this.r=e,this.g=t,this.b=n,Wt.colorSpaceToWorking(this,r),this}setHSL(e,t,n,r=Wt.workingColorSpace){if(e=gt(e,1),t=B(t,0,1),n=B(n,0,1),t===0)this.r=this.g=this.b=n;else{let r=n<=.5?n*(1+t):n+t-n*t,i=2*n-r;this.r=Nn(i,r,e+1/3),this.g=Nn(i,r,e),this.b=Nn(i,r,e-1/3)}return Wt.colorSpaceToWorking(this,r),this}setStyle(e,t=Xe){function n(t){t!==void 0&&parseFloat(t)<1&&R(`Color: Alpha component of `+e+` will be ignored.`)}let r;if(r=/^(\w+)\(([^\)]*)\)/.exec(e)){let i,a=r[1],o=r[2];switch(a){case`rgb`:case`rgba`:if(i=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))return n(i[4]),this.setRGB(Math.min(255,parseInt(i[1],10))/255,Math.min(255,parseInt(i[2],10))/255,Math.min(255,parseInt(i[3],10))/255,t);if(i=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))return n(i[4]),this.setRGB(Math.min(100,parseInt(i[1],10))/100,Math.min(100,parseInt(i[2],10))/100,Math.min(100,parseInt(i[3],10))/100,t);break;case`hsl`:case`hsla`:if(i=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(o))return n(i[4]),this.setHSL(parseFloat(i[1])/360,parseFloat(i[2])/100,parseFloat(i[3])/100,t);break;default:R(`Color: Unknown color model `+e)}}else if(r=/^\#([A-Fa-f\d]+)$/.exec(e)){let n=r[1],i=n.length;if(i===3)return this.setRGB(parseInt(n.charAt(0),16)/15,parseInt(n.charAt(1),16)/15,parseInt(n.charAt(2),16)/15,t);if(i===6)return this.setHex(parseInt(n,16),t);R(`Color: Invalid hex color `+e)}else if(e&&e.length>0)return this.setColorName(e,t);return this}setColorName(e,t=Xe){let n=An[e.toLowerCase()];return n===void 0?R(`Color: Unknown color `+e):this.setHex(n,t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(e){return this.r=e.r,this.g=e.g,this.b=e.b,this}copySRGBToLinear(e){return this.r=Gt(e.r),this.g=Gt(e.g),this.b=Gt(e.b),this}copyLinearToSRGB(e){return this.r=Kt(e.r),this.g=Kt(e.g),this.b=Kt(e.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(e=Xe){return Wt.workingToColorSpace(Pn.copy(this),e),Math.round(B(Pn.r*255,0,255))*65536+Math.round(B(Pn.g*255,0,255))*256+Math.round(B(Pn.b*255,0,255))}getHexString(e=Xe){return(`000000`+this.getHex(e).toString(16)).slice(-6)}getHSL(e,t=Wt.workingColorSpace){Wt.workingToColorSpace(Pn.copy(this),t);let n=Pn.r,r=Pn.g,i=Pn.b,a=Math.max(n,r,i),o=Math.min(n,r,i),s,c,l=(o+a)/2;if(o===a)s=0,c=0;else{let e=a-o;switch(c=l<=.5?e/(a+o):e/(2-a-o),a){case n:s=(r-i)/e+(r<i?6:0);break;case r:s=(i-n)/e+2;break;case i:s=(n-r)/e+4}s/=6}return e.h=s,e.s=c,e.l=l,e}getRGB(e,t=Wt.workingColorSpace){return Wt.workingToColorSpace(Pn.copy(this),t),e.r=Pn.r,e.g=Pn.g,e.b=Pn.b,e}getStyle(e=Xe){Wt.workingToColorSpace(Pn.copy(this),e);let t=Pn.r,n=Pn.g,r=Pn.b;return e===`srgb`?`rgb(${Math.round(t*255)},${Math.round(n*255)},${Math.round(r*255)})`:`color(${e} ${t.toFixed(3)} ${n.toFixed(3)} ${r.toFixed(3)})`}offsetHSL(e,t,n){return this.getHSL(jn),this.setHSL(jn.h+e,jn.s+t,jn.l+n)}add(e){return this.r+=e.r,this.g+=e.g,this.b+=e.b,this}addColors(e,t){return this.r=e.r+t.r,this.g=e.g+t.g,this.b=e.b+t.b,this}addScalar(e){return this.r+=e,this.g+=e,this.b+=e,this}sub(e){return this.r=Math.max(0,this.r-e.r),this.g=Math.max(0,this.g-e.g),this.b=Math.max(0,this.b-e.b),this}multiply(e){return this.r*=e.r,this.g*=e.g,this.b*=e.b,this}multiplyScalar(e){return this.r*=e,this.g*=e,this.b*=e,this}lerp(e,t){return this.r+=(e.r-this.r)*t,this.g+=(e.g-this.g)*t,this.b+=(e.b-this.b)*t,this}lerpColors(e,t,n){return this.r=e.r+(t.r-e.r)*n,this.g=e.g+(t.g-e.g)*n,this.b=e.b+(t.b-e.b)*n,this}lerpHSL(e,t){this.getHSL(jn),e.getHSL(Mn);let n=yt(jn.h,Mn.h,t),r=yt(jn.s,Mn.s,t),i=yt(jn.l,Mn.l,t);return this.setHSL(n,r,i),this}setFromVector3(e){return this.r=e.x,this.g=e.y,this.b=e.z,this}applyMatrix3(e){let t=this.r,n=this.g,r=this.b,i=e.elements;return this.r=i[0]*t+i[3]*n+i[6]*r,this.g=i[1]*t+i[4]*n+i[7]*r,this.b=i[2]*t+i[5]*n+i[8]*r,this}equals(e){return e.r===this.r&&e.g===this.g&&e.b===this.b}fromArray(e,t=0){return this.r=e[t],this.g=e[t+1],this.b=e[t+2],this}toArray(e=[],t=0){return e[t]=this.r,e[t+1]=this.g,e[t+2]=this.b,e}fromBufferAttribute(e,t){return this.r=e.getX(t),this.g=e.getY(t),this.b=e.getZ(t),this}toJSON(){return this.getHex()}*[Symbol.iterator](){yield this.r,yield this.g,yield this.b}},Pn=new K;K.NAMES=An;var Fn=new U,In=new U,Ln=new U,Rn=new U,zn=new U,Bn=new U,Vn=new U,Hn=new U,Un=new U,Wn=new U,Gn=new tn,Kn=new tn,qn=new tn,Jn=class e{constructor(e=new U,t=new U,n=new U){this.a=e,this.b=t,this.c=n}static getNormal(e,t,n,r){r.subVectors(n,t),Fn.subVectors(e,t),r.cross(Fn);let i=r.lengthSq();return i>0?r.multiplyScalar(1/Math.sqrt(i)):r.set(0,0,0)}static getBarycoord(e,t,n,r,i){Fn.subVectors(r,t),In.subVectors(n,t),Ln.subVectors(e,t);let a=Fn.dot(Fn),o=Fn.dot(In),s=Fn.dot(Ln),c=In.dot(In),l=In.dot(Ln),u=a*c-o*o;if(u===0)return i.set(0,0,0),null;let d=1/u,f=(c*s-o*l)*d,p=(a*l-o*s)*d;return i.set(1-f-p,p,f)}static containsPoint(e,t,n,r){return this.getBarycoord(e,t,n,r,Rn)!==null&&Rn.x>=0&&Rn.y>=0&&Rn.x+Rn.y<=1}static getInterpolation(e,t,n,r,i,a,o,s){return this.getBarycoord(e,t,n,r,Rn)===null?(s.x=0,s.y=0,`z`in s&&(s.z=0),`w`in s&&(s.w=0),null):(s.setScalar(0),s.addScaledVector(i,Rn.x),s.addScaledVector(a,Rn.y),s.addScaledVector(o,Rn.z),s)}static getInterpolatedAttribute(e,t,n,r,i,a){return Gn.setScalar(0),Kn.setScalar(0),qn.setScalar(0),Gn.fromBufferAttribute(e,t),Kn.fromBufferAttribute(e,n),qn.fromBufferAttribute(e,r),a.setScalar(0),a.addScaledVector(Gn,i.x),a.addScaledVector(Kn,i.y),a.addScaledVector(qn,i.z),a}static isFrontFacing(e,t,n,r){return Fn.subVectors(n,t),In.subVectors(e,t),Fn.cross(In).dot(r)<0}set(e,t,n){return this.a.copy(e),this.b.copy(t),this.c.copy(n),this}setFromPointsAndIndices(e,t,n,r){return this.a.copy(e[t]),this.b.copy(e[n]),this.c.copy(e[r]),this}setFromAttributeAndIndices(e,t,n,r){return this.a.fromBufferAttribute(e,t),this.b.fromBufferAttribute(e,n),this.c.fromBufferAttribute(e,r),this}clone(){return new this.constructor().copy(this)}copy(e){return this.a.copy(e.a),this.b.copy(e.b),this.c.copy(e.c),this}getArea(){return Fn.subVectors(this.c,this.b),In.subVectors(this.a,this.b),Fn.cross(In).length()*.5}getMidpoint(e){return e.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return e.getNormal(this.a,this.b,this.c,t)}getPlane(e){return e.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,n){return e.getBarycoord(t,this.a,this.b,this.c,n)}getInterpolation(t,n,r,i,a){return e.getInterpolation(t,this.a,this.b,this.c,n,r,i,a)}containsPoint(t){return e.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return e.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(e){return e.intersectsTriangle(this)}closestPointToPoint(e,t){let n=this.a,r=this.b,i=this.c,a,o;zn.subVectors(r,n),Bn.subVectors(i,n),Hn.subVectors(e,n);let s=zn.dot(Hn),c=Bn.dot(Hn);if(s<=0&&c<=0)return t.copy(n);Un.subVectors(e,r);let l=zn.dot(Un),u=Bn.dot(Un);if(l>=0&&u<=l)return t.copy(r);let d=s*u-l*c;if(d<=0&&s>=0&&l<=0)return a=s/(s-l),t.copy(n).addScaledVector(zn,a);Wn.subVectors(e,i);let f=zn.dot(Wn),p=Bn.dot(Wn);if(p>=0&&f<=p)return t.copy(i);let m=f*c-s*p;if(m<=0&&c>=0&&p<=0)return o=c/(c-p),t.copy(n).addScaledVector(Bn,o);let h=l*p-f*u;if(h<=0&&u-l>=0&&f-p>=0)return Vn.subVectors(i,r),o=(u-l)/(u-l+(f-p)),t.copy(r).addScaledVector(Vn,o);let g=1/(h+m+d);return a=m*g,o=d*g,t.copy(n).addScaledVector(zn,a).addScaledVector(Bn,o)}equals(e){return e.a.equals(this.a)&&e.b.equals(this.b)&&e.c.equals(this.c)}},Yn=class{constructor(e=new U(1/0,1/0,1/0),t=new U(-1/0,-1/0,-1/0)){this.isBox3=!0,this.min=e,this.max=t}set(e,t){return this.min.copy(e),this.max.copy(t),this}setFromArray(e){this.makeEmpty();for(let t=0,n=e.length;t<n;t+=3)this.expandByPoint(Zn.fromArray(e,t));return this}setFromBufferAttribute(e){this.makeEmpty();for(let t=0,n=e.count;t<n;t++)this.expandByPoint(Zn.fromBufferAttribute(e,t));return this}setFromPoints(e){this.makeEmpty();for(let t=0,n=e.length;t<n;t++)this.expandByPoint(e[t]);return this}setFromCenterAndSize(e,t){let n=Zn.copy(t).multiplyScalar(.5);return this.min.copy(e).sub(n),this.max.copy(e).add(n),this}setFromObject(e,t=!1){return this.makeEmpty(),this.expandByObject(e,t)}clone(){return new this.constructor().copy(this)}copy(e){return this.min.copy(e.min),this.max.copy(e.max),this}makeEmpty(){return this.min.x=this.min.y=this.min.z=1/0,this.max.x=this.max.y=this.max.z=-1/0,this}isEmpty(){return this.max.x<this.min.x||this.max.y<this.min.y||this.max.z<this.min.z}getCenter(e){return this.isEmpty()?e.set(0,0,0):e.addVectors(this.min,this.max).multiplyScalar(.5)}getSize(e){return this.isEmpty()?e.set(0,0,0):e.subVectors(this.max,this.min)}expandByPoint(e){return this.min.min(e),this.max.max(e),this}expandByVector(e){return this.min.sub(e),this.max.add(e),this}expandByScalar(e){return this.min.addScalar(-e),this.max.addScalar(e),this}expandByObject(e,t=!1){e.updateWorldMatrix(!1,!1);let n=e.geometry;if(n!==void 0){let r=n.getAttribute(`position`);if(t===!0&&r!==void 0&&e.isInstancedMesh!==!0)for(let t=0,n=r.count;t<n;t++)e.isMesh===!0?e.getVertexPosition(t,Zn):Zn.fromBufferAttribute(r,t),Zn.applyMatrix4(e.matrixWorld),this.expandByPoint(Zn);else e.boundingBox===void 0?(n.boundingBox===null&&n.computeBoundingBox(),Qn.copy(n.boundingBox)):(e.boundingBox===null&&e.computeBoundingBox(),Qn.copy(e.boundingBox)),Qn.applyMatrix4(e.matrixWorld),this.union(Qn)}let r=e.children;for(let e=0,n=r.length;e<n;e++)this.expandByObject(r[e],t);return this}containsPoint(e){return e.x>=this.min.x&&e.x<=this.max.x&&e.y>=this.min.y&&e.y<=this.max.y&&e.z>=this.min.z&&e.z<=this.max.z}containsBox(e){return this.min.x<=e.min.x&&e.max.x<=this.max.x&&this.min.y<=e.min.y&&e.max.y<=this.max.y&&this.min.z<=e.min.z&&e.max.z<=this.max.z}getParameter(e,t){return t.set((e.x-this.min.x)/(this.max.x-this.min.x),(e.y-this.min.y)/(this.max.y-this.min.y),(e.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(e){return e.max.x>=this.min.x&&e.min.x<=this.max.x&&e.max.y>=this.min.y&&e.min.y<=this.max.y&&e.max.z>=this.min.z&&e.min.z<=this.max.z}intersectsSphere(e){return this.clampPoint(e.center,Zn),Zn.distanceToSquared(e.center)<=e.radius*e.radius}intersectsPlane(e){let t,n;return e.normal.x>0?(t=e.normal.x*this.min.x,n=e.normal.x*this.max.x):(t=e.normal.x*this.max.x,n=e.normal.x*this.min.x),e.normal.y>0?(t+=e.normal.y*this.min.y,n+=e.normal.y*this.max.y):(t+=e.normal.y*this.max.y,n+=e.normal.y*this.min.y),e.normal.z>0?(t+=e.normal.z*this.min.z,n+=e.normal.z*this.max.z):(t+=e.normal.z*this.max.z,n+=e.normal.z*this.min.z),t<=-e.constant&&n>=-e.constant}intersectsTriangle(e){if(this.isEmpty())return!1;this.getCenter(ar),or.subVectors(this.max,ar),$n.subVectors(e.a,ar),er.subVectors(e.b,ar),tr.subVectors(e.c,ar),nr.subVectors(er,$n),rr.subVectors(tr,er),ir.subVectors($n,tr);let t=[0,-nr.z,nr.y,0,-rr.z,rr.y,0,-ir.z,ir.y,nr.z,0,-nr.x,rr.z,0,-rr.x,ir.z,0,-ir.x,-nr.y,nr.x,0,-rr.y,rr.x,0,-ir.y,ir.x,0];return!lr(t,$n,er,tr,or)||(t=[1,0,0,0,1,0,0,0,1],!lr(t,$n,er,tr,or))?!1:(sr.crossVectors(nr,rr),t=[sr.x,sr.y,sr.z],lr(t,$n,er,tr,or))}clampPoint(e,t){return t.copy(e).clamp(this.min,this.max)}distanceToPoint(e){return this.clampPoint(e,Zn).distanceTo(e)}getBoundingSphere(e){return this.isEmpty()?e.makeEmpty():(this.getCenter(e.center),e.radius=this.getSize(Zn).length()*.5),e}intersect(e){return this.min.max(e.min),this.max.min(e.max),this.isEmpty()&&this.makeEmpty(),this}union(e){return this.min.min(e.min),this.max.max(e.max),this}applyMatrix4(e){return this.isEmpty()||(Xn[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(e),Xn[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(e),Xn[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(e),Xn[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(e),Xn[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(e),Xn[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(e),Xn[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(e),Xn[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(e),this.setFromPoints(Xn)),this}translate(e){return this.min.add(e),this.max.add(e),this}equals(e){return e.min.equals(this.min)&&e.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(e){return this.min.fromArray(e.min),this.max.fromArray(e.max),this}},Xn=[new U,new U,new U,new U,new U,new U,new U,new U],Zn=new U,Qn=new Yn,$n=new U,er=new U,tr=new U,nr=new U,rr=new U,ir=new U,ar=new U,or=new U,sr=new U,cr=new U;function lr(e,t,n,r,i){for(let a=0,o=e.length-3;a<=o;a+=3){cr.fromArray(e,a);let o=i.x*Math.abs(cr.x)+i.y*Math.abs(cr.y)+i.z*Math.abs(cr.z),s=t.dot(cr),c=n.dot(cr),l=r.dot(cr);if(Math.max(-Math.max(s,c,l),Math.min(s,c,l))>o)return!1}return!0}var ur=new U,dr=new H,fr=0,pr=class extends ut{constructor(e,t,n=!1){if(super(),Array.isArray(e))throw TypeError(`THREE.BufferAttribute: array should be a Typed Array.`);this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:fr++}),this.name=``,this.array=e,this.itemSize=t,this.count=e===void 0?0:e.length/t,this.normalized=n,this.usage=tt,this.updateRanges=[],this.gpuType=ze,this.version=0}onUploadCallback(){}set needsUpdate(e){e===!0&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.name=e.name,this.array=new e.array.constructor(e.array),this.itemSize=e.itemSize,this.count=e.count,this.normalized=e.normalized,this.usage=e.usage,this.gpuType=e.gpuType,this}copyAt(e,t,n){e*=this.itemSize,n*=t.itemSize;for(let r=0,i=this.itemSize;r<i;r++)this.array[e+r]=t.array[n+r];return this}copyArray(e){return this.array.set(e),this}applyMatrix3(e){if(this.itemSize===2)for(let t=0,n=this.count;t<n;t++)dr.fromBufferAttribute(this,t),dr.applyMatrix3(e),this.setXY(t,dr.x,dr.y);else if(this.itemSize===3)for(let t=0,n=this.count;t<n;t++)ur.fromBufferAttribute(this,t),ur.applyMatrix3(e),this.setXYZ(t,ur.x,ur.y,ur.z);return this}applyMatrix4(e){for(let t=0,n=this.count;t<n;t++)ur.fromBufferAttribute(this,t),ur.applyMatrix4(e),this.setXYZ(t,ur.x,ur.y,ur.z);return this}applyNormalMatrix(e){for(let t=0,n=this.count;t<n;t++)ur.fromBufferAttribute(this,t),ur.applyNormalMatrix(e),this.setXYZ(t,ur.x,ur.y,ur.z);return this}transformDirection(e){for(let t=0,n=this.count;t<n;t++)ur.fromBufferAttribute(this,t),ur.transformDirection(e),this.setXYZ(t,ur.x,ur.y,ur.z);return this}set(e,t=0){return this.array.set(e,t),this}getComponent(e,t){let n=this.array[e*this.itemSize+t];return this.normalized&&(n=Pt(n,this.array)),n}setComponent(e,t,n){return this.normalized&&(n=V(n,this.array)),this.array[e*this.itemSize+t]=n,this}getX(e){let t=this.array[e*this.itemSize];return this.normalized&&(t=Pt(t,this.array)),t}setX(e,t){return this.normalized&&(t=V(t,this.array)),this.array[e*this.itemSize]=t,this}getY(e){let t=this.array[e*this.itemSize+1];return this.normalized&&(t=Pt(t,this.array)),t}setY(e,t){return this.normalized&&(t=V(t,this.array)),this.array[e*this.itemSize+1]=t,this}getZ(e){let t=this.array[e*this.itemSize+2];return this.normalized&&(t=Pt(t,this.array)),t}setZ(e,t){return this.normalized&&(t=V(t,this.array)),this.array[e*this.itemSize+2]=t,this}getW(e){let t=this.array[e*this.itemSize+3];return this.normalized&&(t=Pt(t,this.array)),t}setW(e,t){return this.normalized&&(t=V(t,this.array)),this.array[e*this.itemSize+3]=t,this}setXY(e,t,n){return e*=this.itemSize,this.normalized&&(t=V(t,this.array),n=V(n,this.array)),this.array[e+0]=t,this.array[e+1]=n,this}setXYZ(e,t,n,r){return e*=this.itemSize,this.normalized&&(t=V(t,this.array),n=V(n,this.array),r=V(r,this.array)),this.array[e+0]=t,this.array[e+1]=n,this.array[e+2]=r,this}setXYZW(e,t,n,r,i){return e*=this.itemSize,this.normalized&&(t=V(t,this.array),n=V(n,this.array),r=V(r,this.array),i=V(i,this.array)),this.array[e+0]=t,this.array[e+1]=n,this.array[e+2]=r,this.array[e+3]=i,this}onUpload(e){return this.onUploadCallback=e,this}clone(){return new this.constructor(this.array,this.itemSize).copy(this)}toJSON(){let e={itemSize:this.itemSize,type:this.array.constructor.name,array:Array.from(this.array),normalized:this.normalized};return e.name=this.name,e.usage=this.usage,e.gpuType=this.gpuType,e}dispose(){this.dispatchEvent({type:`dispose`})}},mr=class extends pr{constructor(e,t,n){super(new Uint16Array(e),t,n)}},hr=class extends pr{constructor(e,t,n){super(new Uint32Array(e),t,n)}},q=class extends pr{constructor(e,t,n){super(new Float32Array(e),t,n)}},gr=new Yn,_r=new U,vr=new U,yr=class{constructor(e=new U,t=-1){this.isSphere=!0,this.center=e,this.radius=t}set(e,t){return this.center.copy(e),this.radius=t,this}setFromPoints(e,t){let n=this.center;t===void 0?gr.setFromPoints(e).getCenter(n):n.copy(t);let r=0;for(let t=0,i=e.length;t<i;t++)r=Math.max(r,n.distanceToSquared(e[t]));return this.radius=Math.sqrt(r),this}copy(e){return this.center.copy(e.center),this.radius=e.radius,this}isEmpty(){return this.radius<0}makeEmpty(){return this.center.set(0,0,0),this.radius=-1,this}containsPoint(e){return e.distanceToSquared(this.center)<=this.radius*this.radius}distanceToPoint(e){return e.distanceTo(this.center)-this.radius}intersectsSphere(e){let t=this.radius+e.radius;return e.center.distanceToSquared(this.center)<=t*t}intersectsBox(e){return e.intersectsSphere(this)}intersectsPlane(e){return Math.abs(e.distanceToPoint(this.center))<=this.radius}clampPoint(e,t){let n=this.center.distanceToSquared(e);return t.copy(e),n>this.radius*this.radius&&(t.sub(this.center).normalize(),t.multiplyScalar(this.radius).add(this.center)),t}getBoundingBox(e){return this.isEmpty()?(e.makeEmpty(),e):(e.set(this.center,this.center),e.expandByScalar(this.radius),e)}applyMatrix4(e){return this.center.applyMatrix4(e),this.radius*=e.getMaxScaleOnAxis(),this}translate(e){return this.center.add(e),this}expandByPoint(e){if(this.isEmpty())return this.center.copy(e),this.radius=0,this;_r.subVectors(e,this.center);let t=_r.lengthSq();if(t>this.radius*this.radius){let e=Math.sqrt(t),n=(e-this.radius)*.5;this.center.addScaledVector(_r,n/e),this.radius+=n}return this}union(e){return e.isEmpty()?this:this.isEmpty()?(this.copy(e),this):(this.center.equals(e.center)===!0?this.radius=Math.max(this.radius,e.radius):(vr.subVectors(e.center,this.center).setLength(e.radius),this.expandByPoint(_r.copy(e.center).add(vr)),this.expandByPoint(_r.copy(e.center).sub(vr))),this)}equals(e){return e.center.equals(this.center)&&e.radius===this.radius}clone(){return new this.constructor().copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(e){return this.radius=e.radius,this.center.fromArray(e.center),this}},br=0,xr=new W,Sr=new G,Cr=new U,wr=new Yn,Tr=new Yn,Er=new U,J=class e extends ut{constructor(){super(),this.isBufferGeometry=!0,Object.defineProperty(this,"id",{value:br++}),this.uuid=ht(),this.name=``,this.type=`BufferGeometry`,this.index=null,this.indirect=null,this.indirectOffset=0,this.attributes={},this.morphAttributes={},this.morphTargetsRelative=!1,this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.drawRange={start:0,count:1/0},this.userData={},this._transformed=!1}getIndex(){return this.index}setIndex(e){return this.index=Array.isArray(e)?new(rt(e)?hr:mr)(e,1):e,this}setIndirect(e,t=0){return this.indirect=e,this.indirectOffset=t,this}getIndirect(){return this.indirect}getAttribute(e){return this.attributes[e]}setAttribute(e,t){return this.attributes[e]=t,this}deleteAttribute(e){return delete this.attributes[e],this}hasAttribute(e){return this.attributes[e]!==void 0}addGroup(e,t,n=0){this.groups.push({start:e,count:t,materialIndex:n})}clearGroups(){this.groups=[]}setDrawRange(e,t){this.drawRange.start=e,this.drawRange.count=t}applyMatrix4(e){let t=this.attributes.position;t!==void 0&&(t.applyMatrix4(e),t.needsUpdate=!0);let n=this.attributes.normal;if(n!==void 0){let t=new zt().getNormalMatrix(e);n.applyNormalMatrix(t),n.needsUpdate=!0}let r=this.attributes.tangent;return r!==void 0&&(r.transformDirection(e),r.needsUpdate=!0),this.boundingBox!==null&&this.computeBoundingBox(),this.boundingSphere!==null&&this.computeBoundingSphere(),this._transformed=!0,this}applyQuaternion(e){return xr.makeRotationFromQuaternion(e),this.applyMatrix4(xr),this}rotateX(e){return xr.makeRotationX(e),this.applyMatrix4(xr),this}rotateY(e){return xr.makeRotationY(e),this.applyMatrix4(xr),this}rotateZ(e){return xr.makeRotationZ(e),this.applyMatrix4(xr),this}translate(e,t,n){return xr.makeTranslation(e,t,n),this.applyMatrix4(xr),this}scale(e,t,n){return xr.makeScale(e,t,n),this.applyMatrix4(xr),this}lookAt(e){return Sr.lookAt(e),Sr.updateMatrix(),this.applyMatrix4(Sr.matrix),this}center(){return this.computeBoundingBox(),this.boundingBox.getCenter(Cr).negate(),this.translate(Cr.x,Cr.y,Cr.z),this}setFromPoints(e){let t=this.getAttribute(`position`);if(t===void 0){let t=[];for(let n=0,r=e.length;n<r;n++){let r=e[n];t.push(r.x,r.y,r.z||0)}this.setAttribute(`position`,new q(t,3))}else{let n=Math.min(e.length,t.count);for(let r=0;r<n;r++){let n=e[r];t.setXYZ(r,n.x,n.y,n.z||0)}e.length>t.count&&R(`BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry.`),t.needsUpdate=!0}return this}computeBoundingBox(){this.boundingBox===null&&(this.boundingBox=new Yn);let e=this.attributes.position,t=this.morphAttributes.position;if(e&&e.isGLBufferAttribute)z(`BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.`,this),this.boundingBox.set(new U(-1/0,-1/0,-1/0),new U(1/0,1/0,1/0));else{if(e!==void 0){if(this.boundingBox.setFromBufferAttribute(e),t)for(let e=0,n=t.length;e<n;e++){let n=t[e];wr.setFromBufferAttribute(n),this.morphTargetsRelative?(Er.addVectors(this.boundingBox.min,wr.min),this.boundingBox.expandByPoint(Er),Er.addVectors(this.boundingBox.max,wr.max),this.boundingBox.expandByPoint(Er)):(this.boundingBox.expandByPoint(wr.min),this.boundingBox.expandByPoint(wr.max))}}else this.boundingBox.makeEmpty();(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&z(`BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.`,this)}}computeBoundingSphere(){this.boundingSphere===null&&(this.boundingSphere=new yr);let e=this.attributes.position,t=this.morphAttributes.position;if(e&&e.isGLBufferAttribute)z(`BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.`,this),this.boundingSphere.set(new U,1/0);else if(e){let n=this.boundingSphere.center;if(wr.setFromBufferAttribute(e),t)for(let e=0,n=t.length;e<n;e++){let n=t[e];Tr.setFromBufferAttribute(n),this.morphTargetsRelative?(Er.addVectors(wr.min,Tr.min),wr.expandByPoint(Er),Er.addVectors(wr.max,Tr.max),wr.expandByPoint(Er)):(wr.expandByPoint(Tr.min),wr.expandByPoint(Tr.max))}wr.getCenter(n);let r=0;for(let t=0,i=e.count;t<i;t++)Er.fromBufferAttribute(e,t),r=Math.max(r,n.distanceToSquared(Er));if(t)for(let i=0,a=t.length;i<a;i++){let a=t[i],o=this.morphTargetsRelative;for(let t=0,i=a.count;t<i;t++)Er.fromBufferAttribute(a,t),o&&(Cr.fromBufferAttribute(e,t),Er.add(Cr)),r=Math.max(r,n.distanceToSquared(Er))}this.boundingSphere.radius=Math.sqrt(r),isNaN(this.boundingSphere.radius)&&z(`BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.`,this)}}computeTangents(){let e=this.index,t=this.attributes;if(e===null||t.position===void 0||t.normal===void 0||t.uv===void 0){z(`BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)`);return}let n=t.position,r=t.normal,i=t.uv,a=this.getAttribute(`tangent`);(a===void 0||a.count!==n.count)&&(a=new pr(new Float32Array(4*n.count),4),this.setAttribute(`tangent`,a));let o=[],s=[];for(let e=0;e<n.count;e++)o[e]=new U,s[e]=new U;let c=new U,l=new U,u=new U,d=new H,f=new H,p=new H,m=new U,h=new U;function g(e,t,r){c.fromBufferAttribute(n,e),l.fromBufferAttribute(n,t),u.fromBufferAttribute(n,r),d.fromBufferAttribute(i,e),f.fromBufferAttribute(i,t),p.fromBufferAttribute(i,r),l.sub(c),u.sub(c),f.sub(d),p.sub(d);let a=1/(f.x*p.y-p.x*f.y);isFinite(a)&&(m.copy(l).multiplyScalar(p.y).addScaledVector(u,-f.y).multiplyScalar(a),h.copy(u).multiplyScalar(f.x).addScaledVector(l,-p.x).multiplyScalar(a),o[e].add(m),o[t].add(m),o[r].add(m),s[e].add(h),s[t].add(h),s[r].add(h))}let _=this.groups;_.length===0&&(_=[{start:0,count:e.count}]);for(let t=0,n=_.length;t<n;++t){let n=_[t],r=n.start,i=n.count;for(let t=r,n=r+i;t<n;t+=3)g(e.getX(t+0),e.getX(t+1),e.getX(t+2))}let v=new U,y=new U,b=new U,x=new U;function S(e){b.fromBufferAttribute(r,e),x.copy(b);let t=o[e];v.copy(t),v.sub(b.multiplyScalar(b.dot(t))).normalize(),y.crossVectors(x,t);let n=y.dot(s[e])<0?-1:1;a.setXYZW(e,v.x,v.y,v.z,n)}for(let t=0,n=_.length;t<n;++t){let n=_[t],r=n.start,i=n.count;for(let t=r,n=r+i;t<n;t+=3)S(e.getX(t+0)),S(e.getX(t+1)),S(e.getX(t+2))}this._transformed=!0}computeVertexNormals(){let e=this.index,t=this.getAttribute(`position`);if(t!==void 0){let n=this.getAttribute(`normal`);if(n===void 0||n.count!==t.count)n=new pr(new Float32Array(t.count*3),3),this.setAttribute(`normal`,n);else for(let e=0,t=n.count;e<t;e++)n.setXYZ(e,0,0,0);let r=new U,i=new U,a=new U,o=new U,s=new U,c=new U,l=new U,u=new U;if(e)for(let d=0,f=e.count;d<f;d+=3){let f=e.getX(d+0),p=e.getX(d+1),m=e.getX(d+2);r.fromBufferAttribute(t,f),i.fromBufferAttribute(t,p),a.fromBufferAttribute(t,m),l.subVectors(a,i),u.subVectors(r,i),l.cross(u),o.fromBufferAttribute(n,f),s.fromBufferAttribute(n,p),c.fromBufferAttribute(n,m),o.add(l),s.add(l),c.add(l),n.setXYZ(f,o.x,o.y,o.z),n.setXYZ(p,s.x,s.y,s.z),n.setXYZ(m,c.x,c.y,c.z)}else for(let e=0,o=t.count;e<o;e+=3)r.fromBufferAttribute(t,e+0),i.fromBufferAttribute(t,e+1),a.fromBufferAttribute(t,e+2),l.subVectors(a,i),u.subVectors(r,i),l.cross(u),n.setXYZ(e+0,l.x,l.y,l.z),n.setXYZ(e+1,l.x,l.y,l.z),n.setXYZ(e+2,l.x,l.y,l.z);this.normalizeNormals(),n.needsUpdate=!0}}normalizeNormals(){let e=this.attributes.normal;for(let t=0,n=e.count;t<n;t++)Er.fromBufferAttribute(e,t),Er.normalize(),e.setXYZ(t,Er.x,Er.y,Er.z)}toNonIndexed(){function t(e,t){let n=e.array,r=e.itemSize,i=e.normalized,a=new n.constructor(t.length*r),o=0,s=0;for(let i=0,c=t.length;i<c;i++){o=e.isInterleavedBufferAttribute?t[i]*e.data.stride+e.offset:t[i]*r;for(let e=0;e<r;e++)a[s++]=n[o++]}return new pr(a,r,i)}if(this.index===null)return R(`BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.`),this;let n=new e,r=this.index.array,i=this.attributes;for(let e in i){let a=i[e],o=t(a,r);n.setAttribute(e,o)}let a=this.morphAttributes;for(let e in a){let i=[],o=a[e];for(let e=0,n=o.length;e<n;e++){let n=o[e],a=t(n,r);i.push(a)}n.morphAttributes[e]=i}n.morphTargetsRelative=this.morphTargetsRelative;let o=this.groups;for(let e=0,t=o.length;e<t;e++){let t=o[e];n.addGroup(t.start,t.count,t.materialIndex)}return n}toJSON(){let e={metadata:{version:4.7,type:`BufferGeometry`,generator:`BufferGeometry.toJSON`}};if(e.uuid=this.uuid,e.type=this.parameters!==void 0&&this._transformed===!0?`BufferGeometry`:this.type,e.name=this.name,Object.keys(this.userData).length>0&&(e.userData=this.userData),this.parameters!==void 0&&this._transformed!==!0){let t=this.parameters;for(let n in t)t[n]!==void 0&&(e[n]=t[n]);return e}e.data={attributes:{}};let t=this.index;t!==null&&(e.data.index={type:t.array.constructor.name,array:Array.prototype.slice.call(t.array)});let n=this.attributes;for(let t in n){let r=n[t];e.data.attributes[t]=r.toJSON(e.data)}let r={},i=!1;for(let t in this.morphAttributes){let n=this.morphAttributes[t],a=[];for(let t=0,r=n.length;t<r;t++){let r=n[t];a.push(r.toJSON(e.data))}a.length>0&&(r[t]=a,i=!0)}i&&(e.data.morphAttributes=r,e.data.morphTargetsRelative=this.morphTargetsRelative);let a=this.groups;a.length>0&&(e.data.groups=JSON.parse(JSON.stringify(a)));let o=this.boundingSphere;return o!==null&&(e.data.boundingSphere=o.toJSON()),e}clone(){return new this.constructor().copy(this)}copy(e){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;let t={};this.name=e.name;let n=e.index;n!==null&&this.setIndex(n.clone());let r=e.attributes;for(let e in r){let n=r[e];this.setAttribute(e,n.clone(t))}let i=e.morphAttributes;for(let e in i){let n=[],r=i[e];for(let e=0,i=r.length;e<i;e++)n.push(r[e].clone(t));this.morphAttributes[e]=n}this.morphTargetsRelative=e.morphTargetsRelative;let a=e.groups;for(let e=0,t=a.length;e<t;e++){let t=a[e];this.addGroup(t.start,t.count,t.materialIndex)}let o=e.boundingBox;o!==null&&(this.boundingBox=o.clone());let s=e.boundingSphere;return s!==null&&(this.boundingSphere=s.clone()),this.drawRange.start=e.drawRange.start,this.drawRange.count=e.drawRange.count,this.userData=e.userData,this._transformed=e._transformed,this}dispose(){this.dispatchEvent({type:`dispose`})}},Dr=class{constructor(e,t){this.isInterleavedBuffer=!0,this.array=e,this.stride=t,this.count=e===void 0?0:e.length/t,this.usage=tt,this.updateRanges=[],this.version=0,this.uuid=ht()}onUploadCallback(){}set needsUpdate(e){e===!0&&this.version++}setUsage(e){return this.usage=e,this}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}copy(e){return this.array=new e.array.constructor(e.array),this.count=e.count,this.stride=e.stride,this.usage=e.usage,this}copyAt(e,t,n){e*=this.stride,n*=t.stride;for(let r=0,i=this.stride;r<i;r++)this.array[e+r]=t.array[n+r];return this}set(e,t=0){return this.array.set(e,t),this}clone(e){e.arrayBuffers===void 0&&(e.arrayBuffers={}),this.array.buffer._uuid===void 0&&(this.array.buffer._uuid=ht()),e.arrayBuffers[this.array.buffer._uuid]===void 0&&(e.arrayBuffers[this.array.buffer._uuid]=this.array.slice(0).buffer);let t=new this.array.constructor(e.arrayBuffers[this.array.buffer._uuid]),n=new this.constructor(t,this.stride);return n.setUsage(this.usage),n}onUpload(e){return this.onUploadCallback=e,this}toJSON(e){e.arrayBuffers===void 0&&(e.arrayBuffers={}),this.array.buffer._uuid===void 0&&(this.array.buffer._uuid=ht()),e.arrayBuffers[this.array.buffer._uuid]===void 0&&(e.arrayBuffers[this.array.buffer._uuid]=Array.from(new Uint32Array(this.array.buffer)));let t={uuid:this.uuid,buffer:this.array.buffer._uuid,type:this.array.constructor.name,stride:this.stride};return t.usage=this.usage,t}},Or=new U,kr=class e{constructor(e,t,n,r=!1){this.isInterleavedBufferAttribute=!0,this.name=``,this.data=e,this.itemSize=t,this.offset=n,this.normalized=r}get count(){return this.data.count}get array(){return this.data.array}set needsUpdate(e){this.data.needsUpdate=e}applyMatrix4(e){for(let t=0,n=this.data.count;t<n;t++)Or.fromBufferAttribute(this,t),Or.applyMatrix4(e),this.setXYZ(t,Or.x,Or.y,Or.z);return this}applyNormalMatrix(e){for(let t=0,n=this.count;t<n;t++)Or.fromBufferAttribute(this,t),Or.applyNormalMatrix(e),this.setXYZ(t,Or.x,Or.y,Or.z);return this}transformDirection(e){for(let t=0,n=this.count;t<n;t++)Or.fromBufferAttribute(this,t),Or.transformDirection(e),this.setXYZ(t,Or.x,Or.y,Or.z);return this}getComponent(e,t){let n=this.array[e*this.data.stride+this.offset+t];return this.normalized&&(n=Pt(n,this.array)),n}setComponent(e,t,n){return this.normalized&&(n=V(n,this.array)),this.data.array[e*this.data.stride+this.offset+t]=n,this}setX(e,t){return this.normalized&&(t=V(t,this.array)),this.data.array[e*this.data.stride+this.offset]=t,this}setY(e,t){return this.normalized&&(t=V(t,this.array)),this.data.array[e*this.data.stride+this.offset+1]=t,this}setZ(e,t){return this.normalized&&(t=V(t,this.array)),this.data.array[e*this.data.stride+this.offset+2]=t,this}setW(e,t){return this.normalized&&(t=V(t,this.array)),this.data.array[e*this.data.stride+this.offset+3]=t,this}getX(e){let t=this.data.array[e*this.data.stride+this.offset];return this.normalized&&(t=Pt(t,this.array)),t}getY(e){let t=this.data.array[e*this.data.stride+this.offset+1];return this.normalized&&(t=Pt(t,this.array)),t}getZ(e){let t=this.data.array[e*this.data.stride+this.offset+2];return this.normalized&&(t=Pt(t,this.array)),t}getW(e){let t=this.data.array[e*this.data.stride+this.offset+3];return this.normalized&&(t=Pt(t,this.array)),t}setXY(e,t,n){return e=e*this.data.stride+this.offset,this.normalized&&(t=V(t,this.array),n=V(n,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=n,this}setXYZ(e,t,n,r){return e=e*this.data.stride+this.offset,this.normalized&&(t=V(t,this.array),n=V(n,this.array),r=V(r,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=n,this.data.array[e+2]=r,this}setXYZW(e,t,n,r,i){return e=e*this.data.stride+this.offset,this.normalized&&(t=V(t,this.array),n=V(n,this.array),r=V(r,this.array),i=V(i,this.array)),this.data.array[e+0]=t,this.data.array[e+1]=n,this.data.array[e+2]=r,this.data.array[e+3]=i,this}clone(t){if(t===void 0){st(`InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.`);let e=[];for(let t=0;t<this.count;t++){let n=t*this.data.stride+this.offset;for(let t=0;t<this.itemSize;t++)e.push(this.data.array[n+t])}return new pr(new this.array.constructor(e),this.itemSize,this.normalized)}return t.interleavedBuffers===void 0&&(t.interleavedBuffers={}),t.interleavedBuffers[this.data.uuid]===void 0&&(t.interleavedBuffers[this.data.uuid]=this.data.clone(t)),new e(t.interleavedBuffers[this.data.uuid],this.itemSize,this.offset,this.normalized)}toJSON(e){if(e===void 0){st(`InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.`);let e=[];for(let t=0;t<this.count;t++){let n=t*this.data.stride+this.offset;for(let t=0;t<this.itemSize;t++)e.push(this.data.array[n+t])}return{itemSize:this.itemSize,type:this.array.constructor.name,array:e,normalized:this.normalized}}return e.interleavedBuffers===void 0&&(e.interleavedBuffers={}),e.interleavedBuffers[this.data.uuid]===void 0&&(e.interleavedBuffers[this.data.uuid]=this.data.toJSON(e)),{isInterleavedBufferAttribute:!0,itemSize:this.itemSize,data:this.data.uuid,offset:this.offset,normalized:this.normalized}}},Ar=new U,jr=new U,Mr=new zt,Nr=class{constructor(e=new U(1,0,0),t=0){this.isPlane=!0,this.normal=e,this.constant=t}set(e,t){return this.normal.copy(e),this.constant=t,this}setComponents(e,t,n,r){return this.normal.set(e,t,n),this.constant=r,this}setFromNormalAndCoplanarPoint(e,t){return this.normal.copy(e),this.constant=-t.dot(this.normal),this}setFromCoplanarPoints(e,t,n){let r=Ar.subVectors(n,t).cross(jr.subVectors(e,t)).normalize();return this.setFromNormalAndCoplanarPoint(r,e),this}copy(e){return this.normal.copy(e.normal),this.constant=e.constant,this}normalize(){let e=1/this.normal.length();return this.normal.multiplyScalar(e),this.constant*=e,this}negate(){return this.constant*=-1,this.normal.negate(),this}distanceToPoint(e){return this.normal.dot(e)+this.constant}distanceToSphere(e){return this.distanceToPoint(e.center)-e.radius}projectPoint(e,t){return t.copy(e).addScaledVector(this.normal,-this.distanceToPoint(e))}intersectLine(e,t,n=!0){let r=e.delta(Ar),i=this.normal.dot(r);if(i===0)return this.distanceToPoint(e.start)===0?t.copy(e.start):null;let a=-(e.start.dot(this.normal)+this.constant)/i;return n===!0&&(a<0||a>1)?null:t.copy(e.start).addScaledVector(r,a)}intersectsLine(e){let t=this.distanceToPoint(e.start),n=this.distanceToPoint(e.end);return t<0&&n>0||n<0&&t>0}intersectsBox(e){return e.intersectsPlane(this)}intersectsSphere(e){return e.intersectsPlane(this)}coplanarPoint(e){return e.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(e,t){let n=t||Mr.getNormalMatrix(e),r=this.coplanarPoint(Ar).applyMatrix4(e),i=this.normal.applyMatrix3(n).normalize();return this.constant=-r.dot(i),this}translate(e){return this.constant-=e.dot(this.normal),this}equals(e){return e.normal.equals(this.normal)&&e.constant===this.constant}clone(){return new this.constructor().copy(this)}toJSON(){return{normal:this.normal.toArray(),constant:this.constant}}fromJSON(e){return this.normal.fromArray(e.normal),this.constant=e.constant,this}},Pr=0,Fr=class extends ut{constructor(){super(),this.isMaterial=!0,Object.defineProperty(this,"id",{value:Pr++}),this.uuid=ht(),this.name=``,this.type=`Material`,this.blending=1,this.side=0,this.vertexColors=!1,this.opacity=1,this.transparent=!1,this.alphaHash=!1,this.blendSrc=204,this.blendDst=205,this.blendEquation=100,this.blendSrcAlpha=null,this.blendDstAlpha=null,this.blendEquationAlpha=null,this.blendColor=new K(0,0,0),this.blendAlpha=0,this.depthFunc=3,this.depthTest=!0,this.depthWrite=!0,this.stencilWriteMask=255,this.stencilFunc=519,this.stencilRef=0,this.stencilFuncMask=255,this.stencilFail=et,this.stencilZFail=et,this.stencilZPass=et,this.stencilWrite=!1,this.clippingPlanes=null,this.clipIntersection=!1,this.clipShadows=!1,this.shadowSide=null,this.colorWrite=!0,this.precision=null,this.polygonOffset=!1,this.polygonOffsetFactor=0,this.polygonOffsetUnits=0,this.dithering=!1,this.alphaToCoverage=!1,this.premultipliedAlpha=!1,this.forceSinglePass=!1,this.allowOverride=!0,this.visible=!0,this.toneMapped=!0,this.userData={},this.version=0,this._alphaTest=0}get alphaTest(){return this._alphaTest}set alphaTest(e){this._alphaTest>0!=e>0&&this.version++,this._alphaTest=e}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(e){if(e!==void 0)for(let t in e){let n=e[t];if(n===void 0){R(`Material: parameter '${t}' has value of undefined.`);continue}let r=this[t];r===void 0?R(`Material: '${t}' is not a property of THREE.${this.type}.`):r&&r.isColor?r.set(n):r&&r.isVector2&&n&&n.isVector2||r&&r.isEuler&&n&&n.isEuler||r&&r.isVector3&&n&&n.isVector3?r.copy(n):this[t]=n}}toJSON(e){let t=e===void 0||typeof e==`string`;t&&(e={textures:{},images:{}});let n={metadata:{version:4.7,type:`Material`,generator:`Material.toJSON`}};n.uuid=this.uuid,n.type=this.type,n.blending=this.blending,n.side=this.side,n.shadowSide=this.shadowSide,n.vertexColors=this.vertexColors,n.opacity=this.opacity,n.transparent=this.transparent,n.blendSrc=this.blendSrc,n.blendDst=this.blendDst,n.blendEquation=this.blendEquation,n.blendSrcAlpha=this.blendSrcAlpha,n.blendDstAlpha=this.blendDstAlpha,n.blendEquationAlpha=this.blendEquationAlpha,n.blendColor=this.blendColor.getHex(),n.blendAlpha=this.blendAlpha,n.depthFunc=this.depthFunc,n.depthTest=this.depthTest,n.depthWrite=this.depthWrite,n.colorWrite=this.colorWrite,n.clipIntersection=this.clipIntersection,n.clipShadows=this.clipShadows,n.stencilWriteMask=this.stencilWriteMask,n.stencilFunc=this.stencilFunc,n.stencilRef=this.stencilRef,n.stencilFuncMask=this.stencilFuncMask,n.stencilFail=this.stencilFail,n.stencilZFail=this.stencilZFail,n.stencilZPass=this.stencilZPass,n.stencilWrite=this.stencilWrite,n.polygonOffset=this.polygonOffset,n.polygonOffsetFactor=this.polygonOffsetFactor,n.polygonOffsetUnits=this.polygonOffsetUnits,n.dithering=this.dithering,n.alphaTest=this.alphaTest,n.alphaHash=this.alphaHash,n.alphaToCoverage=this.alphaToCoverage,n.premultipliedAlpha=this.premultipliedAlpha,n.forceSinglePass=this.forceSinglePass,n.allowOverride=this.allowOverride,n.visible=this.visible,n.toneMapped=this.toneMapped,n.name=this.name,this.color&&this.color.isColor&&(n.color=this.color.getHex()),this.roughness!==void 0&&(n.roughness=this.roughness),this.metalness!==void 0&&(n.metalness=this.metalness),this.sheen!==void 0&&(n.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(n.sheenColor=this.sheenColor.getHex()),this.sheenRoughness!==void 0&&(n.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(n.emissive=this.emissive.getHex()),this.emissiveIntensity!==void 0&&(n.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(n.specular=this.specular.getHex()),this.specularIntensity!==void 0&&(n.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(n.specularColor=this.specularColor.getHex()),this.shininess!==void 0&&(n.shininess=this.shininess),this.clearcoat!==void 0&&(n.clearcoat=this.clearcoat),this.clearcoatRoughness!==void 0&&(n.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(n.clearcoatMap=this.clearcoatMap.toJSON(e).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(n.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(e).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(n.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(e).uuid,n.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.sheenColorMap&&this.sheenColorMap.isTexture&&(n.sheenColorMap=this.sheenColorMap.toJSON(e).uuid),this.sheenRoughnessMap&&this.sheenRoughnessMap.isTexture&&(n.sheenRoughnessMap=this.sheenRoughnessMap.toJSON(e).uuid),this.dispersion!==void 0&&(n.dispersion=this.dispersion),this.retroreflectivity!==void 0&&(n.retroreflectivity=this.retroreflectivity),this.iridescence!==void 0&&(n.iridescence=this.iridescence),this.iridescenceIOR!==void 0&&(n.iridescenceIOR=this.iridescenceIOR),this.iridescenceThicknessRange!==void 0&&(n.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(n.iridescenceMap=this.iridescenceMap.toJSON(e).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(n.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(e).uuid),this.anisotropy!==void 0&&(n.anisotropy=this.anisotropy),this.anisotropyRotation!==void 0&&(n.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(n.anisotropyMap=this.anisotropyMap.toJSON(e).uuid),this.map&&this.map.isTexture&&(n.map=this.map.toJSON(e).uuid),this.matcap&&this.matcap.isTexture&&(n.matcap=this.matcap.toJSON(e).uuid),this.alphaMap&&this.alphaMap.isTexture&&(n.alphaMap=this.alphaMap.toJSON(e).uuid),this.lightMap&&this.lightMap.isTexture&&(n.lightMap=this.lightMap.toJSON(e).uuid,n.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(n.aoMap=this.aoMap.toJSON(e).uuid,n.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(n.bumpMap=this.bumpMap.toJSON(e).uuid,n.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(n.normalMap=this.normalMap.toJSON(e).uuid,n.normalMapType=this.normalMapType,n.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(n.displacementMap=this.displacementMap.toJSON(e).uuid,n.displacementScale=this.displacementScale,n.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(n.roughnessMap=this.roughnessMap.toJSON(e).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(n.metalnessMap=this.metalnessMap.toJSON(e).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(n.emissiveMap=this.emissiveMap.toJSON(e).uuid),this.specularMap&&this.specularMap.isTexture&&(n.specularMap=this.specularMap.toJSON(e).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(n.specularIntensityMap=this.specularIntensityMap.toJSON(e).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(n.specularColorMap=this.specularColorMap.toJSON(e).uuid),this.envMap&&this.envMap.isTexture&&(n.envMap=this.envMap.toJSON(e).uuid,this.combine!==void 0&&(n.combine=this.combine)),this.envMapRotation!==void 0&&(n.envMapRotation=this.envMapRotation.toArray()),this.envMapIntensity!==void 0&&(n.envMapIntensity=this.envMapIntensity),this.reflectivity!==void 0&&(n.reflectivity=this.reflectivity),this.refractionRatio!==void 0&&(n.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(n.gradientMap=this.gradientMap.toJSON(e).uuid),this.transmission!==void 0&&(n.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(n.transmissionMap=this.transmissionMap.toJSON(e).uuid),this.thickness!==void 0&&(n.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(n.thicknessMap=this.thicknessMap.toJSON(e).uuid),this.attenuationDistance!==void 0&&(n.attenuationDistance=this.attenuationDistance),this.attenuationColor!==void 0&&(n.attenuationColor=this.attenuationColor.getHex()),this.size!==void 0&&(n.size=this.size),this.sizeAttenuation!==void 0&&(n.sizeAttenuation=this.sizeAttenuation),Array.isArray(this.clippingPlanes)&&this.clippingPlanes.length>0&&(n.clippingPlanes=this.clippingPlanes.map(e=>e.toJSON())),this.rotation!==void 0&&(n.rotation=this.rotation),this.depthPacking!==void 0&&(n.depthPacking=this.depthPacking),this.linewidth!==void 0&&(n.linewidth=this.linewidth),this.linecap!==void 0&&(n.linecap=this.linecap),this.linejoin!==void 0&&(n.linejoin=this.linejoin),this.dashSize!==void 0&&(n.dashSize=this.dashSize),this.gapSize!==void 0&&(n.gapSize=this.gapSize),this.scale!==void 0&&(n.scale=this.scale),this.wireframe!==void 0&&(n.wireframe=this.wireframe),this.wireframeLinewidth!==void 0&&(n.wireframeLinewidth=this.wireframeLinewidth),this.wireframeLinecap!==void 0&&(n.wireframeLinecap=this.wireframeLinecap),this.wireframeLinejoin!==void 0&&(n.wireframeLinejoin=this.wireframeLinejoin),this.flatShading!==void 0&&(n.flatShading=this.flatShading),this.fog!==void 0&&(n.fog=this.fog),Object.keys(this.userData).length>0&&(n.userData=this.userData);function r(e){let t=[];for(let n in e){let r=e[n];delete r.metadata,t.push(r)}return t}if(t){let t=r(e.textures),i=r(e.images);t.length>0&&(n.textures=t),i.length>0&&(n.images=i)}return n}fromJSON(e,t){if(e.uuid!==void 0&&(this.uuid=e.uuid),e.name!==void 0&&(this.name=e.name),e.color!==void 0&&this.color!==void 0&&this.color.setHex(e.color),e.roughness!==void 0&&(this.roughness=e.roughness),e.metalness!==void 0&&(this.metalness=e.metalness),e.sheen!==void 0&&(this.sheen=e.sheen),e.sheenColor!==void 0&&(this.sheenColor=new K().setHex(e.sheenColor)),e.sheenRoughness!==void 0&&(this.sheenRoughness=e.sheenRoughness),e.emissive!==void 0&&this.emissive!==void 0&&this.emissive.setHex(e.emissive),e.specular!==void 0&&this.specular!==void 0&&this.specular.setHex(e.specular),e.specularIntensity!==void 0&&(this.specularIntensity=e.specularIntensity),e.specularColor!==void 0&&this.specularColor!==void 0&&this.specularColor.setHex(e.specularColor),e.shininess!==void 0&&(this.shininess=e.shininess),e.clearcoat!==void 0&&(this.clearcoat=e.clearcoat),e.clearcoatRoughness!==void 0&&(this.clearcoatRoughness=e.clearcoatRoughness),e.dispersion!==void 0&&(this.dispersion=e.dispersion),e.retroreflectivity!==void 0&&(this.retroreflectivity=e.retroreflectivity),e.iridescence!==void 0&&(this.iridescence=e.iridescence),e.iridescenceIOR!==void 0&&(this.iridescenceIOR=e.iridescenceIOR),e.iridescenceThicknessRange!==void 0&&(this.iridescenceThicknessRange=e.iridescenceThicknessRange),e.transmission!==void 0&&(this.transmission=e.transmission),e.thickness!==void 0&&(this.thickness=e.thickness),e.attenuationDistance!==void 0&&(this.attenuationDistance=e.attenuationDistance),e.attenuationColor!==void 0&&this.attenuationColor!==void 0&&this.attenuationColor.setHex(e.attenuationColor),e.anisotropy!==void 0&&(this.anisotropy=e.anisotropy),e.anisotropyRotation!==void 0&&(this.anisotropyRotation=e.anisotropyRotation),e.fog!==void 0&&(this.fog=e.fog),e.flatShading!==void 0&&(this.flatShading=e.flatShading),e.blending!==void 0&&(this.blending=e.blending),e.combine!==void 0&&(this.combine=e.combine),e.side!==void 0&&(this.side=e.side),e.shadowSide!==void 0&&(this.shadowSide=e.shadowSide),e.opacity!==void 0&&(this.opacity=e.opacity),e.transparent!==void 0&&(this.transparent=e.transparent),e.alphaTest!==void 0&&(this.alphaTest=e.alphaTest),e.alphaHash!==void 0&&(this.alphaHash=e.alphaHash),e.depthFunc!==void 0&&(this.depthFunc=e.depthFunc),e.depthTest!==void 0&&(this.depthTest=e.depthTest),e.depthWrite!==void 0&&(this.depthWrite=e.depthWrite),e.colorWrite!==void 0&&(this.colorWrite=e.colorWrite),e.clippingPlanes!==void 0&&(this.clippingPlanes=e.clippingPlanes.map(e=>new Nr().fromJSON(e))),e.clipIntersection!==void 0&&(this.clipIntersection=e.clipIntersection),e.clipShadows!==void 0&&(this.clipShadows=e.clipShadows),e.depthPacking!==void 0&&(this.depthPacking=e.depthPacking),e.blendSrc!==void 0&&(this.blendSrc=e.blendSrc),e.blendDst!==void 0&&(this.blendDst=e.blendDst),e.blendEquation!==void 0&&(this.blendEquation=e.blendEquation),e.blendSrcAlpha!==void 0&&(this.blendSrcAlpha=e.blendSrcAlpha),e.blendDstAlpha!==void 0&&(this.blendDstAlpha=e.blendDstAlpha),e.blendEquationAlpha!==void 0&&(this.blendEquationAlpha=e.blendEquationAlpha),e.blendColor!==void 0&&this.blendColor!==void 0&&this.blendColor.setHex(e.blendColor),e.blendAlpha!==void 0&&(this.blendAlpha=e.blendAlpha),e.stencilWriteMask!==void 0&&(this.stencilWriteMask=e.stencilWriteMask),e.stencilFunc!==void 0&&(this.stencilFunc=e.stencilFunc),e.stencilRef!==void 0&&(this.stencilRef=e.stencilRef),e.stencilFuncMask!==void 0&&(this.stencilFuncMask=e.stencilFuncMask),e.stencilFail!==void 0&&(this.stencilFail=e.stencilFail),e.stencilZFail!==void 0&&(this.stencilZFail=e.stencilZFail),e.stencilZPass!==void 0&&(this.stencilZPass=e.stencilZPass),e.stencilWrite!==void 0&&(this.stencilWrite=e.stencilWrite),e.wireframe!==void 0&&(this.wireframe=e.wireframe),e.wireframeLinewidth!==void 0&&(this.wireframeLinewidth=e.wireframeLinewidth),e.wireframeLinecap!==void 0&&(this.wireframeLinecap=e.wireframeLinecap),e.wireframeLinejoin!==void 0&&(this.wireframeLinejoin=e.wireframeLinejoin),e.rotation!==void 0&&(this.rotation=e.rotation),e.linewidth!==void 0&&(this.linewidth=e.linewidth),e.linecap!==void 0&&(this.linecap=e.linecap),e.linejoin!==void 0&&(this.linejoin=e.linejoin),e.dashSize!==void 0&&(this.dashSize=e.dashSize),e.gapSize!==void 0&&(this.gapSize=e.gapSize),e.scale!==void 0&&(this.scale=e.scale),e.polygonOffset!==void 0&&(this.polygonOffset=e.polygonOffset),e.polygonOffsetFactor!==void 0&&(this.polygonOffsetFactor=e.polygonOffsetFactor),e.polygonOffsetUnits!==void 0&&(this.polygonOffsetUnits=e.polygonOffsetUnits),e.dithering!==void 0&&(this.dithering=e.dithering),e.alphaToCoverage!==void 0&&(this.alphaToCoverage=e.alphaToCoverage),e.premultipliedAlpha!==void 0&&(this.premultipliedAlpha=e.premultipliedAlpha),e.forceSinglePass!==void 0&&(this.forceSinglePass=e.forceSinglePass),e.allowOverride!==void 0&&(this.allowOverride=e.allowOverride),e.visible!==void 0&&(this.visible=e.visible),e.toneMapped!==void 0&&(this.toneMapped=e.toneMapped),e.userData!==void 0&&(this.userData=e.userData),e.vertexColors!==void 0&&(this.vertexColors=typeof e.vertexColors==`number`?e.vertexColors>0:e.vertexColors),e.size!==void 0&&(this.size=e.size),e.sizeAttenuation!==void 0&&(this.sizeAttenuation=e.sizeAttenuation),e.map!==void 0&&(this.map=t[e.map]||null),e.matcap!==void 0&&(this.matcap=t[e.matcap]||null),e.alphaMap!==void 0&&(this.alphaMap=t[e.alphaMap]||null),e.bumpMap!==void 0&&(this.bumpMap=t[e.bumpMap]||null),e.bumpScale!==void 0&&(this.bumpScale=e.bumpScale),e.normalMap!==void 0&&(this.normalMap=t[e.normalMap]||null),e.normalMapType!==void 0&&(this.normalMapType=e.normalMapType),e.normalScale!==void 0){let t=e.normalScale;Array.isArray(t)===!1&&(t=[t,t]),this.normalScale=new H().fromArray(t)}return e.displacementMap!==void 0&&(this.displacementMap=t[e.displacementMap]||null),e.displacementScale!==void 0&&(this.displacementScale=e.displacementScale),e.displacementBias!==void 0&&(this.displacementBias=e.displacementBias),e.roughnessMap!==void 0&&(this.roughnessMap=t[e.roughnessMap]||null),e.metalnessMap!==void 0&&(this.metalnessMap=t[e.metalnessMap]||null),e.emissiveMap!==void 0&&(this.emissiveMap=t[e.emissiveMap]||null),e.emissiveIntensity!==void 0&&(this.emissiveIntensity=e.emissiveIntensity),e.specularMap!==void 0&&(this.specularMap=t[e.specularMap]||null),e.specularIntensityMap!==void 0&&(this.specularIntensityMap=t[e.specularIntensityMap]||null),e.specularColorMap!==void 0&&(this.specularColorMap=t[e.specularColorMap]||null),e.envMap!==void 0&&(this.envMap=t[e.envMap]||null),e.envMapRotation!==void 0&&this.envMapRotation.fromArray(e.envMapRotation),e.envMapIntensity!==void 0&&(this.envMapIntensity=e.envMapIntensity),e.reflectivity!==void 0&&(this.reflectivity=e.reflectivity),e.refractionRatio!==void 0&&(this.refractionRatio=e.refractionRatio),e.lightMap!==void 0&&(this.lightMap=t[e.lightMap]||null),e.lightMapIntensity!==void 0&&(this.lightMapIntensity=e.lightMapIntensity),e.aoMap!==void 0&&(this.aoMap=t[e.aoMap]||null),e.aoMapIntensity!==void 0&&(this.aoMapIntensity=e.aoMapIntensity),e.gradientMap!==void 0&&(this.gradientMap=t[e.gradientMap]||null),e.clearcoatMap!==void 0&&(this.clearcoatMap=t[e.clearcoatMap]||null),e.clearcoatRoughnessMap!==void 0&&(this.clearcoatRoughnessMap=t[e.clearcoatRoughnessMap]||null),e.clearcoatNormalMap!==void 0&&(this.clearcoatNormalMap=t[e.clearcoatNormalMap]||null),e.clearcoatNormalScale!==void 0&&(this.clearcoatNormalScale=new H().fromArray(e.clearcoatNormalScale)),e.iridescenceMap!==void 0&&(this.iridescenceMap=t[e.iridescenceMap]||null),e.iridescenceThicknessMap!==void 0&&(this.iridescenceThicknessMap=t[e.iridescenceThicknessMap]||null),e.transmissionMap!==void 0&&(this.transmissionMap=t[e.transmissionMap]||null),e.thicknessMap!==void 0&&(this.thicknessMap=t[e.thicknessMap]||null),e.anisotropyMap!==void 0&&(this.anisotropyMap=t[e.anisotropyMap]||null),e.sheenColorMap!==void 0&&(this.sheenColorMap=t[e.sheenColorMap]||null),e.sheenRoughnessMap!==void 0&&(this.sheenRoughnessMap=t[e.sheenRoughnessMap]||null),this}clone(){return new this.constructor().copy(this)}copy(e){this.name=e.name,this.blending=e.blending,this.side=e.side,this.vertexColors=e.vertexColors,this.opacity=e.opacity,this.transparent=e.transparent,this.blendSrc=e.blendSrc,this.blendDst=e.blendDst,this.blendEquation=e.blendEquation,this.blendSrcAlpha=e.blendSrcAlpha,this.blendDstAlpha=e.blendDstAlpha,this.blendEquationAlpha=e.blendEquationAlpha,this.blendColor.copy(e.blendColor),this.blendAlpha=e.blendAlpha,this.depthFunc=e.depthFunc,this.depthTest=e.depthTest,this.depthWrite=e.depthWrite,this.stencilWriteMask=e.stencilWriteMask,this.stencilFunc=e.stencilFunc,this.stencilRef=e.stencilRef,this.stencilFuncMask=e.stencilFuncMask,this.stencilFail=e.stencilFail,this.stencilZFail=e.stencilZFail,this.stencilZPass=e.stencilZPass,this.stencilWrite=e.stencilWrite;let t=e.clippingPlanes,n=null;if(t!==null){let e=t.length;n=Array(e);for(let r=0;r!==e;++r)n[r]=t[r].clone()}return this.clippingPlanes=n,this.clipIntersection=e.clipIntersection,this.clipShadows=e.clipShadows,this.shadowSide=e.shadowSide,this.colorWrite=e.colorWrite,this.precision=e.precision,this.polygonOffset=e.polygonOffset,this.polygonOffsetFactor=e.polygonOffsetFactor,this.polygonOffsetUnits=e.polygonOffsetUnits,this.dithering=e.dithering,this.alphaTest=e.alphaTest,this.alphaHash=e.alphaHash,this.alphaToCoverage=e.alphaToCoverage,this.premultipliedAlpha=e.premultipliedAlpha,this.forceSinglePass=e.forceSinglePass,this.allowOverride=e.allowOverride,this.visible=e.visible,this.toneMapped=e.toneMapped,this.userData=JSON.parse(JSON.stringify(e.userData)),this}dispose(){this.dispatchEvent({type:`dispose`})}set needsUpdate(e){e===!0&&this.version++}},Ir=class extends Fr{constructor(e){super(),this.isSpriteMaterial=!0,this.type=`SpriteMaterial`,this.color=new K(16777215),this.map=null,this.alphaMap=null,this.rotation=0,this.sizeAttenuation=!0,this.transparent=!0,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.alphaMap=e.alphaMap,this.rotation=e.rotation,this.sizeAttenuation=e.sizeAttenuation,this.fog=e.fog,this}},Lr,Rr=new U,zr=new U,Br=new U,Vr=new H,Hr=new H,Ur=new W,Wr=new U,Gr=new U,Kr=new U,qr=new H,Jr=new H,Yr=new H,Xr=class extends G{constructor(e=new Ir){if(super(),this.isSprite=!0,this.type=`Sprite`,Lr===void 0){Lr=new J;let e=new Dr(new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]),5);Lr.setIndex([0,1,2,0,2,3]),Lr.setAttribute(`position`,new kr(e,3,0,!1)),Lr.setAttribute(`uv`,new kr(e,2,3,!1))}this.geometry=Lr,this.material=e,this.center=new H(.5,.5),this.count=1}intersectsFrustum(e){return e.intersectsSprite(this)}raycast(e,t){e.camera===null&&z(`Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.`),zr.setFromMatrixScale(this.matrixWorld),Ur.copy(e.camera.matrixWorld),this.modelViewMatrix.multiplyMatrices(e.camera.matrixWorldInverse,this.matrixWorld),Br.setFromMatrixPosition(this.modelViewMatrix),e.camera.isPerspectiveCamera&&this.material.sizeAttenuation===!1&&zr.multiplyScalar(-Br.z);let n=this.material.rotation,r,i;n!==0&&(i=Math.cos(n),r=Math.sin(n));let a=this.center;Zr(Wr.set(-.5,-.5,0),Br,a,zr,r,i),Zr(Gr.set(.5,-.5,0),Br,a,zr,r,i),Zr(Kr.set(.5,.5,0),Br,a,zr,r,i),qr.set(0,0),Jr.set(1,0),Yr.set(1,1);let o=e.ray.intersectTriangle(Wr,Gr,Kr,!1,Rr);if(o===null&&(Zr(Gr.set(-.5,.5,0),Br,a,zr,r,i),Jr.set(0,1),o=e.ray.intersectTriangle(Wr,Kr,Gr,!1,Rr),o===null))return;let s=e.ray.origin.distanceTo(Rr);s<e.near||s>e.far||t.push({distance:s,point:Rr.clone(),uv:Jn.getInterpolation(Rr,Wr,Gr,Kr,qr,Jr,Yr,new H),face:null,object:this})}copy(e,t){return super.copy(e,t),e.center!==void 0&&this.center.copy(e.center),this.material=e.material,this}};function Zr(e,t,n,r,i,a){Vr.subVectors(e,n).addScalar(.5).multiply(r),i===void 0?Hr.copy(Vr):(Hr.x=a*Vr.x-i*Vr.y,Hr.y=i*Vr.x+a*Vr.y),e.copy(t),e.x+=Hr.x,e.y+=Hr.y,e.applyMatrix4(Ur)}var Qr=new U,$r=new U,ei=new U,ti=new U,ni=class{constructor(e=new U,t=new U(0,0,-1)){this.origin=e,this.direction=t}set(e,t){return this.origin.copy(e),this.direction.copy(t),this}copy(e){return this.origin.copy(e.origin),this.direction.copy(e.direction),this}at(e,t){return t.copy(this.origin).addScaledVector(this.direction,e)}lookAt(e){return this.direction.copy(e).sub(this.origin).normalize(),this}recast(e){return this.origin.copy(this.at(e,Qr)),this}closestPointToPoint(e,t){t.subVectors(e,this.origin);let n=t.dot(this.direction);return n<0?t.copy(this.origin):t.copy(this.origin).addScaledVector(this.direction,n)}distanceToPoint(e){return Math.sqrt(this.distanceSqToPoint(e))}distanceSqToPoint(e){let t=Qr.subVectors(e,this.origin).dot(this.direction);return t<0?this.origin.distanceToSquared(e):(Qr.copy(this.origin).addScaledVector(this.direction,t),Qr.distanceToSquared(e))}distanceSqToSegment(e,t,n,r){$r.copy(e).add(t).multiplyScalar(.5),ei.copy(t).sub(e).normalize(),ti.copy(this.origin).sub($r);let i=e.distanceTo(t)*.5,a=-this.direction.dot(ei),o=ti.dot(this.direction),s=-ti.dot(ei),c=ti.lengthSq(),l=Math.abs(1-a*a),u,d,f,p;if(l>0){if(u=a*s-o,d=a*o-s,p=i*l,u>=0){if(d>=-p){if(d<=p){let e=1/l;u*=e,d*=e,f=u*(u+a*d+2*o)+d*(a*u+d+2*s)+c}else d=i,u=Math.max(0,-(a*d+o)),f=-u*u+d*(d+2*s)+c}else d=-i,u=Math.max(0,-(a*d+o)),f=-u*u+d*(d+2*s)+c}else d<=-p?(u=Math.max(0,-(-a*i+o)),d=u>0?-i:Math.min(Math.max(-i,-s),i),f=-u*u+d*(d+2*s)+c):d<=p?(u=0,d=Math.min(Math.max(-i,-s),i),f=d*(d+2*s)+c):(u=Math.max(0,-(a*i+o)),d=u>0?i:Math.min(Math.max(-i,-s),i),f=-u*u+d*(d+2*s)+c)}else d=a>0?-i:i,u=Math.max(0,-(a*d+o)),f=-u*u+d*(d+2*s)+c;return n&&n.copy(this.origin).addScaledVector(this.direction,u),r&&r.copy($r).addScaledVector(ei,d),f}intersectSphere(e,t){if(e.radius<0)return null;Qr.subVectors(e.center,this.origin);let n=Qr.dot(this.direction),r=Qr.dot(Qr)-n*n,i=e.radius*e.radius;if(r>i)return null;let a=Math.sqrt(i-r),o=n-a,s=n+a;return s<0?null:o<0?this.at(s,t):this.at(o,t)}intersectsSphere(e){return e.radius<0?!1:this.distanceSqToPoint(e.center)<=e.radius*e.radius}distanceToPlane(e){let t=e.normal.dot(this.direction);if(t===0)return e.distanceToPoint(this.origin)===0?0:null;let n=-(this.origin.dot(e.normal)+e.constant)/t;return n>=0?n:null}intersectPlane(e,t){let n=this.distanceToPlane(e);return n===null?null:this.at(n,t)}intersectsPlane(e){let t=e.distanceToPoint(this.origin);return t===0||e.normal.dot(this.direction)*t<0}intersectBox(e,t){let n,r,i,a,o,s,c=1/this.direction.x,l=1/this.direction.y,u=1/this.direction.z,d=this.origin;return c>=0?(n=(e.min.x-d.x)*c,r=(e.max.x-d.x)*c):(n=(e.max.x-d.x)*c,r=(e.min.x-d.x)*c),l>=0?(i=(e.min.y-d.y)*l,a=(e.max.y-d.y)*l):(i=(e.max.y-d.y)*l,a=(e.min.y-d.y)*l),n>a||i>r||((i>n||isNaN(n))&&(n=i),(a<r||isNaN(r))&&(r=a),u>=0?(o=(e.min.z-d.z)*u,s=(e.max.z-d.z)*u):(o=(e.max.z-d.z)*u,s=(e.min.z-d.z)*u),n>s||o>r)||((o>n||n!==n)&&(n=o),(s<r||r!==r)&&(r=s),r<0)?null:this.at(n>=0?n:r,t)}intersectsBox(e){return this.intersectBox(e,Qr)!==null}intersectTriangle(e,t,n,r,i){let a=this.origin,o=this.direction,s=o.x,c=o.y,l=o.z,u=e.x-a.x,d=e.y-a.y,f=e.z-a.z,p=t.x-a.x,m=t.y-a.y,h=t.z-a.z,g=n.x-a.x,_=n.y-a.y,v=n.z-a.z,y=Math.abs(s),b=Math.abs(c),x=Math.abs(l),S,C,w,T,E,D,O,k,A,j,M,N;if(y>=b&&y>=x?(w=s,D=u,A=p,N=g,s>=0?(S=c,C=l,T=d,E=f,O=m,k=h,j=_,M=v):(S=l,C=c,T=f,E=d,O=h,k=m,j=v,M=_)):b>=x?(w=c,D=d,A=m,N=_,c>=0?(S=l,C=s,T=f,E=u,O=h,k=p,j=v,M=g):(S=s,C=l,T=u,E=f,O=p,k=h,j=g,M=v)):(w=l,D=f,A=h,N=v,l>=0?(S=s,C=c,T=u,E=d,O=p,k=m,j=g,M=_):(S=c,C=s,T=d,E=u,O=m,k=p,j=_,M=g)),w===0)return null;let P=S/w,ee=C/w,F=1/w,te=T-P*D,ne=E-ee*D,re=O-P*A,ie=k-ee*A,ae=j-P*N,oe=M-ee*N,se=ae*ie-oe*re,ce=te*oe-ne*ae,le=re*ne-ie*te;if(r){if(se<0||ce<0||le<0)return null}else if((se<0||ce<0||le<0)&&(se>0||ce>0||le>0))return null;let ue=se+ce+le;if(ue===0)return null;let de=F*(se*D+ce*A+le*N);return(ue>0?de<0:de>0)?null:this.at(de/ue,i)}applyMatrix4(e){return this.origin.applyMatrix4(e),this.direction.transformDirection(e),this}equals(e){return e.origin.equals(this.origin)&&e.direction.equals(this.direction)}clone(){return new this.constructor().copy(this)}},ri=class extends Fr{constructor(e){super(),this.isMeshBasicMaterial=!0,this.type=`MeshBasicMaterial`,this.color=new K(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new fn,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap=`round`,this.wireframeLinejoin=`round`,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.specularMap=e.specularMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.combine=e.combine,this.reflectivity=e.reflectivity,this.refractionRatio=e.refractionRatio,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.fog=e.fog,this}},ii=new W,ai=new ni,oi=new yr,si=new U,ci=new U,li=new U,ui=new U,di=new U,fi=new U,pi=new U,mi=new U,Y=class extends G{constructor(e=new J,t=new ri){super(),this.isMesh=!0,this.type=`Mesh`,this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.count=1,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),e.morphTargetInfluences!==void 0&&(this.morphTargetInfluences=e.morphTargetInfluences.slice()),e.morphTargetDictionary!==void 0&&(this.morphTargetDictionary=Object.assign({},e.morphTargetDictionary)),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}updateMorphTargets(){let e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){let n=e[t[0]];if(n!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=n.length;e<t;e++){let t=n[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}getVertexPosition(e,t){let n=this.geometry,r=n.attributes.position,i=n.morphAttributes.position,a=n.morphTargetsRelative;t.fromBufferAttribute(r,e);let o=this.morphTargetInfluences;if(i&&o){fi.set(0,0,0);for(let n=0,r=i.length;n<r;n++){let r=o[n],s=i[n];r!==0&&(di.fromBufferAttribute(s,e),a?fi.addScaledVector(di,r):fi.addScaledVector(di.sub(t),r))}t.add(fi)}return t}intersectsFrustum(e){return e.intersectsObject(this)}raycast(e,t){let n=this.geometry,r=this.material,i=this.matrixWorld;r!==void 0&&(n.boundingSphere===null&&n.computeBoundingSphere(),oi.copy(n.boundingSphere),oi.applyMatrix4(i),ai.copy(e.ray).recast(e.near),!(oi.containsPoint(ai.origin)===!1&&(ai.intersectSphere(oi,si)===null||ai.origin.distanceToSquared(si)>(e.far-e.near)**2))&&(ii.copy(i).invert(),ai.copy(e.ray).applyMatrix4(ii),(n.boundingBox===null||ai.intersectsBox(n.boundingBox)!==!1)&&this._computeIntersections(e,t,ai)))}_computeIntersections(e,t,n){let r,i=this.geometry,a=this.material,o=i.index,s=i.attributes.position,c=i.attributes.uv,l=i.attributes.uv1,u=i.attributes.normal,d=i.groups,f=i.drawRange;if(o!==null){if(Array.isArray(a))for(let i=0,s=d.length;i<s;i++){let s=d[i],p=a[s.materialIndex],m=Math.max(s.start,f.start),h=Math.min(o.count,Math.min(s.start+s.count,f.start+f.count));for(let i=m,a=h;i<a;i+=3){let a=o.getX(i),d=o.getX(i+1),f=o.getX(i+2);r=gi(this,p,e,n,c,l,u,a,d,f),r&&(r.faceIndex=Math.floor(i/3),r.face.materialIndex=s.materialIndex,t.push(r))}}else{let i=Math.max(0,f.start),s=Math.min(o.count,f.start+f.count);for(let d=i,f=s;d<f;d+=3){let i=o.getX(d),s=o.getX(d+1),f=o.getX(d+2);r=gi(this,a,e,n,c,l,u,i,s,f),r&&(r.faceIndex=Math.floor(d/3),t.push(r))}}}else if(s!==void 0){if(Array.isArray(a))for(let i=0,o=d.length;i<o;i++){let o=d[i],p=a[o.materialIndex],m=Math.max(o.start,f.start),h=Math.min(s.count,Math.min(o.start+o.count,f.start+f.count));for(let i=m,a=h;i<a;i+=3){let a=i,s=i+1,d=i+2;r=gi(this,p,e,n,c,l,u,a,s,d),r&&(r.faceIndex=Math.floor(i/3),r.face.materialIndex=o.materialIndex,t.push(r))}}else{let i=Math.max(0,f.start),o=Math.min(s.count,f.start+f.count);for(let s=i,d=o;s<d;s+=3){let i=s,o=s+1,d=s+2;r=gi(this,a,e,n,c,l,u,i,o,d),r&&(r.faceIndex=Math.floor(s/3),t.push(r))}}}}};function hi(e,t,n,r,i,a,o,s){let c;if(c=t.side===1?r.intersectTriangle(o,a,i,!0,s):r.intersectTriangle(i,a,o,t.side===0,s),c===null)return null;mi.copy(s),mi.applyMatrix4(e.matrixWorld);let l=n.ray.origin.distanceTo(mi);return l<n.near||l>n.far?null:{distance:l,point:mi.clone(),object:e}}function gi(e,t,n,r,i,a,o,s,c,l){e.getVertexPosition(s,ci),e.getVertexPosition(c,li),e.getVertexPosition(l,ui);let u=hi(e,t,n,r,ci,li,ui,pi);if(u){let e=new U;Jn.getBarycoord(pi,ci,li,ui,e),i&&(u.uv=Jn.getInterpolatedAttribute(i,s,c,l,e,new H)),a&&(u.uv1=Jn.getInterpolatedAttribute(a,s,c,l,e,new H)),o&&(u.normal=Jn.getInterpolatedAttribute(o,s,c,l,e,new U),u.normal.dot(r.direction)>0&&u.normal.multiplyScalar(-1));let t={a:s,b:c,c:l,normal:new U,materialIndex:0};Jn.getNormal(ci,li,ui,t.normal),u.face=t,u.barycoord=e}return u}var _i=new tn,vi=new tn,yi=new tn,bi=new tn,xi=new W,Si=new U,Ci=new yr,wi=new W,Ti=new ni,Ei=class extends Y{constructor(e,t){super(e,t),this.isSkinnedMesh=!0,this.type=`SkinnedMesh`,this.bindMode=Oe,this.bindMatrix=new W,this.bindMatrixInverse=new W,this.boundingBox=null,this.boundingSphere=null}computeBoundingBox(){let e=this.geometry;this.boundingBox===null&&(this.boundingBox=new Yn),this.boundingBox.makeEmpty();let t=e.getAttribute(`position`);for(let e=0;e<t.count;e++)this.getVertexPosition(e,Si),this.boundingBox.expandByPoint(Si)}computeBoundingSphere(){let e=this.geometry;this.boundingSphere===null&&(this.boundingSphere=new yr),this.boundingSphere.makeEmpty();let t=e.getAttribute(`position`);for(let e=0;e<t.count;e++)this.getVertexPosition(e,Si),this.boundingSphere.expandByPoint(Si)}copy(e,t){return super.copy(e,t),this.bindMode=e.bindMode,this.bindMatrix.copy(e.bindMatrix),this.bindMatrixInverse.copy(e.bindMatrixInverse),this.skeleton=e.skeleton,e.boundingBox!==null&&(this.boundingBox=e.boundingBox.clone()),e.boundingSphere!==null&&(this.boundingSphere=e.boundingSphere.clone()),this}raycast(e,t){let n=this.material,r=this.matrixWorld;n!==void 0&&(this.boundingSphere===null&&this.computeBoundingSphere(),Ci.copy(this.boundingSphere),Ci.applyMatrix4(r),e.ray.intersectsSphere(Ci)!==!1&&(wi.copy(r).invert(),Ti.copy(e.ray).applyMatrix4(wi),(this.boundingBox===null||Ti.intersectsBox(this.boundingBox)!==!1)&&this._computeIntersections(e,t,Ti)))}getVertexPosition(e,t){return super.getVertexPosition(e,t),this.applyBoneTransform(e,t),t}bind(e,t){this.skeleton=e,t===void 0&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),t=this.matrixWorld),this.bindMatrix.copy(t),this.bindMatrixInverse.copy(t).invert()}pose(){this.skeleton.pose()}normalizeSkinWeights(){let e=new tn,t=this.geometry.attributes.skinWeight;for(let n=0,r=t.count;n<r;n++){e.fromBufferAttribute(t,n);let r=1/e.manhattanLength();r===1/0?e.set(1,0,0,0):e.multiplyScalar(r),t.setXYZW(n,e.x,e.y,e.z,e.w)}}updateMatrixWorld(e){super.updateMatrixWorld(e),this.bindMode===`attached`?this.bindMatrixInverse.copy(this.matrixWorld).invert():this.bindMode===`detached`?this.bindMatrixInverse.copy(this.bindMatrix).invert():R(`SkinnedMesh: Unrecognized bindMode: `+this.bindMode)}applyBoneTransform(e,t){let n=this.skeleton,r=this.geometry;vi.fromBufferAttribute(r.attributes.skinIndex,e),yi.fromBufferAttribute(r.attributes.skinWeight,e),t.isVector4?(_i.copy(t),t.set(0,0,0,0)):(_i.set(...t,1),t.set(0,0,0)),_i.applyMatrix4(this.bindMatrix);for(let e=0;e<4;e++){let r=yi.getComponent(e);if(r!==0){let i=vi.getComponent(e);xi.multiplyMatrices(n.bones[i].matrixWorld,n.boneInverses[i]),t.addScaledVector(bi.copy(_i).applyMatrix4(xi),r)}}return t.isVector4&&(t.w=_i.w),t.applyMatrix4(this.bindMatrixInverse)}},Di=class extends G{constructor(){super(),this.isBone=!0,this.type=`Bone`}},Oi=class extends en{constructor(e=null,t=1,n=1,r,i,a,o,s,c=Me,l=Me,u,d){super(null,a,o,s,c,l,r,i,u,d),this.isDataTexture=!0,this.image={data:e,width:t,height:n},this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1}},ki=new W,Ai=new W,ji=class e{constructor(e=[],t=[]){this.uuid=ht(),this.bones=e.slice(0),this.boneInverses=t,this.boneMatrices=null,this.boneTexture=null,this.init()}init(){let e=this.bones,t=this.boneInverses;if(this.boneMatrices=new Float32Array(e.length*16),t.length===0)this.calculateInverses();else if(e.length!==t.length){R(`Skeleton: Number of inverse bone matrices does not match amount of bones.`),this.boneInverses=[];for(let e=0,t=this.bones.length;e<t;e++)this.boneInverses.push(new W)}}calculateInverses(){this.boneInverses.length=0;for(let e=0,t=this.bones.length;e<t;e++){let t=new W;this.bones[e]&&t.copy(this.bones[e].matrixWorld).invert(),this.boneInverses.push(t)}}pose(){for(let e=0,t=this.bones.length;e<t;e++){let t=this.bones[e];t&&t.matrixWorld.copy(this.boneInverses[e]).invert()}for(let e=0,t=this.bones.length;e<t;e++){let t=this.bones[e];t&&(t.parent&&t.parent.isBone?(t.matrix.copy(t.parent.matrixWorld).invert(),t.matrix.multiply(t.matrixWorld)):t.matrix.copy(t.matrixWorld),t.matrix.decompose(t.position,t.quaternion,t.scale))}}update(){let e=this.bones,t=this.boneInverses,n=this.boneMatrices,r=this.boneTexture;for(let r=0,i=e.length;r<i;r++){let i=e[r]?e[r].matrixWorld:Ai;ki.multiplyMatrices(i,t[r]),ki.toArray(n,r*16)}r!==null&&(r.needsUpdate=!0)}clone(){return new e(this.bones,this.boneInverses)}computeBoneTexture(){let e=Math.sqrt(this.bones.length*4);e=Math.ceil(e/4)*4,e=Math.max(e,4);let t=new Float32Array(e*e*4);t.set(this.boneMatrices);let n=new Oi(t,e,e,Be,ze);return n.needsUpdate=!0,this.boneMatrices=t,this.boneTexture=n,this}getBoneByName(e){for(let t=0,n=this.bones.length;t<n;t++){let n=this.bones[t];if(n.name===e)return n}}dispose(){this.boneTexture!==null&&(this.boneTexture.dispose(),this.boneTexture=null)}fromJSON(e,t){this.uuid=e.uuid;for(let n=0,r=e.bones.length;n<r;n++){let r=e.bones[n],i=t[r];i===void 0&&(R(`Skeleton: No bone found with UUID:`,r),i=new Di),this.bones.push(i),this.boneInverses.push(new W().fromArray(e.boneInverses[n]))}return this.init(),this}toJSON(){let e={metadata:{version:4.7,type:`Skeleton`,generator:`Skeleton.toJSON`},bones:[],boneInverses:[]};e.uuid=this.uuid;let t=this.bones,n=this.boneInverses;for(let r=0,i=t.length;r<i;r++){let i=t[r];e.bones.push(i.uuid);let a=n[r];e.boneInverses.push(a.toArray())}return e}},Mi=class extends pr{constructor(e,t,n,r=1){super(e,t,n),this.isInstancedBufferAttribute=!0,this.meshPerAttribute=r}copy(e){return super.copy(e),this.meshPerAttribute=e.meshPerAttribute,this}toJSON(){let e=super.toJSON();return e.meshPerAttribute=this.meshPerAttribute,e.isInstancedBufferAttribute=!0,e}},Ni=new W,Pi=new W,Fi=[],Ii=new Yn,Li=new W,Ri=new Y,zi=new yr,Bi=class extends Y{constructor(e,t,n){super(e,t),this.isInstancedMesh=!0,this.instanceMatrix=new Mi(new Float32Array(n*16),16),this.instanceColor=null,this.morphTexture=null,this.count=n,this.boundingBox=null,this.boundingSphere=null;for(let e=0;e<n;e++)this.setMatrixAt(e,Li)}computeBoundingBox(){let e=this.geometry,t=this.count;this.boundingBox===null&&(this.boundingBox=new Yn),e.boundingBox===null&&e.computeBoundingBox(),this.boundingBox.makeEmpty();for(let n=0;n<t;n++)this.getMatrixAt(n,Ni),Ii.copy(e.boundingBox).applyMatrix4(Ni),this.boundingBox.union(Ii)}computeBoundingSphere(){let e=this.geometry,t=this.count;this.boundingSphere===null&&(this.boundingSphere=new yr),e.boundingSphere===null&&e.computeBoundingSphere(),this.boundingSphere.makeEmpty();for(let n=0;n<t;n++)this.getMatrixAt(n,Ni),zi.copy(e.boundingSphere).applyMatrix4(Ni),this.boundingSphere.union(zi)}copy(e,t){return super.copy(e,t),this.instanceMatrix.copy(e.instanceMatrix),e.morphTexture!==null&&(this.morphTexture=e.morphTexture.clone()),e.instanceColor!==null&&(this.instanceColor=e.instanceColor.clone()),this.count=e.count,e.boundingBox!==null&&(this.boundingBox=e.boundingBox.clone()),e.boundingSphere!==null&&(this.boundingSphere=e.boundingSphere.clone()),this}getColorAt(e,t){return this.instanceColor===null?t.setRGB(1,1,1):t.fromArray(this.instanceColor.array,e*3)}getMatrixAt(e,t){return t.fromArray(this.instanceMatrix.array,e*16)}getMorphAt(e,t){let n=t.morphTargetInfluences,r=this.morphTexture.source.data.data,i=e*(n.length+1)+1;for(let e=0;e<n.length;e++)n[e]=r[i+e]}raycast(e,t){let n=this.matrixWorld,r=this.count;if(Ri.geometry=this.geometry,Ri.material=this.material,Ri.material!==void 0&&(this.boundingSphere===null&&this.computeBoundingSphere(),zi.copy(this.boundingSphere),zi.applyMatrix4(n),e.ray.intersectsSphere(zi)!==!1))for(let i=0;i<r;i++){this.getMatrixAt(i,Ni),Pi.multiplyMatrices(n,Ni),Ri.matrixWorld=Pi,Ri.raycast(e,Fi);for(let e=0,n=Fi.length;e<n;e++){let n=Fi[e];n.instanceId=i,n.object=this,t.push(n)}Fi.length=0}}setColorAt(e,t){return this.instanceColor===null&&(this.instanceColor=new Mi(new Float32Array(this.instanceMatrix.count*3).fill(1),3)),t.toArray(this.instanceColor.array,e*3),this}setMatrixAt(e,t){return t.toArray(this.instanceMatrix.array,e*16),this}setMorphAt(e,t){let n=t.morphTargetInfluences,r=n.length+1;this.morphTexture===null&&(this.morphTexture=new Oi(new Float32Array(r*this.count),r,this.count,Ve,ze));let i=this.morphTexture.source.data.data,a=0;for(let e=0;e<n.length;e++)a+=n[e];let o=this.geometry.morphTargetsRelative?1:1-a,s=r*e;return i[s]=o,i.set(n,s+1),this}updateMorphTargets(){}dispose(){super.dispose(),this.morphTexture!==null&&(this.morphTexture.dispose(),this.morphTexture=null)}},Vi=new yr,Hi=new H(.5,.5),Ui=new U,Wi=class{constructor(e=new Nr,t=new Nr,n=new Nr,r=new Nr,i=new Nr,a=new Nr){this.planes=[e,t,n,r,i,a]}set(e,t,n,r,i,a){let o=this.planes;return o[0].copy(e),o[1].copy(t),o[2].copy(n),o[3].copy(r),o[4].copy(i),o[5].copy(a),this}copy(e){let t=this.planes;for(let n=0;n<6;n++)t[n].copy(e.planes[n]);return this}setFromProjectionMatrix(e,t=nt,n=!1){let r=this.planes,i=e.elements,a=i[0],o=i[1],s=i[2],c=i[3],l=i[4],u=i[5],d=i[6],f=i[7],p=i[8],m=i[9],h=i[10],g=i[11],_=i[12],v=i[13],y=i[14],b=i[15];if(r[0].setComponents(c-a,f-l,g-p,b-_).normalize(),r[1].setComponents(c+a,f+l,g+p,b+_).normalize(),r[2].setComponents(c+o,f+u,g+m,b+v).normalize(),r[3].setComponents(c-o,f-u,g-m,b-v).normalize(),n)r[4].setComponents(s,d,h,y).normalize(),r[5].setComponents(c-s,f-d,g-h,b-y).normalize();else if(r[4].setComponents(c-s,f-d,g-h,b-y).normalize(),t===2e3)r[5].setComponents(c+s,f+d,g+h,b+y).normalize();else if(t===2001)r[5].setComponents(s,d,h,y).normalize();else throw Error(`THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: `+t);return this}intersectsObject(e){if(e.boundingSphere!==void 0)e.boundingSphere===null&&e.computeBoundingSphere(),Vi.copy(e.boundingSphere).applyMatrix4(e.matrixWorld);else{let t=e.geometry;t.boundingSphere===null&&t.computeBoundingSphere(),Vi.copy(t.boundingSphere).applyMatrix4(e.matrixWorld)}return this.intersectsSphere(Vi)}intersectsSprite(e){return Vi.center.set(0,0,0),Vi.radius=.7071067811865476+Hi.distanceTo(e.center),Vi.applyMatrix4(e.matrixWorld),this.intersectsSphere(Vi)}intersectsSphere(e){let t=this.planes,n=e.center,r=-e.radius;for(let e=0;e<6;e++)if(t[e].distanceToPoint(n)<r)return!1;return!0}intersectsBox(e){let t=this.planes;for(let n=0;n<6;n++){let r=t[n];if(Ui.x=r.normal.x>0?e.max.x:e.min.x,Ui.y=r.normal.y>0?e.max.y:e.min.y,Ui.z=r.normal.z>0?e.max.z:e.min.z,r.distanceToPoint(Ui)<0)return!1}return!0}containsPoint(e){let t=this.planes;for(let n=0;n<6;n++)if(t[n].distanceToPoint(e)<0)return!1;return!0}clone(){return new this.constructor().copy(this)}},Gi=class extends Fr{constructor(e){super(),this.isLineBasicMaterial=!0,this.type=`LineBasicMaterial`,this.color=new K(16777215),this.map=null,this.linewidth=1,this.linecap=`round`,this.linejoin=`round`,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.linewidth=e.linewidth,this.linecap=e.linecap,this.linejoin=e.linejoin,this.fog=e.fog,this}},Ki=new U,qi=new U,Ji=new W,Yi=new ni,Xi=new yr,Zi=new U,Qi=new U,$i=class extends G{constructor(e=new J,t=new Gi){super(),this.isLine=!0,this.type=`Line`,this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}computeLineDistances(){let e=this.geometry;if(e.index===null){let t=e.attributes.position,n=[0];for(let e=1,r=t.count;e<r;e++)Ki.fromBufferAttribute(t,e-1),qi.fromBufferAttribute(t,e),n[e]=n[e-1],n[e]+=Ki.distanceTo(qi);e.setAttribute(`lineDistance`,new q(n,1))}else R(`Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.`);return this}intersectsFrustum(e){return e.intersectsObject(this)}raycast(e,t){let n=this.geometry,r=this.matrixWorld,i=e.params.Line.threshold,a=n.drawRange;if(n.boundingSphere===null&&n.computeBoundingSphere(),Xi.copy(n.boundingSphere),Xi.applyMatrix4(r),Xi.radius+=i,e.ray.intersectsSphere(Xi)===!1)return;Ji.copy(r).invert(),Yi.copy(e.ray).applyMatrix4(Ji);let o=i/((this.scale.x+this.scale.y+this.scale.z)/3),s=o*o,c=this.isLineSegments?2:1,l=n.index,u=n.attributes.position;if(l!==null){let n=Math.max(0,a.start),r=Math.min(l.count,a.start+a.count);for(let i=n,a=r-1;i<a;i+=c){let n=l.getX(i),r=l.getX(i+1),a=ea(this,e,Yi,s,n,r,i);a&&t.push(a)}if(this.isLineLoop){let i=l.getX(r-1),a=l.getX(n),o=ea(this,e,Yi,s,i,a,r-1);o&&t.push(o)}}else{let n=Math.max(0,a.start),r=Math.min(u.count,a.start+a.count);for(let i=n,a=r-1;i<a;i+=c){let n=ea(this,e,Yi,s,i,i+1,i);n&&t.push(n)}if(this.isLineLoop){let i=ea(this,e,Yi,s,r-1,n,r-1);i&&t.push(i)}}}updateMorphTargets(){let e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){let n=e[t[0]];if(n!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=n.length;e<t;e++){let t=n[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}};function ea(e,t,n,r,i,a,o){let s=e.geometry.attributes.position;if(Ki.fromBufferAttribute(s,i),qi.fromBufferAttribute(s,a),n.distanceSqToSegment(Ki,qi,Zi,Qi)>r)return;Zi.applyMatrix4(e.matrixWorld);let c=t.ray.origin.distanceTo(Zi);if(!(c<t.near||c>t.far))return{distance:c,point:Qi.clone().applyMatrix4(e.matrixWorld),index:o,face:null,faceIndex:null,barycoord:null,object:e}}var ta=new U,na=new U,ra=class extends $i{constructor(e,t){super(e,t),this.isLineSegments=!0,this.type=`LineSegments`}computeLineDistances(){let e=this.geometry;if(e.index===null){let t=e.attributes.position,n=[];for(let e=0,r=t.count;e<r;e+=2)ta.fromBufferAttribute(t,e),na.fromBufferAttribute(t,e+1),n[e]=e===0?0:n[e-1],n[e+1]=n[e]+ta.distanceTo(na);e.setAttribute(`lineDistance`,new q(n,1))}else R(`LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.`);return this}},ia=class extends $i{constructor(e,t){super(e,t),this.isLineLoop=!0,this.type=`LineLoop`}},aa=class extends Fr{constructor(e){super(),this.isPointsMaterial=!0,this.type=`PointsMaterial`,this.color=new K(16777215),this.map=null,this.alphaMap=null,this.size=1,this.sizeAttenuation=!0,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.color.copy(e.color),this.map=e.map,this.alphaMap=e.alphaMap,this.size=e.size,this.sizeAttenuation=e.sizeAttenuation,this.fog=e.fog,this}},oa=new W,sa=new ni,ca=new yr,la=new U,ua=class extends G{constructor(e=new J,t=new aa){super(),this.isPoints=!0,this.type=`Points`,this.geometry=e,this.material=t,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.updateMorphTargets()}copy(e,t){return super.copy(e,t),this.material=Array.isArray(e.material)?e.material.slice():e.material,this.geometry=e.geometry,this}intersectsFrustum(e){return e.intersectsObject(this)}raycast(e,t){let n=this.geometry,r=this.matrixWorld,i=e.params.Points.threshold,a=n.drawRange;if(n.boundingSphere===null&&n.computeBoundingSphere(),ca.copy(n.boundingSphere),ca.applyMatrix4(r),ca.radius+=i,e.ray.intersectsSphere(ca)===!1)return;oa.copy(r).invert(),sa.copy(e.ray).applyMatrix4(oa);let o=i/((this.scale.x+this.scale.y+this.scale.z)/3),s=o*o,c=n.index,l=n.attributes.position;if(c!==null){let n=Math.max(0,a.start),i=Math.min(c.count,a.start+a.count);for(let a=n,o=i;a<o;a++){let n=c.getX(a);la.fromBufferAttribute(l,n),da(la,n,s,r,e,t,this)}}else{let n=Math.max(0,a.start),i=Math.min(l.count,a.start+a.count);for(let a=n,o=i;a<o;a++)la.fromBufferAttribute(l,a),da(la,a,s,r,e,t,this)}}updateMorphTargets(){let e=this.geometry.morphAttributes,t=Object.keys(e);if(t.length>0){let n=e[t[0]];if(n!==void 0){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let e=0,t=n.length;e<t;e++){let t=n[e].name||String(e);this.morphTargetInfluences.push(0),this.morphTargetDictionary[t]=e}}}}};function da(e,t,n,r,i,a,o){let s=sa.distanceSqToPoint(e);if(s<n){let n=new U;sa.closestPointToPoint(e,n),n.applyMatrix4(r);let c=i.ray.origin.distanceTo(n);if(c<i.near||c>i.far)return;a.push({distance:c,distanceToRay:Math.sqrt(s),point:n,index:t,face:null,faceIndex:null,barycoord:null,object:o})}}var fa=class extends en{constructor(e,t,n,r,i,a,o,s,c){super(e,t,n,r,i,a,o,s,c),this.isCanvasTexture=!0,this.needsUpdate=!0}},pa=class e extends J{constructor(e=1,t=1,n=1,r=1,i=1,a=1){super(),this.type=`BoxGeometry`,this.parameters={width:e,height:t,depth:n,widthSegments:r,heightSegments:i,depthSegments:a};let o=this;r=Math.floor(r),i=Math.floor(i),a=Math.floor(a);let s=[],c=[],l=[],u=[],d=0,f=0;p(`z`,`y`,`x`,-1,-1,n,t,e,a,i,0),p(`z`,`y`,`x`,1,-1,n,t,-e,a,i,1),p(`x`,`z`,`y`,1,1,e,n,t,r,a,2),p(`x`,`z`,`y`,1,-1,e,n,-t,r,a,3),p(`x`,`y`,`z`,1,-1,e,t,n,r,i,4),p(`x`,`y`,`z`,-1,-1,e,t,-n,r,i,5),this.setIndex(s),this.setAttribute(`position`,new q(c,3)),this.setAttribute(`normal`,new q(l,3)),this.setAttribute(`uv`,new q(u,2));function p(e,t,n,r,i,a,p,m,h,g,_){let v=a/h,y=p/g,b=a/2,x=p/2,S=m/2,C=h+1,w=g+1,T=0,E=0,D=new U;for(let a=0;a<w;a++){let o=a*y-x;for(let s=0;s<C;s++)D[e]=(s*v-b)*r,D[t]=o*i,D[n]=S,c.push(D.x,D.y,D.z),D[e]=0,D[t]=0,D[n]=m>0?1:-1,l.push(D.x,D.y,D.z),u.push(s/h),u.push(1-a/g),T+=1}for(let e=0;e<g;e++)for(let t=0;t<h;t++){let n=d+t+C*e,r=d+t+C*(e+1),i=d+(t+1)+C*(e+1),a=d+(t+1)+C*e;s.push(n,r,a),s.push(r,i,a),E+=6}o.addGroup(f,E,_),f+=E,d+=T}}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.width,t.height,t.depth,t.widthSegments,t.heightSegments,t.depthSegments)}},ma=class e extends J{constructor(e=1,t=32,n=0,r=Math.PI*2){super(),this.type=`CircleGeometry`,this.parameters={radius:e,segments:t,thetaStart:n,thetaLength:r},t=Math.max(3,t);let i=[],a=[],o=[],s=[],c=new U,l=new H;a.push(0,0,0),o.push(0,0,1),s.push(.5,.5);for(let i=0,u=3;i<=t;i++,u+=3){let d=n+i/t*r;c.x=e*Math.cos(d),c.y=e*Math.sin(d),a.push(c.x,c.y,c.z),o.push(0,0,1),l.x=(a[u]/e+1)/2,l.y=(a[u+1]/e+1)/2,s.push(l.x,l.y)}for(let e=1;e<=t;e++)i.push(e,e+1,0);this.setIndex(i),this.setAttribute(`position`,new q(a,3)),this.setAttribute(`normal`,new q(o,3)),this.setAttribute(`uv`,new q(s,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.radius,t.segments,t.thetaStart,t.thetaLength)}},ha=class e extends J{constructor(e=1,t=1,n=1,r=32,i=1,a=!1,o=0,s=Math.PI*2){super(),this.type=`CylinderGeometry`,this.parameters={radiusTop:e,radiusBottom:t,height:n,radialSegments:r,heightSegments:i,openEnded:a,thetaStart:o,thetaLength:s};let c=this;r=Math.floor(r),i=Math.floor(i);let l=[],u=[],d=[],f=[],p=0,m=[],h=n/2,g=0;_(),a===!1&&(e>0&&v(!0),t>0&&v(!1)),this.setIndex(l),this.setAttribute(`position`,new q(u,3)),this.setAttribute(`normal`,new q(d,3)),this.setAttribute(`uv`,new q(f,2));function _(){let a=new U,_=new U,v=0,y=(t-e)/n;for(let c=0;c<=i;c++){let l=[],g=c/i,v=g*(t-e)+e;for(let e=0;e<=r;e++){let t=e/r,i=t*s+o,c=Math.sin(i),m=Math.cos(i);_.x=v*c,_.y=-g*n+h,_.z=v*m,u.push(_.x,_.y,_.z),a.set(c,y,m).normalize(),d.push(a.x,a.y,a.z),f.push(t,1-g),l.push(p++)}m.push(l)}for(let n=0;n<r;n++)for(let r=0;r<i;r++){let a=m[r][n],o=m[r+1][n],s=m[r+1][n+1],c=m[r][n+1];(e>0||r!==0)&&(l.push(a,o,c),v+=3),(t>0||r!==i-1)&&(l.push(o,s,c),v+=3)}c.addGroup(g,v,0),g+=v}function v(n){let i=p,a=new H,m=new U,_=0,v=n===!0?e:t,y=n===!0?1:-1;for(let e=1;e<=r;e++)u.push(0,h*y,0),d.push(0,y,0),f.push(.5,.5),p++;let b=p;for(let e=0;e<=r;e++){let t=e/r*s+o,n=Math.cos(t),i=Math.sin(t);m.x=v*i,m.y=h*y,m.z=v*n,u.push(m.x,m.y,m.z),d.push(0,y,0),a.x=n*.5+.5,a.y=i*.5*y+.5,f.push(a.x,a.y),p++}for(let e=0;e<r;e++){let t=i+e,r=b+e;n===!0?l.push(r,r+1,t):l.push(r+1,r,t),_+=3}c.addGroup(g,_,n===!0?1:2),g+=_}}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}},ga=class e extends ha{constructor(e=1,t=1,n=32,r=1,i=!1,a=0,o=Math.PI*2){super(0,e,t,n,r,i,a,o),this.type=`ConeGeometry`,this.parameters={radius:e,height:t,radialSegments:n,heightSegments:r,openEnded:i,thetaStart:a,thetaLength:o}}static fromJSON(t){return new e(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}},_a=class{constructor(){this.type=`Curve`,this.arcLengthDivisions=200,this.needsUpdate=!1,this.cacheArcLengths=null}getPoint(){R(`Curve: .getPoint() not implemented.`)}getPointAt(e,t){let n=this.getUtoTmapping(e);return this.getPoint(n,t)}getPoints(e=5){let t=[];for(let n=0;n<=e;n++)t.push(this.getPoint(n/e));return t}getSpacedPoints(e=5){let t=[];for(let n=0;n<=e;n++)t.push(this.getPointAt(n/e));return t}getLength(){let e=this.getLengths();return e[e.length-1]}getLengths(e=this.arcLengthDivisions){if(this.cacheArcLengths&&this.cacheArcLengths.length===e+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;let t=[],n,r=this.getPoint(0),i=0;t.push(0);for(let a=1;a<=e;a++)n=this.getPoint(a/e),i+=n.distanceTo(r),t.push(i),r=n;return this.cacheArcLengths=t,t}updateArcLengths(){this.needsUpdate=!0,this.getLengths()}getUtoTmapping(e,t=null){let n=this.getLengths(),r=0,i=n.length,a;a=t||e*n[i-1];let o=0,s=i-1,c;for(;o<=s;)if(r=Math.floor(o+(s-o)/2),c=n[r]-a,c<0)o=r+1;else if(c>0)s=r-1;else{s=r;break}if(r=s,n[r]===a)return r/(i-1);let l=n[r],u=n[r+1]-l,d=(a-l)/u;return(r+d)/(i-1)}getTangent(e,t){let n=1e-4,r=e-n,i=e+n;r<0&&(r=0),i>1&&(i=1);let a=this.getPoint(r),o=this.getPoint(i),s=t||(a.isVector2?new H:new U);return s.copy(o).sub(a).normalize(),s}getTangentAt(e,t){let n=this.getUtoTmapping(e);return this.getTangent(n,t)}computeFrenetFrames(e,t=!1){let n=new U,r=[],i=[],a=[],o=new U,s=new W;for(let t=0;t<=e;t++){let n=t/e;r[t]=this.getTangentAt(n,new U)}i[0]=new U,a[0]=new U;let c=Number.MAX_VALUE,l=Math.abs(r[0].x),u=Math.abs(r[0].y),d=Math.abs(r[0].z);l<=c&&(c=l,n.set(1,0,0)),u<=c&&(c=u,n.set(0,1,0)),d<=c&&n.set(0,0,1),o.crossVectors(r[0],n).normalize(),i[0].crossVectors(r[0],o),a[0].crossVectors(r[0],i[0]);for(let t=1;t<=e;t++){if(i[t]=i[t-1].clone(),a[t]=a[t-1].clone(),o.crossVectors(r[t-1],r[t]),o.length()>2**-52){o.normalize();let e=Math.acos(B(r[t-1].dot(r[t]),-1,1));i[t].applyMatrix4(s.makeRotationAxis(o,e))}a[t].crossVectors(r[t],i[t])}if(t===!0){let t=Math.acos(B(i[0].dot(i[e]),-1,1));t/=e,r[0].dot(o.crossVectors(i[0],i[e]))>0&&(t=-t);for(let n=1;n<=e;n++)i[n].applyMatrix4(s.makeRotationAxis(r[n],t*n)),a[n].crossVectors(r[n],i[n])}return{tangents:r,normals:i,binormals:a}}clone(){return new this.constructor().copy(this)}copy(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}toJSON(){let e={metadata:{version:4.7,type:`Curve`,generator:`Curve.toJSON`}};return e.arcLengthDivisions=this.arcLengthDivisions,e.type=this.type,e}fromJSON(e){return this.arcLengthDivisions=e.arcLengthDivisions,this}},va=class extends _a{constructor(e=0,t=0,n=1,r=1,i=0,a=Math.PI*2,o=!1,s=0){super(),this.isEllipseCurve=!0,this.type=`EllipseCurve`,this.aX=e,this.aY=t,this.xRadius=n,this.yRadius=r,this.aStartAngle=i,this.aEndAngle=a,this.aClockwise=o,this.aRotation=s}getPoint(e,t=new H){let n=t,r=Math.PI*2,i=this.aEndAngle-this.aStartAngle,a=Math.abs(i)<2**-52;for(;i<0;)i+=r;for(;i>r;)i-=r;i<2**-52&&(i=a?0:r),this.aClockwise===!0&&!a&&(i===r?i=-r:i-=r);let o=this.aStartAngle+e*i,s=this.aX+this.xRadius*Math.cos(o),c=this.aY+this.yRadius*Math.sin(o);if(this.aRotation!==0){let e=Math.cos(this.aRotation),t=Math.sin(this.aRotation),n=s-this.aX,r=c-this.aY;s=n*e-r*t+this.aX,c=n*t+r*e+this.aY}return n.set(s,c)}copy(e){return super.copy(e),this.aX=e.aX,this.aY=e.aY,this.xRadius=e.xRadius,this.yRadius=e.yRadius,this.aStartAngle=e.aStartAngle,this.aEndAngle=e.aEndAngle,this.aClockwise=e.aClockwise,this.aRotation=e.aRotation,this}toJSON(){let e=super.toJSON();return e.aX=this.aX,e.aY=this.aY,e.xRadius=this.xRadius,e.yRadius=this.yRadius,e.aStartAngle=this.aStartAngle,e.aEndAngle=this.aEndAngle,e.aClockwise=this.aClockwise,e.aRotation=this.aRotation,e}fromJSON(e){return super.fromJSON(e),this.aX=e.aX,this.aY=e.aY,this.xRadius=e.xRadius,this.yRadius=e.yRadius,this.aStartAngle=e.aStartAngle,this.aEndAngle=e.aEndAngle,this.aClockwise=e.aClockwise,this.aRotation=e.aRotation,this}},ya=class extends va{constructor(e,t,n,r,i,a){super(e,t,n,n,r,i,a),this.isArcCurve=!0,this.type=`ArcCurve`}};function ba(){let e=0,t=0,n=0,r=0;function i(i,a,o,s){e=i,t=o,n=-3*i+3*a-2*o-s,r=2*i-2*a+o+s}return{initCatmullRom:function(e,t,n,r,a){i(t,n,a*(n-e),a*(r-t))},initNonuniformCatmullRom:function(e,t,n,r,a,o,s){let c=(t-e)/a-(n-e)/(a+o)+(n-t)/o,l=(n-t)/o-(r-t)/(o+s)+(r-n)/s;c*=o,l*=o,i(t,n,c,l)},calc:function(i){let a=i*i,o=a*i;return e+t*i+n*a+r*o}}}var xa=new U,Sa=new U,Ca=new ba,wa=new ba,Ta=new ba,Ea=class extends _a{constructor(e=[],t=!1,n=`centripetal`,r=.5){super(),this.isCatmullRomCurve3=!0,this.type=`CatmullRomCurve3`,this.points=e,this.closed=t,this.curveType=n,this.tension=r}getPoint(e,t=new U){let n=t,r=this.points,i=r.length,a=(i-+!this.closed)*e,o=Math.floor(a),s=a-o;this.closed?o+=o>0?0:(Math.floor(Math.abs(o)/i)+1)*i:s===0&&o===i-1&&(o=i-2,s=1);let c,l;this.closed||o>0?c=r[(o-1)%i]:(Sa.subVectors(r[0],r[1]).add(r[0]),c=Sa);let u=r[o%i],d=r[(o+1)%i];if(this.closed||o+2<i?l=r[(o+2)%i]:(xa.subVectors(r[i-1],r[i-2]).add(r[i-1]),l=xa),this.curveType===`centripetal`||this.curveType===`chordal`){let e=this.curveType===`chordal`?.5:.25,t=c.distanceToSquared(u)**+e,n=u.distanceToSquared(d)**+e,r=d.distanceToSquared(l)**+e;n<1e-4&&(n=1),t<1e-4&&(t=n),r<1e-4&&(r=n),Ca.initNonuniformCatmullRom(c.x,u.x,d.x,l.x,t,n,r),wa.initNonuniformCatmullRom(c.y,u.y,d.y,l.y,t,n,r),Ta.initNonuniformCatmullRom(c.z,u.z,d.z,l.z,t,n,r)}else this.curveType===`catmullrom`&&(Ca.initCatmullRom(c.x,u.x,d.x,l.x,this.tension),wa.initCatmullRom(c.y,u.y,d.y,l.y,this.tension),Ta.initCatmullRom(c.z,u.z,d.z,l.z,this.tension));return n.set(Ca.calc(s),wa.calc(s),Ta.calc(s)),n}copy(e){super.copy(e),this.points=[];for(let t=0,n=e.points.length;t<n;t++){let n=e.points[t];this.points.push(n.clone())}return this.closed=e.closed,this.curveType=e.curveType,this.tension=e.tension,this}toJSON(){let e=super.toJSON();e.points=[];for(let t=0,n=this.points.length;t<n;t++){let n=this.points[t];e.points.push(n.toArray())}return e.closed=this.closed,e.curveType=this.curveType,e.tension=this.tension,e}fromJSON(e){super.fromJSON(e),this.points=[];for(let t=0,n=e.points.length;t<n;t++){let n=e.points[t];this.points.push(new U().fromArray(n))}return this.closed=e.closed,this.curveType=e.curveType,this.tension=e.tension,this}};function Da(e,t,n,r,i){let a=(r-t)*.5,o=(i-n)*.5,s=e*e,c=e*s;return(2*n-2*r+a+o)*c+(-3*n+3*r-2*a-o)*s+a*e+n}function Oa(e,t){let n=1-e;return n*n*t}function ka(e,t){return 2*(1-e)*e*t}function Aa(e,t){return e*e*t}function ja(e,t,n,r){return Oa(e,t)+ka(e,n)+Aa(e,r)}function Ma(e,t){let n=1-e;return n*n*n*t}function Na(e,t){let n=1-e;return 3*n*n*e*t}function Pa(e,t){return 3*(1-e)*e*e*t}function Fa(e,t){return e*e*e*t}function Ia(e,t,n,r,i){return Ma(e,t)+Na(e,n)+Pa(e,r)+Fa(e,i)}var La=class extends _a{constructor(e=new H,t=new H,n=new H,r=new H){super(),this.isCubicBezierCurve=!0,this.type=`CubicBezierCurve`,this.v0=e,this.v1=t,this.v2=n,this.v3=r}getPoint(e,t=new H){let n=t,r=this.v0,i=this.v1,a=this.v2,o=this.v3;return n.set(Ia(e,r.x,i.x,a.x,o.x),Ia(e,r.y,i.y,a.y,o.y)),n}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this.v3.copy(e.v3),this}toJSON(){let e=super.toJSON();return e.v0=this.v0.toArray(),e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e.v3=this.v3.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v0.fromArray(e.v0),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this.v3.fromArray(e.v3),this}},Ra=class extends _a{constructor(e=new U,t=new U,n=new U,r=new U){super(),this.isCubicBezierCurve3=!0,this.type=`CubicBezierCurve3`,this.v0=e,this.v1=t,this.v2=n,this.v3=r}getPoint(e,t=new U){let n=t,r=this.v0,i=this.v1,a=this.v2,o=this.v3;return n.set(Ia(e,r.x,i.x,a.x,o.x),Ia(e,r.y,i.y,a.y,o.y),Ia(e,r.z,i.z,a.z,o.z)),n}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this.v3.copy(e.v3),this}toJSON(){let e=super.toJSON();return e.v0=this.v0.toArray(),e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e.v3=this.v3.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v0.fromArray(e.v0),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this.v3.fromArray(e.v3),this}},za=class extends _a{constructor(e=new H,t=new H){super(),this.isLineCurve=!0,this.type=`LineCurve`,this.v1=e,this.v2=t}getPoint(e,t=new H){let n=t;return e===1?n.copy(this.v2):(n.copy(this.v2).sub(this.v1),n.multiplyScalar(e).add(this.v1)),n}getPointAt(e,t){return this.getPoint(e,t)}getTangent(e,t=new H){return t.subVectors(this.v2,this.v1).normalize()}getTangentAt(e,t){return this.getTangent(e,t)}copy(e){return super.copy(e),this.v1.copy(e.v1),this.v2.copy(e.v2),this}toJSON(){let e=super.toJSON();return e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this}},Ba=class extends _a{constructor(e=new U,t=new U){super(),this.isLineCurve3=!0,this.type=`LineCurve3`,this.v1=e,this.v2=t}getPoint(e,t=new U){let n=t;return e===1?n.copy(this.v2):(n.copy(this.v2).sub(this.v1),n.multiplyScalar(e).add(this.v1)),n}getPointAt(e,t){return this.getPoint(e,t)}getTangent(e,t=new U){return t.subVectors(this.v2,this.v1).normalize()}getTangentAt(e,t){return this.getTangent(e,t)}copy(e){return super.copy(e),this.v1.copy(e.v1),this.v2.copy(e.v2),this}toJSON(){let e=super.toJSON();return e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this}},Va=class extends _a{constructor(e=new H,t=new H,n=new H){super(),this.isQuadraticBezierCurve=!0,this.type=`QuadraticBezierCurve`,this.v0=e,this.v1=t,this.v2=n}getPoint(e,t=new H){let n=t,r=this.v0,i=this.v1,a=this.v2;return n.set(ja(e,r.x,i.x,a.x),ja(e,r.y,i.y,a.y)),n}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this}toJSON(){let e=super.toJSON();return e.v0=this.v0.toArray(),e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v0.fromArray(e.v0),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this}},Ha=class extends _a{constructor(e=new U,t=new U,n=new U){super(),this.isQuadraticBezierCurve3=!0,this.type=`QuadraticBezierCurve3`,this.v0=e,this.v1=t,this.v2=n}getPoint(e,t=new U){let n=t,r=this.v0,i=this.v1,a=this.v2;return n.set(ja(e,r.x,i.x,a.x),ja(e,r.y,i.y,a.y),ja(e,r.z,i.z,a.z)),n}copy(e){return super.copy(e),this.v0.copy(e.v0),this.v1.copy(e.v1),this.v2.copy(e.v2),this}toJSON(){let e=super.toJSON();return e.v0=this.v0.toArray(),e.v1=this.v1.toArray(),e.v2=this.v2.toArray(),e}fromJSON(e){return super.fromJSON(e),this.v0.fromArray(e.v0),this.v1.fromArray(e.v1),this.v2.fromArray(e.v2),this}},Ua=class extends _a{constructor(e=[]){super(),this.isSplineCurve=!0,this.type=`SplineCurve`,this.points=e}getPoint(e,t=new H){let n=t,r=this.points,i=(r.length-1)*e,a=Math.floor(i),o=i-a,s=r[a===0?a:a-1],c=r[a],l=r[a>r.length-2?r.length-1:a+1],u=r[a>r.length-3?r.length-1:a+2];return n.set(Da(o,s.x,c.x,l.x,u.x),Da(o,s.y,c.y,l.y,u.y)),n}copy(e){super.copy(e),this.points=[];for(let t=0,n=e.points.length;t<n;t++){let n=e.points[t];this.points.push(n.clone())}return this}toJSON(){let e=super.toJSON();e.points=[];for(let t=0,n=this.points.length;t<n;t++){let n=this.points[t];e.points.push(n.toArray())}return e}fromJSON(e){super.fromJSON(e),this.points=[];for(let t=0,n=e.points.length;t<n;t++){let n=e.points[t];this.points.push(new H().fromArray(n))}return this}},Wa=Object.freeze({__proto__:null,ArcCurve:ya,CatmullRomCurve3:Ea,CubicBezierCurve:La,CubicBezierCurve3:Ra,EllipseCurve:va,LineCurve:za,LineCurve3:Ba,QuadraticBezierCurve:Va,QuadraticBezierCurve3:Ha,SplineCurve:Ua}),Ga=class extends _a{constructor(){super(),this.type=`CurvePath`,this.curves=[],this.autoClose=!1}add(e){this.curves.push(e)}closePath(){let e=this.curves[0].getPoint(0),t=this.curves[this.curves.length-1].getPoint(1);if(!e.equals(t)){let n=e.isVector2===!0?`LineCurve`:`LineCurve3`;this.curves.push(new Wa[n](t,e))}return this}getPoint(e,t){let n=e*this.getLength(),r=this.getCurveLengths(),i=0;for(;i<r.length;){if(r[i]>=n){let e=r[i]-n,a=this.curves[i],o=a.getLength(),s=o===0?0:1-e/o;return a.getPointAt(s,t)}i++}return null}getLength(){let e=this.getCurveLengths();return e[e.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;let e=[],t=0;for(let n=0,r=this.curves.length;n<r;n++)t+=this.curves[n].getLength(),e.push(t);return this.cacheLengths=e,e}getSpacedPoints(e=40){let t=[];for(let n=0;n<=e;n++)t.push(this.getPoint(n/e));return this.autoClose&&t.push(t[0]),t}getPoints(e=12){let t=[],n;for(let r=0,i=this.curves;r<i.length;r++){let a=i[r],o=a.isEllipseCurve?e*2:a.isLineCurve||a.isLineCurve3?1:a.isSplineCurve?e*a.points.length:e,s=a.getPoints(o);for(let e=0;e<s.length;e++){let r=s[e];n&&n.equals(r)||(t.push(r),n=r)}}return this.autoClose&&t.length>1&&!t[t.length-1].equals(t[0])&&t.push(t[0]),t}copy(e){super.copy(e),this.curves=[];for(let t=0,n=e.curves.length;t<n;t++){let n=e.curves[t];this.curves.push(n.clone())}return this.autoClose=e.autoClose,this}toJSON(){let e=super.toJSON();e.autoClose=this.autoClose,e.curves=[];for(let t=0,n=this.curves.length;t<n;t++){let n=this.curves[t];e.curves.push(n.toJSON())}return e}fromJSON(e){super.fromJSON(e),this.autoClose=e.autoClose,this.curves=[];for(let t=0,n=e.curves.length;t<n;t++){let n=e.curves[t];this.curves.push(new Wa[n.type]().fromJSON(n))}return this}},Ka=class extends Ga{constructor(e){super(),this.type=`Path`,this.currentPoint=new H,e&&this.setFromPoints(e)}setFromPoints(e){this.moveTo(e[0].x,e[0].y);for(let t=1,n=e.length;t<n;t++)this.lineTo(e[t].x,e[t].y);return this}moveTo(e,t){return this.currentPoint.set(e,t),this}lineTo(e,t){let n=new za(this.currentPoint.clone(),new H(e,t));return this.curves.push(n),this.currentPoint.set(e,t),this}quadraticCurveTo(e,t,n,r){let i=new Va(this.currentPoint.clone(),new H(e,t),new H(n,r));return this.curves.push(i),this.currentPoint.set(n,r),this}bezierCurveTo(e,t,n,r,i,a){let o=new La(this.currentPoint.clone(),new H(e,t),new H(n,r),new H(i,a));return this.curves.push(o),this.currentPoint.set(i,a),this}splineThru(e){let t=new Ua([this.currentPoint.clone()].concat(e));return this.curves.push(t),this.currentPoint.copy(e[e.length-1]),this}arc(e,t,n,r,i,a){let o=this.currentPoint.x,s=this.currentPoint.y;return this.absarc(e+o,t+s,n,r,i,a),this}absarc(e,t,n,r,i,a){return this.absellipse(e,t,n,n,r,i,a),this}ellipse(e,t,n,r,i,a,o,s){let c=this.currentPoint.x,l=this.currentPoint.y;return this.absellipse(e+c,t+l,n,r,i,a,o,s),this}absellipse(e,t,n,r,i,a,o,s){let c=new va(e,t,n,r,i,a,o,s);if(this.curves.length>0){let e=c.getPoint(0);e.equals(this.currentPoint)||this.lineTo(e.x,e.y)}this.curves.push(c);let l=c.getPoint(1);return this.currentPoint.copy(l),this}copy(e){return super.copy(e),this.currentPoint.copy(e.currentPoint),this}toJSON(){let e=super.toJSON();return e.currentPoint=this.currentPoint.toArray(),e}fromJSON(e){return super.fromJSON(e),this.currentPoint.fromArray(e.currentPoint),this}},qa=class extends Ka{constructor(e){super(e),this.uuid=ht(),this.type=`Shape`,this.holes=[]}getPointsHoles(e){let t=[];for(let n=0,r=this.holes.length;n<r;n++)t[n]=this.holes[n].getPoints(e);return t}extractPoints(e){return{shape:this.getPoints(e),holes:this.getPointsHoles(e)}}copy(e){super.copy(e),this.holes=[];for(let t=0,n=e.holes.length;t<n;t++){let n=e.holes[t];this.holes.push(n.clone())}return this}toJSON(){let e=super.toJSON();e.uuid=this.uuid,e.holes=[];for(let t=0,n=this.holes.length;t<n;t++){let n=this.holes[t];e.holes.push(n.toJSON())}return e}fromJSON(e){super.fromJSON(e),this.uuid=e.uuid,this.holes=[];for(let t=0,n=e.holes.length;t<n;t++){let n=e.holes[t];this.holes.push(new Ka().fromJSON(n))}return this}};function Ja(e,t,n=2){let r=t&&t.length,i=r?t[0]*n:e.length,a=Ya(e,0,i,n,!0),o=[];if(!a||a.next===a.prev)return o;let s,c,l;if(r&&(a=no(e,t,a,n)),e.length>80*n){s=e[0],c=e[1];let t=s,r=c;for(let a=n;a<i;a+=n){let n=e[a],i=e[a+1];n<s&&(s=n),i<c&&(c=i),n>t&&(t=n),i>r&&(r=i)}l=Math.max(t-s,r-c),l=l===0?0:32767/l}return Za(a,o,n,s,c,l,0),o}function Ya(e,t,n,r,i){let a;if(i===Eo(e,t,n,r)>0)for(let i=t;i<n;i+=r)a=Co(i/r|0,e[i],e[i+1],a);else for(let i=n-r;i>=t;i-=r)a=Co(i/r|0,e[i],e[i+1],a);return a&&ho(a,a.next)&&(wo(a),a=a.next),a}function Xa(e,t){if(!e)return e;t||(t=e);let n=e,r;do if(r=!1,!n.steiner&&(ho(n,n.next)||X(n.prev,n,n.next)===0)){if(wo(n),n=t=n.prev,n===n.next)break;r=!0}else n=n.next;while(r||n!==t);return t}function Za(e,t,n,r,i,a,o){if(!e)return;!o&&a&&so(e,r,i,a);let s=e;for(;e.prev!==e.next;){let c=e.prev,l=e.next;if(a?$a(e,r,i,a):Qa(e))t.push(c.i,e.i,l.i),wo(e),e=l.next,s=l.next;else if(e=l,e===s){o?o===1?(e=eo(Xa(e),t),Za(e,t,n,r,i,a,2)):o===2&&to(e,t,n,r,i,a):Za(Xa(e),t,n,r,i,a,1);break}}}function Qa(e){let t=e.prev,n=e,r=e.next;if(X(t,n,r)>=0)return!1;let i=t.x,a=n.x,o=r.x,s=t.y,c=n.y,l=r.y,u=Math.min(i,a,o),d=Math.min(s,c,l),f=Math.max(i,a,o),p=Math.max(s,c,l),m=r.next;for(;m!==t;){if(m.x>=u&&m.x<=f&&m.y>=d&&m.y<=p&&po(i,s,a,c,o,l,m.x,m.y)&&X(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function $a(e,t,n,r){let i=e.prev,a=e,o=e.next;if(X(i,a,o)>=0)return!1;let s=i.x,c=a.x,l=o.x,u=i.y,d=a.y,f=o.y,p=Math.min(s,c,l),m=Math.min(u,d,f),h=Math.max(s,c,l),g=Math.max(u,d,f),_=lo(p,m,t,n,r),v=lo(h,g,t,n,r),y=e.prevZ,b=e.nextZ;for(;y&&y.z>=_&&b&&b.z<=v;){if(y.x>=p&&y.x<=h&&y.y>=m&&y.y<=g&&y!==i&&y!==o&&po(s,u,c,d,l,f,y.x,y.y)&&X(y.prev,y,y.next)>=0||(y=y.prevZ,b.x>=p&&b.x<=h&&b.y>=m&&b.y<=g&&b!==i&&b!==o&&po(s,u,c,d,l,f,b.x,b.y)&&X(b.prev,b,b.next)>=0))return!1;b=b.nextZ}for(;y&&y.z>=_;){if(y.x>=p&&y.x<=h&&y.y>=m&&y.y<=g&&y!==i&&y!==o&&po(s,u,c,d,l,f,y.x,y.y)&&X(y.prev,y,y.next)>=0)return!1;y=y.prevZ}for(;b&&b.z<=v;){if(b.x>=p&&b.x<=h&&b.y>=m&&b.y<=g&&b!==i&&b!==o&&po(s,u,c,d,l,f,b.x,b.y)&&X(b.prev,b,b.next)>=0)return!1;b=b.nextZ}return!0}function eo(e,t){let n=e;do{let r=n.prev,i=n.next.next;!ho(r,i)&&go(r,n,n.next,i)&&bo(r,i)&&bo(i,r)&&(t.push(r.i,n.i,i.i),wo(n),wo(n.next),n=e=i),n=n.next}while(n!==e);return Xa(n)}function to(e,t,n,r,i,a){let o=e;do{let e=o.next.next;for(;e!==o.prev;){if(o.i!==e.i&&mo(o,e)){let s=So(o,e);o=Xa(o,o.next),s=Xa(s,s.next),Za(o,t,n,r,i,a,0),Za(s,t,n,r,i,a,0);return}e=e.next}o=o.next}while(o!==e)}function no(e,t,n,r){let i=[];for(let n=0,a=t.length;n<a;n++){let o=Ya(e,t[n]*r,n<a-1?t[n+1]*r:e.length,r,!1);o===o.next&&(o.steiner=!0),i.push(uo(o))}i.sort(ro);for(let e=0;e<i.length;e++)n=io(i[e],n);return n}function ro(e,t){let n=e.x-t.x;return n===0&&(n=e.y-t.y,n===0&&(n=(e.next.y-e.y)/(e.next.x-e.x)-(t.next.y-t.y)/(t.next.x-t.x))),n}function io(e,t){let n=ao(e,t);if(!n)return t;let r=So(n,e);return Xa(r,r.next),Xa(n,n.next)}function ao(e,t){let n=t,r=e.x,i=e.y,a=-1/0,o;if(ho(e,n))return n;do{if(ho(e,n.next))return n.next;if(i<=n.y&&i>=n.next.y&&n.next.y!==n.y){let e=n.x+(i-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(e<=r&&e>a&&(a=e,o=n.x<n.next.x?n:n.next,e===r))return o}n=n.next}while(n!==t);if(!o)return null;let s=o,c=o.x,l=o.y,u=1/0;n=o;do{if(r>=n.x&&n.x>=c&&r!==n.x&&fo(i<l?r:a,i,c,l,i<l?a:r,i,n.x,n.y)){let t=Math.abs(i-n.y)/(r-n.x);bo(n,e)&&(t<u||t===u&&(n.x>o.x||n.x===o.x&&oo(o,n)))&&(o=n,u=t)}n=n.next}while(n!==s);return o}function oo(e,t){return X(e.prev,e,t.prev)<0&&X(t.next,e,e.next)<0}function so(e,t,n,r){let i=e;do i.z===0&&(i.z=lo(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,co(i)}function co(e){let t,n=1;do{let r=e,i;e=null;let a=null;for(t=0;r;){t++;let o=r,s=0;for(let e=0;e<n&&(s++,o=o.nextZ,o);e++);let c=n;for(;s>0||c>0&&o;)s!==0&&(c===0||!o||r.z<=o.z)?(i=r,r=r.nextZ,s--):(i=o,o=o.nextZ,c--),a?a.nextZ=i:e=i,i.prevZ=a,a=i;r=o}a.nextZ=null,n*=2}while(t>1);return e}function lo(e,t,n,r,i){return e=(e-n)*i|0,t=(t-r)*i|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,t=(t|t<<8)&16711935,t=(t|t<<4)&252645135,t=(t|t<<2)&858993459,t=(t|t<<1)&1431655765,e|t<<1}function uo(e){let t=e,n=e;do(t.x<n.x||t.x===n.x&&t.y<n.y)&&(n=t),t=t.next;while(t!==e);return n}function fo(e,t,n,r,i,a,o,s){return(i-o)*(t-s)>=(e-o)*(a-s)&&(e-o)*(r-s)>=(n-o)*(t-s)&&(n-o)*(a-s)>=(i-o)*(r-s)}function po(e,t,n,r,i,a,o,s){return(e!==o||t!==s)&&fo(e,t,n,r,i,a,o,s)}function mo(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!yo(e,t)&&(bo(e,t)&&bo(t,e)&&xo(e,t)&&(X(e.prev,e,t.prev)||X(e,t.prev,t))||ho(e,t)&&X(e.prev,e,e.next)>0&&X(t.prev,t,t.next)>0)}function X(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function ho(e,t){return e.x===t.x&&e.y===t.y}function go(e,t,n,r){let i=vo(X(e,t,n)),a=vo(X(e,t,r)),o=vo(X(n,r,e)),s=vo(X(n,r,t));return!!(i!==a&&o!==s||i===0&&_o(e,n,t)||a===0&&_o(e,r,t)||o===0&&_o(n,e,r)||s===0&&_o(n,t,r))}function _o(e,t,n){return t.x<=Math.max(e.x,n.x)&&t.x>=Math.min(e.x,n.x)&&t.y<=Math.max(e.y,n.y)&&t.y>=Math.min(e.y,n.y)}function vo(e){return e>0?1:e<0?-1:0}function yo(e,t){let n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&go(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function bo(e,t){return X(e.prev,e,e.next)<0?X(e,t,e.next)>=0&&X(e,e.prev,t)>=0:X(e,t,e.prev)<0||X(e,e.next,t)<0}function xo(e,t){let n=e,r=!1,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do n.y>a!=n.next.y>a&&n.next.y!==n.y&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next;while(n!==e);return r}function So(e,t){let n=To(e.i,e.x,e.y),r=To(t.i,t.x,t.y),i=e.next,a=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,a.next=r,r.prev=a,r}function Co(e,t,n,r){let i=To(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function wo(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function To(e,t,n){return{i:e,x:t,y:n,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}function Eo(e,t,n,r){let i=0;for(let a=t,o=n-r;a<n;a+=r)i+=(e[o]-e[a])*(e[a+1]+e[o+1]),o=a;return i}var Do=class{static triangulate(e,t,n=2){return Ja(e,t,n)}},Oo=class e{static area(e){let t=e.length,n=0;for(let r=t-1,i=0;i<t;r=i++)n+=e[r].x*e[i].y-e[i].x*e[r].y;return n*.5}static isClockWise(t){return e.area(t)<0}static triangulateShape(e,t){let n=[],r=[],i=[];ko(e),Ao(n,e);let a=e.length;t.forEach(ko);for(let e=0;e<t.length;e++)r.push(a),a+=t[e].length,Ao(n,t[e]);let o=Do.triangulate(n,r);for(let e=0;e<o.length;e+=3)i.push(o.slice(e,e+3));return i}};function ko(e){let t=e.length;t>2&&e[t-1].equals(e[0])&&e.pop()}function Ao(e,t){for(let n=0;n<t.length;n++)e.push(t[n].x),e.push(t[n].y)}var jo=class e extends J{constructor(e=new qa([new H(.5,.5),new H(-.5,.5),new H(-.5,-.5),new H(.5,-.5)]),t={}){super(),this.type=`ExtrudeGeometry`,this.parameters={shapes:e,options:t},e=Array.isArray(e)?e:[e];let n=this,r=[],i=[];for(let t=0,n=e.length;t<n;t++){let n=e[t];a(n)}this.setAttribute(`position`,new q(r,3)),this.setAttribute(`uv`,new q(i,2)),this.computeVertexNormals();function a(e){let a=[],o=t.curveSegments===void 0?12:t.curveSegments,s=t.steps===void 0?1:t.steps,c=t.depth===void 0?1:t.depth,l=t.bevelEnabled===void 0||t.bevelEnabled,u=t.bevelThickness===void 0?.2:t.bevelThickness,d=t.bevelSize===void 0?u-.1:t.bevelSize,f=t.bevelOffset===void 0?0:t.bevelOffset,p=t.bevelSegments===void 0?3:t.bevelSegments,m=t.extrudePath,h=t.UVGenerator===void 0?Mo:t.UVGenerator,g,_=!1,v,y,b,x;if(m){g=m.getSpacedPoints(s),_=!0,l=!1;let e=m.isCatmullRomCurve3?m.closed:!1;v=m.computeFrenetFrames(s,e),y=new U,b=new U,x=new U}l||(p=0,u=0,d=0,f=0);let S=e.extractPoints(o),C=S.shape,w=S.holes;if(!Oo.isClockWise(C)){C=C.reverse();for(let e=0,t=w.length;e<t;e++){let t=w[e];Oo.isClockWise(t)&&(w[e]=t.reverse())}}function T(e){let t=e[0];for(let n=1;n<=e.length;n++){let r=n%e.length,i=e[r],a=i.x-t.x,o=i.y-t.y,s=a*a+o*o,c=Math.max(Math.abs(i.x),Math.abs(i.y),Math.abs(t.x),Math.abs(t.y));s<=10000000000000001e-36*c*c?(e.splice(r,1),n--):t=i}}T(C),w.forEach(T);let E=w.length,D=C;for(let e=0;e<E;e++){let t=w[e];C=C.concat(t)}function O(e,t,n){return t||z(`ExtrudeGeometry: vec does not exist`),e.clone().addScaledVector(t,n)}let k=C.length;function A(e,t,n){let r,i,a,o=e.x-t.x,s=e.y-t.y,c=n.x-e.x,l=n.y-e.y,u=o*o+s*s,d=o*l-s*c;if(Math.abs(d)>2**-52){let d=Math.sqrt(u),f=Math.sqrt(c*c+l*l),p=t.x-s/d,m=t.y+o/d,h=n.x-l/f,g=n.y+c/f,_=((h-p)*l-(g-m)*c)/(o*l-s*c);r=p+o*_-e.x,i=m+s*_-e.y;let v=r*r+i*i;if(v<=2)return new H(r,i);a=Math.sqrt(v/2)}else{let e=!1;o>2**-52?c>2**-52&&(e=!0):o<-(2**-52)?c<-(2**-52)&&(e=!0):Math.sign(s)===Math.sign(l)&&(e=!0),e?(r=-s,i=o,a=Math.sqrt(u)):(r=o,i=s,a=Math.sqrt(u/2))}return new H(r/a,i/a)}let j=[];for(let e=0,t=D.length,n=t-1,r=e+1;e<t;e++,n++,r++)n===t&&(n=0),r===t&&(r=0),j[e]=A(D[e],D[n],D[r]);let M=[],N,P=j.concat();for(let e=0,t=E;e<t;e++){let t=w[e];N=[];for(let e=0,n=t.length,r=n-1,i=e+1;e<n;e++,r++,i++)r===n&&(r=0),i===n&&(i=0),N[e]=A(t[e],t[r],t[i]);M.push(N),P=P.concat(N)}let ee;if(p===0)ee=Oo.triangulateShape(D,w);else{let e=[],t=[];for(let n=0;n<p;n++){let r=n/p,i=u*Math.cos(r*Math.PI/2),a=d*Math.sin(r*Math.PI/2)+f;for(let t=0,n=D.length;t<n;t++){let n=O(D[t],j[t],a);ae(n.x,n.y,-i),r===0&&e.push(n)}for(let e=0,n=E;e<n;e++){let n=w[e];N=M[e];let o=[];for(let e=0,t=n.length;e<t;e++){let t=O(n[e],N[e],a);ae(t.x,t.y,-i),r===0&&o.push(t)}r===0&&t.push(o)}}ee=Oo.triangulateShape(e,t)}let F=ee.length,te=d+f;for(let e=0;e<k;e++){let t=l?O(C[e],P[e],te):C[e];_?(b.copy(v.normals[0]).multiplyScalar(t.x),y.copy(v.binormals[0]).multiplyScalar(t.y),x.copy(g[0]).add(b).add(y),ae(x.x,x.y,x.z)):ae(t.x,t.y,0)}for(let e=1;e<=s;e++)for(let t=0;t<k;t++){let n=l?O(C[t],P[t],te):C[t];_?(b.copy(v.normals[e]).multiplyScalar(n.x),y.copy(v.binormals[e]).multiplyScalar(n.y),x.copy(g[e]).add(b).add(y),ae(x.x,x.y,x.z)):ae(n.x,n.y,c/s*e)}for(let e=p-1;e>=0;e--){let t=e/p,n=u*Math.cos(t*Math.PI/2),r=d*Math.sin(t*Math.PI/2)+f;for(let e=0,t=D.length;e<t;e++){let t=O(D[e],j[e],r);ae(t.x,t.y,c+n)}for(let e=0,t=w.length;e<t;e++){let t=w[e];N=M[e];for(let e=0,i=t.length;e<i;e++){let i=O(t[e],N[e],r);_?ae(i.x,i.y+g[s-1].y,g[s-1].x+n):ae(i.x,i.y,c+n)}}}ne(),re();function ne(){let e=r.length/3;if(l){let e=0,t=k*e;for(let e=0;e<F;e++){let n=ee[e];oe(n[2]+t,n[1]+t,n[0]+t)}e=s+p*2,t=k*e;for(let e=0;e<F;e++){let n=ee[e];oe(n[0]+t,n[1]+t,n[2]+t)}}else{for(let e=0;e<F;e++){let t=ee[e];oe(t[2],t[1],t[0])}for(let e=0;e<F;e++){let t=ee[e];oe(t[0]+k*s,t[1]+k*s,t[2]+k*s)}}n.addGroup(e,r.length/3-e,0)}function re(){let e=r.length/3,t=0;ie(D,t),t+=D.length;for(let e=0,n=w.length;e<n;e++){let n=w[e];ie(n,t),t+=n.length}n.addGroup(e,r.length/3-e,1)}function ie(e,t){let n=e.length;for(;--n>=0;){let r=n,i=n-1;i<0&&(i=e.length-1);for(let e=0,n=s+p*2;e<n;e++){let n=k*e,a=k*(e+1);se(t+r+n,t+i+n,t+i+a,t+r+a)}}}function ae(e,t,n){a.push(e),a.push(t),a.push(n)}function oe(e,t,i){ce(e),ce(t),ce(i);let a=r.length/3,o=h.generateTopUV(n,r,a-3,a-2,a-1);le(o[0]),le(o[1]),le(o[2])}function se(e,t,i,a){ce(e),ce(t),ce(a),ce(t),ce(i),ce(a);let o=r.length/3,s=h.generateSideWallUV(n,r,o-6,o-3,o-2,o-1);le(s[0]),le(s[1]),le(s[3]),le(s[1]),le(s[2]),le(s[3])}function ce(e){r.push(a[e*3+0]),r.push(a[e*3+1]),r.push(a[e*3+2])}function le(e){i.push(e.x),i.push(e.y)}}}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}toJSON(){let e=super.toJSON(),t=this.parameters.shapes,n=this.parameters.options;return No(t,n,e)}static fromJSON(t,n){let r=[];for(let e=0,i=t.shapes.length;e<i;e++){let i=n[t.shapes[e]];r.push(i)}let i=t.options.extrudePath;return i!==void 0&&(t.options.extrudePath=new Wa[i.type]().fromJSON(i)),new e(r,t.options)}},Mo={generateTopUV:function(e,t,n,r,i){let a=t[n*3],o=t[n*3+1],s=t[r*3],c=t[r*3+1],l=t[i*3],u=t[i*3+1];return[new H(a,o),new H(s,c),new H(l,u)]},generateSideWallUV:function(e,t,n,r,i,a){let o=t[n*3],s=t[n*3+1],c=t[n*3+2],l=t[r*3],u=t[r*3+1],d=t[r*3+2],f=t[i*3],p=t[i*3+1],m=t[i*3+2],h=t[a*3],g=t[a*3+1],_=t[a*3+2];return Math.abs(s-u)<Math.abs(o-l)?[new H(o,1-c),new H(l,1-d),new H(f,1-m),new H(h,1-_)]:[new H(s,1-c),new H(u,1-d),new H(p,1-m),new H(g,1-_)]}};function No(e,t,n){if(n.shapes=[],Array.isArray(e))for(let t=0,r=e.length;t<r;t++){let r=e[t];n.shapes.push(r.uuid)}else n.shapes.push(e.uuid);return n.options=Object.assign({},t),t.extrudePath!==void 0&&(n.options.extrudePath=t.extrudePath.toJSON()),n}var Po=class e extends J{constructor(e=[new H(0,-.5),new H(.5,0),new H(0,.5)],t=12,n=0,r=Math.PI*2){super(),this.type=`LatheGeometry`,this.parameters={points:e,segments:t,phiStart:n,phiLength:r},t=Math.floor(t),r=B(r,0,Math.PI*2);let i=[],a=[],o=[],s=[],c=[],l=1/t,u=new U,d=new H,f=new U,p=new U,m=new U,h=0,g=0;for(let t=0;t<=e.length-1;t++)switch(t){case 0:h=e[t+1].x-e[t].x,g=e[t+1].y-e[t].y,f.x=g*1,f.y=-h,f.z=g*0,m.copy(f),f.normalize(),s.push(f.x,f.y,f.z);break;case e.length-1:s.push(m.x,m.y,m.z);break;default:h=e[t+1].x-e[t].x,g=e[t+1].y-e[t].y,f.x=g*1,f.y=-h,f.z=g*0,p.copy(f),f.x+=m.x,f.y+=m.y,f.z+=m.z,f.normalize(),s.push(f.x,f.y,f.z),m.copy(p)}for(let i=0;i<=t;i++){let f=n+i*l*r,p=Math.sin(f),m=Math.cos(f);for(let n=0;n<=e.length-1;n++){u.x=e[n].x*p,u.y=e[n].y,u.z=e[n].x*m,a.push(u.x,u.y,u.z),d.x=i/t,d.y=n/(e.length-1),o.push(d.x,d.y);let r=s[3*n+0]*p,l=s[3*n+1],f=s[3*n+0]*m;c.push(r,l,f)}}for(let n=0;n<t;n++)for(let t=0;t<e.length-1;t++){let r=t+n*e.length,a=r,o=r+e.length,s=r+e.length+1,c=r+1;i.push(a,o,c),i.push(s,c,o)}this.setIndex(i),this.setAttribute(`position`,new q(a,3)),this.setAttribute(`uv`,new q(o,2)),this.setAttribute(`normal`,new q(c,3))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.points,t.segments,t.phiStart,t.phiLength)}},Fo=class e extends J{constructor(e=1,t=1,n=1,r=1){super(),this.type=`PlaneGeometry`,this.parameters={width:e,height:t,widthSegments:n,heightSegments:r};let i=e/2,a=t/2,o=Math.floor(n),s=Math.floor(r),c=o+1,l=s+1,u=e/o,d=t/s,f=[],p=[],m=[],h=[];for(let e=0;e<l;e++){let t=e*d-a;for(let n=0;n<c;n++){let r=n*u-i;p.push(r,-t,0),m.push(0,0,1),h.push(n/o),h.push(1-e/s)}}for(let e=0;e<s;e++)for(let t=0;t<o;t++){let n=t+c*e,r=t+c*(e+1),i=t+1+c*(e+1),a=t+1+c*e;f.push(n,r,a),f.push(r,i,a)}this.setIndex(f),this.setAttribute(`position`,new q(p,3)),this.setAttribute(`normal`,new q(m,3)),this.setAttribute(`uv`,new q(h,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.width,t.height,t.widthSegments,t.heightSegments)}},Io=class e extends J{constructor(e=.5,t=1,n=32,r=1,i=0,a=Math.PI*2){super(),this.type=`RingGeometry`,this.parameters={innerRadius:e,outerRadius:t,thetaSegments:n,phiSegments:r,thetaStart:i,thetaLength:a},n=Math.max(3,n),r=Math.max(1,r);let o=[],s=[],c=[],l=[],u=e,d=(t-e)/r,f=new U,p=new H;for(let e=0;e<=r;e++){for(let e=0;e<=n;e++){let r=i+e/n*a;f.x=u*Math.cos(r),f.y=u*Math.sin(r),s.push(f.x,f.y,f.z),c.push(0,0,1),p.x=(f.x/t+1)/2,p.y=(f.y/t+1)/2,l.push(p.x,p.y)}u+=d}for(let e=0;e<r;e++){let t=e*(n+1);for(let e=0;e<n;e++){let r=e+t,i=r,a=r+n+1,s=r+n+2,c=r+1;o.push(i,a,c),o.push(a,s,c)}}this.setIndex(o),this.setAttribute(`position`,new q(s,3)),this.setAttribute(`normal`,new q(c,3)),this.setAttribute(`uv`,new q(l,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.innerRadius,t.outerRadius,t.thetaSegments,t.phiSegments,t.thetaStart,t.thetaLength)}},Lo=class e extends J{constructor(e=1,t=32,n=16,r=0,i=Math.PI*2,a=0,o=Math.PI){super(),this.type=`SphereGeometry`,this.parameters={radius:e,widthSegments:t,heightSegments:n,phiStart:r,phiLength:i,thetaStart:a,thetaLength:o},t=Math.max(3,Math.floor(t)),n=Math.max(2,Math.floor(n));let s=Math.min(a+o,Math.PI),c=0,l=[],u=new U,d=new U,f=[],p=[],m=[],h=[];for(let f=0;f<=n;f++){let g=[],_=f/n,v=a+_*o,y=e*Math.cos(v),b=Math.sqrt(e*e-y*y),x=0;f===0&&a===0?x=.5/t:f===n&&s===Math.PI&&(x=-.5/t);for(let e=0;e<=t;e++){let n=e/t,a=r+n*i;u.x=-b*Math.cos(a),u.y=y,u.z=b*Math.sin(a),p.push(u.x,u.y,u.z),d.copy(u).normalize(),m.push(d.x,d.y,d.z),h.push(n+x,1-_),g.push(c++)}l.push(g)}for(let e=0;e<n;e++)for(let r=0;r<t;r++){let t=l[e][r+1],i=l[e][r],o=l[e+1][r],c=l[e+1][r+1];(e!==0||a>0)&&f.push(t,i,c),(e!==n-1||s<Math.PI)&&f.push(i,o,c)}this.setIndex(f),this.setAttribute(`position`,new q(p,3)),this.setAttribute(`normal`,new q(m,3)),this.setAttribute(`uv`,new q(h,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.radius,t.widthSegments,t.heightSegments,t.phiStart,t.phiLength,t.thetaStart,t.thetaLength)}},Ro=class e extends J{constructor(e=1,t=.4,n=12,r=48,i=Math.PI*2,a=0,o=Math.PI*2){super(),this.type=`TorusGeometry`,this.parameters={radius:e,tube:t,radialSegments:n,tubularSegments:r,arc:i,thetaStart:a,thetaLength:o},n=Math.floor(n),r=Math.floor(r);let s=[],c=[],l=[],u=[],d=new U,f=new U,p=new U;for(let s=0;s<=n;s++){let m=a+s/n*o;for(let a=0;a<=r;a++){let o=a/r*i;f.x=(e+t*Math.cos(m))*Math.cos(o),f.y=(e+t*Math.cos(m))*Math.sin(o),f.z=t*Math.sin(m),c.push(f.x,f.y,f.z),d.x=e*Math.cos(o),d.y=e*Math.sin(o),p.subVectors(f,d).normalize(),l.push(p.x,p.y,p.z),u.push(a/r),u.push(s/n)}}for(let e=1;e<=n;e++)for(let t=1;t<=r;t++){let n=(r+1)*e+t-1,i=(r+1)*(e-1)+t-1,a=(r+1)*(e-1)+t,o=(r+1)*e+t;s.push(n,i,o),s.push(i,a,o)}this.setIndex(s),this.setAttribute(`position`,new q(c,3)),this.setAttribute(`normal`,new q(l,3)),this.setAttribute(`uv`,new q(u,2))}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}static fromJSON(t){return new e(t.radius,t.tube,t.radialSegments,t.tubularSegments,t.arc,t.thetaStart,t.thetaLength)}},zo=class e extends J{constructor(e=new Ha(new U(-1,-1,0),new U(-1,1,0),new U(1,1,0)),t=64,n=1,r=8,i=!1){super(),this.type=`TubeGeometry`,this.parameters={path:e,tubularSegments:t,radius:n,radialSegments:r,closed:i};let a=e.computeFrenetFrames(t,i);this.tangents=a.tangents,this.normals=a.normals,this.binormals=a.binormals;let o=new U,s=new U,c=new H,l=new U,u=[],d=[],f=[],p=[];m(),this.setIndex(p),this.setAttribute(`position`,new q(u,3)),this.setAttribute(`normal`,new q(d,3)),this.setAttribute(`uv`,new q(f,2));function m(){for(let e=0;e<t;e++)h(e);h(i===!1?t:0),_(),g()}function h(i){l=e.getPointAt(i/t,l);let c=a.normals[i],f=a.binormals[i];for(let e=0;e<=r;e++){let t=e/r*Math.PI*2,i=Math.sin(t),a=-Math.cos(t);s.x=a*c.x+i*f.x,s.y=a*c.y+i*f.y,s.z=a*c.z+i*f.z,s.normalize(),d.push(s.x,s.y,s.z),o.x=l.x+n*s.x,o.y=l.y+n*s.y,o.z=l.z+n*s.z,u.push(o.x,o.y,o.z)}}function g(){for(let e=1;e<=t;e++)for(let t=1;t<=r;t++){let n=(r+1)*(e-1)+(t-1),i=(r+1)*e+(t-1),a=(r+1)*e+t,o=(r+1)*(e-1)+t;p.push(n,i,o),p.push(i,a,o)}}function _(){for(let e=0;e<=t;e++)for(let n=0;n<=r;n++)c.x=e/t,c.y=n/r,f.push(c.x,c.y)}}copy(e){return super.copy(e),this.parameters=Object.assign({},e.parameters),this}toJSON(){let e=super.toJSON();return e.path=this.parameters.path.toJSON(),e}static fromJSON(t){return new e(new Wa[t.path.type]().fromJSON(t.path),t.tubularSegments,t.radius,t.radialSegments,t.closed)}},Bo=class extends Fr{constructor(e){super(),this.isMeshStandardMaterial=!0,this.type=`MeshStandardMaterial`,this.defines={STANDARD:``},this.color=new K(16777215),this.roughness=1,this.metalness=0,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new K(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new H(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.roughnessMap=null,this.metalnessMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new fn,this.envMapIntensity=1,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap=`round`,this.wireframeLinejoin=`round`,this.flatShading=!1,this.fog=!0,this.setValues(e)}copy(e){return super.copy(e),this.defines={STANDARD:``},this.color.copy(e.color),this.roughness=e.roughness,this.metalness=e.metalness,this.map=e.map,this.lightMap=e.lightMap,this.lightMapIntensity=e.lightMapIntensity,this.aoMap=e.aoMap,this.aoMapIntensity=e.aoMapIntensity,this.emissive.copy(e.emissive),this.emissiveMap=e.emissiveMap,this.emissiveIntensity=e.emissiveIntensity,this.bumpMap=e.bumpMap,this.bumpScale=e.bumpScale,this.normalMap=e.normalMap,this.normalMapType=e.normalMapType,this.normalScale.copy(e.normalScale),this.displacementMap=e.displacementMap,this.displacementScale=e.displacementScale,this.displacementBias=e.displacementBias,this.roughnessMap=e.roughnessMap,this.metalnessMap=e.metalnessMap,this.alphaMap=e.alphaMap,this.envMap=e.envMap,this.envMapRotation.copy(e.envMapRotation),this.envMapIntensity=e.envMapIntensity,this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.wireframeLinecap=e.wireframeLinecap,this.wireframeLinejoin=e.wireframeLinejoin,this.flatShading=e.flatShading,this.fog=e.fog,this}},Vo=class extends Bo{constructor(e){super(),this.isMeshPhysicalMaterial=!0,this.defines={STANDARD:``,PHYSICAL:``},this.type=`MeshPhysicalMaterial`,this.anisotropyRotation=0,this.anisotropyMap=null,this.clearcoatMap=null,this.clearcoatRoughness=0,this.clearcoatRoughnessMap=null,this.clearcoatNormalScale=new H(1,1),this.clearcoatNormalMap=null,this.ior=1.5,Object.defineProperty(this,"reflectivity",{get:function(){return B(2.5*(this.ior-1)/(this.ior+1),0,1)},set:function(e){this.ior=(1+.4*e)/(1-.4*e)}}),this.iridescenceMap=null,this.iridescenceIOR=1.3,this.iridescenceThicknessRange=[100,400],this.iridescenceThicknessMap=null,this.sheenColor=new K(0),this.sheenColorMap=null,this.sheenRoughness=1,this.sheenRoughnessMap=null,this.transmissionMap=null,this.thickness=0,this.thicknessMap=null,this.attenuationDistance=1/0,this.attenuationColor=new K(1,1,1),this.specularIntensity=1,this.specularIntensityMap=null,this.specularColor=new K(1,1,1),this.specularColorMap=null,this._anisotropy=0,this._clearcoat=0,this._dispersion=0,this._iridescence=0,this._retroreflectivity=0,this._sheen=0,this._transmission=0,this.setValues(e)}get anisotropy(){return this._anisotropy}set anisotropy(e){this._anisotropy>0!=e>0&&this.version++,this._anisotropy=e}get clearcoat(){return this._clearcoat}set clearcoat(e){this._clearcoat>0!=e>0&&this.version++,this._clearcoat=e}get iridescence(){return this._iridescence}set iridescence(e){this._iridescence>0!=e>0&&this.version++,this._iridescence=e}get dispersion(){return this._dispersion}set dispersion(e){this._dispersion>0!=e>0&&this.version++,this._dispersion=e}get retroreflectivity(){return this._retroreflectivity}set retroreflectivity(e){this._retroreflectivity>0!=e>0&&this.version++,this._retroreflectivity=e}get sheen(){return this._sheen}set sheen(e){this._sheen>0!=e>0&&this.version++,this._sheen=e}get transmission(){return this._transmission}set transmission(e){this._transmission>0!=e>0&&this.version++,this._transmission=e}copy(e){return super.copy(e),this.defines={STANDARD:``,PHYSICAL:``},this.anisotropy=e.anisotropy,this.anisotropyRotation=e.anisotropyRotation,this.anisotropyMap=e.anisotropyMap,this.clearcoat=e.clearcoat,this.clearcoatMap=e.clearcoatMap,this.clearcoatRoughness=e.clearcoatRoughness,this.clearcoatRoughnessMap=e.clearcoatRoughnessMap,this.clearcoatNormalMap=e.clearcoatNormalMap,this.clearcoatNormalScale.copy(e.clearcoatNormalScale),this.dispersion=e.dispersion,this.ior=e.ior,this.iridescence=e.iridescence,this.iridescenceMap=e.iridescenceMap,this.iridescenceIOR=e.iridescenceIOR,this.iridescenceThicknessRange=[...e.iridescenceThicknessRange],this.iridescenceThicknessMap=e.iridescenceThicknessMap,this.retroreflectivity=e.retroreflectivity,this.sheen=e.sheen,this.sheenColor.copy(e.sheenColor),this.sheenColorMap=e.sheenColorMap,this.sheenRoughness=e.sheenRoughness,this.sheenRoughnessMap=e.sheenRoughnessMap,this.transmission=e.transmission,this.transmissionMap=e.transmissionMap,this.thickness=e.thickness,this.thicknessMap=e.thicknessMap,this.attenuationDistance=e.attenuationDistance,this.attenuationColor.copy(e.attenuationColor),this.specularIntensity=e.specularIntensity,this.specularIntensityMap=e.specularIntensityMap,this.specularColor.copy(e.specularColor),this.specularColorMap=e.specularColorMap,this}},Ho=class extends Gi{constructor(e){super(),this.isLineDashedMaterial=!0,this.type=`LineDashedMaterial`,this.scale=1,this.dashSize=3,this.gapSize=1,this.setValues(e)}copy(e){return super.copy(e),this.scale=e.scale,this.dashSize=e.dashSize,this.gapSize=e.gapSize,this}};function Uo(e,t){return!e||e.constructor===t?e:typeof t.BYTES_PER_ELEMENT==`number`?new t(e):Array.prototype.slice.call(e)}function Wo(e){return e!==void 0&&e.inTangents!==void 0&&e.outTangents!==void 0}function Go(e){function t(t,n){return e[t]-e[n]}let n=e.length,r=Array(n);for(let e=0;e!==n;++e)r[e]=e;return r.sort(t),r}function Ko(e,t,n){let r=e.length,i=new e.constructor(r);for(let a=0,o=0;o!==r;++a){let r=n[a]*t;for(let n=0;n!==t;++n)i[o++]=e[r+n]}return i}function qo(e,t,n,r){let i=1,a=e[0];for(;a!==void 0&&a[r]===void 0;)a=e[i++];if(a===void 0)return;let o=a[r];if(o!==void 0){if(Array.isArray(o))do o=a[r],o!==void 0&&(t.push(a.time),n.push(...o)),a=e[i++];while(a!==void 0);else if(o.toArray!==void 0)do o=a[r],o!==void 0&&(t.push(a.time),o.toArray(n,n.length)),a=e[i++];while(a!==void 0);else do o=a[r],o!==void 0&&(t.push(a.time),n.push(o)),a=e[i++];while(a!==void 0)}}var Jo=class{constructor(e,t,n,r){this.parameterPositions=e,this._cachedIndex=0,this.resultBuffer=r===void 0?new t.constructor(n):r,this.sampleValues=t,this.valueSize=n,this.settings=null,this.DefaultSettings_={}}evaluate(e){let t=this.parameterPositions,n=this._cachedIndex,r=t[n],i=t[n-1];validate_interval:{seek:{let a;linear_scan:{forward_scan:if(!(e<r)){for(let a=n+2;;){if(r===void 0){if(e<i)break forward_scan;return n=t.length,this._cachedIndex=n,this.copySampleValue_(n-1)}if(n===a)break;if(i=r,r=t[++n],e<r)break seek}a=t.length;break linear_scan}if(!(e>=i)){let o=t[1];e<o&&(n=2,i=o);for(let a=n-2;;){if(i===void 0)return this._cachedIndex=0,this.copySampleValue_(0);if(n===a)break;if(r=i,i=t[--n-1],e>=i)break seek}a=n,n=0;break linear_scan}break validate_interval}for(;n<a;){let r=n+a>>>1;e<t[r]?a=r:n=r+1}if(r=t[n],i=t[n-1],i===void 0)return this._cachedIndex=0,this.copySampleValue_(0);if(r===void 0)return n=t.length,this._cachedIndex=n,this.copySampleValue_(n-1)}this._cachedIndex=n,this.intervalChanged_(n,i,r)}return this.interpolate_(n,i,e,r)}getSettings_(){return this.settings||this.DefaultSettings_}copySampleValue_(e){let t=this.resultBuffer,n=this.sampleValues,r=this.valueSize,i=e*r;for(let e=0;e!==r;++e)t[e]=n[i+e];return t}interpolate_(){throw Error(`THREE.Interpolant: Call to abstract method.`)}intervalChanged_(){}},Yo=class extends Jo{constructor(e,t,n,r){super(e,t,n,r),this._weightPrev=-0,this._offsetPrev=-0,this._weightNext=-0,this._offsetNext=-0,this.DefaultSettings_={endingStart:Ke,endingEnd:Ke}}intervalChanged_(e,t,n){let r=this.parameterPositions,i=e-2,a=e+1,o=r[i],s=r[a];if(o===void 0)switch(this.getSettings_().endingStart){case qe:i=e,o=2*t-n;break;case Je:i=r.length-2,o=t+r[i]-r[i+1];break;default:i=e,o=n}if(s===void 0)switch(this.getSettings_().endingEnd){case qe:a=e,s=2*n-t;break;case Je:a=1,s=n+r[1]-r[0];break;default:a=e-1,s=t}let c=(n-t)*.5,l=this.valueSize;this._weightPrev=c/(t-o),this._weightNext=c/(s-n),this._offsetPrev=i*l,this._offsetNext=a*l}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=e*o,c=s-o,l=this._offsetPrev,u=this._offsetNext,d=this._weightPrev,f=this._weightNext,p=(n-t)/(r-t),m=p*p,h=m*p,g=-d*h+2*d*m-d*p,_=(1+d)*h+(-1.5-2*d)*m+(-.5+d)*p+1,v=(-1-f)*h+(1.5+f)*m+.5*p,y=f*h-f*m;for(let e=0;e!==o;++e)i[e]=g*a[l+e]+_*a[c+e]+v*a[s+e]+y*a[u+e];return i}},Xo=class extends Jo{constructor(e,t,n,r){super(e,t,n,r)}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=e*o,c=s-o,l=(n-t)/(r-t),u=1-l;for(let e=0;e!==o;++e)i[e]=a[c+e]*u+a[s+e]*l;return i}},Zo=class extends Jo{constructor(e,t,n,r){super(e,t,n,r)}interpolate_(e){return this.copySampleValue_(e-1)}},Qo=class extends Jo{interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=e*o,c=s-o,l=this.inTangents,u=this.outTangents;if(!l||!u){let e=(n-t)/(r-t),l=1-e;for(let t=0;t!==o;++t)i[t]=a[c+t]*l+a[s+t]*e;return i}let d=o*2,f=e-1;for(let p=0;p!==o;++p){let o=a[c+p],m=a[s+p],h=f*d+p*2,g=u[h],_=u[h+1],v=e*d+p*2,y=l[v],b=l[v+1],x=ts(n,t,g,y,r);i[p]=$o(x,o,_,b,m)}return i}};function $o(e,t,n,r,i){let a=1-e;return a*a*a*t+3*a*a*e*n+3*a*e*e*r+e*e*e*i}function es(e,t,n,r,i){let a=1-e;return 3*a*a*(n-t)+6*a*e*(r-n)+3*e*e*(i-r)}function ts(e,t,n,r,i){let a=(e-t)/(i-t);for(let o=0;o<8;o++){let o=$o(a,t,n,r,i)-e;if(Math.abs(o)<1e-10)break;let s=es(a,t,n,r,i);if(Math.abs(s)<1e-10)break;a=Math.max(0,Math.min(1,a-o/s))}return a}var ns=class{constructor(e,t,n,r){if(e===void 0)throw Error(`THREE.KeyframeTrack: track name is undefined`);if(t===void 0||t.length===0)throw Error(`THREE.KeyframeTrack: no keyframes in track named `+e);this.name=e,this.times=Uo(t,this.TimeBufferType),this.values=Uo(n,this.ValueBufferType),this.setInterpolation(r||this.DefaultInterpolation)}static toJSON(e){let t=e.constructor,n;if(t.toJSON!==this.toJSON)n=t.toJSON(e);else{n={name:e.name,times:Uo(e.times,Array),values:Uo(e.values,Array)};let t=e.getInterpolation();t!==e.DefaultInterpolation&&(n.interpolation=t),Wo(e.settings)&&(n.settings={inTangents:Uo(e.settings.inTangents,Array),outTangents:Uo(e.settings.outTangents,Array)})}return n.type=e.ValueTypeName,n}InterpolantFactoryMethodDiscrete(e){return new Zo(this.times,this.values,this.getValueSize(),e)}InterpolantFactoryMethodLinear(e){return new Xo(this.times,this.values,this.getValueSize(),e)}InterpolantFactoryMethodSmooth(e){return new Yo(this.times,this.values,this.getValueSize(),e)}InterpolantFactoryMethodBezier(e){let t=new Qo(this.times,this.values,this.getValueSize(),e);return this.settings&&(t.inTangents=this.settings.inTangents,t.outTangents=this.settings.outTangents),t}setInterpolation(e){let t;switch(e){case He:t=this.InterpolantFactoryMethodDiscrete;break;case Ue:t=this.InterpolantFactoryMethodLinear;break;case We:t=this.InterpolantFactoryMethodSmooth;break;case Ge:t=this.InterpolantFactoryMethodBezier}if(t===void 0){let t=`unsupported interpolation for `+this.ValueTypeName+` keyframe track named `+this.name;if(this.createInterpolant===void 0){if(e!==this.DefaultInterpolation)this.setInterpolation(this.DefaultInterpolation);else throw Error(t)}return R(`KeyframeTrack:`,t),this}return this.createInterpolant=t,this}getInterpolation(){switch(this.createInterpolant){case this.InterpolantFactoryMethodDiscrete:return He;case this.InterpolantFactoryMethodLinear:return Ue;case this.InterpolantFactoryMethodSmooth:return We;case this.InterpolantFactoryMethodBezier:return Ge}}getValueSize(){return this.values.length/this.times.length}shift(e){if(e!==0){let t=this.times;for(let n=0,r=t.length;n!==r;++n)t[n]+=e}return this}scale(e){if(e!==1){let t=this.times;for(let n=0,r=t.length;n!==r;++n)t[n]*=e;Wo(this.settings)&&(rs(this.settings.inTangents,e),rs(this.settings.outTangents,e))}return this}trim(e,t){let n=this.times,r=n.length,i=0,a=r-1;for(;i!==r&&n[i]<e;)++i;for(;a!==-1&&n[a]>t;)--a;if(++a,i!==0||a!==r){i>=a&&(a=Math.max(a,1),i=a-1);let e=this.getValueSize();this.times=n.slice(i,a),this.values=this.values.slice(i*e,a*e)}return this}validate(){let e=!0,t=this.getValueSize();t-Math.floor(t)!==0&&(z(`KeyframeTrack: Invalid value size in track.`,this),e=!1);let n=this.times,r=this.values,i=n.length;i===0&&(z(`KeyframeTrack: Track is empty.`,this),e=!1);let a=null;for(let t=0;t!==i;t++){let r=n[t];if(typeof r==`number`&&isNaN(r)){z(`KeyframeTrack: Time is not a valid number.`,this,t,r),e=!1;break}if(a!==null&&a>r){z(`KeyframeTrack: Out of order keys.`,this,t,r,a),e=!1;break}a=r}if(r!==void 0&&it(r))for(let t=0,n=r.length;t!==n;++t){let n=r[t];if(isNaN(n)){z(`KeyframeTrack: Value is not a valid number.`,this,t,n),e=!1;break}}return e}optimize(){let e=this.times.slice(),t=this.values.slice(),n=this.getValueSize(),r=this.getInterpolation()===We,i=e.length-1,a=1;for(let o=1;o<i;++o){let i=!1,s=e[o];if(s!==e[o+1]&&(o!==1||s!==e[0])){if(r)i=!0;else{let e=o*n,r=e-n,a=e+n;for(let o=0;o!==n;++o){let n=t[e+o];if(n!==t[r+o]||n!==t[a+o]){i=!0;break}}}}if(i){if(o!==a){e[a]=e[o];let r=o*n,i=a*n;for(let e=0;e!==n;++e)t[i+e]=t[r+e]}++a}}if(i>0){e[a]=e[i];for(let e=i*n,r=a*n,o=0;o!==n;++o)t[r+o]=t[e+o];++a}return a===e.length?(this.times=e,this.values=t):(this.times=e.slice(0,a),this.values=t.slice(0,a*n)),this}clone(){let e=this.times.slice(),t=this.values.slice(),n=this.constructor,r=new n(this.name,e,t);return r.createInterpolant=this.createInterpolant,Wo(this.settings)&&(r.settings={inTangents:this.settings.inTangents.slice(),outTangents:this.settings.outTangents.slice()}),r}};function rs(e,t){for(let n=0,r=e.length;n!==r;n+=2)e[n]*=t}ns.prototype.ValueTypeName=``,ns.prototype.TimeBufferType=Float32Array,ns.prototype.ValueBufferType=Float32Array,ns.prototype.DefaultInterpolation=Ue;var is=class extends ns{constructor(e,t,n){super(e,t,n)}};is.prototype.ValueTypeName=`bool`,is.prototype.ValueBufferType=Array,is.prototype.DefaultInterpolation=He,is.prototype.InterpolantFactoryMethodLinear=void 0,is.prototype.InterpolantFactoryMethodSmooth=void 0;var as=class extends ns{constructor(e,t,n,r){super(e,t,n,r)}};as.prototype.ValueTypeName=`color`;var os=class extends ns{constructor(e,t,n,r){super(e,t,n,r)}};os.prototype.ValueTypeName=`number`;var ss=class extends Jo{constructor(e,t,n,r){super(e,t,n,r)}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=(n-t)/(r-t),c=e*o;for(let e=c+o;c!==e;c+=4)It.slerpFlat(i,0,a,c-o,a,c,s);return i}},cs=class extends ns{constructor(e,t,n,r){super(e,t,n,r)}InterpolantFactoryMethodLinear(e){return new ss(this.times,this.values,this.getValueSize(),e)}};cs.prototype.ValueTypeName=`quaternion`,cs.prototype.InterpolantFactoryMethodSmooth=void 0;var ls=class extends ns{constructor(e,t,n){super(e,t,n)}};ls.prototype.ValueTypeName=`string`,ls.prototype.ValueBufferType=Array,ls.prototype.DefaultInterpolation=He,ls.prototype.InterpolantFactoryMethodLinear=void 0,ls.prototype.InterpolantFactoryMethodSmooth=void 0;var us=class extends ns{constructor(e,t,n,r){super(e,t,n,r)}};us.prototype.ValueTypeName=`vector`;var ds=class{constructor(e=``,t=-1,n=[],r=Ye){this.name=e,this.tracks=n,this.duration=t,this.blendMode=r,this.uuid=ht(),this.userData={},this.duration<0&&this.resetDuration()}static parse(e){let t=[],n=e.tracks,r=1/(e.fps||1);for(let e=0,i=n.length;e!==i;++e)t.push(ps(n[e]).scale(r));let i=new this(e.name,e.duration,t,e.blendMode);return i.uuid=e.uuid,i.userData=JSON.parse(e.userData||`{}`),i}static toJSON(e){let t=[],n=e.tracks,r={name:e.name,duration:e.duration,tracks:t,uuid:e.uuid,blendMode:e.blendMode,userData:JSON.stringify(e.userData)};for(let e=0,r=n.length;e!==r;++e)t.push(ns.toJSON(n[e]));return r}static CreateFromMorphTargetSequence(e,t,n,r){let i=t.length,a=[];for(let e=0;e<i;e++){let o=[],s=[];o.push((e+i-1)%i,e,(e+1)%i),s.push(0,1,0);let c=Go(o);o=Ko(o,1,c),s=Ko(s,1,c),!r&&o[0]===0&&(o.push(i),s.push(s[0])),a.push(new os(`.morphTargetInfluences[`+t[e].name+`]`,o,s).scale(1/n))}return new this(e,-1,a)}static findByName(e,t){let n=e;if(!Array.isArray(e)){let t=e;n=t.geometry&&t.geometry.animations||t.animations}for(let e=0;e<n.length;e++)if(n[e].name===t)return n[e];return null}static CreateClipsFromMorphTargetSequences(e,t,n){let r={},i=/^([\w-]*?)([\d]+)$/;for(let t=0,n=e.length;t<n;t++){let n=e[t],a=n.name.match(i);if(a&&a.length>1){let e=a[1],t=r[e];t||(r[e]=t=[]),t.push(n)}}let a=[];for(let e in r)a.push(this.CreateFromMorphTargetSequence(e,r[e],t,n));return a}resetDuration(){let e=this.tracks,t=0;for(let n=0,r=e.length;n!==r;++n){let e=this.tracks[n];t=Math.max(t,e.times[e.times.length-1])}return this.duration=t,this}trim(){for(let e=0;e<this.tracks.length;e++)this.tracks[e].trim(0,this.duration);return this}validate(){let e=!0;for(let t=0;t<this.tracks.length;t++)e=e&&this.tracks[t].validate();return e}optimize(){for(let e=0;e<this.tracks.length;e++)this.tracks[e].optimize();return this}clone(){let e=[];for(let t=0;t<this.tracks.length;t++)e.push(this.tracks[t].clone());let t=new this.constructor(this.name,this.duration,e,this.blendMode);return t.userData=JSON.parse(JSON.stringify(this.userData)),t}toJSON(){return this.constructor.toJSON(this)}};function fs(e){switch(e.toLowerCase()){case`scalar`:case`double`:case`float`:case`number`:case`integer`:return os;case`vector`:case`vector2`:case`vector3`:case`vector4`:return us;case`color`:return as;case`quaternion`:return cs;case`bool`:case`boolean`:return is;case`string`:return ls}throw Error(`THREE.KeyframeTrack: Unsupported typeName: `+e)}function ps(e){if(e.type===void 0)throw Error(`THREE.KeyframeTrack: track type undefined, can not parse`);let t=fs(e.type);if(e.times===void 0){let t=[],n=[];qo(e.keys,t,n,`value`),e.times=t,e.values=n}let n;return n=t.parse===void 0?new t(e.name,e.times,e.values,e.interpolation):t.parse(e),Wo(e.settings)&&(n.settings={inTangents:Uo(e.settings.inTangents,Float32Array),outTangents:Uo(e.settings.outTangents,Float32Array)}),n}var ms={enabled:!1,files:{},add:function(e,t){this.enabled!==!1&&(hs(e)||(this.files[e]=t))},get:function(e){if(this.enabled!==!1&&!hs(e))return this.files[e]},remove:function(e){delete this.files[e]},clear:function(){this.files={}}};function hs(e){try{let t=e.slice(e.indexOf(`:`)+1);return new URL(t).protocol===`blob:`}catch{return!1}}var gs=new class{constructor(e,t,n){let r=this,i=!1,a=0,o=0,s,c=[];this.onStart=void 0,this.onLoad=e,this.onProgress=t,this.onError=n,this._abortController=null,this.itemStart=function(e){o++,i===!1&&r.onStart!==void 0&&r.onStart(e,a,o),i=!0},this.itemEnd=function(e){a++,r.onProgress!==void 0&&r.onProgress(e,a,o),a===o&&(i=!1,r.onLoad!==void 0&&r.onLoad())},this.itemError=function(e){r.onError!==void 0&&r.onError(e)},this.resolveURL=function(e){return e=e.normalize(`NFC`),s?s(e):e},this.setURLModifier=function(e){return s=e,this},this.addHandler=function(e,t){return c.push(e,t),this},this.removeHandler=function(e){let t=c.indexOf(e);return t!==-1&&c.splice(t,2),this},this.getHandler=function(e){for(let t=0,n=c.length;t<n;t+=2){let n=c[t],r=c[t+1];if(n.global&&(n.lastIndex=0),n.test(e))return r}return null},this.abort=function(){return this.abortController.abort(),this._abortController=null,this}}get abortController(){return this._abortController||(this._abortController=new AbortController),this._abortController}},_s=class{constructor(e){this.manager=e===void 0?gs:e,this.crossOrigin=`anonymous`,this.withCredentials=!1,this.path=``,this.resourcePath=``,this.requestHeader={},typeof __THREE_DEVTOOLS__<`u`&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent(`observe`,{detail:this}))}load(){}loadAsync(e,t){let n=this;return new Promise(function(r,i){n.load(e,r,t,i)})}parse(){}setCrossOrigin(e){return this.crossOrigin=e,this}setWithCredentials(e){return this.withCredentials=e,this}setPath(e){return this.path=e,this}setResourcePath(e){return this.resourcePath=e,this}setRequestHeader(e){return this.requestHeader=e,this}abort(){return this}};_s.DEFAULT_MATERIAL_NAME=`__DEFAULT`;var vs={},ys=class extends Error{constructor(e,t){super(e),this.response=t}},bs=class extends _s{constructor(e){super(e),this.mimeType=``,this.responseType=``,this._abortController=new AbortController}load(e,t,n,r){e===void 0&&(e=``),this.path!==void 0&&(e=this.path+e),e=this.manager.resolveURL(e);let i=ms.get(`file:${e}`);if(i!==void 0){this.manager.itemStart(e),setTimeout(()=>{t&&t(i),this.manager.itemEnd(e)},0);return}if(vs[e]!==void 0){vs[e].push({onLoad:t,onProgress:n,onError:r});return}vs[e]=[],vs[e].push({onLoad:t,onProgress:n,onError:r});let a=new Request(e,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?`include`:`same-origin`,signal:typeof AbortSignal.any==`function`?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal}),o=this.mimeType,s=this.responseType;fetch(a).then(t=>{if(t.status===200||t.status===0){if(t.status===0&&R(`FileLoader: HTTP Status 0 received.`),typeof ReadableStream>`u`||t.body===void 0||t.body.getReader===void 0)return t;let n=vs[e],r=t.body.getReader(),i=t.headers.get(`X-File-Size`)||t.headers.get(`Content-Length`),a=i?parseInt(i):0,o=a!==0,s=0,c=new ReadableStream({start(e){t();function t(){r.read().then(({done:r,value:i})=>{if(r)e.close();else{s+=i.byteLength;let r=new ProgressEvent(`progress`,{lengthComputable:o,loaded:s,total:a});for(let e=0,t=n.length;e<t;e++){let t=n[e];t.onProgress&&t.onProgress(r)}e.enqueue(i),t()}},t=>{e.error(t)})}}});return new Response(c)}throw new ys(`fetch for "${t.url}" responded with ${t.status}: ${t.statusText}`,t)}).then(e=>{switch(s){case`arraybuffer`:return e.arrayBuffer();case`blob`:return e.blob();case`document`:return e.text().then(e=>new DOMParser().parseFromString(e,o));case`json`:return e.json();default:if(o===``)return e.text();{let t=/charset="?([^;"\s]*)"?/i.exec(o),n=t&&t[1]?t[1].toLowerCase():void 0,r=new TextDecoder(n);return e.arrayBuffer().then(e=>r.decode(e))}}}).then(t=>{ms.add(`file:${e}`,t);let n=vs[e];delete vs[e];for(let e=0,r=n.length;e<r;e++){let r=n[e];r.onLoad&&r.onLoad(t)}}).catch(t=>{let n=vs[e];if(n===void 0)throw this.manager.itemError(e),t;delete vs[e];for(let e=0,r=n.length;e<r;e++){let r=n[e];r.onError&&r.onError(t)}this.manager.itemError(e)}).finally(()=>{this.manager.itemEnd(e)}),this.manager.itemStart(e)}setResponseType(e){return this.responseType=e,this}setMimeType(e){return this.mimeType=e,this}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}},xs=new WeakMap,Ss=class extends _s{constructor(e){super(e)}load(e,t,n,r){this.path!==void 0&&(e=this.path+e),e=this.manager.resolveURL(e);let i=this,a=ms.get(`image:${e}`);if(a!==void 0){if(a.complete===!0)i.manager.itemStart(e),setTimeout(function(){t&&t(a),i.manager.itemEnd(e)},0);else{let e=xs.get(a);e===void 0&&(e=[],xs.set(a,e)),e.push({onLoad:t,onError:r})}return a}let o=at(`img`);function s(){l(),t&&t(this);let n=xs.get(this)||[];for(let e=0;e<n.length;e++){let t=n[e];t.onLoad&&t.onLoad(this)}xs.delete(this),i.manager.itemEnd(e)}function c(t){l(),r&&r(t),ms.remove(`image:${e}`);let n=xs.get(this)||[];for(let e=0;e<n.length;e++){let r=n[e];r.onError&&r.onError(t)}xs.delete(this),i.manager.itemError(e),i.manager.itemEnd(e)}function l(){o.removeEventListener(`load`,s,!1),o.removeEventListener(`error`,c,!1)}return o.addEventListener(`load`,s,!1),o.addEventListener(`error`,c,!1),e.slice(0,5)!==`data:`&&this.crossOrigin!==void 0&&(o.crossOrigin=this.crossOrigin),ms.add(`image:${e}`,o),i.manager.itemStart(e),o.src=e,o}},Cs=class extends _s{constructor(e){super(e)}load(e,t,n,r){let i=new en,a=new Ss(this.manager);return a.setCrossOrigin(this.crossOrigin),a.setPath(this.path),a.load(e,function(e){i.image=e,i.needsUpdate=!0,t!==void 0&&t(i)},n,r),i}},ws=class extends G{constructor(e,t=1){super(),this.isLight=!0,this.type=`Light`,this.color=new K(e),this.intensity=t}copy(e,t){return super.copy(e,t),this.color.copy(e.color),this.intensity=e.intensity,this}toJSON(e){let t=super.toJSON(e);return t.object.color=this.color.getHex(),t.object.intensity=this.intensity,t}},Ts=new W,Es=new U,Ds=new U,Os=class{constructor(e){this.camera=e,this.intensity=1,this.bias=0,this.biasNode=null,this.normalBias=0,this.radius=1,this.blurSamples=8,this.mapSize=new H(512,512),this.mapType=Re,this.map=null,this.mapPass=null,this.matrix=new W,this.autoUpdate=!0,this.needsUpdate=!1,this._frustum=new Wi,this._frameExtents=new H(1,1),this._viewportCount=1,this._viewports=[new tn(0,0,1,1)]}getViewportCount(){return this._viewportCount}getCamera(){return this.camera}getFrustum(){return this._frustum}updateMatrices(e){let t=this.camera;Es.setFromMatrixPosition(e.matrixWorld),t.position.copy(Es),Ds.setFromMatrixPosition(e.target.matrixWorld),t.lookAt(Ds),t.updateMatrixWorld(),this._updateMatrix(t,this.matrix,this._frustum)}_updateMatrix(e,t,n,r){Ts.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),n.setFromProjectionMatrix(Ts,e.coordinateSystem,e.reversedDepth);let i=this._frameExtents,a=r?r.z/i.x:1,o=r?r.w/i.y:1,s=r?r.x/i.x:0,c=r?r.y/i.y:0;e.coordinateSystem===2001||e.reversedDepth?t.set(.5*a,0,0,.5*a+s,0,.5*o,0,.5*o+c,0,0,1,0,0,0,0,1):t.set(.5*a,0,0,.5*a+s,0,.5*o,0,.5*o+c,0,0,.5,.5,0,0,0,1),t.multiply(Ts)}getViewport(e){return this._viewports[e]}getFrameExtents(){return this._frameExtents}dispose(){this.map&&this.map.dispose(),this.mapPass&&this.mapPass.dispose()}copy(e){return this.camera=e.camera.clone(),this.intensity=e.intensity,this.bias=e.bias,this.radius=e.radius,this.autoUpdate=e.autoUpdate,this.needsUpdate=e.needsUpdate,this.normalBias=e.normalBias,this.blurSamples=e.blurSamples,this.mapSize.copy(e.mapSize),this.biasNode=e.biasNode,this}clone(){return new this.constructor().copy(this)}toJSON(){let e={};return e.intensity=this.intensity,e.bias=this.bias,e.normalBias=this.normalBias,e.radius=this.radius,e.blurSamples=this.blurSamples,e.mapSize=this.mapSize.toArray(),e.camera=this.camera.toJSON(!1).object,delete e.camera.matrix,e}},ks=new U,As=new It,js=new U,Ms=class extends G{constructor(){super(),this.isCamera=!0,this.type=`Camera`,this.matrixWorldInverse=new W,this.projectionMatrix=new W,this.projectionMatrixInverse=new W,this.coordinateSystem=nt,this._reversedDepth=!1}get reversedDepth(){return this._reversedDepth}copy(e,t){return super.copy(e,t),this.matrixWorldInverse.copy(e.matrixWorldInverse),this.projectionMatrix.copy(e.projectionMatrix),this.projectionMatrixInverse.copy(e.projectionMatrixInverse),this.coordinateSystem=e.coordinateSystem,this}getWorldDirection(e){return super.getWorldDirection(e).negate()}updateMatrixWorld(e){super.updateMatrixWorld(e),this.matrixWorld.decompose(ks,As,js),js.x===1&&js.y===1&&js.z===1?this.matrixWorldInverse.copy(this.matrixWorld).invert():this.matrixWorldInverse.compose(ks,As,js.set(1,1,1)).invert()}updateWorldMatrix(e,t,n=!1){super.updateWorldMatrix(e,t,n),this.matrixWorld.decompose(ks,As,js),js.x===1&&js.y===1&&js.z===1?this.matrixWorldInverse.copy(this.matrixWorld).invert():this.matrixWorldInverse.compose(ks,As,js.set(1,1,1)).invert()}clone(){return new this.constructor().copy(this)}},Ns=new U,Ps=new H,Fs=new H,Is=class extends Ms{constructor(e=50,t=1,n=.1,r=2e3){super(),this.isPerspectiveCamera=!0,this.type=`PerspectiveCamera`,this.fov=e,this.zoom=1,this.near=n,this.far=r,this.focus=10,this.aspect=t,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(e,t){return super.copy(e,t),this.fov=e.fov,this.zoom=e.zoom,this.near=e.near,this.far=e.far,this.focus=e.focus,this.aspect=e.aspect,this.view=e.view===null?null:Object.assign({},e.view),this.filmGauge=e.filmGauge,this.filmOffset=e.filmOffset,this}setFocalLength(e){let t=.5*this.getFilmHeight()/e;this.fov=mt*2*Math.atan(t),this.updateProjectionMatrix()}getFocalLength(){let e=Math.tan(pt*.5*this.fov);return .5*this.getFilmHeight()/e}getEffectiveFOV(){return mt*2*Math.atan(Math.tan(pt*.5*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(e,t,n){Ns.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),t.set(Ns.x,Ns.y).multiplyScalar(-e/Ns.z),Ns.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),n.set(Ns.x,Ns.y).multiplyScalar(-e/Ns.z)}getViewSize(e,t){return this.getViewBounds(e,Ps,Fs),t.subVectors(Fs,Ps)}setViewOffset(e,t,n,r,i,a){this.aspect=e/t,this.view===null&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=t,this.view.offsetX=n,this.view.offsetY=r,this.view.width=i,this.view.height=a,this.updateProjectionMatrix()}clearViewOffset(){this.view!==null&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){let e=this.near,t=e*Math.tan(pt*.5*this.fov)/this.zoom,n=2*t,r=this.aspect*n,i=-.5*r,a=this.view;if(this.view!==null&&this.view.enabled){let e=a.fullWidth,o=a.fullHeight;i+=a.offsetX*r/e,t-=a.offsetY*n/o,r*=a.width/e,n*=a.height/o}let o=this.filmOffset;o!==0&&(i+=e*o/this.getFilmWidth()),this.projectionMatrix.makePerspective(i,i+r,t,t-n,e,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(e){let t=super.toJSON(e);return t.object.fov=this.fov,t.object.zoom=this.zoom,t.object.near=this.near,t.object.far=this.far,t.object.focus=this.focus,t.object.aspect=this.aspect,this.view!==null&&(t.object.view=Object.assign({},this.view)),t.object.filmGauge=this.filmGauge,t.object.filmOffset=this.filmOffset,t}},Ls=class extends Os{constructor(){super(new Is(50,1,.5,500)),this.isSpotLightShadow=!0,this.focus=1,this.aspect=1}updateMatrices(e){let t=this.camera,n=mt*2*e.angle*this.focus,r=this.mapSize.width/this.mapSize.height*this.aspect,i=e.distance||t.far;(n!==t.fov||r!==t.aspect||i!==t.far)&&(t.fov=n,t.aspect=r,t.far=i,t.updateProjectionMatrix()),super.updateMatrices(e)}copy(e){return super.copy(e),this.focus=e.focus,this.aspect=e.aspect,this}toJSON(){let e=super.toJSON();return e.focus=this.focus,e.aspect=this.aspect,e}},Rs=class extends ws{constructor(e,t,n=0,r=Math.PI/3,i=0,a=2){super(e,t),this.isSpotLight=!0,this.type=`SpotLight`,this.position.copy(G.DEFAULT_UP),this.updateMatrix(),this.target=new G,this.distance=n,this.angle=r,this.penumbra=i,this.decay=a,this.map=null,this.shadow=new Ls}get power(){return this.intensity*Math.PI}set power(e){this.intensity=e/Math.PI}dispose(){super.dispose(),this.shadow.dispose()}copy(e,t){return super.copy(e,t),this.distance=e.distance,this.angle=e.angle,this.penumbra=e.penumbra,this.decay=e.decay,this.target=e.target.clone(),this.map=e.map,this.shadow=e.shadow.clone(),this}toJSON(e){let t=super.toJSON(e);return t.object.distance=this.distance,t.object.angle=this.angle,t.object.decay=this.decay,t.object.penumbra=this.penumbra,t.object.target=this.target.uuid,this.map&&this.map.isTexture&&(t.object.map=this.map.toJSON(e).uuid),t.object.shadow=this.shadow.toJSON(),t}},zs=class extends Os{constructor(){super(new Is(90,1,.5,500)),this.isPointLightShadow=!0}},Bs=class extends ws{constructor(e,t,n=0,r=2){super(e,t),this.isPointLight=!0,this.type=`PointLight`,this.distance=n,this.decay=r,this.shadow=new zs}get power(){return this.intensity*4*Math.PI}set power(e){this.intensity=e/(4*Math.PI)}dispose(){super.dispose(),this.shadow.dispose()}copy(e,t){return super.copy(e,t),this.distance=e.distance,this.decay=e.decay,this.shadow=e.shadow.clone(),this}toJSON(e){let t=super.toJSON(e);return t.object.distance=this.distance,t.object.decay=this.decay,t.object.shadow=this.shadow.toJSON(),t}},Vs=class extends Ms{constructor(e=-1,t=1,n=1,r=-1,i=.1,a=2e3){super(),this.isOrthographicCamera=!0,this.type=`OrthographicCamera`,this.zoom=1,this.view=null,this.left=e,this.right=t,this.top=n,this.bottom=r,this.near=i,this.far=a,this.updateProjectionMatrix()}copy(e,t){return super.copy(e,t),this.left=e.left,this.right=e.right,this.top=e.top,this.bottom=e.bottom,this.near=e.near,this.far=e.far,this.zoom=e.zoom,this.view=e.view===null?null:Object.assign({},e.view),this}setViewOffset(e,t,n,r,i,a){this.view===null&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=t,this.view.offsetX=n,this.view.offsetY=r,this.view.width=i,this.view.height=a,this.updateProjectionMatrix()}clearViewOffset(){this.view!==null&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){let e=(this.right-this.left)/(2*this.zoom),t=(this.top-this.bottom)/(2*this.zoom),n=(this.right+this.left)/2,r=(this.top+this.bottom)/2,i=n-e,a=n+e,o=r+t,s=r-t;if(this.view!==null&&this.view.enabled){let e=(this.right-this.left)/this.view.fullWidth/this.zoom,t=(this.top-this.bottom)/this.view.fullHeight/this.zoom;i+=e*this.view.offsetX,a=i+e*this.view.width,o-=t*this.view.offsetY,s=o-t*this.view.height}this.projectionMatrix.makeOrthographic(i,a,o,s,this.near,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(e){let t=super.toJSON(e);return t.object.zoom=this.zoom,t.object.left=this.left,t.object.right=this.right,t.object.top=this.top,t.object.bottom=this.bottom,t.object.near=this.near,t.object.far=this.far,this.view!==null&&(t.object.view=Object.assign({},this.view)),t}},Hs=class extends Os{constructor(){super(new Vs(-5,5,5,-5,.5,500)),this.isDirectionalLightShadow=!0}},Us=class extends ws{constructor(e,t){super(e,t),this.isDirectionalLight=!0,this.type=`DirectionalLight`,this.position.copy(G.DEFAULT_UP),this.updateMatrix(),this.target=new G,this.shadow=new Hs}dispose(){super.dispose(),this.shadow.dispose()}copy(e){return super.copy(e),this.target=e.target.clone(),this.shadow=e.shadow.clone(),this}toJSON(e){let t=super.toJSON(e);return t.object.shadow=this.shadow.toJSON(),t.object.target=this.target.uuid,t}},Ws=class{static extractUrlBase(e){let t=e.lastIndexOf(`/`);return t===-1?`./`:e.slice(0,t+1)}static resolveURL(e,t){return typeof e!=`string`||e===``?``:(/^https?:\/\//i.test(t)&&/^\//.test(e)&&(t=t.replace(/(^https?:\/\/[^\/]+).*/i,`$1`)),/^(https?:)?\/\//i.test(e)||/^data:.*,.*$/i.test(e)||/^blob:.*$/i.test(e)?e:t+e)}},Gs=new WeakMap,Ks=class extends _s{constructor(e){super(e),this.isImageBitmapLoader=!0,typeof createImageBitmap>`u`&&R(`ImageBitmapLoader: createImageBitmap() not supported.`),typeof fetch>`u`&&R(`ImageBitmapLoader: fetch() not supported.`),this.options={premultiplyAlpha:`none`},this._abortController=new AbortController}setOptions(e){return this.options=e,this}load(e,t,n,r){e===void 0&&(e=``),this.path!==void 0&&(e=this.path+e),e=this.manager.resolveURL(e);let i=this,a=ms.get(`image-bitmap:${e}`);if(a!==void 0){if(i.manager.itemStart(e),a.then){a.then(n=>{Gs.has(a)===!0?(r&&r(Gs.get(a)),i.manager.itemError(e),i.manager.itemEnd(e)):(t&&t(n),i.manager.itemEnd(e))});return}setTimeout(function(){t&&t(a),i.manager.itemEnd(e)},0);return}let o={};o.credentials=this.crossOrigin===`anonymous`?`same-origin`:`include`,o.headers=this.requestHeader,o.signal=typeof AbortSignal.any==`function`?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal;let s=fetch(e,o).then(function(e){return e.blob()}).then(function(e){return createImageBitmap(e,Object.assign({},i.options,{colorSpaceConversion:`none`}))}).then(function(n){return ms.add(`image-bitmap:${e}`,n),t&&t(n),i.manager.itemEnd(e),n}).catch(function(t){r&&r(t),Gs.set(s,t),ms.remove(`image-bitmap:${e}`),i.manager.itemError(e),i.manager.itemEnd(e)});ms.add(`image-bitmap:${e}`,s),i.manager.itemStart(e)}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}},qs=`\\[\\]\\.:\\/`,Js=RegExp(`[\\[\\]\\.:\\/]`,`g`),Ys=`[^\\[\\]\\.:\\/]`,Xs=`[^`+qs.replace(`\\.`,``)+`]`,Zs=`((?:WC+[\\/:])*)`.replace(`WC`,Ys),Qs=`(WCOD+)?`.replace(`WCOD`,Xs),$s=`(?:\\.(WC+)(?:\\[(.+)\\])?)?`.replace(`WC`,Ys),ec=`\\.(WC+)(?:\\[(.+)\\])?`.replace(`WC`,Ys),tc=RegExp(`^`+Zs+Qs+$s+ec+`$`),nc=[`material`,`materials`,`bones`,`map`],rc=class{constructor(e,t,n){let r=n||ic.parseTrackName(t);this._targetGroup=e,this._bindings=e.subscribe_(t,r)}getValue(e,t){this.bind();let n=this._targetGroup.nCachedObjects_,r=this._bindings[n];r!==void 0&&r.getValue(e,t)}setValue(e,t){let n=this._bindings;for(let r=this._targetGroup.nCachedObjects_,i=n.length;r!==i;++r)n[r].setValue(e,t)}bind(){let e=this._bindings;for(let t=this._targetGroup.nCachedObjects_,n=e.length;t!==n;++t)e[t].bind()}unbind(){let e=this._bindings;for(let t=this._targetGroup.nCachedObjects_,n=e.length;t!==n;++t)e[t].unbind()}},ic=class e{constructor(t,n,r){this.path=n,this.parsedPath=r||e.parseTrackName(n),this.node=e.findNode(t,this.parsedPath.nodeName),this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,n,r){return t&&t.isAnimationObjectGroup?new e.Composite(t,n,r):new e(t,n,r)}static sanitizeNodeName(e){return e.replace(/\s/g,`_`).replace(Js,``)}static parseTrackName(e){let t=tc.exec(e);if(t===null)throw Error(`THREE.PropertyBinding: Cannot parse trackName: `+e);let n={nodeName:t[2],objectName:t[3],objectIndex:t[4],propertyName:t[5],propertyIndex:t[6]},r=n.nodeName&&n.nodeName.lastIndexOf(`.`);if(r!==void 0&&r!==-1){let e=n.nodeName.substring(r+1);nc.indexOf(e)!==-1&&(n.nodeName=n.nodeName.substring(0,r),n.objectName=e)}if(n.propertyName===null||n.propertyName.length===0)throw Error(`THREE.PropertyBinding: can not parse propertyName from trackName: `+e);return n}static findNode(e,t){if(t===void 0||t===``||t===`.`||t===-1||t===e.name||t===e.uuid)return e;if(e.skeleton){let n=e.skeleton.getBoneByName(t);if(n!==void 0)return n}if(e.children){let n=function(e){for(let r=0;r<e.length;r++){let i=e[r];if(i.name===t||i.uuid===t)return i;let a=n(i.children);if(a)return a}return null},r=n(e.children);if(r)return r}return null}_getValue_unavailable(){}_setValue_unavailable(){}_getValue_direct(e,t){e[t]=this.targetObject[this.propertyName]}_getValue_array(e,t){let n=this.resolvedProperty;for(let r=0,i=n.length;r!==i;++r)e[t++]=n[r]}_getValue_arrayElement(e,t){e[t]=this.resolvedProperty[this.propertyIndex]}_getValue_toArray(e,t){this.resolvedProperty.toArray(e,t)}_setValue_direct(e,t){this.targetObject[this.propertyName]=e[t]}_setValue_direct_setNeedsUpdate(e,t){this.targetObject[this.propertyName]=e[t],this.targetObject.needsUpdate=!0}_setValue_direct_setMatrixWorldNeedsUpdate(e,t){this.targetObject[this.propertyName]=e[t],this.targetObject.matrixWorldNeedsUpdate=!0}_setValue_array(e,t){let n=this.resolvedProperty;for(let r=0,i=n.length;r!==i;++r)n[r]=e[t++]}_setValue_array_setNeedsUpdate(e,t){let n=this.resolvedProperty;for(let r=0,i=n.length;r!==i;++r)n[r]=e[t++];this.targetObject.needsUpdate=!0}_setValue_array_setMatrixWorldNeedsUpdate(e,t){let n=this.resolvedProperty;for(let r=0,i=n.length;r!==i;++r)n[r]=e[t++];this.targetObject.matrixWorldNeedsUpdate=!0}_setValue_arrayElement(e,t){this.resolvedProperty[this.propertyIndex]=e[t]}_setValue_arrayElement_setNeedsUpdate(e,t){this.resolvedProperty[this.propertyIndex]=e[t],this.targetObject.needsUpdate=!0}_setValue_arrayElement_setMatrixWorldNeedsUpdate(e,t){this.resolvedProperty[this.propertyIndex]=e[t],this.targetObject.matrixWorldNeedsUpdate=!0}_setValue_fromArray(e,t){this.resolvedProperty.fromArray(e,t)}_setValue_fromArray_setNeedsUpdate(e,t){this.resolvedProperty.fromArray(e,t),this.targetObject.needsUpdate=!0}_setValue_fromArray_setMatrixWorldNeedsUpdate(e,t){this.resolvedProperty.fromArray(e,t),this.targetObject.matrixWorldNeedsUpdate=!0}_getValue_unbound(e,t){this.bind(),this.getValue(e,t)}_setValue_unbound(e,t){this.bind(),this.setValue(e,t)}bind(){let t=this.node,n=this.parsedPath,r=n.objectName,i=n.propertyName,a=n.propertyIndex;if(t||(t=e.findNode(this.rootNode,n.nodeName),this.node=t),this.getValue=this._getValue_unavailable,this.setValue=this._setValue_unavailable,!t){R(`PropertyBinding: No target node found for track: `+this.path+`.`);return}if(r){let e=n.objectIndex;switch(r){case`materials`:if(!t.material){z(`PropertyBinding: Can not bind to material as node does not have a material.`,this);return}if(!t.material.materials){z(`PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.`,this);return}t=t.material.materials;break;case`bones`:if(!t.skeleton){z(`PropertyBinding: Can not bind to bones as node does not have a skeleton.`,this);return}t=t.skeleton.bones;for(let n=0;n<t.length;n++)if(t[n].name===e){e=n;break}break;case`map`:if(`map`in t){t=t.map;break}if(!t.material){z(`PropertyBinding: Can not bind to material as node does not have a material.`,this);return}if(!t.material.map){z(`PropertyBinding: Can not bind to material.map as node.material does not have a map.`,this);return}t=t.material.map;break;default:if(t[r]===void 0){z(`PropertyBinding: Can not bind to objectName of node undefined.`,this);return}t=t[r]}if(e!==void 0){if(t[e]===void 0){z(`PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.`,this,t);return}t=t[e]}}let o=t[i];if(o===void 0){let e=n.nodeName;z(`PropertyBinding: Trying to update property for track: `+e+`.`+i+` but it wasn't found.`,t);return}let s=this.Versioning.None;this.targetObject=t,t.isMaterial===!0?s=this.Versioning.NeedsUpdate:t.isObject3D===!0&&(s=this.Versioning.MatrixWorldNeedsUpdate);let c=this.BindingType.Direct;if(a!==void 0){if(i===`morphTargetInfluences`){if(!t.geometry){z(`PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.`,this);return}if(!t.geometry.morphAttributes){z(`PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.`,this);return}t.morphTargetDictionary[a]!==void 0&&(a=t.morphTargetDictionary[a])}c=this.BindingType.ArrayElement,this.resolvedProperty=o,this.propertyIndex=a}else o.fromArray!==void 0&&o.toArray!==void 0?(c=this.BindingType.HasFromToArray,this.resolvedProperty=o):Array.isArray(o)?(c=this.BindingType.EntireArray,this.resolvedProperty=o):this.propertyName=i;this.getValue=this.GetterByBindingType[c],this.setValue=this.SetterByBindingTypeAndVersioning[c][s]}unbind(){this.node=null,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}};ic.Composite=rc,ic.prototype.BindingType={Direct:0,EntireArray:1,ArrayElement:2,HasFromToArray:3},ic.prototype.Versioning={None:0,NeedsUpdate:1,MatrixWorldNeedsUpdate:2},ic.prototype.GetterByBindingType=[ic.prototype._getValue_direct,ic.prototype._getValue_array,ic.prototype._getValue_arrayElement,ic.prototype._getValue_toArray],ic.prototype.SetterByBindingTypeAndVersioning=[[ic.prototype._setValue_direct,ic.prototype._setValue_direct_setNeedsUpdate,ic.prototype._setValue_direct_setMatrixWorldNeedsUpdate],[ic.prototype._setValue_array,ic.prototype._setValue_array_setNeedsUpdate,ic.prototype._setValue_array_setMatrixWorldNeedsUpdate],[ic.prototype._setValue_arrayElement,ic.prototype._setValue_arrayElement_setNeedsUpdate,ic.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate],[ic.prototype._setValue_fromArray,ic.prototype._setValue_fromArray_setNeedsUpdate,ic.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]];var ac=new W,oc=class{constructor(e,t,n=0,r=1/0){this.ray=new ni(e,t),this.near=n,this.far=r,this.camera=null,this.layers=new pn,this.params={Mesh:{},Line:{threshold:1},LOD:{},Points:{threshold:1},Sprite:{}}}set(e,t){this.ray.set(e,t)}setFromCamera(e,t){t.isPerspectiveCamera?(this.ray.origin.setFromMatrixPosition(t.matrixWorld),this.ray.direction.set(e.x,e.y,.5).unproject(t).sub(this.ray.origin).normalize(),this.camera=t):t.isOrthographicCamera?(this.ray.origin.set(e.x,e.y,t.projectionMatrix.elements[14]).unproject(t),this.ray.direction.set(0,0,-1).transformDirection(t.matrixWorld),this.camera=t):z(`Raycaster: Unsupported camera type: `+t.type)}setFromXRController(e){return ac.identity().extractRotation(e.matrixWorld),this.ray.origin.setFromMatrixPosition(e.matrixWorld),this.ray.direction.set(0,0,-1).applyMatrix4(ac),this}intersectObject(e,t=!0,n=[]){return cc(e,this,n,t),n.sort(sc),n}intersectObjects(e,t=!0,n=[]){for(let r=0,i=e.length;r<i;r++)cc(e[r],this,n,t);return n.sort(sc),n}};function sc(e,t){return e.distance-t.distance}function cc(e,t,n,r){let i=!0;if(e.layers.test(t.layers)&&e.raycast(t,n)===!1&&(i=!1),i===!0&&r===!0){let r=e.children;for(let e=0,i=r.length;e<i;e++)cc(r[e],t,n,!0)}}we=class{constructor(e,t,n,r){this.elements=[1,0,0,1],e!==void 0&&this.set(e,t,n,r)}identity(){return this.set(1,0,0,1),this}fromArray(e,t=0){for(let n=0;n<4;n++)this.elements[n]=e[n+t];return this}set(e,t,n,r){let i=this.elements;return i[0]=e,i[2]=t,i[1]=n,i[3]=r,this}},we.prototype.isMatrix2=!0;var lc=class extends ra{constructor(e=10,t=10,n=4473924,r=8947848){n=new K(n),r=new K(r);let i=t/2,a=e/t,o=e/2,s=[],c=[];for(let e=0,l=0,u=-o;e<=t;e++,u+=a){s.push(-o,0,u,o,0,u),s.push(u,0,-o,u,0,o);let t=e===i?n:r;t.toArray(c,l),l+=3,t.toArray(c,l),l+=3,t.toArray(c,l),l+=3,t.toArray(c,l),l+=3}let l=new J;l.setAttribute(`position`,new q(s,3)),l.setAttribute(`color`,new q(c,3));let u=new Gi({vertexColors:!0,toneMapped:!1});super(l,u),this.type=`GridHelper`}dispose(){super.dispose(),this.geometry.dispose(),this.material.dispose()}};typeof __THREE_DEVTOOLS__<`u`&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent(`register`,{detail:{revision:`186`}})),typeof window<`u`&&(window.__THREE__?R(`WARNING: Multiple instances of Three.js being imported.`):window.__THREE__=`186`);var uc=[{name:`BUILDING_A`,label:`建筑 A`,x:16,z:-12,width:9,depth:9,height:13,color:2898500},{name:`BUILDING_B`,label:`建筑 B`,x:-20,z:10,width:11,depth:15,height:7,color:2766656},{name:`LAMP_POST`,label:`灯杆`,x:0,z:-16,width:.3,depth:.3,height:8,color:4477791},{name:`SKY_BRIDGE`,label:`天桥`,x:0,z:10.5,width:18,depth:6,height:2,color:3820117,baseY:7.5},{name:`TREE_1`,label:`树 1`,x:9,z:14,width:3.2,depth:3.2,height:6,color:2376762},{name:`TREE_2`,label:`树 2`,x:-10,z:-17,width:2.8,depth:2.8,height:4.6,color:2179130},{name:`TREE_3`,label:`树 3`,x:24,z:7,width:3,depth:3,height:5.4,color:2376762}],dc=2400,fc=3788976,pc=16762173,mc=10417407,hc=14679039,gc=1.7,_c=class{constructor(e,t=uc){i(this,`scene`,void 0),i(this,`group`,new kn),i(this,`homeMarker`,new G),i(this,`gridHelpers`,[]),i(this,`obstacles`,[]),i(this,`disposables`,[]),i(this,`trailPositions`,void 0),i(this,`trailLine`,null),i(this,`trailCount`,0),i(this,`lastTrailPoint`,new U(NaN,0,0)),i(this,`missionGroup`,new kn),i(this,`missionMarkerGroup`,new kn),i(this,`missionPathGroup`,new kn),i(this,`missionActiveGroup`,new kn),i(this,`missionSelectGroup`,new kn),i(this,`missionHoverGroup`,new kn),i(this,`missionDisposables`,[]),i(this,`missionMarkerNodes`,[]),i(this,`missionMarkers`,[]),i(this,`missionOrigin`,{x:0,z:0}),i(this,`missionPathLine`,null),i(this,`missionPathPositions`,null),i(this,`missionActiveAltitudeRing`,null),i(this,`missionSelectAltitudeRing`,null),i(this,`missionHoverAltitudeRing`,null),i(this,`missionVisible`,!0),i(this,`missionMarkersVisible`,!0),i(this,`missionPathVisible`,!0),i(this,`missionActiveIndex`,-1),i(this,`missionSelectIndex`,-1),i(this,`missionHoverIndex`,-1),i(this,`groundPlane`,new Nr(new U(0,1,0),0)),i(this,`groundHit`,new U),i(this,`missionPillarMaterial`,new ri({color:fc,transparent:!0,opacity:.26,side:2,depthWrite:!1,toneMapped:!1})),i(this,`missionRingMaterial`,new ri({color:fc,transparent:!0,opacity:.72,side:2,depthWrite:!1,toneMapped:!1})),i(this,`missionActiveMaterial`,new ri({color:pc,transparent:!0,opacity:.9,side:2,depthWrite:!1,toneMapped:!1})),i(this,`missionSelectMaterial`,new ri({color:mc,transparent:!0,opacity:.95,side:2,depthWrite:!1,toneMapped:!1})),i(this,`missionHoverMaterial`,new ri({color:hc,transparent:!0,opacity:.42,side:2,depthWrite:!1,toneMapped:!1})),i(this,`missionPickMaterial`,new ri({transparent:!0,opacity:0,side:2,depthWrite:!1,depthTest:!1})),i(this,`collisionBoxes`,[]),i(this,`specs`,void 0),this.scene=e,this.specs=t;let n=new Fo(4e3,4e3),r=new Bo({color:659990,roughness:.95,metalness:.05});this.disposables.push(n,r);let a=new Y(n,r);a.rotation.x=-Math.PI/2,a.position.y=-.012,a.receiveShadow=!0,this.group.add(a);let o=new lc(200,200,1916226,1323059);o.position.y=0,this.tintGrid(o,.55),this.group.add(o);let s=new lc(2e3,20,3108722,2050637);s.position.y=.004,this.tintGrid(s,.75),this.group.add(s),this.gridHelpers.push(o,s);let c=new Io(1.1,1.5,40);c.rotateX(-Math.PI/2);let l=new ri({color:7336144,transparent:!0,opacity:.7,side:2,toneMapped:!1});this.disposables.push(c,l);let u=new Y(c,l);u.position.y=.02,this.homeMarker.add(u);let d=new ha(.045,.045,3,8,1,!0);d.translate(0,1.5,0);let f=new ri({color:7336144,transparent:!0,opacity:.28,blending:2,depthWrite:!1,toneMapped:!1});this.disposables.push(d,f);let p=new Y(d,f);p.position.y=.02,this.homeMarker.add(p),this.group.add(this.homeMarker);for(let e of t){let t=e.baseY??0,n=new pa(e.width,e.height,e.depth),r=new Bo({color:e.color,roughness:.8,metalness:.12});this.disposables.push(n,r);let i=new Y(n,r);i.position.set(e.x,t+e.height/2,e.z),i.castShadow=!0,i.receiveShadow=!0,i.name=e.name,this.group.add(i),this.obstacles.push(i),this.collisionBoxes.push({name:e.label,minX:e.x-e.width/2,maxX:e.x+e.width/2,minY:t,maxY:t+e.height,minZ:e.z-e.depth/2,maxZ:e.z+e.depth/2,solid:!0})}this.trailPositions=new Float32Array(dc*3);let m=new J;m.setAttribute(`position`,new pr(this.trailPositions,3)),m.setDrawRange(0,0);let h=new Gi({color:8378623,transparent:!0,opacity:.75,toneMapped:!1});this.disposables.push(m,h),this.trailLine=new $i(m,h),this.trailLine.frustumCulled=!1,this.group.add(this.trailLine);let g=new Io(2.5,3.1,40);g.rotateX(-Math.PI/2);let _=new Y(g,this.missionActiveMaterial);_.position.y=.04,this.missionActiveGroup.add(_);let v=new Io(1.25,1.65,28);v.rotateX(-Math.PI/2),this.missionActiveAltitudeRing=new Y(v,this.missionActiveMaterial),this.missionActiveGroup.add(this.missionActiveAltitudeRing);let y=new Io(2.3,2.55,40);y.rotateX(-Math.PI/2);let b=new Y(y,this.missionSelectMaterial);b.position.y=.05,this.missionSelectGroup.add(b);let x=new Io(1.15,1.35,28);x.rotateX(-Math.PI/2),this.missionSelectAltitudeRing=new Y(x,this.missionSelectMaterial),this.missionSelectGroup.add(this.missionSelectAltitudeRing);let S=new Io(2.05,2.2,36);S.rotateX(-Math.PI/2);let C=new Y(S,this.missionHoverMaterial);C.position.y=.05,this.missionHoverGroup.add(C);let w=new Io(1,1.12,28);w.rotateX(-Math.PI/2),this.missionHoverAltitudeRing=new Y(w,this.missionHoverMaterial),this.missionHoverGroup.add(this.missionHoverAltitudeRing),this.disposables.push(g,v,y,x,S,w,this.missionPillarMaterial,this.missionRingMaterial,this.missionActiveMaterial,this.missionSelectMaterial,this.missionHoverMaterial,this.missionPickMaterial),this.missionActiveGroup.visible=!1,this.missionSelectGroup.visible=!1,this.missionHoverGroup.visible=!1,this.missionGroup.add(this.missionMarkerGroup),this.missionGroup.add(this.missionPathGroup),this.group.add(this.missionGroup),this.group.add(this.missionActiveGroup),this.group.add(this.missionSelectGroup),this.group.add(this.missionHoverGroup),e.add(this.group)}tintGrid(e,t){let n=e.material;(Array.isArray(n)?n:[n]).forEach(e=>{e.transparent=!0,e.opacity=t,e.depthWrite=!1,this.disposables.push(e)})}pushTrail(e,t,n){if(Number.isNaN(this.lastTrailPoint.x)&&this.lastTrailPoint.set(e,t,n),!(Math.hypot(e-this.lastTrailPoint.x,t-this.lastTrailPoint.y,n-this.lastTrailPoint.z)<.25)&&!(this.trailCount>=dc)&&(this.trailPositions[this.trailCount*3]=e,this.trailPositions[this.trailCount*3+1]=t,this.trailPositions[this.trailCount*3+2]=n,this.trailCount+=1,this.lastTrailPoint.set(e,t,n),this.trailLine)){let e=this.trailLine.geometry.getAttribute(`position`);e.needsUpdate=!0,this.trailLine.geometry.setDrawRange(0,this.trailCount),this.trailLine.geometry.computeBoundingSphere()}}clearTrail(){this.trailCount=0,this.lastTrailPoint.set(NaN,0,0),this.trailLine&&this.trailLine.geometry.setDrawRange(0,0)}getTrail(){return{positions:this.trailPositions,count:this.trailCount}}setObstaclesVisible(e){this.obstacles.forEach(t=>{t.visible=e})}setCaptureHelpersVisible(e){this.homeMarker.visible=e,this.trailLine&&(this.trailLine.visible=e),this.missionGroup.visible=e;for(let t of this.gridHelpers)t.visible=e}coneCast(e,t,n,r,i,a,o){let s=null;for(let c of this.collisionBoxes){let l=(c.minX+c.maxX)/2,u=(c.minY+c.maxY)/2,d=(c.minZ+c.maxZ)/2,f=(c.maxX-c.minX)/2,p=(c.maxY-c.minY)/2,m=(c.maxZ-c.minZ)/2,h=e=>Math.abs(e.x)*f+Math.abs(e.y)*p+Math.abs(e.z)*m,g=l-e.x,_=u-e.y,v=d-e.z,y=g*t.x+_*t.y+v*t.z,b=h(t),x=y-b;if(x>o||y+b<0)continue;let S=Math.abs(g*n.x+_*n.y+v*n.z)-h(n),C=Math.abs(g*r.x+_*r.y+v*r.z)-h(r),w=Math.max(0,S),T=Math.max(0,C),E=Math.max(x,.05);if((w/(E*i))**2+(T/(E*a))**2>1)continue;let D=Math.min(Math.max(e.x,c.minX),c.maxX),O=Math.min(Math.max(e.y,c.minY),c.maxY),k=Math.min(Math.max(e.z,c.minZ),c.maxZ),A=Math.max(0,(D-e.x)*t.x+(O-e.y)*t.y+(k-e.z)*t.z);(!s||A<s.distance)&&(s={distance:A,label:c.name})}return s}setMissionWaypoints(e,t){this.clearMissionWaypoints(),this.missionOrigin={x:t.x,z:t.z};for(let t of e)this.missionMarkers.push({x:t.x,z:t.z,altitude:t.altitude});if(e.length===0)this.applyMissionVisibility();else{for(let t=0;t<e.length;t+=1){let n=e[t];if(!n)continue;let r=Math.max(1,n.altitude),i=new kn;i.position.set(n.x,0,n.z);let a=new Io(1.7,2.05,36);a.rotateX(-Math.PI/2);let o=new Y(a,this.missionRingMaterial);o.position.y=.03,i.add(o);let s=new ha(.07,.07,1,6,1,!0);s.translate(0,.5,0);let c=new Y(s,this.missionPillarMaterial);c.scale.y=r,i.add(c);let l=new Io(.8,1.1,28);l.rotateX(-Math.PI/2);let u=new Y(l,this.missionRingMaterial);u.position.y=r,i.add(u);let d=this.createMissionLabel(`${t+1}`,r+2);i.add(d);let f=new ha(gc,gc,1,10,1,!0),p=new Y(f,this.missionPickMaterial);p.scale.y=r,p.position.y=r/2,i.add(p),this.missionDisposables.push(a,s,l,f),this.missionMarkerGroup.add(i),this.missionMarkerNodes.push({group:i,pillar:c,altitudeRing:u,label:d,pick:p})}this.buildMissionPath(),this.applyMissionVisibility()}}updateMissionWaypoint(e,t){let n=this.missionMarkerNodes[e],r=this.missionMarkers[e];if(!n||!r)return;r.x=t.x,r.z=t.z,r.altitude=t.altitude;let i=Math.max(1,t.altitude);n.group.position.set(t.x,0,t.z),n.pillar.scale.y=i,n.altitudeRing.position.y=i,n.label.position.y=i+2,n.pick.scale.y=i,n.pick.position.y=i/2,this.refreshMissionPath(),this.missionActiveIndex===e&&this.setMissionActive(e,null),this.missionSelectIndex===e&&this.setMissionSelection(e,null),this.missionHoverIndex===e&&this.setMissionHover(e,null)}setMissionActive(e,t){this.missionActiveIndex=e>=0?e:-1,this.placeHighlightGroup(this.missionActiveGroup,this.missionActiveAltitudeRing,e,t)}setMissionSelection(e,t=null){this.missionSelectIndex=e>=0?e:-1,this.placeHighlightGroup(this.missionSelectGroup,this.missionSelectAltitudeRing,e,t)}setMissionHover(e,t=null){this.missionHoverIndex=e>=0?e:-1,this.placeHighlightGroup(this.missionHoverGroup,this.missionHoverAltitudeRing,e,t)}placeHighlightGroup(e,t,n,r){let i=n>=0?r??this.missionMarkers[n]??null:null;i?(e.position.set(i.x,0,i.z),t&&(t.position.y=Math.max(1,i.altitude)),e.visible=this.missionVisible):e.visible=!1}pickMissionWaypoint(e){if(!this.missionVisible||!this.missionMarkersVisible||this.missionMarkerNodes.length===0)return-1;let t=this.missionMarkerNodes.map(e=>e.pick),n=e.intersectObjects(t,!1)[0];return n?this.missionMarkerNodes.findIndex(e=>e.pick===n.object):-1}pickMissionGround(e){let t=e.ray.intersectPlane(this.groundPlane,this.groundHit);return t?{x:t.x,z:t.z}:null}setMissionVisible(e){this.missionVisible=e,this.applyMissionVisibility()}isMissionVisible(){return this.missionVisible}setMissionWaypointsVisible(e){this.missionMarkersVisible=e,this.applyMissionVisibility()}isMissionWaypointsVisible(){return this.missionMarkersVisible}setMissionPathVisible(e){this.missionPathVisible=e,this.applyMissionVisibility()}isMissionPathVisible(){return this.missionPathVisible}applyMissionVisibility(){this.missionGroup.visible=this.missionVisible,this.missionMarkerGroup.visible=this.missionVisible&&this.missionMarkersVisible,this.missionPathGroup.visible=this.missionVisible&&this.missionPathVisible,this.missionActiveGroup.visible=this.missionVisible&&this.missionActiveIndex>=0,this.missionSelectGroup.visible=this.missionVisible&&this.missionSelectIndex>=0,this.missionHoverGroup.visible=this.missionVisible&&this.missionHoverIndex>=0}buildMissionPath(){if(this.missionMarkers.length===0)return;let e=this.missionMarkers.length+1;this.missionPathPositions=new Float32Array(e*3);let t=new J;t.setAttribute(`position`,new pr(this.missionPathPositions,3));let n=new Ho({color:fc,transparent:!0,opacity:.55,dashSize:1.6,gapSize:1.1,toneMapped:!1}),r=new $i(t,n);r.frustumCulled=!1,this.writeMissionPathPositions(),r.computeLineDistances(),this.missionPathLine=r,this.missionPathGroup.add(r),this.missionDisposables.push(t,n)}refreshMissionPath(){let e=this.missionPathLine;if(!e)return;this.writeMissionPathPositions();let t=e.geometry.getAttribute(`position`);t.needsUpdate=!0,e.geometry.computeBoundingSphere(),e.computeLineDistances()}writeMissionPathPositions(){let e=this.missionPathPositions;if(!e)return;let t=this.missionMarkers[0];if(t){e[0]=this.missionOrigin.x,e[1]=Math.max(1,t.altitude),e[2]=this.missionOrigin.z;for(let t=0;t<this.missionMarkers.length;t+=1){let n=this.missionMarkers[t];if(!n)continue;let r=(t+1)*3;e[r]=n.x,e[r+1]=Math.max(1,n.altitude),e[r+2]=n.z}}}clearMissionWaypoints(){this.missionMarkerGroup.clear(),this.missionPathGroup.clear(),this.missionMarkerNodes.length=0,this.missionMarkers.length=0,this.missionPathLine=null,this.missionPathPositions=null,this.missionDisposables.forEach(e=>e.dispose()),this.missionDisposables.length=0}createMissionLabel(e,t){let n=document.createElement(`canvas`);n.width=96,n.height=96;let r=new fa(n),i=n.getContext(`2d`);i&&(i.fillStyle=`rgba(7, 26, 30, 0.84)`,i.beginPath(),i.arc(48,48,43,0,Math.PI*2),i.fill(),i.lineWidth=4,i.strokeStyle=`#39d0b0`,i.stroke(),i.fillStyle=`#d8fff5`,i.font=`bold 46px ui-sans-serif, system-ui, sans-serif`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(e,48,50),r.needsUpdate=!0);let a=new Ir({map:r,transparent:!0,depthWrite:!1,toneMapped:!1}),o=new Xr(a);return o.position.y=t,o.scale.setScalar(2.4),this.missionDisposables.push(r,a),o}setHome(e,t){this.homeMarker.position.set(e,0,t)}destroy(){this.scene.remove(this.group),this.clearMissionWaypoints(),this.disposables.forEach(e=>e.dispose()),this.disposables.length=0,this.obstacles.length=0,this.collisionBoxes.length=0,this.trailLine=null,this.missionActiveAltitudeRing=null,this.missionSelectAltitudeRing=null,this.missionHoverAltitudeRing=null,this.missionGroup.clear(),this.missionSelectGroup.clear(),this.missionHoverGroup.clear()}},vc=[`FrontLeft`,`FrontRight`,`RearLeft`,`RearRight`],yc=e=>e*Math.PI/180,bc={FrontLeft:-1,RearRight:-1,FrontRight:1,RearLeft:1},xc={FrontLeft:`前左机臂`,FrontRight:`前右机臂`,RearLeft:`后左机臂`,RearRight:`后右机臂`},Sc={Hip:65,Knee:-145,Ankle:45},Cc=new U(1,0,0),wc=new It,Tc=.3,Ec=.08,Dc={pitchMin:-90,pitchMax:60,rollLimit:45,yawLimit:5},Oc=new It,kc=new It,Ac=new U,jc=new fn,Mc=new U(0,1,0),Nc=.02,Pc=9,Fc=.01,Ic=.004,Lc=(e,t)=>`${Math.round(e/Fc)},${Math.round(t/Fc)}`,Rc=(e,t,n,r)=>{let i=e.get(t);if(!i)e.set(t,[{lo:n,hi:r}]);else{for(let e of i)if(n<=e.hi+1e-4&&r>=e.lo-1e-4){e.lo=Math.min(e.lo,n),e.hi=Math.max(e.hi,r);return}i.push({lo:n,hi:r})}},zc=(e,t,n,r)=>{let i=e.get(Lc(t,r));if(!i)return 0;let a=0;for(let e of i)if(n<e.hi&&n>e.lo-Ic){let t=e.hi-n;t>a&&(a=t)}return a},Bc=e=>{let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)},Vc=class{constructor(e){i(this,`model`,void 0),i(this,`parts`,[]),i(this,`root`,void 0),i(this,`rigBonesRoot`,void 0),i(this,`props`,[]),i(this,`arms`,[]),i(this,`legs`,[]),i(this,`gimbalYaw`,null),i(this,`gimbalPitch`,null),i(this,`gimbalRoll`,null),i(this,`gimbalPod`,null),i(this,`gimbalClearanceLocal`,0),i(this,`gimbalBodyClearanceLocal`,0),i(this,`gimbalBindPosition`,new U),i(this,`gimbalCenterOffset`,new U),i(this,`gimbalMountLocal`,new U),i(this,`gimbalMountReady`,!1),i(this,`gimbalMountQuat`,new It),i(this,`gimbalOrientationReady`,!1),i(this,`gimbalScratchQuat`,new It),i(this,`gimbalJointYaw`,0),i(this,`gimbalJointPitch`,0),i(this,`gimbalJointRoll`,0),i(this,`gimbalBodyQuat`,new It),i(this,`gimbalTargetQuat`,new It),i(this,`gimbalJointQuat`,new It),i(this,`gimbalResponse`,Nc),i(this,`disposables`,[]),i(this,`fold`,0),i(this,`spinAngle`,0),i(this,`lastLoad`,0),i(this,`legDeployState`,1),i(this,`bladeOpenState`,1),i(this,`stancePitchOpen`,0),i(this,`stanceDropOpen`,0),i(this,`stanceDropFolded`,0),this.model=e,e.updateMatrixWorld(!0),this.root=e.getObjectByName(`CTRL_DJI_Root`)??null,this.rigBonesRoot=e.getObjectByName(`RIG_DJI_Arms_Props`)??null,this.collectParts(),this.buildProps(),this.buildArms(),this.collectLegs(),this.computeBladeFold(),this.computeStanceTrim(),this.bindGimbal()}get armFold(){return this.fold}get bladeOpen(){return this.bladeOpenState}get motorsSpinning(){return this.spinAngle>0}setArmFold(e){let t=Math.max(0,Math.min(1,e));Math.abs(t-this.fold)<1e-4||(this.fold=t,this.arms.forEach(e=>{this.applyArmFold(e,t)}))}applyArmFold(e,t){kc.setFromAxisAngle(Mc,e.foldAngle*t),e.node.quaternion.copy(kc).multiply(e.bindQuaternion)}get legDeploy(){return this.legs.length===0?1:this.legDeployState}setLegDeploy(e){if(this.legs.length===0)return;let t=Hc(e,0,1);if(Math.abs(t-this.legDeployState)<1e-4)return;this.legDeployState=t;let n=1-t;for(let e of this.legs)for(let t of e.joints)wc.setFromAxisAngle(Cc,t.foldAngle*n),t.node.quaternion.copy(wc).multiply(t.bindQuaternion)}collectLegs(){let e=/^LEG_(FrontLeft|FrontRight|RearLeft|RearRight)_(Hip|Knee|Ankle)$/;this.model.traverse(t=>{let n=e.exec(t.name);if(!n)return;let r=n[1],i=this.legs.find(e=>e.position===r);i||(i={position:r,joints:[]},this.legs.push(i)),i.joints.push({node:t,bindQuaternion:t.quaternion.clone(),foldAngle:yc(Sc[n[2]])})})}updateBlades(e){let t=+(this.lastLoad>.01||this.fold<.02),n=Pc;this.bladeOpenState+=(t-this.bladeOpenState)*Math.min(1,e*n),Math.abs(t-this.bladeOpenState)<.002&&(this.bladeOpenState=t);let r=1-this.bladeOpenState,i=Bc(this.fold);for(let e of this.props){this.applyBladeFold(e,r);for(let t of e.lifts)t.node.position.copy(t.bindPosition).addScaledVector(t.axisParent,e.foldLift*t.localUnits*i)}}applyBladeFold(e,t){for(let[n,r]of e.blades.entries())kc.setFromAxisAngle(e.bladeFoldAxis,r.stackYaw*t),r.mesh.position.copy(r.bindPosition).applyQuaternion(kc),r.mesh.quaternion.copy(kc).multiply(r.bindQuaternion),n===1&&r.mesh.position.addScaledVector(e.bladeFoldAxis,.012*e.localUnits*t)}applyPropRotation(e){for(let t of e.spinners)Oc.setFromAxisAngle(t.axisParent,e.angle),t.node.quaternion.copy(Oc).multiply(t.bindQuaternion)}updateProps(e,t){let n=typeof e==`number`?e:null;this.lastLoad=Math.max(0,Math.min(1.15,n??Math.max(...Object.values(e??{}),0)));let r=0;for(let n of this.props){let i=typeof e==`number`?e:e?.[n.position]??0,a=Math.max(0,Math.min(1.15,i));if(r=Math.max(r,a),a<=.01)continue;let o=3.8+a*7;n.angle=(n.angle+o*t*n.spinSign*Math.PI*2)%(Math.PI*2),this.applyPropRotation(n)}}applyBodyPose(e){let t=1-this.fold;this.model.position.set(e.x,e.y-this.stanceDropOpen*t-this.stanceDropFolded*this.fold,e.z),this.model.rotation.y=-yc(e.headingDeg);let n=yc(e.pitchDeg+this.stancePitchOpen*t),r=-yc(e.rollDeg);this.root&&(this.root.rotation.x=n,this.root.rotation.z=r),this.rigBonesRoot&&(this.rigBonesRoot.rotation.x=n,this.rigBonesRoot.rotation.z=r)}setGimbalAttitude(e,t,n,r=0,i=0,a=0){if(!this.gimbalYaw&&!this.gimbalPitch&&!this.gimbalRoll)return;let o=this.model.rotation.y+yc(n);this.gimbalTargetQuat.setFromEuler(jc.set(yc(e),o,-yc(t),`YXZ`));let s=this.gimbalYaw?.parent??this.gimbalRoll?.parent??this.gimbalPitch?.parent??null;s&&(s.updateWorldMatrix(!0,!1),s.getWorldQuaternion(this.gimbalBodyQuat),this.gimbalTargetQuat.premultiply(this.gimbalBodyQuat.invert())),jc.setFromQuaternion(this.gimbalTargetQuat,`YXZ`);let c=yc(Dc.yawLimit),l=Hc(jc.y,-c,c),u=Hc(jc.x,yc(Dc.pitchMin),yc(Dc.pitchMax)),d=yc(Dc.rollLimit),f=Hc(jc.z,-d,d),p=a>0&&this.gimbalResponse>0?1-Math.exp(-a/this.gimbalResponse):1;this.gimbalJointYaw+=(l-this.gimbalJointYaw)*p,this.gimbalJointPitch+=(u-this.gimbalJointPitch)*p,this.gimbalJointRoll+=(f-this.gimbalJointRoll)*p,this.gimbalPitch&&(this.gimbalPitch.rotation.x=this.gimbalJointPitch),this.gimbalRoll&&(this.gimbalRoll.rotation.z=this.gimbalJointRoll),this.gimbalYaw&&(this.gimbalYaw.rotation.y=this.gimbalJointYaw),this.gimbalYaw&&this.gimbalCenterOffset.lengthSq()>1e-10&&(this.gimbalJointQuat.setFromEuler(jc.set(this.gimbalJointPitch,this.gimbalJointYaw,this.gimbalJointRoll,`YXZ`)),Ac.copy(this.gimbalCenterOffset).applyQuaternion(this.gimbalJointQuat),this.gimbalYaw.position.copy(this.gimbalBindPosition).add(this.gimbalCenterOffset).sub(Ac))}getGimbalCameraTransform(e){return this.gimbalRoll?(this.gimbalRoll.updateWorldMatrix(!0,!1),this.gimbalRoll.getWorldPosition(e.position),this.gimbalRoll.getWorldQuaternion(e.quaternion),!0):!1}getGimbalCameraMount(e,t,n=0){if(!this.gimbalMountReady)return!1;let r=this.model.rotation.y;e.copy(this.gimbalMountLocal).multiply(this.model.scale).applyAxisAngle(Mc,r).add(this.model.position);let i=yc(n);return Ac.set(0,0,-1).applyAxisAngle(Mc,r),e.addScaledVector(Ac,t*Math.cos(i)),e.y+=t*Math.sin(i),!0}getGimbalCameraOrientation(e,t,n,r){if(!this.gimbalOrientationReady)return!1;let i=this.model.rotation.y+yc(r);return e.setFromEuler(jc.set(yc(t),i,-yc(n),`YXZ`)),e.multiply(this.gimbalMountQuat),!0}destroy(){this.disposables.forEach(e=>e.dispose()),this.disposables.length=0,this.props.length=0,this.arms.length=0}collectParts(){for(let e of[{id:`BODY_Main_Fuselage`,label:`机身主体`},{id:`BODY_Black_Underside_SensorHousing`,label:`黑色下壳`},{id:`GIMBAL_CameraHousing`,label:`云台相机壳体`},{id:`GIMBAL_CameraLensFrame`,label:`云台镜头框`},{id:`GIMBAL_Camera_SideRing_Right`,label:`云台侧环`},{id:`SENSOR_Glass_GimbalLens`,label:`云台主镜片`},{id:`SENSOR_Glass_Front_Left`,label:`前视玻璃(左)`},{id:`SENSOR_Glass_Front_Right`,label:`前视玻璃(右)`},{id:`SENSOR_Glass_Side_Left`,label:`侧视玻璃(左)`},{id:`SENSOR_Glass_Side_Right`,label:`侧视玻璃(右)`},{id:`SENSOR_Glass_Downward`,label:`下视玻璃`},{id:`SENSOR_FrontHousing_Left`,label:`前视壳体(左)`},{id:`SENSOR_FrontHousing_Right`,label:`前视壳体(右)`},{id:`LED_Status_Tail_Left`,label:`尾灯(左)`},{id:`LED_Status_Tail_Right`,label:`尾灯(右)`},{id:`LED_BatteryCharge_01`,label:`电池指示灯珠 1`},{id:`LED_BatteryCharge_02`,label:`电池指示灯珠 2`},{id:`LED_BatteryCharge_03`,label:`电池指示灯珠 3`},{id:`LED_BatteryCharge_04`,label:`电池指示灯珠 4`},{id:`BUTTON_Power`,label:`电源按键`},{id:`DECAL_Text_Labels`,label:`文字贴花`},{id:`SRC_GeometryRoot`,label:`几何根节点`},{id:`SRC_TailStatusLED_Group`,label:`尾灯几何组`},{id:`SRC_Decals_Group`,label:`贴花几何组`},{id:`SRC_BlackHousing_Group`,label:`黑色壳体组`},{id:`SRC_SensorGlass_Group`,label:`传感器玻璃组`},{id:`CTRL_DJI_Root`,label:`整机总控`,drivable:!0},{id:`CTRL_Gimbal_Yaw`,label:`云台偏航`,drivable:!0},{id:`CTRL_Gimbal_Pitch`,label:`云台俯仰`,drivable:!0},{id:`CTRL_Gimbal_Roll`,label:`云台横滚`,drivable:!0}])this.parts.push({id:e.id,label:e.label,found:this.model.getObjectByName(e.id)!==void 0,drivable:e.drivable??!1});for(let e of vc)this.parts.push({id:`ARM_${e}`,label:`${xc[e]}网格`,found:this.model.getObjectByName(`ARM_${e}`)!==void 0,drivable:!1}),this.parts.push({id:`CTRL_Arm_${e}_Fold`,label:`${xc[e]}折叠`,found:this.model.getObjectByName(`CTRL_Arm_${e}_Fold`)!==void 0,drivable:!0}),this.parts.push({id:`CTRL_Prop_${e}_Spin`,label:`${xc[e]}桨叶自转`,found:this.model.getObjectByName(`CTRL_Prop_${e}_Spin`)!==void 0,drivable:!0}),this.parts.push({id:`ROTOR_${e}`,label:`${xc[e]}转子桨毂`,found:this.model.getObjectByName(`ROTOR_${e}`)!==void 0,drivable:!0}),this.parts.push({id:`MOTOR_${e}_RotorBell`,label:`${xc[e]}电机钟罩(固定外壳)`,found:this.model.getObjectByName(`MOTOR_${e}_RotorBell`)!==void 0,drivable:!1})}buildProps(){this.model.updateMatrixWorld(!0);for(let e of vc){let t=this.model.getObjectByName(`CTRL_Prop_${e}_Spin`);if(!t)continue;let n=t.getObjectByName(`MOTOR_${e}_RotorBell`);n&&t.parent&&(t.parent.attach(n),this.model.updateMatrixWorld(!0));let r=new U(0,1,0).applyQuaternion(t.getWorldQuaternion(new It)).normalize(),i=[];for(let t of[1,2]){let n=this.model.getObjectByName(`PROP_${e}_Blade_${t}`);n?.isMesh&&i.push({mesh:n,bindPosition:n.position.clone(),bindQuaternion:n.quaternion.clone(),stackYaw:0})}let a=e=>{let t=(e??this.model).getWorldQuaternion(new It).invert();return r.clone().applyQuaternion(t).normalize()},o=[],s=e=>{o.push({node:e,bindQuaternion:e.quaternion.clone(),axisParent:a(e.parent)})};s(t);for(let t of[1,2]){let n=this.model.getObjectByName(`PROP_${e}_Blade_${t}_Fold_Bone`);n&&s(n)}let c=a(i[0]?.mesh.parent??t),l=[],u=e=>{l.push({node:e,bindPosition:e.position.clone(),axisParent:a(e.parent),localUnits:1/e.matrixWorld.getMaxScaleOnAxis()})};u(t),o.forEach(e=>{e.node!==t&&u(e.node)}),this.props.push({position:e,node:t,bindPosition:t.position.clone(),spinSign:bc[e],angle:0,bindQuaternion:t.quaternion.clone(),blades:i,bladeFoldAxis:c,spinners:o,lifts:l,foldLift:0,localUnits:1/t.matrixWorld.getMaxScaleOnAxis()})}}computeBladeFold(){this.model.updateMatrixWorld(!0);let e=new Map;this.arms.forEach(e=>{this.applyArmFold(e,1)}),this.model.updateMatrixWorld(!0);let t=this.buildBodyHeightfield();for(let n of this.props){let r=this.arms.find(e=>e.position===n.position);if(!r||n.blades.length===0)continue;let i=r.node.getWorldPosition(new U),a=n.node.getWorldPosition(new U).clone().sub(i);if(a.y=0,a.lengthSq()<1e-6)continue;a.normalize();let o=n.blades[0];if(!o)continue;let s=n.bladeFoldAxis,c=(o.mesh.parent??n.node).getWorldQuaternion(new It),l=a.clone().applyQuaternion(c.clone().invert());if(l.addScaledVector(s,-s.dot(l)),l.lengthSq()<1e-6)continue;l.normalize();for(let e of n.blades){let t=new Yn().setFromObject(e.mesh).getCenter(new U),r=new W().copy((e.mesh.parent??n.node).matrixWorld).invert(),i=t.applyMatrix4(r);if(i.addScaledVector(s,-s.dot(i)),i.lengthSq()<1e-6)continue;i.normalize();let a=new U().crossVectors(i,l);e.stackYaw=Math.atan2(a.dot(s),i.dot(l))}let u=0,d=1/0,f=-1;for(let r=-180;r<180;r+=5){let i=this.measureStackPenetration(n,yc(r),t,e),a=this.stackAxisAlignment(n);(i<d-1e-6||Math.abs(i-d)<=1e-6&&a>f+1e-6)&&(d=i,f=a,u=r)}let p=u;for(let r=p-4;r<=p+4;r+=1){let i=this.measureStackPenetration(n,yc(r),t,e),a=this.stackAxisAlignment(n);(i<d-1e-6||Math.abs(i-d)<=1e-6&&a>f+1e-6)&&(d=i,f=a,u=r)}n.blades.forEach(e=>{e.stackYaw+=yc(u)}),n.foldLift=d>.004?Hc(d+.008,0,.2):0,this.applyBladeFold(n,1),this.model.updateMatrixWorld(!0);let m=new U;for(let t of n.blades){let n=t.mesh.geometry.getAttribute(`position`);for(let r=0;r<n.count;r+=1)m.fromBufferAttribute(n,r).applyMatrix4(t.mesh.matrixWorld),Rc(e,Lc(m.x,m.z),m.y-.004,m.y+.004)}}this.arms.forEach(e=>{this.applyArmFold(e,0)}),this.model.updateMatrixWorld(!0)}stackAxisAlignment(e){let t=e.blades[0];if(!t)return 0;let n=e.node.getWorldPosition(new U),r=new Yn().setFromObject(t.mesh).getCenter(new U).sub(n);r.y=0;let i=r.length();return i<1e-6?0:Math.abs(r.z)/i}measureStackPenetration(e,t,n,r){let i=e.blades.map(e=>e.stackYaw);e.blades.forEach(e=>{e.stackYaw+=t}),this.applyBladeFold(e,1),this.model.updateMatrixWorld(!0);let a=new U,o=0;for(let t of e.blades){let e=t.mesh.geometry.getAttribute(`position`);for(let i=0;i<e.count;i+=1){a.fromBufferAttribute(e,i).applyMatrix4(t.mesh.matrixWorld);let s=zc(n,a.x,a.y,a.z);s>o&&(o=s);let c=zc(r,a.x,a.y,a.z);c>o&&(o=c)}}return e.blades.forEach((e,t)=>{let n=i[t];n!==void 0&&(e.stackYaw=n)}),o}buildBodyHeightfield(){let e=new Map,t=new U;return this.model.traverse(n=>{let r=n;if(!r.isMesh||!r.geometry||!r.name.startsWith(`BODY_`)&&!r.name.startsWith(`ARM_`)&&!r.name.startsWith(`MOTOR_`))return;let i=r.geometry.getAttribute(`position`);for(let n=0;n<i.count;n+=1)t.fromBufferAttribute(i,n).applyMatrix4(r.matrixWorld),Rc(e,Lc(t.x,t.z),t.y,t.y)}),e}buildArms(){let e=new U,t=new U;for(let n of vc){let r=this.model.getObjectByName(`ARM_${n}_Fold_Bone`)??this.model.getObjectByName(`CTRL_Arm_${n}_Fold`),i=this.model.getObjectByName(`CTRL_Prop_${n}_Spin`);if(!r||!i)continue;r.getWorldPosition(e),i.getWorldPosition(t);let a=t.x-e.x,o=t.z-e.z,s=Math.atan2(o,a)-(n.startsWith(`Front`)?Math.atan2(1,0):Math.atan2(-1,0));s=((s+Math.PI)%(Math.PI*2)+Math.PI*2)%(Math.PI*2)-Math.PI,this.arms.push({position:n,node:r,bindQuaternion:r.quaternion.clone(),foldAngle:s})}}computeStanceTrim(){this.model.updateMatrixWorld(!0);let e=new W().copy(this.model.matrixWorld).invert(),t=this.arms.map(e=>e.node.quaternion.clone());this.arms.forEach(e=>{this.applyArmFold(e,0)}),this.model.updateMatrixWorld(!0);let n=this.scanStanceContacts(e),r=this.measureMotorForwardTilt();if(r!==null)this.stancePitchOpen=Ft.radToDeg(Hc(r,-yc(25),yc(25)));else if(n.front&&n.rear){let e=n.front.z-n.rear.z;if(Math.abs(e)>.001){let t=Hc(Math.atan((n.front.y-n.rear.y)/e),-yc(25),yc(25));this.stancePitchOpen=Ft.radToDeg(t)}}this.stancePitchOpen!==0&&(this.setBodyPitchRad(yc(this.stancePitchOpen)),this.model.updateMatrixWorld(!0),this.stanceDropOpen=this.measureLowest([`GEAR_`,`BODY_`]),this.setBodyPitchRad(0),this.model.updateMatrixWorld(!0)),this.arms.forEach((e,n)=>{let r=t[n];r&&e.node.quaternion.copy(r)}),this.model.updateMatrixWorld(!0),this.stanceDropFolded=Math.max(0,this.model.position.y-this.measureLowest([`BODY_`,`ARM_`,`MOTOR_`]))}setBodyPitchRad(e){this.root&&(this.root.rotation.x=e),this.rigBonesRoot&&(this.rigBonesRoot.rotation.x=e)}measureMotorForwardTilt(){if(this.props.length===0)return null;let e=new U,t=0,n=0;for(let r of this.props)e.set(0,1,0).transformDirection(r.node.matrixWorld),Number.isFinite(e.z)&&(t+=Math.asin(Ft.clamp(-e.z,-1,1)),n+=1);return n>0?t/n:null}measureLowest(e,t){let n=new U,r=1/0;return this.model.traverse(i=>{let a=i;if(!a.isMesh||!a.geometry||!e.some(e=>a.name.startsWith(e)))return;let o=a.geometry.getAttribute(`position`);for(let e=0;e<o.count;e+=1)n.fromBufferAttribute(o,e).applyMatrix4(a.matrixWorld),t&&n.applyMatrix4(t),n.y<r&&(r=n.y)}),Number.isFinite(r)?r:0}scanStanceContacts(e){let t=new U,n=null,r=null;return this.model.traverse(i=>{let a=i;if(!a.isMesh||!a.geometry)return;let o=a.name.startsWith(`GEAR_`),s=a.name.startsWith(`BODY_`);if(!o&&!s)return;let c=a.geometry.getAttribute(`position`);for(let i=0;i<c.count;i+=1)t.fromBufferAttribute(c,i).applyMatrix4(a.matrixWorld).applyMatrix4(e),o&&(n===null||t.y<n.y)&&(n=t.clone()),s&&t.z>.15&&(r===null||t.y<r.y)&&(r=t.clone())}),{front:n,rear:r}}bindGimbal(){if(this.gimbalYaw=this.model.getObjectByName(`CTRL_Gimbal_Yaw`)??null,this.gimbalPitch=this.model.getObjectByName(`CTRL_Gimbal_Pitch`)??null,this.gimbalRoll=this.model.getObjectByName(`CTRL_Gimbal_Roll`)??null,this.gimbalYaw?.parent){this.gimbalBindPosition.copy(this.gimbalYaw.position);let e=this.gimbalRoll??this.gimbalYaw;this.model.updateWorldMatrix(!0,!0);let t=e.getWorldPosition(new U);this.gimbalMountLocal.copy(this.model.worldToLocal(t)),this.gimbalMountReady=!0;let n=this.gimbalRoll??this.gimbalPitch??this.gimbalYaw;n&&(n.updateWorldMatrix(!0,!1),n.getWorldQuaternion(this.gimbalMountQuat),this.gimbalMountQuat.premultiply(this.gimbalScratchQuat.setFromAxisAngle(Mc,-this.model.rotation.y)),this.gimbalOrientationReady=!0);let r=this.model.getObjectByName(`GIMBAL_BlackCameraPod`)??this.gimbalRoll;if(this.gimbalPod=r,this.measureGimbalClearance(r),this.measureBodyClearance(),r){let e=new Yn,t=!1;if(r.traverse(n=>{let r=n;r.isMesh&&r.geometry&&(t=!0,e.union(new Yn().setFromObject(r)))}),t&&!e.isEmpty()){let t=e.getCenter(new U);this.gimbalYaw.parent.updateWorldMatrix(!0,!1);let n=this.gimbalYaw.parent.matrixWorld.clone().invert();t.applyMatrix4(n),this.gimbalCenterOffset.copy(t).sub(this.gimbalBindPosition)}}}}measureGimbalClearance(e){this.gimbalClearanceLocal=0;let t=e??this.gimbalRoll;if(!t||!this.gimbalRoll)return;t.updateWorldMatrix(!0,!0);let n=new Yn().setFromObject(t);if(n.isEmpty())return;this.gimbalRoll.updateWorldMatrix(!0,!1);let r=this.gimbalRoll.matrixWorld.clone().invert(),i=new U,a=1/0;for(let e=0;e<8;e+=1)i.set(e&1?n.max.x:n.min.x,e&2?n.max.y:n.min.y,e&4?n.max.z:n.min.z),i.applyMatrix4(r),i.z<a&&(a=i.z);Number.isFinite(a)&&(this.gimbalClearanceLocal=Math.max(0,-a))}measureBodyClearance(){if(this.gimbalBodyClearanceLocal=0,!this.gimbalMountReady)return;let e=this.model.getWorldScale(new U),t=(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z))/3;if(t<=0)return;let n=Tc/t,r=this.gimbalMountLocal;this.model.updateWorldMatrix(!0,!1);let i=this.model.matrixWorld.clone().invert(),a=new Yn,o=new U,s=0;this.model.traverse(e=>{let t=e;if(t.isMesh&&t.geometry&&(a.setFromObject(t),!a.isEmpty()))for(let e=0;e<8;e+=1){o.set(e&1?a.max.x:a.min.x,e&2?a.max.y:a.min.y,e&4?a.max.z:a.min.z),o.applyMatrix4(i);let t=o.z-r.z;t>=0||Math.abs(o.x-r.x)>n||Math.abs(o.y-r.y)>n||-t>s&&(s=-t)}}),this.gimbalBodyClearanceLocal=s}getGimbalCameraClearance(){if(!this.gimbalRoll)return null;this.gimbalRoll.updateWorldMatrix(!0,!1);let e=this.gimbalRoll.getWorldScale(new U),t=(Math.abs(e.x)+Math.abs(e.y)+Math.abs(e.z))/3,n=this.gimbalClearanceLocal*t,r=this.gimbalBodyClearanceLocal*t+Ec;return Math.max(n,r)}getArmFoldNode(e){return this.model.getObjectByName(`CTRL_Arm_${e}_Fold`)??null}};function Hc(e,t,n){return Math.min(n,Math.max(t,e))}var Uc=16726832,Wc=3211120,Gc=16762173,Kc=10485707,qc=(e,t,n=0)=>({colors:e,onMs:t,offMs:n}),Jc={selfCheck:{label:`开机系统自检`,meaning:`红绿黄交替闪烁`,uiColor:`#ff3b30`,steps:[qc([Uc],150,110),qc([Wc],150,110),qc([Gc],150,110)]},sensorWarmup:{label:`传感器预热中`,meaning:`黄灯连续闪 4 次`,uiColor:`#ffc53d`,steps:[...((e,t)=>Array.from({length:t},()=>({...e})))(qc([Gc],140,130),4),qc([Gc],0,1e3)]},gnssNormal:{label:`GNSS 定位正常`,meaning:`绿灯慢闪 · 可以起飞`,uiColor:`#30ff70`,steps:[qc([Wc],450,1250)]},gnssWeak:{label:`GNSS 信号弱`,meaning:`绿灯双闪 · 依靠视觉定位`,uiColor:`#30ff70`,steps:[qc([Wc],130,160),qc([Wc],130,1150)]},attiMode:{label:`姿态模式`,meaning:`黄灯慢闪 · 无 GPS 无视觉定位,谨慎飞行`,uiColor:`#ffc53d`,steps:[qc([Gc],450,1250)]},rcLost:{label:`遥控器信号丢失`,meaning:`黄灯快闪`,uiColor:`#ffc53d`,steps:[qc([Gc],110,110)]},lowBattery:{label:`低电量预警`,meaning:`红灯慢闪 · 准备自动返航`,uiColor:`#ff3b30`,steps:[qc([Uc],450,1250)]},criticalBattery:{label:`严重低电量`,meaning:`红灯快闪 · 强制返航`,uiColor:`#ff3b30`,steps:[qc([Uc],110,110)]},tilted:{label:`机身放置不平`,meaning:`红灯间隔闪烁 · 传感器误差大`,uiColor:`#ff3b30`,steps:[qc([Uc],220,1700)]},fcError:{label:`飞控严重故障`,meaning:`红灯常亮 · 禁止起飞`,uiColor:`#ff3b30`,steps:[qc([Uc],1200,0)]},compassError:{label:`指南针异常`,meaning:`红黄灯交替闪烁 · 需要校准`,uiColor:`#ff8c1a`,steps:[qc([Uc],330,140),qc([Gc],330,140)]},motorRunning:{label:`电机启动 · Remote ID`,meaning:`国内固件规则:左侧红灯闪烁、右侧绿灯闪烁`,uiColor:`#ff3b30`,steps:[qc([Uc,Wc],500,500)]},off:{label:`未上电 / 关闭`,meaning:`状态灯熄灭`,uiColor:`#5a6b70`,steps:[qc([0],1200,0)]}},Yc=Object.keys(Jc).map(e=>({key:e,...Jc[e]}));function Xc(e){let t=Math.max(0,Math.min(100,e));return t>=88?{lit:4,blinkIndex:null}:t>=76?{lit:3,blinkIndex:3}:t>=63?{lit:3,blinkIndex:null}:t>=51?{lit:2,blinkIndex:2}:t>=38?{lit:2,blinkIndex:null}:t>=26?{lit:1,blinkIndex:1}:{lit:1,blinkIndex:null}}function Zc(e){let{lit:t,blinkIndex:n}=Xc(e);return n===null?`${t} 灯常亮`:`${t} 常亮 + 1 闪烁`}function Qc(e){if(e.damaged)return`fcError`;if(e.phase===`powerOff`)return`off`;switch(e.phase){case`selfCheck`:return`selfCheck`;case`warmingUp`:return`sensorWarmup`;case`emergency`:return`fcError`}if(e.faults.imuError)return`fcError`;if(e.faults.compassError)return`compassError`;if(e.faults.rcLost)return`rcLost`;if(e.criticalBattery)return`criticalBattery`;if(e.lowBattery)return`lowBattery`;if(e.motorsOn)return`motorRunning`;let t=e.positionSource;return t===`gps`?e.gpsBars>=3?`gnssNormal`:`gnssWeak`:t===`vision`?`gnssWeak`:`attiMode`}var $c=8,el=.42,tl=26,nl=.12,rl=1.6,il=1.6,al=class{constructor(){i(this,`rig`,new kn),i(this,`model`,null),i(this,`scene`,null),i(this,`statusLeds`,[]),i(this,`batteryLeds`,[]),i(this,`auxDisc`,null),i(this,`auxDiscMaterial`,null),i(this,`auxSpot`,null),i(this,`auxGlow`,null),i(this,`auxBeam`,null),i(this,`auxModelLight`,null),i(this,`statusKey`,`gnssNormal`),i(this,`batteryMode`,`level`),i(this,`beamEnabled`,!1),i(this,`batteryLevel`,80),i(this,`auxMode`,`auto`),i(this,`flying`,!1),i(this,`auxOn`,!1),i(this,`auxIntensity`,0),i(this,`timeMs`,0),i(this,`statusArmsAttached`,!1),i(this,`statusArmFolds`,[null,null]),i(this,`batteryLedsUi`,[]),i(this,`tmpVector`,new U),i(this,`disposables`,[])}attach(e,t){this.model=e,this.scene=t;let n=e.position.clone(),r=e.quaternion.clone(),i=e.scale.clone();e.position.set(0,0,0),e.quaternion.identity(),e.scale.set(1,1,1),e.updateMatrixWorld(!0);let a=new Yn().setFromObject(e);e.position.copy(n),e.quaternion.copy(r),e.scale.copy(i),e.updateMatrixWorld(!0);let o=a.getSize(new U);e.updateMatrixWorld(!0);let s=new oc,c=(t,n,r,i)=>{let a=e.localToWorld(new U(t,n,r));s.set(a,i.clone().normalize());let o=s.intersectObject(e,!0)[0];return o?e.worldToLocal(o.point.clone()):new U(t,n,r)},l=t=>{let n=e.getObjectByName(t);if(!n)return null;if(n instanceof Y&&n.geometry){n.geometry.computeBoundingBox();let t=n.geometry.boundingBox;if(t){let r=t.getCenter(new U);return e.worldToLocal(n.localToWorld(r.clone()))}}return e.worldToLocal(n.getWorldPosition(new U))},u=(t,n)=>{let r=e.getObjectByName(t);if(!(r instanceof Bs))return null;let i=r.parent??e;return r.position.copy(i.worldToLocal(e.localToWorld(n.clone()))),r.intensity=0,r.distance=rl,r.decay=2,r};for(let t of[{meshName:`LED_Status_Tail_Right`,lightName:`LIGHT_StatusLED_Right`,fallback:new U(8.6,.95,9.71)},{meshName:`LED_Status_Tail_Left`,lightName:`LIGHT_StatusLED_Left`,fallback:new U(-8.6,.95,9.71)}]){let n=e.getObjectByName(t.meshName)??null,r=l(t.meshName)??t.fallback,i=null,a=0;n instanceof Y&&(n.geometry.boundingSphere||n.geometry.computeBoundingSphere(),i=n.geometry.boundingSphere.center.clone(),a=n.geometry.boundingSphere.radius);let o=this.createLedMaterial(1,sl(n),i,a),s,c=null,d=null;if(n instanceof Y)c=n.material,d=n.parent,n.material=o,s=n;else{let e=new Lo(.62,14,12);this.disposables.push(e),s=new Y(e,o),s.position.copy(r),this.rig.add(s)}let f=u(t.lightName,r);this.statusLeds.push({mesh:s,material:o,sourceMesh:n,originalMaterial:c,originalParent:d,originalLightParent:f?.parent??null,light:f})}for(let t=0;t<4;t+=1){let n=`LED_BatteryCharge_0${t+1}`,r=e.getObjectByName(n)??null,i=null,a=0;r instanceof Y&&(r.geometry.boundingSphere||r.geometry.computeBoundingSphere(),i=r.geometry.boundingSphere.center.clone(),a=r.geometry.boundingSphere.radius);let o=this.createLedMaterial(.9,sl(r),i,a),s,c=null,d,f=null;if(r instanceof Y)c=r.material,f=r.parent,r.material=o,s=r,d=l(n)??new U;else{d=new U(-1.5+t,1.4,6.48);let e=new Lo(.32,14,12);this.disposables.push(e),s=new Y(e,o),s.position.copy(d),this.rig.add(s)}let p=u(`LIGHT_BatteryLED_0${t+1}`,d),m={mesh:s,material:o,sourceMesh:r,originalMaterial:c,originalParent:f,originalLightParent:p?.parent??null,light:p,lightIntensity:0};this.batteryLeds.push(m)}this.batteryLedsUi=this.batteryLeds.map(()=>({on:!1,blinking:!1}));let d=(l(`SENSOR_Glass_Downward`)??new U(0,-2.45,-.93)).z+1.15,f=c(0,a.min.y-o.y,d,new U(0,1,0)).y-.06;this.auxModelLight=u(`LIGHT_BottomAssist`,new U(0,f-.25,d));let p=new ma(1.15,20);p.rotateX(Math.PI/2),this.disposables.push(p),this.auxDiscMaterial=new Bo({color:1843494,emissive:16771520,emissiveIntensity:0,roughness:.5}),this.installLedGradient(this.auxDiscMaterial,new U(0,0,0),1.15),this.auxDisc=new Y(p,this.auxDiscMaterial),this.auxDisc.position.set(0,f,d),this.rig.add(this.auxDisc),this.auxSpot=new Rs(`#ffe9c4`,0,0,el,.45,1.4),this.auxSpot.position.copy(this.auxDisc.position);let m=new G;m.position.set(0,f-1.2,d),this.rig.add(m),this.auxSpot.target=m,this.rig.add(this.auxSpot),this.auxGlow=new Bs(`#ffe9c4`,0,2.4,1.8),this.auxGlow.position.set(0,f-.3,d),this.rig.add(this.auxGlow);let h=new ga(1,1,24,1,!0);h.translate(0,-.5,0),this.disposables.push(h);let g=new ri({color:`#ffe2a8`,transparent:!0,opacity:0,blending:2,depthWrite:!1,side:2,toneMapped:!1});this.disposables.push(g),this.auxBeam=new Y(h,g),this.auxBeam.visible=!1,t.add(this.auxBeam),e.add(this.rig)}update(e){let t=Math.max(0,Math.min(e,.1));this.timeMs+=t*1e3,this.applyStatusPattern(),this.applyBattery(),this.applyAux(t)}setStatusPattern(e){e in Jc&&(this.statusKey=e)}setBatteryMode(e){this.batteryMode=e}setBatteryLevel(e){this.batteryLevel=Math.max(0,Math.min(100,e))}setAuxLightMode(e){this.auxMode=e}setBeamVisible(e){this.beamEnabled=e,this.applyAux(0)}isBeamVisible(){return this.beamEnabled}setFlying(e){this.flying=e}attachStatusToArms(e,t){if(!this.model)return;if(this.statusArmsAttached){this.statusArmFolds=[t,e];for(let[e,t]of this.statusLeds.entries()){let n=this.statusArmFolds[e];t&&n&&t.mesh.parent!==n&&(n.attach(t.mesh),t.light&&n.attach(t.light))}return}this.model.updateMatrixWorld(!0);let n=[{led:this.statusLeds[1],fold:e},{led:this.statusLeds[0],fold:t}];for(let{led:e,fold:t}of n)e&&t&&(t.attach(e.mesh),e.light&&t.attach(e.light),e.bindLocal={position:e.mesh.position.clone(),quaternion:e.mesh.quaternion.clone(),scale:e.mesh.scale.clone()});this.statusArmFolds=[t,e],this.statusArmsAttached=!0}syncStatusToArms(){if(this.statusArmsAttached)for(let[e,t]of this.statusLeds.entries()){let n=t?.bindLocal,r=this.statusArmFolds[e];n&&r&&t.mesh.parent===r&&(t.mesh.position.copy(n.position),t.mesh.quaternion.copy(n.quaternion),t.mesh.scale.copy(n.scale))}}getSnapshot(){let e=Jc[this.statusKey];return{statusKey:this.statusKey,statusLabel:e.label,statusMeaning:e.meaning,batteryMode:this.batteryMode,batteryLevel:this.batteryLevel,batteryLeds:this.batteryLedsUi,auxMode:this.auxMode,auxOn:this.auxOn,auxLocked:!this.flying}}destroy(){this.rig.parent?.remove(this.rig),this.auxBeam&&this.scene?.remove(this.auxBeam);for(let e of[...this.statusLeds,...this.batteryLeds])e.originalParent?e.mesh.parent!==e.originalParent&&e.originalParent.attach(e.mesh):e.mesh.parent?.remove(e.mesh),e.light&&e.originalLightParent&&e.light.parent!==e.originalLightParent&&e.originalLightParent.attach(e.light),e.originalMaterial&&e.sourceMesh instanceof Y&&(e.sourceMesh.material=e.originalMaterial);for(let e of this.disposables)e.dispose();this.disposables.length=0,this.statusLeds=[],this.batteryLeds=[],this.auxDisc=null,this.auxDiscMaterial=null,this.auxSpot=null,this.auxGlow=null,this.auxBeam=null,this.auxModelLight=null,this.statusArmsAttached=!1,this.model=null,this.scene=null}createLedMaterial(e=2.4,t=null,n=null,r=0){let i=new Bo({color:t?16777215:1580321,map:t,emissive:0,emissiveIntensity:e,roughness:.4,metalness:.1,side:2,toneMapped:!1});return i.userData.baseColorHex=t?16777215:1580321,i.userData.baseRoughness=i.roughness,i.userData.baseMetalness=i.metalness,n&&r>0&&this.installLedGradient(i,n,r),this.disposables.push(i),i}installLedGradient(e,t,n){let r=t.clone();e.onBeforeCompile=e=>{e.uniforms.uLedCenter={value:r},e.uniforms.uLedRadius={value:n},e.vertexShader=e.vertexShader.replace(`#include <common>`,`#include <common>
|
|
3
|
+
varying vec3 vLedLocal;`).replace(`#include <begin_vertex>`,`#include <begin_vertex>
|
|
4
|
+
vLedLocal = position;`),e.fragmentShader=e.fragmentShader.replace(`#include <common>`,`#include <common>
|
|
5
|
+
varying vec3 vLedLocal;
|
|
6
|
+
uniform vec3 uLedCenter;
|
|
7
|
+
uniform float uLedRadius;`).replace(`#include <emissivemap_fragment>`,[`#include <emissivemap_fragment>`,`float ledT = clamp(length(vLedLocal - uLedCenter) / uLedRadius, 0.0, 1.0);`,`totalEmissiveRadiance *= (1.0 + 5.0 * (1.0 - ledT) * (1.0 - ledT));`].join(`
|
|
8
|
+
`))}}setLed(e,t,n){let r=e.material;r.emissive.setHex(n?t:0),r.color.setHex(n?0:r.userData.baseColorHex),r.roughness=n?1:r.userData.baseRoughness,r.metalness=n?0:r.userData.baseMetalness,r.envMapIntensity=+!n,e.light&&(e.light.intensity=n?e.lightIntensity??nl:0,n&&e.light.color.setHex(t))}applyStatusPattern(){let e=Jc[this.statusKey],t=e.steps.reduce((e,t)=>e+t.onMs+t.offMs,0),n=t>0?this.timeMs%t:0,r=e.steps[0]?.colors??[0],i=!1;for(let t of e.steps){if(n<t.onMs){r=t.colors,i=!0;break}if(n<t.onMs+t.offMs){r=t.colors,i=!1;break}n-=t.onMs+t.offMs}let a=this.statusLeds[1],o=this.statusLeds[0];a&&o&&(this.setLed(a,r[0]??0,i),this.setLed(o,r[1]??r[0]??0,i))}applyBattery(){if(this.batteryLeds.length===0)return;let e,t;if(this.batteryMode===`off`)e=[!1,!1,!1,!1],t=[!1,!1,!1,!1];else if(this.batteryMode===`full`)e=[!0,!0,!0,!0],t=[!1,!1,!1,!1];else if(this.batteryMode===`fault`)e=this.batteryLeds.map(()=>ol(this.timeMs,110,110)),t=[!0,!0,!0,!0];else if(this.batteryMode===`charging`){let n=Math.floor(this.timeMs/240)%4;e=this.batteryLeds.map((e,t)=>t===n),t=[!1,!1,!1,!1]}else{let n=Xc(this.batteryLevel);e=this.batteryLeds.map((e,t)=>t<n.lit||n.blinkIndex!==null&&t===n.blinkIndex&&ol(this.timeMs,240,240)),t=this.batteryLeds.map((e,t)=>n.blinkIndex!==null&&t===n.blinkIndex)}this.batteryLeds.forEach((n,r)=>{let i=this.batteryLedsUi[r];i&&(this.setLed(n,Kc,e[r]??!1),i.on=e[r]??!1,i.blinking=t[r]??!1)})}applyAux(e){if(!this.auxSpot||!this.auxDisc||!this.auxBeam||!this.auxDiscMaterial||!this.auxGlow)return;let t=!1;this.flying&&(this.auxMode===`on`?t=!0:this.auxMode===`auto`&&(this.auxDisc.getWorldPosition(this.tmpVector),t=this.tmpVector.y<=$c)),this.auxOn=t;let n=t?tl:0;this.auxIntensity+=(n-this.auxIntensity)*Math.min(1,e*9);let r=this.auxIntensity/tl;this.auxSpot.intensity=this.auxIntensity,this.auxGlow.intensity=this.auxIntensity*.06,this.auxDiscMaterial.emissiveIntensity=2.6*r,this.auxModelLight&&(this.auxModelLight.intensity=il*r),this.auxDisc.getWorldPosition(this.tmpVector);let i=Math.max(.05,this.tmpVector.y),a=this.beamEnabled&&r>.03;if(this.auxBeam.visible=a,a){let e=Math.tan(el);this.auxBeam.position.copy(this.tmpVector),this.auxBeam.scale.set(i*e,i,i*e),this.auxBeam.material.opacity=.12*r}}};function ol(e,t,n){return e%(t+n)<t}function sl(e){if(!(e instanceof Y))return null;let t=Array.isArray(e.material)?e.material[0]:e.material,n=t?t.map:null;return n instanceof en?n:null}var cl=[`SENSOR_Glass_Front_Left`,`SENSOR_Glass_Front_Right`],ll=[`SENSOR_Glass_Side_Left`,`SENSOR_Glass_Side_Right`],ul=18,dl=15,fl=(e,t,n)=>new U(e,t,n),pl=3,ml=9,hl=16731469,gl=16761165,_l=3530890,vl=5096447,yl=3.2,bl=Math.PI/180,xl=20,Sl=22.5,Cl=36,wl={detecting:!1,left:null,right:null,range:ul,upLeft:null,upRight:null,upRange:dl,aim:`forward`};function Tl(e){let t=e.geometry,n=t.getAttribute(`position`),r=t.getIndex(),i=new U,a=new U,o=new U,s=new U,c=new U,l=new U,u=new U,d=r?r.count:n.count;for(let e=0;e<d;e+=3){let t=r?r.getX(e):e,d=r?r.getX(e+1):e+1,f=r?r.getX(e+2):e+2;i.fromBufferAttribute(n,t),a.fromBufferAttribute(n,d),o.fromBufferAttribute(n,f),c.subVectors(o,a),l.subVectors(i,a),s.crossVectors(c,l),u.add(s)}return u.lengthSq()>1e-12?u.normalize():fl(0,1,0)}var El=Math.sin(xl*bl),Dl=Math.cos(xl*bl),Ol=[{group:`front`,position:`left`,nodeName:cl[0],range:ul,farColor:_l,fallbackOffset:fl(-.215,.161,-.489),fallbackDir:fl(-.683,.086,-.725),aimDir:fl(-El,0,-Dl),refU1:fl(1,0,0),refU2:fl(0,1,0),halfU1:Sl*bl,halfU2:Cl*bl},{group:`front`,position:`right`,nodeName:cl[1],range:ul,farColor:_l,fallbackOffset:fl(.215,.161,-.489),fallbackDir:fl(.683,.086,-.725),aimDir:fl(El,0,-Dl),refU1:fl(1,0,0),refU2:fl(0,1,0),halfU1:Sl*bl,halfU2:Cl*bl},{group:`up`,position:`left`,nodeName:ll[0],range:dl,farColor:vl,fallbackOffset:fl(-.18,.194,-.207),fallbackDir:fl(-.579,.697,.423),aimDir:fl(-El,Dl,0),refU1:fl(1,0,0),refU2:fl(0,0,-1),halfU1:Sl*bl,halfU2:Cl*bl},{group:`up`,position:`right`,nodeName:ll[1],range:dl,farColor:vl,fallbackOffset:fl(.18,.194,-.207),fallbackDir:fl(.579,.697,.423),aimDir:fl(El,Dl,0),refU1:fl(1,0,0),refU2:fl(0,0,-1),halfU1:Sl*bl,halfU2:Cl*bl}],kl=class{constructor(e){i(this,`group`,new kn),i(this,`disposables`,[]),i(this,`beams`,[]),i(this,`sensors`,Ol.map(e=>({...e,mesh:null,localCenter:new U,normalGeo:e.fallbackDir.clone(),sign:1,aimWorld:e.aimDir.clone(),aimReady:!1}))),i(this,`aim`,`forward`),i(this,`beamsVisible`,!1),i(this,`base`,new U),i(this,`origin`,new U),i(this,`targetAxis`,new U),i(this,`axis`,new U),i(this,`u1`,new U),i(this,`u2`,new U),i(this,`refU1World`,new U),i(this,`refU2World`,new U),i(this,`tmp`,new U),i(this,`tmp2`,new U),i(this,`rotation`,new W),i(this,`snapshot`,wl);for(let e=0;e<this.sensors.length;e+=1){let t=this.sensors[e];if(t)for(let e=0;e<5;e+=1){let n=new Float32Array(6),r=new J;r.setAttribute(`position`,new pr(n,3));let i=new Gi({color:t.farColor,transparent:!0,opacity:e===0?.75:.16,toneMapped:!1}),a=new $i(r,i);a.frustumCulled=!1,this.group.add(a),this.disposables.push(r,i),this.beams.push({line:a,positions:n,material:i})}}this.group.visible=!1,e.add(this.group)}get range(){return ul}get upRange(){return dl}getSnapshot(){return this.snapshot}setAim(e){this.aim=e,this.snapshot={...this.snapshot,aim:e}}getAim(){return this.aim}bindSensors(e){e.updateMatrixWorld(!0);let t=new W().extractRotation(e.matrixWorld);for(let n of this.sensors){let r=e.getObjectByName(n.nodeName);if(!(r instanceof Y))continue;let i=r.geometry;i.computeBoundingBox();let a=new U;i.boundingBox?.getCenter(a)??a.set(0,0,0);let o=Tl(r),s=o.clone().transformDirection(r.matrixWorld).normalize(),c=fl(0,0,-1).applyMatrix4(t).normalize(),l=fl(0,1,0).applyMatrix4(t).normalize(),u=n.group===`front`?c:l;n.mesh=r,n.localCenter.copy(a),n.normalGeo.copy(o),n.sign=s.dot(u)<0?-1:1}}isBoundToSensors(){return this.sensors.every(e=>e.mesh!==null)}debugInfo(){return this.sensors.map(e=>({group:e.group,position:e.position,nodeName:e.nodeName,bound:e.mesh!==null,aimDeg:e.aimWorld.toArray().map(e=>Math.round(e*1e3)/1e3)}))}update(e,t,n,r){if(!r){this.snapshot!==wl&&(this.snapshot={...wl,aim:this.aim}),this.group.visible=!1;return}this.group.visible=this.beamsVisible,e.updateMatrixWorld(!0),this.rotation.extractRotation(e.matrixWorld),e.getWorldPosition(this.base);let i=[];for(let e=0;e<this.sensors.length;e+=1){let r=this.sensors[e];if(!r)continue;r.mesh?this.origin.copy(r.localCenter).applyMatrix4(r.mesh.matrixWorld):this.origin.copy(r.fallbackOffset).applyMatrix4(this.rotation).add(this.base),this.aim===`sensor`&&r.mesh?this.targetAxis.copy(r.normalGeo).transformDirection(r.mesh.matrixWorld).normalize().multiplyScalar(r.sign):this.targetAxis.copy(r.aimDir).applyMatrix4(this.rotation).normalize(),r.aimReady?r.aimWorld.lerp(this.targetAxis,Math.min(1,Math.max(0,n)*yl)).normalize():(r.aimWorld.copy(this.targetAxis),r.aimReady=!0),this.axis.copy(r.aimWorld),this.refU1World.copy(r.refU1).applyMatrix4(this.rotation),this.refU2World.copy(r.refU2).applyMatrix4(this.rotation),this.u1.copy(this.refU1World).addScaledVector(this.axis,-this.refU1World.dot(this.axis)),this.u1.lengthSq()<1e-8&&this.u1.set(0,1,0).addScaledVector(this.axis,-this.axis.y),this.u1.normalize(),this.u2.crossVectors(this.axis,this.u1).normalize();let a=t.coneCast(this.origin,this.axis,this.u1,this.u2,Math.tan(r.halfU1),Math.tan(r.halfU2),r.range);i.push(a),this.updateSensorVisual(e,r,this.origin,this.axis,a)}this.snapshot={detecting:!0,left:i[0]??null,right:i[1]??null,range:ul,upLeft:i[2]??null,upRight:i[3]??null,upRange:dl,aim:this.aim}}updateSensorVisual(e,t,n,r,i){let a=this.levelColor(i?.distance??1/0,t.farColor),o=i?i.distance:t.range,s=this.beams[e*5];if(!s)return;this.tmp.copy(n).addScaledVector(r,o),this.writeBeam(s,n,this.tmp,a);let c=[[this.u2,t.halfU1,0],[this.u2,-t.halfU1,0],[this.u1,t.halfU2,0],[this.u1,-t.halfU2,0]];for(let i=0;i<c.length;i+=1){let o=c[i],s=this.beams[e*5+1+i];if(!o||!s)continue;let[l,u]=o;this.tmp.copy(r).applyAxisAngle(l,u).normalize(),this.tmp2.copy(n).addScaledVector(this.tmp,t.range),this.writeBeam(s,n,this.tmp2,a)}}writeBeam(e,t,n,r){e.positions[0]=t.x,e.positions[1]=t.y,e.positions[2]=t.z,e.positions[3]=n.x,e.positions[4]=n.y,e.positions[5]=n.z;let i=e.line.geometry.getAttribute(`position`);i.needsUpdate=!0,e.material.color.setHex(r)}levelColor(e,t){return e<pl?hl:e<ml?gl:t}setVisible(e){this.beamsVisible=e,this.group.visible=e&&this.snapshot.detecting}isBeamsVisible(){return this.beamsVisible}destroy(){this.group.parent?.remove(this.group);for(let e of this.disposables)e.dispose();this.disposables.length=0,this.beams.length=0;for(let e of this.sensors)e.mesh=null,e.aimReady=!1;this.snapshot=wl}},Al=3,jl=1,Ml=.2;function Nl(e,t,n){return Math.min(n,Math.max(t,e))}function Pl(e,t){return Math.round(e/t)*t}function Fl(e,t){try{let n=e.setPointerCapture(t);n&&typeof n.catch==`function`&&n.catch(()=>{})}catch{}}function Il(e,t){try{let n=e.releasePointerCapture(t);n&&typeof n.catch==`function`&&n.catch(()=>{})}catch{}}var Ll=class{constructor(e){i(this,`host`,void 0),i(this,`enabled`,!1),i(this,`hoverIndex`,-1),i(this,`drag`,null),i(this,`emptyClick`,null),i(this,`raycaster`,new oc),i(this,`pointer`,new H),i(this,`groundNormal`,new U(0,1,0)),i(this,`cameraForward`,new U),i(this,`planeNormal`,new U),i(this,`hitPoint`,new U),i(this,`onPointerDown`,e=>{if(!this.active()||e.button!==0)return;let t=this.pickWaypoint(e);if(t<0){this.emptyClick={x:e.clientX,y:e.clientY};return}let n=this.host.getWaypoints()[t];n&&(this.emptyClick=null,this.host.setSelected(t),this.drag=this.createDrag(e,t,n),this.host.setOrbitEnabled(!1),this.host.canvas.style.cursor=e.shiftKey?`ns-resize`:`grabbing`,Fl(this.host.canvas,e.pointerId))}),i(this,`onPointerMove`,e=>{if(!this.enabled)return;let t=this.drag;if(!t)this.setHover(this.active()?this.pickWaypoint(e):-1),this.host.canvas.style.cursor=this.hoverIndex>=0?`grab`:``;else{if(!t.moved){if(Math.hypot(e.clientX-t.startClientX,e.clientY-t.startClientY)<Al)return;t.moved=!0}this.applyDrag(e,t)}}),i(this,`onPointerUp`,e=>{Il(this.host.canvas,e.pointerId);let t=this.emptyClick;this.emptyClick=null;let n=this.drag;if(!n){t&&Math.hypot(e.clientX-t.x,e.clientY-t.y)<Al&&this.host.setSelected(-1);return}if(this.drag=null,this.host.setOrbitEnabled(!0),this.host.canvas.style.cursor=this.hoverIndex>=0?`grab`:``,!n.moved)return;let r=this.host.getWaypoints()[n.index];r&&this.host.log(`info`,`场景编辑:航点 ${n.index+1} 已更新为 E ${r.x.toFixed(0)} / S ${r.z.toFixed(0)} / 高度 ${r.altitude.toFixed(1)} m`)}),i(this,`onPointerLeave`,()=>{this.drag||this.setHover(-1)}),i(this,`onDoubleClick`,e=>{if(!this.active()||e.button!==0||this.pickWaypoint(e)>=0)return;this.updateRaycaster(e.clientX,e.clientY);let t=this.host.world.pickMissionGround(this.raycaster);if(!t)return;let n=this.host.getLimits(),r=t.x-n.homeX,i=t.z-n.homeZ,a=Math.hypot(r,i),o=t.x,s=t.z;if(a>n.maxDistance){let e=n.maxDistance/a;o=n.homeX+r*e,s=n.homeZ+i*e}o=Pl(o,jl),s=Pl(s,jl);let c=this.host.getWaypoints(),l=k(c,o,s,n.homeX,n.homeZ),u=this.host.newWaypointTemplate(l),d=c.map(e=>({...e}));d.splice(l,0,{...u,x:o,z:s}),this.host.commitWaypoints(d,l),this.host.log(`info`,`场景编辑:在 E ${o.toFixed(0)} / S ${s.toFixed(0)} 新增航点 ${l+1}(双击地面新增)`)}),i(this,`onKeyDown`,e=>{if(!this.enabled)return;let t=e.target;if(t&&[`INPUT`,`SELECT`,`TEXTAREA`].includes(t.tagName))return;if(e.key===`Escape`){this.host.setSelected(-1);return}if(e.key!==`Delete`&&e.key!==`Backspace`)return;let n=this.host.getSelected();n<0||(e.preventDefault(),this.deleteWaypoint(n))}),this.host=e;let t=e.canvas;t.addEventListener(`pointerdown`,this.onPointerDown),t.addEventListener(`pointermove`,this.onPointerMove),t.addEventListener(`pointerup`,this.onPointerUp),t.addEventListener(`pointercancel`,this.onPointerUp),t.addEventListener(`pointerleave`,this.onPointerLeave),t.addEventListener(`dblclick`,this.onDoubleClick),window.addEventListener(`keydown`,this.onKeyDown)}get isEnabled(){return this.enabled}setEnabled(e){this.enabled!==e&&(this.enabled=e,e||(this.cancelDrag(),this.setHover(-1),this.host.canvas.style.cursor=``))}update(){this.host.canEdit()||(this.drag&&this.cancelDrag(),this.hoverIndex>=0&&this.setHover(-1),this.host.getSelected()>=0&&this.host.setSelected(-1))}getState(){return{enabled:this.enabled,active:this.enabled&&this.host.canEdit(),selectedIndex:this.host.getSelected(),hoverIndex:this.hoverIndex,dragging:this.drag!==null,mode:this.drag?.mode??null}}destroy(){let e=this.host.canvas;e.removeEventListener(`pointerdown`,this.onPointerDown),e.removeEventListener(`pointermove`,this.onPointerMove),e.removeEventListener(`pointerup`,this.onPointerUp),e.removeEventListener(`pointercancel`,this.onPointerUp),e.removeEventListener(`pointerleave`,this.onPointerLeave),e.removeEventListener(`dblclick`,this.onDoubleClick),window.removeEventListener(`keydown`,this.onKeyDown),this.cancelDrag(),this.host.canvas.style.cursor=``}createDrag(e,t,n){this.updateRaycaster(e.clientX,e.clientY);let r=Math.max(1,n.altitude),i=new Nr;if(e.shiftKey){let e=this.cameraForward.set(0,0,0);this.host.camera.getWorldDirection(e),this.planeNormal.set(e.x,0,e.z),this.planeNormal.lengthSq()<1e-4&&this.planeNormal.set(0,0,1),this.planeNormal.normalize(),this.hitPoint.set(n.x,r,n.z),i.setFromNormalAndCoplanarPoint(this.planeNormal,this.hitPoint)}else i.setFromNormalAndCoplanarPoint(this.groundNormal,this.hitPoint.set(n.x,r,n.z));let a=this.raycaster.ray.intersectPlane(i,this.hitPoint);return{index:t,mode:e.shiftKey?`altitude`:`move`,pointerId:e.pointerId,startClientX:e.clientX,startClientY:e.clientY,startX:n.x,startZ:n.z,startAltitude:n.altitude,moved:!1,plane:i,refX:a?.x??n.x,refY:a?.y??r,refZ:a?.z??n.z}}deleteWaypoint(e){if(!this.host.canEdit())return!1;let t=this.host.getWaypoints();if(e<0||e>=t.length)return!1;let n=t.filter((t,n)=>n!==e).map(e=>({...e}));return this.host.commitWaypoints(n,Math.min(e,n.length-1)),this.host.log(`info`,`场景编辑:已删除航点 ${e+1}`),!0}applyDrag(e,t){this.updateRaycaster(e.clientX,e.clientY);let n=e.altKey?Ml:jl,r=this.raycaster.ray.intersectPlane(t.plane,this.hitPoint);if(t.mode===`move`){if(!r)return;this.host.moveWaypoint(t.index,{x:Pl(t.startX+(r.x-t.refX),n),z:Pl(t.startZ+(r.z-t.refZ),n)});return}let i=r?t.startAltitude+(r.y-t.refY):t.startAltitude-(e.clientY-t.startClientY)*this.metersPerPixel(t);this.host.moveWaypoint(t.index,{altitude:Nl(Pl(i,n),1,this.host.getLimits().maxAltitude)})}metersPerPixel(e){let t=this.host.camera,n=t.position.distanceTo(this.hitPoint.set(e.startX,e.startAltitude,e.startZ)),r=2*Math.tan(Ft.degToRad(t.fov/2))*n/Math.max(.01,t.zoom),i=this.host.canvas.getBoundingClientRect();return i.height>0?r/i.height:.2}active(){return this.enabled&&this.host.canEdit()}pickWaypoint(e){return this.updateRaycaster(e.clientX,e.clientY),this.host.world.pickMissionWaypoint(this.raycaster)}updateRaycaster(e,t){let n=this.host.canvas.getBoundingClientRect();n.width<=0||n.height<=0||(this.pointer.x=(e-n.left)/n.width*2-1,this.pointer.y=-((t-n.top)/n.height)*2+1,this.raycaster.setFromCamera(this.pointer,this.host.camera))}setHover(e){this.hoverIndex!==e&&(this.hoverIndex=e,this.host.world.setMissionHover(e))}cancelDrag(){this.drag&&(this.drag=null,this.host.setOrbitEnabled(!0))}};function Rl(e,t=!1){let n=e[0].index!==null,r=new Set(Object.keys(e[0].attributes)),i=new Set(Object.keys(e[0].morphAttributes)),a={},o={},s=e[0].morphTargetsRelative,c=new J,l=0;for(let u=0;u<e.length;++u){let d=e[u],f=0;if(n!==(d.index!==null))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.`),null;for(let e in d.attributes){if(!r.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. All geometries must have compatible attributes; make sure "`+e+`" attribute exists among all geometries, or in none of them.`),null;a[e]===void 0&&(a[e]=[]),a[e].push(d.attributes[e]),f++}if(f!==r.size)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. Make sure all geometries have the same number of attributes.`),null;if(s!==d.morphTargetsRelative)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. .morphTargetsRelative must be consistent throughout all geometries.`),null;for(let e in d.morphAttributes){if(!i.has(e))return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. .morphAttributes must be consistent throughout all geometries.`),null;o[e]===void 0&&(o[e]=[]),o[e].push(d.morphAttributes[e])}if(t){let e;if(n)e=d.index.count;else if(d.attributes.position!==void 0)e=d.attributes.position.count;else return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index `+u+`. The geometry must have either an index or a position attribute`),null;c.addGroup(l,e,u),l+=e}}if(n){let t=0,n=[];for(let r=0;r<e.length;++r){let i=e[r].index;for(let e=0;e<i.count;++e)n.push(i.getX(e)+t);t+=e[r].attributes.position.count}c.setIndex(n)}for(let e in a){let t=zl(a[e]);if(!t)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` attribute.`),null;c.setAttribute(e,t)}for(let e in o){let t=o[e][0].length;if(t!==0){c.morphAttributes=c.morphAttributes||{},c.morphAttributes[e]=[];for(let n=0;n<t;++n){let t=[];for(let r=0;r<o[e].length;++r)t.push(o[e][r][n]);let r=zl(t);if(!r)return console.error(`THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the `+e+` morphAttribute.`),null;c.morphAttributes[e].push(r)}}}return c}function zl(e){let t,n,r,i=-1,a=0;for(let o=0;o<e.length;++o){let s=e[o];if(t===void 0&&(t=s.array.constructor),t!==s.array.constructor)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.`),null;if(n===void 0&&(n=s.itemSize),n!==s.itemSize)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.`),null;if(r===void 0&&(r=s.normalized),r!==s.normalized)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.`),null;if(i===-1&&(i=s.gpuType),i!==s.gpuType)return console.error(`THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.`),null;a+=s.count*n}let o=new t(a),s=new pr(o,n,r),c=0;for(let t=0;t<e.length;++t){let r=e[t];if(r.isInterleavedBufferAttribute){let e=c/n;for(let t=0,i=r.count;t<i;t++)for(let i=0;i<n;i++){let n=r.getComponent(t,i);s.setComponent(t+e,i,n)}}else o.set(r.array,c);c+=r.count*n}return i!==void 0&&(s.gpuType=i),s}function Bl(e,t=1e-4){t=Math.max(t,2**-52);let n={},r=e.getIndex(),i=e.getAttribute(`position`),a=r?r.count:i.count,o=0,s=Object.keys(e.attributes),c={},l={},u=[],d=[`getX`,`getY`,`getZ`,`getW`],f=[`setX`,`setY`,`setZ`,`setW`];for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.attributes[n];c[n]=new r.constructor(new r.array.constructor(r.count*r.itemSize),r.itemSize,r.normalized);let i=e.morphAttributes[n];i&&(l[n]||(l[n]=[]),i.forEach((e,t)=>{let r=new e.array.constructor(e.count*e.itemSize);l[n][t]=new e.constructor(r,e.itemSize,e.normalized)}))}let p=t*.5,m=10**Math.log10(1/t),h=p*m;for(let t=0;t<a;t++){let i=r?r.getX(t):t,a=``;for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),o=r.itemSize;for(let e=0;e<o;e++)a+=`${Math.trunc(r[d[e]](i)*m+h)},`}if(a in n)u.push(n[a]);else{for(let t=0,n=s.length;t<n;t++){let n=s[t],r=e.getAttribute(n),a=e.morphAttributes[n],u=r.itemSize,p=c[n],m=l[n];for(let e=0;e<u;e++){let t=d[e],n=f[e];if(p[n](o,r[t](i)),a)for(let e=0,r=a.length;e<r;e++)m[e][n](o,a[e][t](i))}}n[a]=o,u.push(o),o++}}let g=e.clone();for(let t in e.attributes){let e=c[t];if(g.setAttribute(t,new e.constructor(e.array.slice(0,o*e.itemSize),e.itemSize,e.normalized)),t in l)for(let e=0;e<l[t].length;e++){let n=l[t][e];g.morphAttributes[t][e]=new n.constructor(n.array.slice(0,o*n.itemSize),n.itemSize,n.normalized)}}return g.setIndex(u),g}function Vl(e,t){if(t===0)return console.warn(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.`),e;if(t===2||t===1){let n=e.getIndex();if(n===null){let t=[],r=e.getAttribute(`position`);if(r!==void 0){for(let e=0;e<r.count;e++)t.push(e);e.setIndex(t),n=e.getIndex()}else return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.`),e}let r=n.count-2,i=[];if(t===2)for(let e=1;e<=r;e++)i.push(n.getX(0)),i.push(n.getX(e)),i.push(n.getX(e+1));else for(let e=0;e<r;e++)e%2==0?(i.push(n.getX(e)),i.push(n.getX(e+1)),i.push(n.getX(e+2))):(i.push(n.getX(e+2)),i.push(n.getX(e+1)),i.push(n.getX(e)));return i.length/3!==r&&console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.`),e.setIndex(i),e.clearGroups(),e}return console.error(`THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:`,t),e}function Hl(e){let t=new Map,n=new Map,r=e.clone();return Ul(e,r,function(e,r){t.set(r,e),n.set(e,r)}),r.traverse(function(e){if(!e.isSkinnedMesh)return;let r=e,i=t.get(e),a=i.skeleton.bones;r.skeleton=i.skeleton.clone(),r.bindMatrix.copy(i.bindMatrix),r.skeleton.bones=a.map(function(e){return n.get(e)}),r.bind(r.skeleton,r.bindMatrix)}),r}function Ul(e,t,n){n(e,t);for(let r=0;r<e.children.length;r++)Ul(e.children[r],t.children[r],n)}var Wl=class extends _s{constructor(e){super(e),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new Xl(e)}),this.register(function(e){return new Zl(e)}),this.register(function(e){return new ou(e)}),this.register(function(e){return new su(e)}),this.register(function(e){return new cu(e)}),this.register(function(e){return new $l(e)}),this.register(function(e){return new eu(e)}),this.register(function(e){return new tu(e)}),this.register(function(e){return new nu(e)}),this.register(function(e){return new Yl(e)}),this.register(function(e){return new ru(e)}),this.register(function(e){return new Ql(e)}),this.register(function(e){return new au(e)}),this.register(function(e){return new iu(e)}),this.register(function(e){return new ql(e)}),this.register(function(e){return new lu(e,Z.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new lu(e,Z.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new uu(e)})}load(e,t,n,r){let i=this,a;if(this.resourcePath!==``)a=this.resourcePath;else if(this.path!==``){let t=Ws.extractUrlBase(e);a=Ws.resolveURL(t,this.path)}else a=Ws.extractUrlBase(e);this.manager.itemStart(e);let o=function(t){r?r(t):console.error(t),i.manager.itemError(e),i.manager.itemEnd(e)},s=new bs(this.manager);s.setPath(this.path),s.setResponseType(`arraybuffer`),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(e,function(n){try{i.parse(n,a,function(n){t(n),i.manager.itemEnd(e)},o)}catch(e){o(e)}},n,o)}setDRACOLoader(e){return this.dracoLoader=e,this}setKTX2Loader(e){return this.ktx2Loader=e,this}setMeshoptDecoder(e){return this.meshoptDecoder=e,this}register(e){return this.pluginCallbacks.indexOf(e)===-1&&this.pluginCallbacks.push(e),this}unregister(e){return this.pluginCallbacks.indexOf(e)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e),1),this}parse(e,t,n,r){let i,a={},o={},s=new TextDecoder;if(typeof e==`string`)i=JSON.parse(e);else if(e instanceof ArrayBuffer){if(s.decode(new Uint8Array(e,0,4))===du){try{a[Z.KHR_BINARY_GLTF]=new mu(e)}catch(e){r&&r(e);return}i=JSON.parse(a[Z.KHR_BINARY_GLTF].content)}else i=JSON.parse(s.decode(e))}else i=e;if(i.asset===void 0||i.asset.version[0]<2){r&&r(Error(`THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.`));return}let c=new Bu(i,{path:t||this.resourcePath||``,crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let e=0;e<this.pluginCallbacks.length;e++){let t=this.pluginCallbacks[e](c);t.name||console.error(`THREE.GLTFLoader: Invalid plugin found: missing name`),o[t.name]=t,a[t.name]=!0}if(i.extensionsUsed)for(let e=0;e<i.extensionsUsed.length;++e){let t=i.extensionsUsed[e],n=i.extensionsRequired||[];switch(t){case Z.KHR_MATERIALS_UNLIT:a[t]=new Jl;break;case Z.KHR_DRACO_MESH_COMPRESSION:a[t]=new hu(i,this.dracoLoader);break;case Z.KHR_TEXTURE_TRANSFORM:a[t]=new gu;break;case Z.KHR_MESH_QUANTIZATION:a[t]=new _u;break;default:n.indexOf(t)>=0&&o[t]===void 0&&console.warn(`THREE.GLTFLoader: Unknown extension "`+t+`".`)}}c.setExtensions(a),c.setPlugins(o),c.parse(n,r)}parseAsync(e,t){let n=this;return new Promise(function(r,i){n.parse(e,t,r,i)})}};function Gl(){let e={};return{get:function(t){return e[t]},add:function(t,n){e[t]=n},remove:function(t){delete e[t]},removeAll:function(){e={}}}}function Kl(e,t,n){let r=e.json.materials[t];return r.extensions&&r.extensions[n]?r.extensions[n]:null}var Z={KHR_BINARY_GLTF:`KHR_binary_glTF`,KHR_DRACO_MESH_COMPRESSION:`KHR_draco_mesh_compression`,KHR_LIGHTS_PUNCTUAL:`KHR_lights_punctual`,KHR_MATERIALS_CLEARCOAT:`KHR_materials_clearcoat`,KHR_MATERIALS_DISPERSION:`KHR_materials_dispersion`,KHR_MATERIALS_IOR:`KHR_materials_ior`,KHR_MATERIALS_SHEEN:`KHR_materials_sheen`,KHR_MATERIALS_SPECULAR:`KHR_materials_specular`,KHR_MATERIALS_TRANSMISSION:`KHR_materials_transmission`,KHR_MATERIALS_IRIDESCENCE:`KHR_materials_iridescence`,KHR_MATERIALS_ANISOTROPY:`KHR_materials_anisotropy`,KHR_MATERIALS_UNLIT:`KHR_materials_unlit`,KHR_MATERIALS_VOLUME:`KHR_materials_volume`,KHR_TEXTURE_BASISU:`KHR_texture_basisu`,KHR_TEXTURE_TRANSFORM:`KHR_texture_transform`,KHR_MESH_QUANTIZATION:`KHR_mesh_quantization`,KHR_MATERIALS_EMISSIVE_STRENGTH:`KHR_materials_emissive_strength`,EXT_MATERIALS_BUMP:`EXT_materials_bump`,EXT_TEXTURE_WEBP:`EXT_texture_webp`,EXT_TEXTURE_AVIF:`EXT_texture_avif`,EXT_MESHOPT_COMPRESSION:`EXT_meshopt_compression`,KHR_MESHOPT_COMPRESSION:`KHR_meshopt_compression`,EXT_MESH_GPU_INSTANCING:`EXT_mesh_gpu_instancing`},ql=class{constructor(e){this.parser=e,this.name=Z.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){let e=this.parser,t=this.parser.json.nodes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n];r.extensions&&r.extensions[this.name]&&r.extensions[this.name].light!==void 0&&e._addNodeRef(this.cache,r.extensions[this.name].light)}}_loadLight(e){let t=this.parser,n=`light:`+e,r=t.cache.get(n);if(r)return r;let i=t.json,a=((i.extensions&&i.extensions[this.name]||{}).lights||[])[e],o,s=new K(16777215);a.color!==void 0&&s.setRGB(a.color[0],a.color[1],a.color[2],Ze);let c=a.range===void 0?0:a.range;switch(a.type){case`directional`:o=new Us(s),o.target.position.set(0,0,-1),o.add(o.target);break;case`point`:o=new Bs(s),o.distance=c;break;case`spot`:o=new Rs(s),o.distance=c,a.spot=a.spot||{},a.spot.innerConeAngle=a.spot.innerConeAngle===void 0?0:a.spot.innerConeAngle,a.spot.outerConeAngle=a.spot.outerConeAngle===void 0?Math.PI/4:a.spot.outerConeAngle,o.angle=a.spot.outerConeAngle,o.penumbra=1-a.spot.innerConeAngle/a.spot.outerConeAngle,o.target.position.set(0,0,-1),o.add(o.target);break;default:throw Error(`THREE.GLTFLoader: Unexpected light type: `+a.type)}return o.position.set(0,0,0),Mu(o,a),a.intensity!==void 0&&(o.intensity=a.intensity),o.name=t.createUniqueName(a.name||`light_`+e),r=Promise.resolve(o),t.cache.add(n,r),r}getDependency(e,t){if(e===`light`)return this._loadLight(t)}createNodeAttachment(e){let t=this,n=this.parser,r=n.json.nodes[e],i=(r.extensions&&r.extensions[this.name]||{}).light;return i===void 0?null:this._loadLight(i).then(function(e){return n._getNodeRef(t.cache,i,e)})}},Jl=class{constructor(){this.name=Z.KHR_MATERIALS_UNLIT}getMaterialType(){return ri}extendParams(e,t,n){let r=[];e.color=new K(1,1,1),e.opacity=1;let i=t.pbrMetallicRoughness;if(i){if(Array.isArray(i.baseColorFactor)){let t=i.baseColorFactor;e.color.setRGB(t[0],t[1],t[2],Ze),e.opacity=t[3]}i.baseColorTexture!==void 0&&r.push(n.assignTexture(e,`map`,i.baseColorTexture,Xe))}return Promise.all(r)}},Yl=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);return n===null||n.emissiveStrength!==void 0&&(t.emissiveIntensity=n.emissiveStrength),Promise.resolve()}},Xl=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_CLEARCOAT}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(n.clearcoatFactor!==void 0&&(t.clearcoat=n.clearcoatFactor),n.clearcoatTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatMap`,n.clearcoatTexture)),n.clearcoatRoughnessFactor!==void 0&&(t.clearcoatRoughness=n.clearcoatRoughnessFactor),n.clearcoatRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`clearcoatRoughnessMap`,n.clearcoatRoughnessTexture)),n.clearcoatNormalTexture!==void 0&&(r.push(this.parser.assignTexture(t,`clearcoatNormalMap`,n.clearcoatNormalTexture)),n.clearcoatNormalTexture.scale!==void 0)){let e=n.clearcoatNormalTexture.scale;t.clearcoatNormalScale=new H(e,e)}return Promise.all(r)}},Zl=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_DISPERSION}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);return n===null||(t.dispersion=n.dispersion===void 0?0:n.dispersion),Promise.resolve()}},Ql=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_IRIDESCENCE}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.iridescenceFactor!==void 0&&(t.iridescence=n.iridescenceFactor),n.iridescenceTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceMap`,n.iridescenceTexture)),n.iridescenceIor!==void 0&&(t.iridescenceIOR=n.iridescenceIor),t.iridescenceThicknessRange===void 0&&(t.iridescenceThicknessRange=[100,400]),n.iridescenceThicknessMinimum!==void 0&&(t.iridescenceThicknessRange[0]=n.iridescenceThicknessMinimum),n.iridescenceThicknessMaximum!==void 0&&(t.iridescenceThicknessRange[1]=n.iridescenceThicknessMaximum),n.iridescenceThicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`iridescenceThicknessMap`,n.iridescenceThicknessTexture)),Promise.all(r)}},$l=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_SHEEN}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];if(t.sheenColor=new K(0,0,0),t.sheenRoughness=0,t.sheen=1,n.sheenColorFactor!==void 0){let e=n.sheenColorFactor;t.sheenColor.setRGB(e[0],e[1],e[2],Ze)}return n.sheenRoughnessFactor!==void 0&&(t.sheenRoughness=n.sheenRoughnessFactor),n.sheenColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenColorMap`,n.sheenColorTexture,Xe)),n.sheenRoughnessTexture!==void 0&&r.push(this.parser.assignTexture(t,`sheenRoughnessMap`,n.sheenRoughnessTexture)),Promise.all(r)}},eu=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_TRANSMISSION}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.transmissionFactor!==void 0&&(t.transmission=n.transmissionFactor),n.transmissionTexture!==void 0&&r.push(this.parser.assignTexture(t,`transmissionMap`,n.transmissionTexture)),Promise.all(r)}},tu=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_VOLUME}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.thickness=n.thicknessFactor===void 0?0:n.thicknessFactor,n.thicknessTexture!==void 0&&r.push(this.parser.assignTexture(t,`thicknessMap`,n.thicknessTexture)),t.attenuationDistance=n.attenuationDistance||1/0;let i=n.attenuationColor||[1,1,1];return t.attenuationColor=new K().setRGB(i[0],i[1],i[2],Ze),Promise.all(r)}},nu=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_IOR}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);return n===null||(t.ior=n.ior===void 0?1.5:n.ior,t.ior===0&&(t.ior=1e3)),Promise.resolve()}},ru=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_SPECULAR}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];t.specularIntensity=n.specularFactor===void 0?1:n.specularFactor,n.specularTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularIntensityMap`,n.specularTexture));let i=n.specularColorFactor||[1,1,1];return t.specularColor=new K().setRGB(i[0],i[1],i[2],Ze),n.specularColorTexture!==void 0&&r.push(this.parser.assignTexture(t,`specularColorMap`,n.specularColorTexture,Xe)),Promise.all(r)}},iu=class{constructor(e){this.parser=e,this.name=Z.EXT_MATERIALS_BUMP}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return t.bumpScale=n.bumpFactor===void 0?1:n.bumpFactor,n.bumpTexture!==void 0&&r.push(this.parser.assignTexture(t,`bumpMap`,n.bumpTexture)),Promise.all(r)}},au=class{constructor(e){this.parser=e,this.name=Z.KHR_MATERIALS_ANISOTROPY}getMaterialType(e){return Kl(this.parser,e,this.name)===null?null:Vo}extendMaterialParams(e,t){let n=Kl(this.parser,e,this.name);if(n===null)return Promise.resolve();let r=[];return n.anisotropyStrength!==void 0&&(t.anisotropy=n.anisotropyStrength),n.anisotropyRotation!==void 0&&(t.anisotropyRotation=n.anisotropyRotation),n.anisotropyTexture!==void 0&&r.push(this.parser.assignTexture(t,`anisotropyMap`,n.anisotropyTexture)),Promise.all(r)}},ou=class{constructor(e){this.parser=e,this.name=Z.KHR_TEXTURE_BASISU}loadTexture(e){let t=this.parser,n=t.json,r=n.textures[e];if(!r.extensions||!r.extensions[this.name])return null;let i=r.extensions[this.name],a=t.options.ktx2Loader;if(!a){if(n.extensionsRequired&&n.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures`);return null}return t.loadTextureImage(e,i.source,a)}},su=class{constructor(e){this.parser=e,this.name=Z.EXT_TEXTURE_WEBP}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},cu=class{constructor(e){this.parser=e,this.name=Z.EXT_TEXTURE_AVIF}loadTexture(e){let t=this.name,n=this.parser,r=n.json,i=r.textures[e];if(!i.extensions||!i.extensions[t])return null;let a=i.extensions[t],o=r.images[a.source],s=n.textureLoader;if(o.uri){let e=n.options.manager.getHandler(o.uri);e!==null&&(s=e)}return n.loadTextureImage(e,a.source,s)}},lu=class{constructor(e,t){this.name=t,this.parser=e}loadBufferView(e){let t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){let e=n.extensions[this.name],r=this.parser.getDependency(`buffer`,e.buffer),i=this.parser.options.meshoptDecoder;if(!i||!i.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw Error(`THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files`);return null}return r.then(function(t){let n=e.byteOffset||0,r=e.byteLength||0,a=e.count,o=e.byteStride,s=new Uint8Array(t,n,r);return i.decodeGltfBufferAsync?i.decodeGltfBufferAsync(a,o,s,e.mode,e.filter).then(function(e){return e.buffer}):i.ready.then(function(){let t=new ArrayBuffer(a*o);return i.decodeGltfBuffer(new Uint8Array(t),a,o,s,e.mode,e.filter),t})})}return null}},uu=class{constructor(e){this.name=Z.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){let t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;let r=t.meshes[n.mesh];for(let e of r.primitives)if(e.mode!==xu.TRIANGLES&&e.mode!==xu.TRIANGLE_STRIP&&e.mode!==xu.TRIANGLE_FAN&&e.mode!==void 0)return null;let i=n.extensions[this.name].attributes,a=[],o={};for(let e in i)a.push(this.parser.getDependency(`accessor`,i[e]).then(t=>(o[e]=t,o[e])));return a.length<1?null:(a.push(this.parser.createNodeMesh(e)),Promise.all(a).then(e=>{let t=e.pop(),n=t.isGroup?t.children:[t],r=e[0].count,i=[];for(let e of n){let t=new W,n=new U,a=new It,s=new U(1,1,1),c=new Bi(e.geometry,e.material,r);for(let e=0;e<r;e++)o.TRANSLATION&&n.fromBufferAttribute(o.TRANSLATION,e),o.ROTATION&&a.fromBufferAttribute(o.ROTATION,e),o.SCALE&&s.fromBufferAttribute(o.SCALE,e),c.setMatrixAt(e,t.compose(n,a,s));let l=null;for(let e in o)if(e===`_COLOR_0`){let t=o[e];c.instanceColor=new Mi(t.array,t.itemSize,t.normalized)}else if(e!==`TRANSLATION`&&e!==`ROTATION`&&e!==`SCALE`){if(l===null){let e=c.geometry;l=new J,l.name=e.name;for(let t in e.attributes)l.setAttribute(t,e.attributes[t]);for(let t in e.morphAttributes)l.morphAttributes[t]=e.morphAttributes[t];e.index!==null&&l.setIndex(e.index),l.morphTargetsRelative=e.morphTargetsRelative;for(let t of e.groups)l.addGroup(t.start,t.count,t.materialIndex);e.boundingBox!==null&&(l.boundingBox=e.boundingBox.clone()),e.boundingSphere!==null&&(l.boundingSphere=e.boundingSphere.clone()),l.drawRange.start=e.drawRange.start,l.drawRange.count=e.drawRange.count,l.userData=Object.assign({},e.userData),c.geometry=l}let t=o[e];l.setAttribute(e,new Mi(t.array,t.itemSize,t.normalized))}G.prototype.copy.call(c,e),this.parser.assignFinalMaterial(c),i.push(c)}return t.isGroup?(t.clear(),t.add(...i),t):i[0]}))}},du=`glTF`,fu=12,pu={JSON:1313821514,BIN:5130562},mu=class{constructor(e){this.name=Z.KHR_BINARY_GLTF,this.content=null,this.body=null;let t=new DataView(e,0,fu),n=new TextDecoder;if(this.header={magic:n.decode(new Uint8Array(e.slice(0,4))),version:t.getUint32(4,!0),length:t.getUint32(8,!0)},this.header.magic!==du)throw Error(`THREE.GLTFLoader: Unsupported glTF-Binary header.`);if(this.header.version<2)throw Error(`THREE.GLTFLoader: Legacy binary file detected.`);let r=this.header.length-fu,i=new DataView(e,fu),a=0;for(;a<r;){let t=i.getUint32(a,!0);a+=4;let r=i.getUint32(a,!0);if(a+=4,r===pu.JSON){let r=new Uint8Array(e,fu+a,t);this.content=n.decode(r)}else if(r===pu.BIN){let n=fu+a;this.body=e.slice(n,n+t)}a+=t}if(this.content===null)throw Error(`THREE.GLTFLoader: JSON content not found.`)}},hu=class{constructor(e,t){if(!t)throw Error(`THREE.GLTFLoader: No DRACOLoader instance provided.`);this.name=Z.KHR_DRACO_MESH_COMPRESSION,this.json=e,this.dracoLoader=t,this.dracoLoader.preload()}decodePrimitive(e,t){let n=this.json,r=this.dracoLoader,i=e.extensions[this.name].bufferView,a=e.extensions[this.name].attributes,o={},s={},c={};for(let e in a){let t=Eu[e]||e.toLowerCase();o[t]=a[e]}for(let t in e.attributes){let r=Eu[t]||t.toLowerCase();if(a[t]!==void 0){let i=n.accessors[e.attributes[t]];c[r]=Su[i.componentType].name,s[r]=i.normalized===!0}}return t.getDependency(`bufferView`,i).then(function(e){return new Promise(function(t,n){r.decodeDracoFile(e,function(e){for(let t in e.attributes){let n=e.attributes[t],r=s[t];r!==void 0&&(n.normalized=r)}t(e)},o,c,Ze,n)})})}},gu=class{constructor(){this.name=Z.KHR_TEXTURE_TRANSFORM}extendTexture(e,t){if((t.texCoord===void 0||t.texCoord===e.channel)&&t.offset===void 0&&t.rotation===void 0&&t.scale===void 0)return e;if(e=e.clone(),t.texCoord!==void 0&&(e.channel=t.texCoord),t.offset!==void 0&&e.offset.fromArray(t.offset),t.rotation!==void 0&&(e.rotation=t.rotation),t.scale!==void 0&&e.repeat.fromArray(t.scale),t.rotation!==void 0){let t=Math.cos(e.rotation),n=Math.sin(e.rotation);e.matrix.set(e.repeat.x*t,e.repeat.y*n,e.offset.x,-e.repeat.x*n,e.repeat.y*t,e.offset.y,0,0,1),e.matrixAutoUpdate=!1}return e.needsUpdate=!0,e}},_u=class{constructor(){this.name=Z.KHR_MESH_QUANTIZATION}},vu=class extends Jo{constructor(e,t,n,r){super(e,t,n,r)}copySampleValue_(e){let t=this.resultBuffer,n=this.sampleValues,r=this.valueSize,i=e*r*3+r;for(let e=0;e!==r;e++)t[e]=n[i+e];return t}interpolate_(e,t,n,r){let i=this.resultBuffer,a=this.sampleValues,o=this.valueSize,s=o*2,c=o*3,l=r-t,u=(n-t)/l,d=u*u,f=d*u,p=e*c,m=p-c,h=-2*f+3*d,g=f-d,_=1-h,v=g-d+u;for(let e=0;e!==o;e++){let t=a[m+e+o],n=a[m+e+s]*l,r=a[p+e+o],c=a[p+e]*l;i[e]=_*t+v*n+h*r+g*c}return i}},yu=new It,bu=class extends vu{interpolate_(e,t,n,r){let i=super.interpolate_(e,t,n,r);return yu.fromArray(i).normalize().toArray(i),i}},xu={FLOAT:5126,FLOAT_MAT3:35675,FLOAT_MAT4:35676,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,LINEAR:9729,REPEAT:10497,SAMPLER_2D:35678,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,UNSIGNED_BYTE:5121,UNSIGNED_SHORT:5123},Su={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},Cu={9728:Me,9729:Fe,9984:Ne,9985:Ie,9986:Pe,9987:Le},wu={33071:Ae,33648:je,10497:ke},Tu={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Eu={POSITION:`position`,NORMAL:`normal`,TANGENT:`tangent`,TEXCOORD_0:`uv`,TEXCOORD_1:`uv1`,TEXCOORD_2:`uv2`,TEXCOORD_3:`uv3`,COLOR_0:`color`,WEIGHTS_0:`skinWeight`,JOINTS_0:`skinIndex`},Du={scale:`scale`,translation:`position`,rotation:`quaternion`,weights:`morphTargetInfluences`},Ou={CUBICSPLINE:void 0,LINEAR:Ue,STEP:He},ku={OPAQUE:`OPAQUE`,MASK:`MASK`,BLEND:`BLEND`};function Au(e){return e.DefaultMaterial===void 0&&(e.DefaultMaterial=new Bo({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:0})),e.DefaultMaterial}function ju(e,t,n){for(let r in n.extensions)e[r]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[r]=n.extensions[r])}function Mu(e,t){t.extras!==void 0&&(typeof t.extras==`object`?Object.assign(e.userData,t.extras):console.warn(`THREE.GLTFLoader: Ignoring primitive type .extras, `+t.extras))}function Nu(e,t,n){let r=!1,i=!1,a=!1;for(let e=0,n=t.length;e<n;e++){let n=t[e];if(n.POSITION!==void 0&&(r=!0),n.NORMAL!==void 0&&(i=!0),n.COLOR_0!==void 0&&(a=!0),r&&i&&a)break}if(!r&&!i&&!a)return Promise.resolve(e);let o=[],s=[],c=[];for(let l=0,u=t.length;l<u;l++){let u=t[l];if(r){let t=u.POSITION===void 0?e.attributes.position:n.getDependency(`accessor`,u.POSITION);o.push(t)}if(i){let t=u.NORMAL===void 0?e.attributes.normal:n.getDependency(`accessor`,u.NORMAL);s.push(t)}if(a){let t=u.COLOR_0===void 0?e.attributes.color:n.getDependency(`accessor`,u.COLOR_0);c.push(t)}}return Promise.all([Promise.all(o),Promise.all(s),Promise.all(c)]).then(function(t){let n=t[0],o=t[1],s=t[2];return r&&(e.morphAttributes.position=n),i&&(e.morphAttributes.normal=o),a&&(e.morphAttributes.color=s),e.morphTargetsRelative=!0,e})}function Pu(e,t){if(e.updateMorphTargets(),t.weights!==void 0)for(let n=0,r=t.weights.length;n<r;n++)e.morphTargetInfluences[n]=t.weights[n];if(t.extras&&Array.isArray(t.extras.targetNames)){let n=t.extras.targetNames;if(e.morphTargetInfluences.length===n.length){e.morphTargetDictionary={};for(let t=0,r=n.length;t<r;t++)e.morphTargetDictionary[n[t]]=t}else console.warn(`THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.`)}}function Fu(e){let t,n=e.extensions&&e.extensions[Z.KHR_DRACO_MESH_COMPRESSION];if(t=n?`draco:`+n.bufferView+`:`+n.indices+`:`+Iu(n.attributes):e.indices+`:`+Iu(e.attributes)+`:`+e.mode,e.targets!==void 0)for(let n=0,r=e.targets.length;n<r;n++)t+=`:`+Iu(e.targets[n]);return t}function Iu(e){let t=``,n=Object.keys(e).sort();for(let r=0,i=n.length;r<i;r++)t+=n[r]+`:`+e[n[r]]+`;`;return t}function Lu(e){switch(e){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw Error(`THREE.GLTFLoader: Unsupported normalized accessor component type.`)}}function Ru(e){return e.search(/\.jpe?g($|\?)/i)>0||e.search(/^data\:image\/jpeg/)===0?`image/jpeg`:e.search(/\.webp($|\?)/i)>0||e.search(/^data\:image\/webp/)===0?`image/webp`:e.search(/\.ktx2($|\?)/i)>0||e.search(/^data\:image\/ktx2/)===0?`image/ktx2`:`image/png`}var zu=new W,Bu=class{constructor(e={},t={}){this.json=e,this.extensions={},this.plugins={},this.options=t,this.cache=new Gl,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,r=-1,i=!1,a=-1;if(typeof navigator<`u`&&navigator.userAgent!==void 0){let e=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(e)===!0;let t=e.match(/Version\/(\d+)/);r=n&&t?parseInt(t[1],10):-1,i=e.indexOf(`Firefox`)>-1,a=i?e.match(/Firefox\/([0-9]+)\./)[1]:-1}this.textureLoader=typeof createImageBitmap>`u`||n&&r<17||i&&a<98?new Cs(this.options.manager):new Ks(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new bs(this.options.manager),this.fileLoader.setResponseType(`arraybuffer`),this.options.crossOrigin===`use-credentials`&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){let n=this,r=this.json,i=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([n.getDependencies(`scene`),n.getDependencies(`animation`),n.getDependencies(`camera`)])}).then(function(t){let a={scene:t[0][r.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:r.asset,parser:n,userData:{}};return ju(i,a,r),Mu(a,r),Promise.all(n._invokeAll(function(e){return e.afterRoot&&e.afterRoot(a)})).then(function(){for(let e of a.scenes)e.updateMatrixWorld();e(a)})}).catch(t)}_markDefs(){let e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let n=0,r=t.length;n<r;n++){let r=t[n].joints;for(let t=0,n=r.length;t<n;t++)e[r[t]].isBone=!0}for(let t=0,r=e.length;t<r;t++){let r=e[t];r.mesh!==void 0&&(this._addNodeRef(this.meshCache,r.mesh),r.skin!==void 0&&(n[r.mesh].isSkinnedMesh=!0)),r.camera!==void 0&&this._addNodeRef(this.cameraCache,r.camera)}}_addNodeRef(e,t){t!==void 0&&(e.refs[t]===void 0&&(e.refs[t]=e.uses[t]=0),e.refs[t]++)}_getNodeRef(e,t,n){if(e.refs[t]<=1)return n;let r=n.clone(),i=(e,t)=>{let n=this.associations.get(e);n!=null&&this.associations.set(t,n);for(let[n,r]of e.children.entries())i(r,t.children[n])};return i(n,r),r.name+=`_instance_`+e.uses[t]++,r}_invokeOne(e){let t=Object.values(this.plugins);t.push(this);for(let n=0;n<t.length;n++){let r=e(t[n]);if(r)return r}return null}_invokeAll(e){let t=Object.values(this.plugins);t.unshift(this);let n=[];for(let r=0;r<t.length;r++){let i=e(t[r]);i&&n.push(i)}return n}getDependency(e,t){let n=e+`:`+t,r=this.cache.get(n);if(!r){switch(e){case`scene`:r=this.loadScene(t);break;case`node`:r=this._invokeOne(function(e){return e.loadNode&&e.loadNode(t)});break;case`mesh`:r=this._invokeOne(function(e){return e.loadMesh&&e.loadMesh(t)});break;case`accessor`:r=this.loadAccessor(t);break;case`bufferView`:r=this._invokeOne(function(e){return e.loadBufferView&&e.loadBufferView(t)});break;case`buffer`:r=this.loadBuffer(t);break;case`material`:r=this._invokeOne(function(e){return e.loadMaterial&&e.loadMaterial(t)});break;case`texture`:r=this._invokeOne(function(e){return e.loadTexture&&e.loadTexture(t)});break;case`skin`:r=this.loadSkin(t);break;case`animation`:r=this._invokeOne(function(e){return e.loadAnimation&&e.loadAnimation(t)});break;case`camera`:r=this.loadCamera(t);break;default:if(r=this._invokeOne(function(n){return n!=this&&n.getDependency&&n.getDependency(e,t)}),!r)throw Error(`Unknown type: `+e)}this.cache.add(n,r)}return r}getDependencies(e){let t=this.cache.get(e);if(!t){let n=this,r=this.json[e+(e===`mesh`?`es`:`s`)]||[];t=Promise.all(r.map(function(t,r){return n.getDependency(e,r)})),this.cache.add(e,t)}return t}loadBuffer(e){let t=this.json.buffers[e],n=this.fileLoader;if(t.type&&t.type!==`arraybuffer`)throw Error(`THREE.GLTFLoader: `+t.type+` buffer type is not supported.`);if(t.uri===void 0&&e===0)return Promise.resolve(this.extensions[Z.KHR_BINARY_GLTF].body);let r=this.options;return new Promise(function(e,i){n.load(Ws.resolveURL(t.uri,r.path),e,void 0,function(){i(Error(`THREE.GLTFLoader: Failed to load buffer "`+t.uri+`".`))})})}loadBufferView(e){let t=this.json.bufferViews[e];return this.getDependency(`buffer`,t.buffer).then(function(e){let n=t.byteLength||0,r=t.byteOffset||0;return e.slice(r,r+n)})}loadAccessor(e){let t=this,n=this.json,r=this.json.accessors[e];if(r.bufferView===void 0&&r.sparse===void 0){let e=Tu[r.type],t=Su[r.componentType],n=r.normalized===!0,i=new t(r.count*e);return Promise.resolve(new pr(i,e,n))}let i=[];return r.bufferView===void 0?i.push(null):i.push(this.getDependency(`bufferView`,r.bufferView)),r.sparse!==void 0&&(i.push(this.getDependency(`bufferView`,r.sparse.indices.bufferView)),i.push(this.getDependency(`bufferView`,r.sparse.values.bufferView))),Promise.all(i).then(function(e){let i=e[0],a=Tu[r.type],o=Su[r.componentType],s=o.BYTES_PER_ELEMENT,c=s*a,l=r.byteOffset||0,u=r.bufferView===void 0?void 0:n.bufferViews[r.bufferView].byteStride,d=r.normalized===!0,f,p;if(u&&u!==c){let e=Math.floor(l/u),n=`InterleavedBuffer:`+r.bufferView+`:`+r.componentType+`:`+e+`:`+r.count,c=t.cache.get(n);c||(f=new o(i,e*u,r.count*u/s),c=new Dr(f,u/s),t.cache.add(n,c)),p=new kr(c,a,l%u/s,d)}else f=i===null?new o(r.count*a):new o(i,l,r.count*a),p=new pr(f,a,d);if(r.sparse!==void 0){let t=Tu.SCALAR,n=Su[r.sparse.indices.componentType],s=r.sparse.indices.byteOffset||0,c=r.sparse.values.byteOffset||0,l=new n(e[1],s,r.sparse.count*t),u=new o(e[2],c,r.sparse.count*a);i!==null&&(p=new pr(p.array.slice(),p.itemSize,p.normalized)),p.normalized=!1;for(let e=0,t=l.length;e<t;e++){let t=l[e];if(p.setX(t,u[e*a]),a>=2&&p.setY(t,u[e*a+1]),a>=3&&p.setZ(t,u[e*a+2]),a>=4&&p.setW(t,u[e*a+3]),a>=5)throw Error(`THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.`)}p.normalized=d}return p})}loadTexture(e){let t=this.json,n=this.options,r=t.textures[e].source,i=t.images[r],a=this.textureLoader;if(i.uri){let e=n.manager.getHandler(i.uri);e!==null&&(a=e)}return this.loadTextureImage(e,r,a)}loadTextureImage(e,t,n){let r=this,i=this.json,a=i.textures[e],o=i.images[t],s=(o.uri||o.bufferView)+`:`+a.sampler;if(this.textureCache[s])return this.textureCache[s];let c=this.loadImageSource(t,n).then(function(t){t.flipY=!1,t.name=a.name||o.name||``,t.name===``&&typeof o.uri==`string`&&o.uri.startsWith(`data:image/`)===!1&&(t.name=o.uri);let n=(i.samplers||{})[a.sampler]||{};return t.magFilter=Cu[n.magFilter]||1006,t.minFilter=Cu[n.minFilter]||1008,t.wrapS=wu[n.wrapS]||1e3,t.wrapT=wu[n.wrapT]||1e3,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==1003&&t.minFilter!==1006,r.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[s]=c,c}loadImageSource(e,t){let n=this,r=this.json,i=this.options;if(this.sourceCache[e]!==void 0)return this.sourceCache[e].then(e=>e.clone());let a=r.images[e],o=self.URL||self.webkitURL,s=a.uri||``,c=!1;if(a.bufferView!==void 0)s=n.getDependency(`bufferView`,a.bufferView).then(function(e){c=!0;let t=new Blob([e],{type:a.mimeType});return s=o.createObjectURL(t),s});else if(a.uri===void 0)throw Error(`THREE.GLTFLoader: Image `+e+` is missing URI and bufferView`);let l=Promise.resolve(s).then(function(e){return new Promise(function(n,r){let a=n;t.isImageBitmapLoader===!0&&(a=function(e){let t=new en(e);t.needsUpdate=!0,n(t)}),t.load(Ws.resolveURL(e,i.path),a,void 0,r)})}).then(function(e){return c===!0&&o.revokeObjectURL(s),Mu(e,a),e.userData.mimeType=a.mimeType||Ru(a.uri),e}).catch(function(e){throw console.error(`THREE.GLTFLoader: Couldn't load texture`,s),e});return this.sourceCache[e]=l,l}assignTexture(e,t,n,r){let i=this;return this.getDependency(`texture`,n.index).then(function(a){if(!a)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(a=a.clone(),a.channel=n.texCoord),i.extensions[Z.KHR_TEXTURE_TRANSFORM]){let e=n.extensions===void 0?void 0:n.extensions[Z.KHR_TEXTURE_TRANSFORM];if(e){let t=i.associations.get(a);a=i.extensions[Z.KHR_TEXTURE_TRANSFORM].extendTexture(a,e),i.associations.set(a,t)}}return r!==void 0&&(a.colorSpace=r),e[t]=a,a})}assignFinalMaterial(e){let t=e.geometry,n=e.material,r=t.attributes.tangent===void 0,i=t.attributes.color!==void 0,a=t.attributes.normal===void 0;if(e.isPoints){let e=`PointsMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new aa,Fr.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,t.sizeAttenuation=!1,this.cache.add(e,t)),n=t}else if(e.isLine){let e=`LineBasicMaterial:`+n.uuid,t=this.cache.get(e);t||(t=new Gi,Fr.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,this.cache.add(e,t)),n=t}if(r||i||a){let e=`ClonedMaterial:`+n.uuid+`:`;r&&(e+=`derivative-tangents:`),i&&(e+=`vertex-colors:`),a&&(e+=`flat-shading:`);let t=this.cache.get(e);t||(t=n.clone(),i&&(t.vertexColors=!0),a&&(t.flatShading=!0),r&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(n))),n=t}e.material=n}getMaterialType(){return Bo}loadMaterial(e){let t=this,n=this.json,r=this.extensions,i=n.materials[e],a,o={},s=i.extensions||{},c=[];if(s[Z.KHR_MATERIALS_UNLIT]){let e=r[Z.KHR_MATERIALS_UNLIT];a=e.getMaterialType(),c.push(e.extendParams(o,i,t))}else{let n=i.pbrMetallicRoughness||{};if(o.color=new K(1,1,1),o.opacity=1,Array.isArray(n.baseColorFactor)){let e=n.baseColorFactor;o.color.setRGB(e[0],e[1],e[2],Ze),o.opacity=e[3]}n.baseColorTexture!==void 0&&c.push(t.assignTexture(o,`map`,n.baseColorTexture,Xe)),o.metalness=n.metallicFactor===void 0?1:n.metallicFactor,o.roughness=n.roughnessFactor===void 0?1:n.roughnessFactor,n.metallicRoughnessTexture!==void 0&&(c.push(t.assignTexture(o,`metalnessMap`,n.metallicRoughnessTexture)),c.push(t.assignTexture(o,`roughnessMap`,n.metallicRoughnessTexture))),a=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),c.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,o)})))}i.doubleSided===!0&&(o.side=2);let l=i.alphaMode||ku.OPAQUE;if(l===ku.BLEND?(o.transparent=!0,o.depthWrite=!1):(o.transparent=!1,l===ku.MASK&&(o.alphaTest=i.alphaCutoff===void 0?.5:i.alphaCutoff)),i.normalTexture!==void 0&&a!==ri&&(c.push(t.assignTexture(o,`normalMap`,i.normalTexture)),o.normalScale=new H(1,1),i.normalTexture.scale!==void 0)){let e=i.normalTexture.scale;o.normalScale.set(e,e)}if(i.occlusionTexture!==void 0&&a!==ri&&(c.push(t.assignTexture(o,`aoMap`,i.occlusionTexture)),i.occlusionTexture.strength!==void 0&&(o.aoMapIntensity=i.occlusionTexture.strength)),i.emissiveFactor!==void 0&&a!==ri){let e=i.emissiveFactor;o.emissive=new K().setRGB(e[0],e[1],e[2],Ze)}return i.emissiveTexture!==void 0&&a!==ri&&c.push(t.assignTexture(o,`emissiveMap`,i.emissiveTexture,Xe)),Promise.all(c).then(function(){let n=new a(o);return i.name&&(n.name=i.name),Mu(n,i),t.associations.set(n,{materials:e}),i.extensions&&ju(r,n,i),n})}createUniqueName(e){let t=ic.sanitizeNodeName(e||``);return t in this.nodeNamesUsed?t+`_`+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){let t=this,n=this.extensions,r=this.primitiveCache;function i(e){return n[Z.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(n){return Hu(n,e,t)})}let a=[];for(let n=0,o=e.length;n<o;n++){let o=e[n],s=Fu(o),c=r[s];if(c)a.push(c.promise);else{let e;e=o.extensions&&o.extensions[Z.KHR_DRACO_MESH_COMPRESSION]?i(o):Hu(new J,o,t),o.mode===xu.TRIANGLE_STRIP?e=e.then(e=>Vl(e,1)):o.mode===xu.TRIANGLE_FAN&&(e=e.then(e=>Vl(e,2))),r[s]={primitive:o,promise:e},a.push(e)}}return Promise.all(a)}loadMesh(e){let t=this,n=this.json,r=this.extensions,i=n.meshes[e],a=i.primitives,o=[];for(let e=0,t=a.length;e<t;e++){let t=a[e].material===void 0?Au(this.cache):this.getDependency(`material`,a[e].material);o.push(t)}return o.push(t.loadGeometries(a)),Promise.all(o).then(async function(n){let o=n.slice(0,n.length-1),s=n[n.length-1],c=[];for(let n=0,l=s.length;n<l;n++){let l=s[n],u=a[n],d,f=o[n];if(u.mode===xu.TRIANGLES||u.mode===xu.TRIANGLE_STRIP||u.mode===xu.TRIANGLE_FAN||u.mode===void 0){let e=i.isSkinnedMesh===!0,t=l.hasAttribute(`skinIndex`)&&l.hasAttribute(`skinWeight`);e&&t===!1&&console.warn(`THREE.GLTFLoader: Missing skinIndex or skinWeight attributes. Skinning disabled.`),d=e&&t?new Ei(l,f):new Y(l,f),d.isSkinnedMesh===!0&&d.normalizeSkinWeights()}else if(u.mode===xu.LINES)d=new ra(l,f);else if(u.mode===xu.LINE_STRIP)d=new $i(l,f);else if(u.mode===xu.LINE_LOOP)d=new ia(l,f);else if(u.mode===xu.POINTS)d=new ua(l,f);else throw Error(`THREE.GLTFLoader: Primitive mode unsupported: `+u.mode);Object.keys(d.geometry.morphAttributes).length>0&&Pu(d,i),d.name=t.createUniqueName(i.name||`mesh_`+e),Mu(d,i),u.extensions&&ju(r,d,u),t.assignFinalMaterial(d),c.push(d)}for(let n=0,r=c.length;n<r;n++)t.associations.set(c[n],{meshes:e,primitives:n});if(c.length===1)return i.extensions&&ju(r,c[0],i),c[0];let l=new kn;i.extensions&&ju(r,l,i),t.associations.set(l,{meshes:e});for(let e=0,t=c.length;e<t;e++)l.add(c[e]);return l})}loadCamera(e){let t,n=this.json.cameras[e],r=n[n.type];if(!r)console.warn(`THREE.GLTFLoader: Missing camera parameters.`);else return n.type===`perspective`?t=new Is(Ft.radToDeg(r.yfov),r.aspectRatio||1,r.znear||1,r.zfar||2e6):n.type===`orthographic`&&(t=new Vs(-r.xmag,r.xmag,r.ymag,-r.ymag,r.znear,r.zfar)),n.name&&(t.name=this.createUniqueName(n.name)),Mu(t,n),Promise.resolve(t)}loadSkin(e){let t=this.json.skins[e],n=[];for(let e=0,r=t.joints.length;e<r;e++)n.push(this._loadNodeShallow(t.joints[e]));return t.inverseBindMatrices===void 0?n.push(null):n.push(this.getDependency(`accessor`,t.inverseBindMatrices)),Promise.all(n).then(function(e){let n=e.pop(),r=e,i=[],a=[];for(let e=0,o=r.length;e<o;e++){let o=r[e];if(o){i.push(o);let t=new W;n!==null&&t.fromArray(n.array,e*16),a.push(t)}else console.warn(`THREE.GLTFLoader: Joint "%s" could not be found.`,t.joints[e])}return new ji(i,a)})}loadAnimation(e){let t=this.json,n=this,r=t.animations[e],i=r.name?r.name:`animation_`+e,a=[],o=[],s=[],c=[],l=[];for(let e=0,t=r.channels.length;e<t;e++){let t=r.channels[e],n=r.samplers[t.sampler],i=t.target,u=i.node,d=r.parameters===void 0?n.input:r.parameters[n.input],f=r.parameters===void 0?n.output:r.parameters[n.output];i.node!==void 0&&(a.push(this.getDependency(`node`,u)),o.push(this.getDependency(`accessor`,d)),s.push(this.getDependency(`accessor`,f)),c.push(n),l.push(i))}return Promise.all([Promise.all(a),Promise.all(o),Promise.all(s),Promise.all(c),Promise.all(l)]).then(function(e){let t=e[0],a=e[1],o=e[2],s=e[3],c=e[4],l=[];for(let e=0,r=t.length;e<r;e++){let r=t[e],i=a[e],u=o[e],d=s[e],f=c[e];if(r===void 0)continue;r.updateMatrix&&r.updateMatrix();let p=n._createAnimationTracks(r,i,u,d,f);if(p)for(let e=0;e<p.length;e++)l.push(p[e])}let u=new ds(i,void 0,l);return Mu(u,r),u})}createNodeMesh(e){let t=this.json,n=this,r=t.nodes[e];return r.mesh===void 0?null:n.getDependency(`mesh`,r.mesh).then(function(e){let t=n._getNodeRef(n.meshCache,r.mesh,e);return r.weights!==void 0&&t.traverse(function(e){if(e.isMesh)for(let t=0,n=r.weights.length;t<n;t++)e.morphTargetInfluences[t]=r.weights[t]}),t})}loadNode(e){let t=this.json,n=this,r=t.nodes[e],i=n._loadNodeShallow(e),a=[],o=r.children||[];for(let e=0,t=o.length;e<t;e++)a.push(n.getDependency(`node`,o[e]));let s=r.skin===void 0?Promise.resolve(null):n.getDependency(`skin`,r.skin);return Promise.all([i,Promise.all(a),s]).then(function(e){let t=e[0],n=e[1],r=e[2];r!==null&&t.traverse(function(e){e.isSkinnedMesh&&e.bind(r,zu)});for(let e=0,r=n.length;e<r;e++)t.add(n[e]);if(t.userData.pivot!==void 0&&n.length>0){let e=t.userData.pivot,r=n[0];t.pivot=new U().fromArray(e),t.position.x-=e[0],t.position.y-=e[1],t.position.z-=e[2],r.position.set(0,0,0),delete t.userData.pivot}return t})}_loadNodeShallow(e){let t=this.json,n=this.extensions,r=this;if(this.nodeCache[e]!==void 0)return this.nodeCache[e];let i=t.nodes[e],a=i.name?r.createUniqueName(i.name):``,o=[],s=r._invokeOne(function(t){return t.createNodeMesh&&t.createNodeMesh(e)});return s&&o.push(s),i.camera!==void 0&&o.push(r.getDependency(`camera`,i.camera).then(function(e){return r._getNodeRef(r.cameraCache,i.camera,e)})),r._invokeAll(function(t){return t.createNodeAttachment&&t.createNodeAttachment(e)}).forEach(function(e){o.push(e)}),this.nodeCache[e]=Promise.all(o).then(function(t){let o;if(o=i.isBone===!0?new Di:t.length>1?new kn:t.length===1?t[0]:new G,o!==t[0])for(let e=0,n=t.length;e<n;e++)o.add(t[e]);if(i.name&&(o.userData.name=i.name,o.name=a),Mu(o,i),i.extensions&&ju(n,o,i),i.matrix!==void 0){let e=new W;e.fromArray(i.matrix),o.applyMatrix4(e)}else i.translation!==void 0&&o.position.fromArray(i.translation),i.rotation!==void 0&&o.quaternion.fromArray(i.rotation),i.scale!==void 0&&o.scale.fromArray(i.scale);if(!r.associations.has(o))r.associations.set(o,{});else if(i.mesh!==void 0&&r.meshCache.refs[i.mesh]>1){let e=r.associations.get(o);r.associations.set(o,{...e})}return r.associations.get(o).nodes=e,o}),this.nodeCache[e]}loadScene(e){let t=this.extensions,n=this.json.scenes[e],r=this,i=new kn;n.name&&(i.name=r.createUniqueName(n.name)),Mu(i,n),n.extensions&&ju(t,i,n);let a=n.nodes||[],o=[];for(let e=0,t=a.length;e<t;e++)o.push(r.getDependency(`node`,a[e]));return Promise.all(o).then(function(e){for(let t=0,n=e.length;t<n;t++){let n=e[t];n.parent===null?i.add(n):i.add(Hl(n))}return r.associations=(e=>{let t=new Map;for(let[e,n]of r.associations)(e instanceof Fr||e instanceof en)&&t.set(e,n);return e.traverse(e=>{let n=r.associations.get(e);n!=null&&t.set(e,n)}),t})(i),i})}_createAnimationTracks(e,t,n,r,i){let a=[],o=e.name?e.name:e.uuid,s=[];function c(e){e.morphTargetInfluences&&s.push(e.name?e.name:e.uuid)}Du[i.path]===Du.weights?(c(e),e.isGroup&&e.children.forEach(c)):s.push(o);let l;switch(Du[i.path]){case Du.weights:l=os;break;case Du.rotation:l=cs;break;case Du.translation:case Du.scale:l=us;break;default:switch(n.itemSize){case 1:l=os;break;default:l=us}}let u=r.interpolation===void 0?Ue:Ou[r.interpolation],d=this._getArrayFromAccessor(n);for(let e=0,n=s.length;e<n;e++){let n=new l(s[e]+`.`+Du[i.path],t.array,d,u);r.interpolation===`CUBICSPLINE`&&this._createCubicSplineTrackInterpolant(n),a.push(n)}return a}_getArrayFromAccessor(e){let t=e.array;if(e.normalized){let e=Lu(t.constructor),n=new Float32Array(t.length);for(let r=0,i=t.length;r<i;r++)n[r]=t[r]*e;t=n}return t}_createCubicSplineTrackInterpolant(e){e.createInterpolant=function(e){return new(this instanceof cs?bu:vu)(this.times,this.values,this.getValueSize()/3,e)},e.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}};function Vu(e,t,n){let r=t.attributes,i=new Yn;if(r.POSITION!==void 0){let e=n.json.accessors[r.POSITION],t=e.min,a=e.max;if(t!==void 0&&a!==void 0){if(i.set(new U(t[0],t[1],t[2]),new U(a[0],a[1],a[2])),e.normalized){let t=Lu(Su[e.componentType]);i.min.multiplyScalar(t),i.max.multiplyScalar(t)}}else{console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`);return}}else return;let a=t.targets;if(a!==void 0){let e=new U,t=new U;for(let r=0,i=a.length;r<i;r++){let i=a[r];if(i.POSITION!==void 0){let r=n.json.accessors[i.POSITION],a=r.min,o=r.max;if(a!==void 0&&o!==void 0){if(t.setX(Math.max(Math.abs(a[0]),Math.abs(o[0]))),t.setY(Math.max(Math.abs(a[1]),Math.abs(o[1]))),t.setZ(Math.max(Math.abs(a[2]),Math.abs(o[2]))),r.normalized){let e=Lu(Su[r.componentType]);t.multiplyScalar(e)}e.max(t)}else console.warn(`THREE.GLTFLoader: Missing min/max properties for accessor POSITION.`)}}i.expandByVector(e)}e.boundingBox=i;let o=new yr;i.getCenter(o.center),o.radius=i.min.distanceTo(i.max)/2,e.boundingSphere=o}function Hu(e,t,n){let r=t.attributes,i=[];function a(t,r){return n.getDependency(`accessor`,t).then(function(t){e.setAttribute(r,t)})}for(let t in r){let n=Eu[t]||t.toLowerCase();n in e.attributes||i.push(a(r[t],n))}if(t.indices!==void 0&&!e.index){let r=n.getDependency(`accessor`,t.indices).then(function(t){e.setIndex(t)});i.push(r)}return Wt.workingColorSpace!==`srgb-linear`&&`COLOR_0`in r&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${Wt.workingColorSpace}" not supported.`),Mu(e,t),Vu(e,t,n),Promise.all(i).then(function(){return t.targets===void 0?e:Nu(e,t.targets,n)})}var Uu=new U;function Wu(e,t,n,r,i,a){let o=2*Math.PI*i/4,s=Math.max(a-2*i,0),c=Math.PI/4;Uu.copy(t),Uu[r]=0,Uu.normalize();let l=.5*o/(o+s),u=1-Uu.angleTo(e)/c;return Math.sign(Uu[n])===1?u*l:s/(o+s)+l+l*(1-u)}var Gu=class e extends pa{constructor(e=1,t=1,n=1,r=2,i=.1){let a=r*2+1;if(i=Math.min(e/2,t/2,n/2,i),super(1,1,1,a,a,a),this.type=`RoundedBoxGeometry`,this.parameters={width:e,height:t,depth:n,segments:r,radius:i},a===1)return;let o=this.toNonIndexed();this.index=null,this.attributes.position=o.attributes.position,this.attributes.normal=o.attributes.normal,this.attributes.uv=o.attributes.uv;let s=new U,c=new U,l=new U(e,t,n).divideScalar(2).subScalar(i),u=this.attributes.position.array,d=this.attributes.normal.array,f=this.attributes.uv.array,p=u.length/6,m=new U,h=.5/a;for(let r=0,a=0;r<u.length;r+=3,a+=2)switch(s.fromArray(u,r),c.copy(s),c.x-=Math.sign(c.x)*h,c.y-=Math.sign(c.y)*h,c.z-=Math.sign(c.z)*h,c.normalize(),u[r+0]=l.x*Math.sign(s.x)+c.x*i,u[r+1]=l.y*Math.sign(s.y)+c.y*i,u[r+2]=l.z*Math.sign(s.z)+c.z*i,d[r+0]=c.x,d[r+1]=c.y,d[r+2]=c.z,Math.floor(r/p)){case 0:m.set(1,0,0),f[a+0]=Wu(m,c,`z`,`y`,i,n),f[a+1]=1-Wu(m,c,`y`,`z`,i,t);break;case 1:m.set(-1,0,0),f[a+0]=1-Wu(m,c,`z`,`y`,i,n),f[a+1]=1-Wu(m,c,`y`,`z`,i,t);break;case 2:m.set(0,1,0),f[a+0]=1-Wu(m,c,`x`,`z`,i,e),f[a+1]=Wu(m,c,`z`,`x`,i,n);break;case 3:m.set(0,-1,0),f[a+0]=1-Wu(m,c,`x`,`z`,i,e),f[a+1]=1-Wu(m,c,`z`,`x`,i,n);break;case 4:m.set(0,0,1),f[a+0]=1-Wu(m,c,`x`,`y`,i,e),f[a+1]=1-Wu(m,c,`y`,`x`,i,t);break;case 5:m.set(0,0,-1),f[a+0]=Wu(m,c,`x`,`y`,i,e),f[a+1]=1-Wu(m,c,`y`,`x`,i,t)}}static fromJSON(t){return new e(t.width,t.height,t.depth,t.segments,t.radius)}};function Ku(e={}){let t=e.pass??`optimization`,n=t!==`blockout`,r=![`blockout`,`structure`].includes(t),i=![`blockout`,`structure`,`form`].includes(t),a=1.35,o=.2730000000000001,s=new kn;s.name=`drone-root`;let c={"drone-root":s},l={},u=[],d=[],f=new Bo({name:`blockout-clay`,color:8161684,roughness:.58,metalness:.12}),p=(e,t,n,r,i={})=>new Vo({name:e,color:t,metalness:n,roughness:r,...i}),m={graphite:p(`graphite-anodized-shell`,3159360,.76,.34),deck:p(`satin-machined-deck`,7830921,.82,.3),rail:p(`machined-arm-alloy`,4410976,.82,.28),silver:p(`brushed-motor-aluminium`,9148329,.94,.26),edge:p(`polished-machined-edge`,10793408,.94,.19),black:p(`recess-and-rubber`,461843,.08,.7),dark:p(`black-anodized-motor-stator`,1186084,.74,.36),yellow:p(`safety-yellow-propeller`,16762139,.18,.28,{clearcoat:.44,clearcoatRoughness:.19}),gold:p(`gold-motor-collar`,14264353,.72,.25),powerLed:p(`power-green-led`,6019468,.05,.28,{emissive:3534706,emissiveIntensity:1.1}),blue:p(`cyan-light-guide`,820713,.1,.22,{emissive:237311,emissiveIntensity:3.4}),eye:p(`cyan-eye-emitter`,359874,.12,.2,{emissive:31950,emissiveIntensity:1.1}),amber:p(`amber-navigation-led`,16760133,.12,.27,{emissive:16754978,emissiveIntensity:2.8}),redLed:p(`red-navigation-led`,9963801,.1,.25,{emissive:16713763,emissiveIntensity:3}),lens:p(`blue-coated-optical-glass`,331820,.55,.09,{clearcoat:1,clearcoatRoughness:.0525,emissive:141154,emissiveIntensity:.18}),iris:p(`deep-optical-aperture`,66314,.24,.14,{clearcoat:.8}),opticRing:p(`blue-optic-ring`,1194363,.68,.15,{emissive:217020,emissiveIntensity:.75}),guard:p(`dark-blue-guard-frame`,2111573,.78,.25),huskyWhite:p(`husky-ceramic-white`,13358045,.32,.36,{clearcoat:.24,clearcoatRoughness:.26}),nose:p(`nose-graphite`,1053981,.18,.3,{clearcoat:.4,clearcoatRoughness:.22})};function h(e,t){if(!i)return f;let n=e.name;if(t.startsWith(`screw-`))return m.silver;if(n===`beast-head`||n===`jaw`){if(t===`muzzle-chin`||t===`armor-mandible`)return m.graphite;if(t.startsWith(`mask-`)||t===`husky-muzzle`)return m.huskyWhite;if(t===`nose-shell`)return m.nose;if(t.startsWith(`nostril`)||t.startsWith(`ear-inset`)||t.startsWith(`mouth-seam`))return m.black;if(t.startsWith(`ear-shell`))return m.deck;if(t.startsWith(`ear-inner-panel`))return m.graphite;if(t.startsWith(`eye-iris`))return m.lens;if(t===`armor-face-mask`||t.startsWith(`armor-crown`))return m.graphite}return t.startsWith(`eye-light`)?m.eye:t.startsWith(`tooth-`)?m.edge:t.includes(`scanner-light`)?m.blue:t.includes(`sole`)||t.includes(`socket`)||t.startsWith(`recess-`)||t.includes(`gasket`)||t.includes(`cable`)||t.includes(`vent-`)||t.includes(`isolator`)||t.includes(`damping`)?m.black:t.includes(`pupil`)?m.iris:n.startsWith(`guard-`)?t===`ring`||t===`outer-rail`?m.blue:t.includes(`clip`)?m.silver:t.includes(`support`)?m.dark:m.guard:n.startsWith(`rotor-`)?t.startsWith(`blade`)?m.yellow:t===`hub-cap`?m.dark:m.silver:n.startsWith(`motor-`)?t===`status-led`||t===`bottom-glow`?m.amber:t===`blue-can-band`?m.blue:t===`can-upper-band`||t===`top-collar`?m.gold:t===`silver-can`?m.silver:t.includes(`band`)||t.includes(`bell-rib`)||t===`shaft`||t===`lower-neck`?m.edge:t.includes(`cooling-fin`)?m.rail:m.dark:n.startsWith(`arm-`)?t.includes(`blue-trim`)?m.blue:t.includes(`spar`)||t.includes(`rail`)?m.silver:t.includes(`slotted`)?m.rail:m.graphite:t.includes(`light-strip`)||t.includes(`blue-trim`)?m.blue:t.startsWith(`power-led-`)?m.powerLed:t.includes(`power-seat`)?m.black:t.includes(`rim`)||t.includes(`fastener`)||t.includes(`hydraulic`)?m.silver:t.startsWith(`armor-`)?t.includes(`inset`)||t.includes(`brow`)?m.graphite:m.deck:t.includes(`drum`)||t.includes(`joint`)?m.dark:t===`skull-shell`?m.graphite:n===`landing-gear`?t.includes(`rubber`)?m.black:t.includes(`strut`)?m.rail:m.graphite:n===`gimbal`?t.includes(`glass`)?m.lens:t===`camera-status`?m.blue:t.startsWith(`focus-ring`)?t.endsWith(`-4`)?m.opticRing:m.dark:t.includes(`pitch-`)||t.includes(`fork-`)?m.silver:t===`camera-bezel`?m.dark:m.graphite:t.startsWith(`power-led-`)?m.powerLed:t.startsWith(`power-icon-`)?m.silver:t.startsWith(`power-`)?m.black:t.startsWith(`front-status`)?m.redLed:t.includes(`light-strip`)||t.includes(`led-cell`)||t.includes(`side-status`)?m.blue:t.includes(`recess`)?m.black:t.startsWith(`split-top`)||t.startsWith(`top-shoulder`)?m.deck:t===`lower-skirt`?m.dark:m.graphite}function g(e,t,n){let r=new kn;r.name=e,r.position.set(...n),r.userData={componentId:e,partId:e,label:t,destructionGroup:e,collider:{shape:`box`}},s.add(r),c[e]=r,u.push(r);let i=new G;return i.name=`socket-${e}`,i.position.set(...n),s.add(i),l[e]=i,r}function _(e,t,n,r=[0,0,0]){let i=new Y(n,h(e,t));return i.name=`${e.name}-${t}`,i.position.set(...r),i.castShadow=!0,i.receiveShadow=!0,i.userData={explodeWithParent:!0,componentId:e.name},e.add(i),i}function v(e,t,n,i=[0,0,0]){return _(e,t,r?new Gu(...n,2,Math.min(.055,Math.min(...n)*.2)):new pa(...n),i)}function y(e,t,n,r,i,a=`y`){let o=_(e,t,new ha(n,n,r,40),i);return a===`x`&&(o.rotation.z=Math.PI/2),a===`z`&&(o.rotation.x=Math.PI/2),o}function b(e,t,n,r,i,a=`y`){let o=_(e,t,new Ro(n,r,8,64),i);return a===`y`&&(o.rotation.x=Math.PI/2),a===`x`&&(o.rotation.y=Math.PI/2),o}function x(e,t,n,r,i){let a=new U(...n),o=new U(...r),s=o.clone().sub(a),c=y(e,t,i,s.length(),a.add(o).multiplyScalar(.5).toArray());return c.quaternion.setFromUnitVectors(new U(0,1,0),s.normalize()),c}function S(e,t,n,i,a,o){let s=(e,t,n,r,i,a)=>{a<=0?(e.moveTo(t,n),e.lineTo(t+r,n),e.lineTo(t+r,n+i),e.lineTo(t,n+i),e.closePath()):(e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath())},c=new qa;s(c,0,-i/2,n,i,r?.035:.025);let l=new Ka,u=.2,d=n-.2,f=i*.19;s(l,u,-f,d-u,f*2,f*.95),c.holes.push(l);let p=new jo(c,{depth:a-(r?.008:0),steps:1,bevelEnabled:r,bevelThickness:.004,bevelSize:.004,bevelSegments:1,curveSegments:6});return p.translate(0,0,-a/2+(r?.004:0)),_(e,t,p,o)}function C(e,t,n,r=`y`,i=.032){if(r===`x`){let a=i*.43,o=new Po([[a,-.006],[i,-.006],[i,.003],[i-.002,.006],[a+.001,.006],[a,.004],[a,-.006]].map(([e,t])=>new H(e,t)),40);o.normalizeNormals();let s=_(e,`screw-`+t,o,n);s.rotation.z=Math.PI/2,y(e,`recess-`+t,a,.004,n,r);return}let a=new qa;a.absarc(0,0,i,0,Math.PI*2,!1);let o=new Ka;for(let e=0;e<6;e++){let t=-e*Math.PI/3,n=Math.cos(t)*i*.43,r=Math.sin(t)*i*.43;e?o.lineTo(n,r):o.moveTo(n,r)}o.closePath(),a.holes.push(o);let s=new jo(a,{depth:.012,bevelEnabled:!1,curveSegments:8});s.translate(0,0,-.006);let c=_(e,`screw-`+t,s,n);r===`y`&&(c.rotation.x=-Math.PI/2),y(e,`recess-`+t,i*.85,.007,n,r)}function w(e,t,n,r=.011){return _(e,t,new zo(new Ea(n.map(e=>new U(...e))),24,r,6,!1))}function T(e,t,n,r=[0,0,0]){let i=[],a=[];for(let e of n){let t=(e.t-e.b)*.24;for(let[n,r]of[[-e.w*.7,e.b],[e.w*.7,e.b],[e.w,e.b+t],[e.w,e.t-t],[e.w*.68,e.t],[-e.w*.68,e.t],[-e.w,e.t-t],[-e.w,e.b+t]])i.push(n,r,e.z)}for(let e=0;e<n.length-1;e++)for(let t=0;t<8;t++){let n=e*8+t,r=e*8+(t+1)%8,i=n+8,o=r+8;a.push(n,r,i,r,o,i)}for(let[e,t]of[[0,!1],[n.length-1,!0]]){let r=n[e],o=i.length/3;i.push(0,(r.b+r.t)/2,r.z);for(let n=0;n<8;n++){let r=e*8+n,i=e*8+(n+1)%8;a.push(o,t?r:i,t?i:r)}}let o=new J;o.setAttribute(`position`,new q(i,3)),o.setIndex(a);let s=o.toNonIndexed();return o.dispose(),s.computeVertexNormals(),_(e,t,s,r)}function E(e,t,n,i,a,o=[0,0,0]){let s=new qa;n.forEach(([e,t],n)=>n?s.lineTo(e,t):s.moveTo(e,t)),s.closePath();let c=r&&!t.startsWith(`armor-jowl`)&&!t.startsWith(`ear-`)&&!t.startsWith(`mask-cheek`)?Math.min(i*.16,.018):0,l=new jo(s,{depth:i-2*c,bevelEnabled:c>0,bevelSize:c,bevelThickness:c,bevelSegments:1,steps:1,curveSegments:1});l.translate(0,0,-i/2+c);let u=_(e,t,l,a);return u.rotation.set(...o),u}function D(e,t,n,r,i,a){let o=new U(...n),s=new U(...r).clone().sub(o),c=s.length(),l=T(e,t,[{z:0,w:i*.32,b:-a*.34,t:a*.34},{z:c*.18,w:i*.5,b:-a*.5,t:a*.5},{z:c*.68,w:i*.45,b:-a*.45,t:a*.45},{z:c,w:i*.26,b:-a*.27,t:a*.27}],n);return l.quaternion.setFromUnitVectors(new U(0,0,1),s.normalize()),l}function O(){let e=new Ea([[.09,.065,0],[.18,.105,0],[.3,.245,.025],[.46,.31,.045],[.64,.29,.055],[.82,.24,.058],[.98,.15,.03],[1.08,.065,.005],[1.105,.008,0]].map(e=>new U(...e))),t=[],n=[];for(let n=0;n<=32;n++){let r=n/32,i=e.getPoint(r),a=.021*(1-.65*r);for(let e=0;e<12;e++){let n=e*Math.PI*2/12,o=Math.cos(n)*i.y/2;t.push(i.x,Math.sin(n)*a+o*(.3-.18*r),i.z+o)}}for(let e=0;e<32;e++)for(let t=0;t<12;t++){let r=e*12+t,i=e*12+(t+1)%12,a=r+12,o=i+12;n.push(r,a,i,i,a,o)}let r=t.length/3;t.push(.09,0,0);let i=t.length/3;t.push(1.105,0,0);for(let e=0;e<12;e++){let t=(e+1)%12;n.push(r,e,t,i,384+t,384+e)}let a=new J;return a.setAttribute(`position`,new q(t,3)),a.setIndex(n),a.computeVertexNormals(),a}let k=g(`chassis`,`长脊装甲机身`,[0,0,0]);if(T(k,`armor-backbone`,[{z:-1.55,w:.78,b:-.25,t:.44},{z:-1.35,w:.96,b:-.43,t:.74},{z:-.3,w:.97,b:-.46,t:.8},{z:.75,w:.86,b:-.42,t:.56},{z:.95,w:.63,b:-.24,t:.32}]),v(k,`belly-core`,[1.45,.37,2],[0,-.54,-.25]),n){T(k,`armor-dorsal-crown`,[{z:-1.34,w:.57,b:.65,t:.73},{z:-.38,w:.65,b:.7,t:.84},{z:.3,w:.49,b:.67,t:.78}]),v(k,`belly-vent-recess`,[1.5,.17,1.84],[0,-.66,-.21]),v(k,`rear-access-panel`,[1.21,.35,.038],[0,-.01,-1.557]),v(k,`rear-light-strip`,[.68,.04,.025],[0,.21,-1.586]);for(let e of[-1,1]){let t=e<0?`l`:`r`;v(k,`power-seat-`+t,[.025,.2,1.12],[e*.967,.24,-.64]);for(let n=0;n<4;n++){let r=-1.045+n*.255;y(k,`power-seat-`+t+`-`+n,.049,.027,[e*.986,.26,r],`x`),y(k,`power-led-`+t+`-`+n,.034,.015,[e*1.003,.26,r],`x`)}y(k,`side-power-ring-`+t,.071,.025,[e*.98,-.045,-.7],`x`),b(k,`blue-trim-power-`+t,.073,.009,[e*.998,-.045,-.7],`x`);for(let n=0;n<16;n++)v(k,`belly-cooling-fin-`+t+`-`+n,[.048,.17,.032],[e*.776,-.64,-.98+n*.104]);E(k,`armor-lower-flank-`+t,[[-.82,.07],[.51,.08],[.7,-.1],[.53,-.23],[-.75,-.23]],.09,[e*.83,-.31,-.21],[0,Math.PI/2,0])}}if(r){for(let e of[-1,1]){for(let t of[-1.1,-.65,-.2,.25])C(k,`flank-`+e+`-`+t,[e*.98,.09,t],`x`,.023);v(k,`side-gasket-`+e,[.014,.022,1.12],[e*.967,-.17,-.64]),v(k,`rear-panel-seam-`+e,[.015,.008,.68],[e*.44,.776,-.81])}T(k,`armor-service-hatch`,[{z:-1.15,w:.26,b:.763,t:.78},{z:-.72,w:.26,b:.794,t:.81}]);for(let e of[-.2,.2])C(k,`hatch-`+e,[e,.802,-.79],`y`,.018);for(let e of[-.44,.44])C(k,`rear-access-`+e,[e,.03,-1.584],`z`,.029)}let A=new W().makeScale(1,1,a);for(let e of k.children){if(!(e instanceof Y)||(e.position.z*=a,[`CylinderGeometry`,`TorusGeometry`].includes(e.geometry.type)||e.name.startsWith(`chassis-screw-`)||e.name.startsWith(`chassis-recess-`)))continue;let t=new W().makeRotationFromQuaternion(e.quaternion),n=t.clone().invert().multiply(A).multiply(t);e.geometry.applyMatrix4(n)}let j=g(`beast-head`,`机械哈士奇头部`,[0,.18,.9525000000000001]),M=(e,t)=>e.map(([e,n])=>[e*t,n]);function N(e,t=.02){let n=new qa;return e.forEach(([r,i],a)=>{let o=new H(...e[(a+e.length-1)%e.length]),s=new H(r,i),c=new H(...e[(a+1)%e.length]),l=Math.min(t,s.distanceTo(o)*.24,s.distanceTo(c)*.24),u=s.clone().add(o.sub(s).normalize().multiplyScalar(l)),d=s.clone().add(c.sub(s).normalize().multiplyScalar(l));a===0?n.moveTo(u.x,u.y):n.lineTo(u.x,u.y),n.quadraticCurveTo(r,i,d.x,d.y)}),n.closePath(),n}function P(e,t,n,r,i,a=1){let o=n.extractPoints(6),s=new qa(Oo.isClockWise(o.shape)?o.shape:o.shape.reverse());s.holes=o.holes.map(e=>new Ka(Oo.isClockWise(e)?e.reverse():e));let c=new jo(s,{depth:r,steps:1,bevelEnabled:!1,curveSegments:6}),l=c.getAttribute(`position`),u=[],d=[],f=(e,t,n,a)=>{if(a>0){let r=e.clone().add(t).multiplyScalar(.5),i=t.clone().add(n).multiplyScalar(.5),o=n.clone().add(e).multiplyScalar(.5);f(e,r,o,a-1),f(r,t,i,a-1),f(o,i,n,a-1),f(r,i,o,a-1);return}let o=Math.abs(e.z-t.z)<1e-6&&Math.abs(e.z-n.z)<1e-6,s=[e,t,n].map(e=>new U(e.x,e.y,i(e.x,e.y)+e.z-r)),c=s[1].clone().sub(s[0]).cross(s[2].clone().sub(s[0])).normalize();s.forEach((r,a)=>{u.push(r.x,r.y,r.z);let s=c.clone();if(o){let r=1e-4,o=[e,t,n][a],l=o.x,u=o.y;s.set(-(i(l+r,u)-i(l-r,u))/(2*r),-(i(l,u+r)-i(l,u-r))/(2*r),1).normalize().multiplyScalar(c.z<0?-1:1)}d.push(s.x,s.y,s.z)})};for(let e=0;e<l.count;e+=3)f(new U().fromBufferAttribute(l,e),new U().fromBufferAttribute(l,e+1),new U().fromBufferAttribute(l,e+2),a);c.dispose();let p=new J;return p.setAttribute(`position`,new q(u,3)),p.setAttribute(`normal`,new q(d,3)),_(e,t,p)}function ee(e,t,n,r=24,i=0){let a=[],o=[];for(let e of n)for(let t=0;t<r;t++){let n=t*Math.PI*2/r,o=Math.sin(n);a.push(Math.cos(n)*e.w*(1-i*Math.max(0,o)),e.y+o*(o>0?e.hUpper??e.h:e.h),e.z)}for(let e=0;e<n.length-1;e++)for(let t=0;t<r;t++){let n=e*r+t,i=e*r+(t+1)%r,a=n+r,s=i+r;o.push(n,i,a,i,s,a)}for(let[e,t]of[[0,!1],[n.length-1,!0]]){let i=n[e],s=a.length/3;a.push(0,i.y,i.z);for(let n=0;n<r;n++){let i=e*r+n,a=e*r+(n+1)%r;o.push(s,t?i:a,t?a:i)}}let s=new J;return s.setAttribute(`position`,new q(a,3)),s.setIndex(o),s.computeVertexNormals(),_(e,t,s)}ee(j,`skull-shell`,[{z:-.24,w:.48,y:.26,h:.55},{z:-.06,w:.68,y:.27,h:.72},{z:.16,w:.77,y:.28,h:.8},{z:.38,w:.78,y:.27,h:.8},{z:.57,w:.72,y:.25,h:.75},{z:.7,w:.64,y:.23,h:.66}],20);let F=(e,t)=>1.02-.28*(e/.8)**2-(t>.3?.4:.06)*((t-.3)/.8)**2,te=[[-.48,-.41],[-.69,-.16],[-.765,.27],[-.69,.7],[-.43,.99],[0,1.07],[.43,.99],[.69,.7],[.765,.27],[.69,-.16],[.48,-.41]],ne=[[-.2,.018],[-.15,-.092],[.07,-.103],[.19,.025],[.18,.12],[.055,.085]],re=N(te,.065);for(let e of[-1,1])re.holes.push(N(ne.map(([t,n])=>[(.39+t)*e,.3+n]),.024));P(j,`armor-face-mask`,re,.095,F,3);for(let e of[-1,1]){let t=e<0?`l`:`r`,a=e*.39,o=.3,s=F(a,o),c=N(ne.map(([t,n])=>[(.39+t)*e,.3+n]),.025);P(j,`eye-socket-`+t,c,.025,(e,t)=>F(e,t)-.092,1).material=i?m.black:f;let l=y(j,`eye-optic-`+t,.102,.018,[a,o,s-.048],`z`);l.rotation.y=e*.33,l.material=i?m.lens:f;let u=b(j,`eye-light-`+t,.074,.012,[a,o,s-.032],`z`);u.rotation.y=e*.33;let d=b(j,`eye-light-inner-`+t,.058,.004,[a,o,s-.031],`z`);d.rotation.y=e*.33,d.material=i?m.eye:f;let p=y(j,`eye-iris-`+t,.052,.012,[a,o,s-.033],`z`);p.rotation.y=e*.33,p.material=i?m.iris:f;let h=y(j,`eye-catchlight-`+t,.009,.007,[a-e*.022,.33499999999999996,s-.025],`z`);h.rotation.y=e*.33,h.material=i?m.eye:f,P(j,`mask-eyebrow-`+t,N(M([[.12,.344],[.215,.423],[.278,.574],[.382,.595],[.468,.535],[.644,.594],[.574,.414],[.314,.311]],e),.025),.026,(e,t)=>F(e,t)+.012,2),P(j,`mask-cheek-`+t,N(M([[.712,.385],[.617,.296],[.549,.13],[.373,.153],[.304,.01],[.244,-.271],[.438,-.392],[.664,-.247],[.754,.002]],e),.036),.04,(e,t)=>F(e,t)+.022,2);let g=[[.225,.785],[.735,.768],[.765,.875],[.692,1.494],[.65,1.6],[.606,1.544]],_=[[.337,.875],[.66,.852],[.684,.944],[.639,1.423],[.606,1.377]],v=(e,t)=>.305+.065*Math.max(0,1-((Math.abs(e)-.515)/.29)**2)-.045*(t-.8),x=N(M(g,e),.018);if(x.holes.push(N(M(_,e),.019)),P(j,`ear-shell-`+t,x,.14,v,1),P(j,`ear-inset-`+t,N(M(_,e),.022),.03,(e,t)=>v(e,t)-.092,1),P(j,`ear-inner-panel-`+t,N(M([[.407,.881],[.515,.912],[.621,1.325],[.605,1.368],[.474,1.089]],e),.013),.025,(e,t)=>v(e,t)-.071,1),n&&(E(j,`armor-temple-`+t,[[-.54,.06],[-.4,.49],[-.08,.6],[.19,.35],[.2,-.12],[-.04,-.38],[-.38,-.31]],.1,[e*.714,.045,.12],[0,Math.PI/2,0]),E(j,`armor-temple-inset-`+t,[[-.445,.065],[-.333,.389],[-.1,.48],[.1,.29],[.11,-.055],[-.067,-.26],[-.292,-.23]],.022,[e*.774,.045,.12],[0,Math.PI/2,0]),P(j,`mask-ear-mount-`+t,N(M([[.282,.803],[.41,.804],[.416,.924],[.35,.965]],e),.013),.045,(e,t)=>v(e,t)+.02,1),r)){for(let[n,r]of[[.42,.21],[-.16,.3]])C(j,`temple-`+t+n,[e*.784,n,r],`x`,.019);for(let[n,r]of[[.696,.901],[.675,1.07]])C(j,`ear-`+t+r,[e*n,r,v(e*n,r)+.008],`z`,.012);C(j,`brow-`+t,[e*.514,.506,F(e*.514,.506)+.035],`z`,.012)}}let ie=[{z:.64,w:.45,y:-.115,h:.315,hUpper:.335},{z:.79,w:.465,y:-.105,h:.317,hUpper:.37},{z:.94,w:.445,y:-.115,h:.294,hUpper:.4},{z:1.1,w:.404,y:-.127,h:.264,hUpper:.34},{z:1.24,w:.349,y:-.139,h:.235,hUpper:.27},{z:1.37,w:.286,y:-.145,h:.202,hUpper:.205},{z:1.405,w:.238,y:-.155,h:.185,hUpper:.185}];ee(j,`husky-muzzle`,ie,24,.22);let ae=N([[-.186,.069],[.186,.069],[.222,.021],[.184,-.076],[.072,-.141],[0,-.153],[-.072,-.141],[-.184,-.076],[-.222,.021]],.025);for(let e of[-1,1]){let t=new Ka;t.absellipse(e*.105,-.03,.053,.036,0,Math.PI*2,!0,-e*.22),ae.holes.push(t)}let oe=(e,t)=>1.58-.063*(e/.225)**2-.025*((t+.025)/.15)**2;P(j,`nose-shell`,ae,.14,oe,3);for(let e of[-1,1]){let t=_(j,`nostril-cavity-`+(e<0?`l`:`r`),new Lo(1,20,12),[e*.105,-.03,oe(e*.105,-.03)-.151]);t.scale.set(.083,.06,.043),t.material=i?m.black:f}if(n){P(j,`armor-crown-panel`,N([[-.2,.63],[-.27,.86],[-.21,1.013],[0,1.07],[.21,1.013],[.27,.86],[.2,.63]],.027),.03,(e,t)=>F(e,t)+.01,2);for(let e of[-1,1]){let t=N(M([[.268,.659],[.308,.903],[.417,.951],[.589,.779],[.654,.655],[.522,.637],[.431,.704]],e),.017);P(j,`armor-forehead-panel-`+e,t,.025,(e,t)=>F(e,t)+.008,2).material=i?m.rail:f}P(j,`mask-forehead-blaze`,N([[-.018,.466],[-.025,.631],[0,.748],[.025,.631],[.018,.466]],.005),.012,(e,t)=>F(e,t)+.023,1);for(let e of[-1,1]){let t=N(M([[.035,.014],[.151,.055],[.123,.193],[.043,.282]],e),.02);P(j,`mask-nose-bridge-`+e,t,.024,(e,t)=>1.026-.27*(t/.31)**2-.17*(e/.46)**2,3)}}let se=g(`jaw`,`闭合机械下颚`,[0,-.1,1.3025]);ee(se,`armor-mandible`,[{z:-.12,w:.405,y:-.025,h:.12},{z:.12,w:.457,y:-.065,h:.14},{z:.41,w:.418,y:-.13,h:.105},{z:.7,w:.347,y:-.132,h:.084},{z:.94,w:.242,y:-.105,h:.06},{z:1.035,w:.205,y:-.098,h:.042}],20),ee(se,`muzzle-chin`,[{z:.38,w:.412,y:-.094,h:.078},{z:.63,w:.371,y:-.1,h:.072},{z:.86,w:.278,y:-.09,h:.057},{z:.99,w:.226,y:-.073,h:.046},{z:1.035,w:.198,y:-.063,h:.032}]);let ce=[];for(let e of ie)ce.push([Math.cos(Math.PI/6)*e.w+.006,e.y-.5*e.h+.278,e.z-.35]);for(let e=1;e<8;e++){let t=.206*(1-2*e/8);ce.push([t,-.02+.0525*(t/.206)**2,1.064])}for(let e of[...ie].reverse())ce.push([-Math.cos(Math.PI/6)*e.w-.006,e.y-.5*e.h+.278,e.z-.35]);ce.push([0,-.035,.285]);let le=_(se,`mouth-seam`,new zo(new Ea(ce.map(e=>new U(...e)),!0,`centripetal`),192,.008,8,!0));le.material=i?m.black:f,le.userData.tubeRadius=.008,x(j,`mouth-philtrum`,[0,-.15,1.417],[0,-.3,1.417],.007).material=i?m.black:f;for(let e of[-1,1])y(se,`jaw-hinge-`+e,.104,.12,[e*.47,.035,0],`x`),n&&(b(se,`jaw-hinge-rim-`+e,.078,.008,[e*.542,.035,0],`x`),r&&C(se,`jaw-pivot-`+e,[e*.554,.035,0],`x`,.02));let ue=[];for(let[e,t,a]of[[`fl`,-1,!0],[`fr`,1,!0],[`rl`,-1,!1],[`rr`,1,!1]]){let o=(a?.78:-1)*.3500000000000001,s=[t*.95,-.42,(a?.78:-1)+o],c=[t*1.16,-1.42,(a?.32:-1.45)+o],l=[t*1.36,-2.37,(a?1.15:-1.06)+o],u=g(`leg-upper-`+e,`髋关节与上腿 `+e.toUpperCase(),s),d=c.map((e,t)=>e-(s[t]??0));y(u,`hip-drum`,.31,.34,[t*.035,0,0],`x`),D(u,`armor-thigh`,[0,-.05,0],d,.48,.48);let p=g(`leg-lower-`+e,`膝关节与下腿 `+e.toUpperCase(),c),h=l.map((e,t)=>e-(c[t]??0));y(p,`knee-drum`,.235,.38,[0,0,0],`x`),D(p,`armor-shin`,[0,-.02,0],h,.29,.3);let _=g(`foot-`+e,`机械支撑足 `+e.toUpperCase(),l);if(y(_,`ankle-drum`,.125,.37,[0,.005,0],`x`),T(_,`armor-toe`,[{z:-.27,w:.17,b:-.15,t:.025},{z:-.1,w:.225,b:-.15,t:.095},{z:.25,w:.23,b:-.15,t:.015},{z:.49,w:.16,b:-.15,t:-.09}]),v(_,`sole`,[.38,.055,.63],[0,-.1525,.075]),n){let e=[[-.23,.22],[.04,.35],[.31,.23],[.39,-.1],[.19,-.36],[-.15,-.31],[-.31,-.06]];E(u,`armor-hip-cover`,e,.16,[t*.225,0,-.02],[0,Math.PI/2,0]),E(u,`armor-hip-inset`,e.map(([e,t])=>[e*.8,t*.8]),.025,[t*.315,0,-.02],[0,Math.PI/2,0]),y(p,`knee-rim`,.24,.04,[t*.214,0,0],`x`),y(p,`knee-cap`,.188,.035,[t*.248,0,0],`x`),b(p,`knee-inner-rim`,.151,.011,[t*.27,0,0],`x`),y(p,`knee-center`,.1,.026,[t*.273,0,0],`x`),D(u,`armor-thigh-inset`,[t*.13,-.2,-.08],[d[0]+t*.13,d[1]+.16,d[2]],.26,.12),D(p,`armor-shin-inset`,[t*.075,-.2,.09],[h[0]+t*.075,h[1]+.18,h[2]-.07],.18,.08),x(u,`hydraulic-piston`,[0,-.18,.12],[d[0],d[1]+.08,d[2]+.13],.045);for(let e of[-1,1])b(_,`ankle-rim-`+e,.102,.012,[e*.203,.005,0],`x`);for(let e=0;e<2;e++)v(_,`toe-panel-seam-`+e,[.008,.008,.23],[-.065+e*.13,-.021,.22])}if(r){for(let[e,n]of[[-.17,.12],[.11,.22],[.22,-.09]])C(u,`hip-`+e,[t*.34,n,e],`x`,.022);C(p,`knee-fastener`,[t*.297,0,0],`x`,.066);for(let e of[.32,.65]){let n=h.map(t=>t*e);C(p,`shin-`+e,[(n[0]??0)+t*.15,n[1]??0,n[2]??0],`x`,.023)}for(let e of[-1,1])C(_,`ankle-`+e,[e*.227,.005,0],`x`,.032);v(u,`hip-gold-mark`,[.01,.015,.16],[t*.335,.12,-.04]).material=i?m.gold:f}ue.push({upper:u,lower:p,foot:_})}for(let[e,t,i]of[[`fl`,-2.6,1.4],[`fr`,2.6,1.4],[`rl`,-2.6,-1.4],[`rr`,2.6,-1.4]]){let s=i+Math.sign(i)*o,c=new U(Math.sign(t)*.79,.05,Math.sign(s)*.78*a),l=new U(t,.05,s).clone().sub(c),u=g(`arm-`+e,`承力机臂 `+e.toUpperCase(),c.toArray());u.rotation.y=-Math.atan2(l.z,l.x);let f=l.length();if(!n)v(u,`beam`,[f,.22,.25],[f/2,0,0]);else{for(let e of[-1,1])S(u,`slotted-web-`+e,f,.22,.045,[0,0,e*.108]);for(let e of[-.115,.115])v(u,`spar-`+e,[f,.035,.23],[f/2,e,0]);for(let e of[.07,f-.2])v(u,`hinge-block-`+e,[.24,.28,.3],[e,0,0]),y(u,`hinge-pin-`+e,.055,.31,[e,.03,0]);let e=[f*.61,-.64,0];if(D(u,`brace-root`,[.19,-.13,0],e,.17,.14),D(u,`brace-tip`,e,[f-.13,-.15,0],.14,.12),y(u,`brace-joint`,.16,.21,e,`z`),b(u,`brace-joint-rim`,.121,.012,[e[0],e[1],.126],`z`),x(u,`blue-trim-brace`,[.36,-.25,.082],[e[0]-.07,e[1]+.06,.082],.008),r){for(let e of[-1,1]){for(let t of[.28,f-.35])C(u,`side-`+e+t,[t,0,e*.141],`z`,.026);v(u,`top-rail-`+e,[f-.44,.012,.017],[f/2,.142,e*.065])}for(let e of[.06,f-.19])C(u,`pivot-`+e,[e,.195,0],`y`,.044);w(u,`under-cable`,[[.15,-.072,-.075],[f*.45,-.1,-.06],[f*.78,-.08,-.065],[f-.1,-.025,-.065]],.012)}}let p=g(`motor-`+e,`无刷电机 `+e.toUpperCase(),[t,.32,s]);if(!n)_(p,`can`,new ha(.24,.24,.7,32));else if(y(p,`stator`,.26,.28,[0,-.24,0]),y(p,`lower-cap`,.205,.075,[0,-.412,0]),y(p,`silver-can`,.228,r?.39:.25,[0,r?.145:.055,0]),y(p,`top-collar`,.217,r?.06:.065,[0,r?.355:.215,0]),y(p,`shaft`,.091,r?.17:.295,[0,r?.475:.38,0]),b(p,`can-lower-band`,.228,.016,[0,-.066,0]),b(p,`can-upper-band`,.23,.016,[0,r?.337:.176,0]),y(p,`vented-bell`,.165,r?.05:.06,[0,r?.425:.28,0]),b(p,`blue-can-band`,.232,.008,[0,.11,0]),b(p,`bottom-glow`,.135,.016,[0,-.46,0]),r){y(p,`lower-neck`,.225,.09,[0,-.07,0]),b(p,`stator-seam`,.26,.008,[0,-.115,0]);for(let e=0;e<20;e++){let t=e*Math.PI/10,n=v(p,`cooling-fin-`+e,[.017,.19,.024],[Math.sin(t)*.258,-.25,Math.cos(t)*.258]);n.rotation.y=t}for(let e=0;e<12;e++){let t=e*Math.PI/6,n=v(p,`bell-rib-`+e,[.031,.043,.048],[Math.sin(t)*.174,.41,Math.cos(t)*.174]);n.rotation.y=t}for(let e=0;e<6;e++){let t=e*Math.PI/3;C(p,`stator-`+e,[Math.sin(t)*.226,-.096,Math.cos(t)*.226],`y`,.016)}v(p,`status-led`,[.046,.065,.014],[0,-.23,.274]),y(p,`bottom-axle`,.09,.05,[0,-.47,0])}let m=g(`rotor-`+e,`三叶旋翼 `+e.toUpperCase(),[t,.94,s]);if(m.rotation.y=e===`fl`||e===`rr`?.22:-.35,_(m,`hub`,new ha(.14,.14,.15,24)),r){let e=O();for(let t=0;t<3;t++){let n=_(m,`blade-`+t,e);n.rotation.y=t*Math.PI*2/3,n.scale.setScalar(.9)}y(m,`hub-cap`,.089,.035,[0,.091,0]),C(m,`hub-lock`,[0,.118,0],`y`,.045)}else for(let e=0;e<3;e++){let t=v(m,`blade-`+e,[.89,.035,.16],[0,0,0]);t.geometry.translate(.52,0,0),t.rotation.y=e*Math.PI*2/3}d.push(m);let h=g(`guard-`+e,`蓝色保护圈 `+e.toUpperCase(),[t,.77,s]);if(_(h,`ring`,new Ro(1.06,.009,6,80)).rotation.x=Math.PI/2,n){b(h,`outer-rail`,1.079,.007,[0,-.024,0]);for(let e=0;e<3;e++){let t=e*Math.PI*2/3+Math.PI/6;x(h,`radial-support-`+e,[Math.cos(t)*.205,-.26,Math.sin(t)*.205],[Math.cos(t)*1.06,-.03,Math.sin(t)*1.06],.014)}if(r)for(let e=0;e<12;e++){let t=e*Math.PI/6,n=v(h,`perimeter-clip-`+e,[.045,.041,.032],[Math.cos(t)*1.07,-.015,Math.sin(t)*1.07]);n.rotation.y=-t}}}let de={chassis:`drone-root`,"beast-head":`chassis`,jaw:`beast-head`};for(let e of[`fl`,`fr`,`rl`,`rr`])de[`arm-`+e]=`chassis`,de[`motor-`+e]=`arm-`+e,de[`rotor-`+e]=`motor-`+e,de[`guard-`+e]=`motor-`+e,de[`leg-upper-`+e]=`chassis`,de[`leg-lower-`+e]=`leg-upper-`+e,de[`foot-`+e]=`leg-lower-`+e;for(let e of u){let t=new Yn;for(let n of e.children)n instanceof Y&&(n.updateMatrix(),n.geometry.computeBoundingBox(),n.geometry.boundingBox&&t.union(n.geometry.boundingBox.clone().applyMatrix4(n.matrix)));e.userData.collider={shape:`box`,center:t.getCenter(new U).toArray(),halfExtents:t.getSize(new U).multiplyScalar(.5).toArray()},e.userData.attachment={parentId:de[e.name],parentSocket:`socket-${e.name}`,contactType:e.name.startsWith(`rotor`)?`shaft`:`mechanical-mount`}}if([`interaction`,`optimization`].includes(t)){s.updateMatrixWorld(!0);for(let e of u){let t=c[de[e.name]];t.attach(e),t.attach(l[e.name])}for(let e of d)e.userData.joint={type:`continuous`,axis:[0,1,0]};se.userData.joint={type:`revolute`,axis:[1,0,0],limits:[-.18,.22]};for(let e of ue)for(let t of[e.upper,e.lower,e.foot])t.userData.joint={type:`revolute`,axis:[1,0,0],limits:[-.25,.25]}}if(t===`optimization`){let e=e=>{let t=2166136261,n=5381,r=0,i=Object.keys(e.attributes).sort().map(t=>e.attributes[t].array);e.index&&i.push(e.index.array);for(let e of i){let i=new Uint8Array(e.buffer,e.byteOffset,e.byteLength);r+=i.length;for(let e of i)t=Math.imul(t^e,16777619),n=Math.imul(n,33)^e}return`${Object.keys(e.attributes).sort().join(`-`)}:${r}:${t>>>0}:${n>>>0}`},t=new Map,n=new Set,r=0;s.traverse(i=>{if(!(i instanceof Y))return;r++;let a=i.geometry,o=e(a),s=t.get(o);s||(s=Bl(a,1e-6),s.clearGroups(),t.set(o,s)),i.geometry=s,n.add(a)});let i=[];s.traverse(e=>{e.children.some(e=>e instanceof Y)&&i.push(e)});for(let e of i){let t=new Map;for(let n of e.children){if(!(n instanceof Y)||Array.isArray(n.material)||n.name.includes(`tooth-`)||n.name.includes(`blade-`)||n.name.includes(`power-led-`))continue;let e=n.geometry.uuid+n.material.uuid,r=t.get(e)??[];r.push(n),t.set(e,r)}let n=0;for(let r of t.values()){if(r.length<2)continue;let t=r.map(e=>(e.updateMatrix(),e.geometry.clone().applyMatrix4(e.matrix))),i=Rl(t,!1);if(t.forEach(e=>e.dispose()),!i)throw Error(`Repeated drone geometry could not be batched.`);let a=new Y(i,r[0].material);a.name=`${e.name}-repeated-${n++}`,a.castShadow=!0,a.receiveShadow=!0,a.userData={...r[0].userData,sourceMeshes:r.map(e=>e.name),repeatedSolidCount:r.length},r.forEach(t=>e.remove(t)),e.add(a)}}let a=new Map,o=0;s.traverse(t=>{if(!(t instanceof Y))return;o++;let r=e(t.geometry),i=a.get(r);i&&i!==t.geometry?(n.add(t.geometry),t.geometry=i):a.set(r,t.geometry)});let c=new Set(a.values());n.forEach(e=>{c.has(e)||e.dispose()}),s.userData.optimization={beforeMeshes:r,afterMeshes:o,uniqueGeometries:a.size,method:`shared buffers; indexed vertices; repeated non-intersecting primitives batched within each part`,decimated:!1}}return s.userData.sculptRuntime={nodes:c,sockets:l,parts:u,rotors:d,jaw:se,legs:ue,parentIds:de,colliders:u.map(e=>({id:e.name,...e.userData.collider})),destructionGroups:u.map(e=>({id:e.name,parentId:de[e.name],parts:[e.name],seam:`mechanical-mount`}))},s.userData.buildPass=t,s.userData.source=`User supplied mechanical-beast concept images; revision-v6 sculpted mechanical husky head`,s.userData.proportions={bodyLengthScale:a,bodyLength:2.5*a,headShiftZ:.3325000000000001,armShiftZ:o},s.userData.design=`Mechanical husky with upright ears and closed muzzle, elongated body, four tri-blade rotors`,s.updateMatrixWorld(!0),s}function qu(e,t,n){let r=new G;return r.name=t,n&&r.position.copy(n),e.add(r),r}function Ju(){let e=new Bo({name:`husky-gimbal-housing`,color:3159360,roughness:.34,metalness:.76}),t=new Bo({name:`husky-sensor-glass`,color:795187,roughness:.16,metalness:.7,emissive:237311,emissiveIntensity:.55,side:2}),n=new Bo({name:`husky-optical-lens`,color:331820,roughness:.09,metalness:.55}),r=new Bo({name:`husky-led-base`,color:1316636,roughness:.3,metalness:.1}),i=new Bo({name:`husky-decal-plate`,color:5002595,roughness:.5,metalness:.3});return{housing:e,glass:t,lens:n,led:r,decal:i,all:[e,t,n,r,i]}}function Yu(){let e=Ju(),t=Ku(),n=new kn;n.name=`机械哈士奇无人机`;let r=qu(n,`CTRL_DJI_Root`),i=qu(n,`RIG_DJI_Arms_Props`),a=qu(r,`BLOCK_Orientation`);a.rotation.y=Math.PI,a.add(t),n.updateMatrixWorld(!0);let o=e=>e.getWorldPosition(new U);for(let e of[`fl`,`fr`,`rl`,`rr`]){let r=t.getObjectByName(`arm-${e}`),a=t.getObjectByName(`rotor-${e}`),s=t.getObjectByName(`motor-${e}`);if(!r||!a||!s)continue;let c=o(r),l=o(a),u=`${l.z<0?`Front`:`Rear`}${l.x<0?`Left`:`Right`}`,d=new U(l.x-c.x,0,l.z-c.z).normalize(),f=qu(i,`CTRL_Arm_${u}_Fold`,c);f.rotation.y=-Math.PI/2-Math.atan2(d.z,d.x),f.attach(r),qu(f,`ARM_${u}`),s.name=`MOTOR_${u}_RotorBell`,a.name=`CTRL_Prop_${u}_Spin`;let p=a.getObjectByName(`rotor-${e}-hub`);p&&(p.name=`ROTOR_${u}`);for(let[t,r]of[`rotor-${e}-blade-0`,`rotor-${e}-blade-1`].entries()){let e=n.getObjectByName(r);e&&(e.name=`PROP_${u}_Blade_${t+1}`)}}for(let[e,n]of Object.entries({fl:`FrontRight`,fr:`FrontLeft`,rl:`RearRight`,rr:`RearLeft`}))for(let[r,i]of[[`leg-upper-${e}`,`Hip`],[`leg-lower-${e}`,`Knee`],[`foot-${e}`,`Ankle`]]){let e=t.getObjectByName(r);e&&(e.name=`LEG_${n}_${i}`)}let s=qu(qu(qu(qu(r,`CTRL_Gimbal_Yaw`,new U(0,-.5,-1.72)),`CTRL_Gimbal_Pitch`),`CTRL_Gimbal_Roll`),`GIMBAL_BlackCameraPod`),c=new Y(new ha(.055,.055,.55,14),e.housing);c.name=`GIMBAL_DampingArm`,c.position.set(0,.3,.02),s.add(c);let l=new Y(new pa(.42,.34,.46),e.housing);l.name=`GIMBAL_CameraHousing`,l.position.set(0,-.02,-.06),s.add(l);let u=new Y(new ha(.135,.15,.16,24),e.housing);u.name=`GIMBAL_CameraLensFrame`,u.rotation.x=Math.PI/2,u.position.set(0,-.02,-.3),s.add(u);let d=new Y(new ma(.105,24),e.lens);d.name=`SENSOR_Glass_GimbalLens`,d.rotation.y=Math.PI,d.position.set(0,-.02,-.385),s.add(d);let f=new Y(new Ro(.105,.02,8,20),e.lens);f.name=`GIMBAL_Camera_SideRing_Right`,f.rotation.y=Math.PI/2,f.position.set(.225,-.02,-.08),s.add(f);let p=qu(r,`SRC_SensorGlass_Group`),m=(t,n,r,i,a)=>{let o=new Y(new Fo(n,r),e.glass);return o.name=t,o.position.copy(i),a===`front`&&(o.rotation.y=Math.PI),a===`up`&&(o.rotation.x=-Math.PI/2),a===`down`&&(o.rotation.x=Math.PI/2),p.add(o),o};m(`SENSOR_Glass_Front_Left`,.26,.15,new U(-.3,.72,-1.32),`front`),m(`SENSOR_Glass_Front_Right`,.26,.15,new U(.3,.72,-1.32),`front`),m(`SENSOR_Glass_Side_Left`,.24,.15,new U(-.42,.795,.1),`up`),m(`SENSOR_Glass_Side_Right`,.24,.15,new U(.42,.795,.1),`up`),m(`SENSOR_Glass_Downward`,.3,.22,new U(0,-.752,.28),`down`);let h=new pa(.2,.13,.07);for(let[t,n]of[[`SENSOR_FrontHousing_Left`,-.31],[`SENSOR_FrontHousing_Right`,.31]]){let r=new Y(h,e.housing);r.name=t,r.position.set(n,.72,-1.34),p.add(r)}let g=qu(r,`SRC_TailStatusLED_Group`);for(let[t,n]of[[`LED_Status_Tail_Left`,-2.2],[`LED_Status_Tail_Right`,2.2]]){let r=new U(n,.15,2.3),i=new Y(new Lo(.038,12,10),e.led);i.name=t,i.position.copy(r),g.add(i);let a=new Bs(16761165,0,0);a.name=t.replace(`LED_Status_Tail`,`LIGHT_StatusLED`),a.position.copy(r),g.add(a)}for(let e=0;e<4;e+=1){let t=n.getObjectByName(`chassis-power-led-l-${e}`);if(!t)continue;t.name=`LED_BatteryCharge_0${e+1}`;let i=o(t),a=new Bs(16761165,0,0);a.name=`LIGHT_BatteryLED_0${e+1}`,a.position.copy(i),r.add(a)}let _=new Y(new ha(.055,.055,.03,16),e.decal);_.name=`BUTTON_Power`,_.position.set(.3,.8,-.55),r.add(_);let v=qu(r,`SRC_Decals_Group`),y=new Y(new pa(.5,.01,.18),e.decal);y.name=`DECAL_Text_Labels`,y.position.set(-.3,.8,-.55),v.add(y),qu(r,`BODY_Main_Fuselage`),qu(r,`BODY_Black_Underside_SensorHousing`),qu(r,`SRC_BlackHousing_Group`),qu(r,`SRC_GeometryRoot`);let b=new Bs(16761165,0,0);return b.name=`LIGHT_BottomAssist`,b.position.set(0,-.66,.28),r.add(b),n}var Xu=`/models/djiair_renamed.glb`,Zu=2.4,Qu=o.sport.horizontalSpeed,$u=[{key:`orbit`,label:`观察者`},{key:`follow`,label:`跟随`},{key:`fpv`,label:`机载`}],ed=1/60,td=240,nd=2.8,rd=.12,id=.02,ad=.08,od=.02,sd=0,cd=9,ld=2.5,ud=.6,dd=2e3,fd=30,pd=8e6,md=500,hd=1500,gd=[`video/webm;codecs=vp9`,`video/webm;codecs=vp8`,`video/webm`];function _d(){if(typeof MediaRecorder<`u`&&typeof MediaRecorder.isTypeSupported==`function`)return gd.find(e=>MediaRecorder.isTypeSupported(e))}function vd(e,t,n){return Math.min(n,Math.max(t,e))}var yd=class{constructor(e,t,n,r){i(this,`camera`,void 0),i(this,`scene`,void 0),i(this,`renderer`,void 0),i(this,`controls`,void 0),i(this,`model`,null),i(this,`lights`,null),i(this,`rig`,null),i(this,`world`,null),i(this,`radar`,null),i(this,`radarBeamsVisible`,!1),i(this,`auxBeamVisible`,!1),i(this,`sim`,new _e),i(this,`engine`,`three`),i(this,`cameraMode`,`orbit`),i(this,`gimbalStabilization`,`full`),i(this,`gimbalResponse`,od),i(this,`fpvSmoothing`,sd),i(this,`captureView`,null),i(this,`loader`,new Wl),i(this,`groundOffsetY`,0),i(this,`accumulator`,0),i(this,`destroyed`,!1),i(this,`cameraTarget`,new U(0,0,0)),i(this,`cameraAutoFollow`,!0),i(this,`cameraScratch`,new G),i(this,`dronePosition`,new U),i(this,`cameraShift`,new U),i(this,`followPosition`,new U),i(this,`followLookAt`,new U),i(this,`forwardVector`,new U),i(this,`fpvQuat`,new It),i(this,`fpvTargetQuat`,new It),i(this,`captureCenter`,new U),i(this,`fpvQuatReady`,!1),i(this,`lastFrameDelta`,1/60),i(this,`lightOverride`,null),i(this,`armFoldTarget`,1),i(this,`missionSignature`,``),i(this,`missionVisible`,!0),i(this,`missionMarkersVisible`,!0),i(this,`missionPathVisible`,!0),i(this,`missionEditor`,null),i(this,`missionEditEnabled`,!1),i(this,`missionEditSelected`,-1),i(this,`photoRequest`,null),i(this,`captureCamera`,new Is),i(this,`recorder`,null),i(this,`recordChunks`,[]),i(this,`recordStream`,null),i(this,`captureTrack`,null),i(this,`recordContext`,null),i(this,`savedZoom`,null),i(this,`onRecordingReady`,null),this.scene=e,this.camera=t,this.renderer=n,this.controls=r}async initialize(e={}){if(!this.scene||this.destroyed)return;let t;if(e.modelUrl){let n=await this.loader.loadAsync(e.modelUrl);if(this.destroyed){this.disposeModel(n.scene);return}t=n.scene,t.name=`DJI Mini 4 Pro`}else t=Yu();this.normalizeModel(t),this.groundOffsetY=t.position.y,t.traverse(e=>{let t=e;t.isMesh&&(t.castShadow=!0,t.receiveShadow=!0)}),this.scene.add(t),this.model=t,this.rig=new Vc(t),this.rig.gimbalResponse=this.gimbalResponse,this.lights=new al,this.lights.attach(t,this.scene),this.lights.setBeamVisible(this.auxBeamVisible),this.world=new _c(this.scene,e.obstacles??uc),this.sim.obstacles=this.world.collisionBoxes;let n=this.renderer?.domElement;n&&this.camera&&(this.missionEditor=new Ll({canvas:n,camera:this.camera,world:this.world,canEdit:()=>this.canMissionSceneEdit(),getWaypoints:()=>this.sim.mission.map(e=>({...e})),getSelected:()=>this.missionEditSelected,setSelected:e=>this.setMissionSelected(e),commitWaypoints:(e,t)=>{this.sim.setMission(e)&&this.setMissionSelected(t)},moveWaypoint:(e,t)=>this.updateMissionWaypoint(e,t),setOrbitEnabled:e=>{this.controls&&(this.controls.enabled=e&&this.isOrbitView)},getLimits:()=>({maxAltitude:this.sim.altitudeCeiling,maxDistance:this.sim.distanceCeiling,homeX:this.sim.homePosition.x,homeZ:this.sim.homePosition.z}),newWaypointTemplate:e=>this.newWaypointTemplate(e),log:(e,t)=>this.sim.pushEvent(e,t)}),this.missionEditor.setEnabled(this.missionEditEnabled)),this.scene&&(this.radar=new kl(this.scene),this.radar.bindSensors(t),this.radar.setVisible(this.radarBeamsVisible));let r=this.rig.parts.every(e=>e.found);this.sim.externalChecks=[{id:`model`,label:`模型部件自检`,ok:r,detail:this.modelHealthText(),blocking:!1},{id:`arms`,label:`机臂已展开`,ok:this.rig.armFold<.02,detail:this.rig.armFold<.02?`已展开`:`机臂处于收纳状态`,blocking:!0}],this.syncPose(0)}modelHealthText(){let e=this.rig?.parts.filter(e=>!e.found)??[];return e.length===0?`ID 表部件全部就位(${this.rig?.parts.length??0} 项)`:`缺失 ${e.length} 项:${e.map(e=>e.id).join(`、`)}`}animate(e){let t=Math.max(0,Math.min(e??1/60,2));this.lastFrameDelta=t;let n=t*vd(this.sim.config.timeScale,1,20);this.accumulator=Math.min(this.accumulator+n,td*ed);let r=0;for(;this.accumulator>=ed&&r<td;)this.sim.step(ed),this.accumulator-=ed,r+=1;this.syncPose(t),this.updateCamera(t),this.pushTrail(),this.recorder&&!this.sim.recording&&this.stopRecording()}syncPose(e){let t=this.sim,n=t.position.x,r=this.groundOffsetY+t.position.y,i=t.position.z;if(this.rig?.applyBodyPose({x:n,y:r,z:i,headingDeg:t.heading,pitchDeg:t.tiltPitch,rollDeg:t.tiltRoll}),this.rig?.setGimbalAttitude(t.gimbalPitch,t.gimbalRoll,t.gimbalYaw,t.tiltPitch,t.tiltRoll,e),this.rig?.updateProps(t.motorSpeeds??t.motorLoad,e),this.rig){let n=this.rig.armFold;this.rig.setArmFold(n+(this.armFoldTarget-n)*Math.min(1,e*cd)),this.rig.updateBlades(e),t.armFold=this.rig.armFold;let r=t.externalChecks.find(e=>e.id===`arms`);r&&(this.rig.armFold<.02?this.rig.bladeOpen<.98?(r.ok=!1,r.detail=`螺旋桨展开中`):(r.ok=!0,r.detail=`已展开`):(r.ok=!1,r.detail=`机臂处于收纳状态`));let i=t.airborne&&t.position.y>ud?0:1,a=this.rig.legDeploy;this.rig.setLegDeploy(a+(i-a)*Math.min(1,e*ld))}let a=this.lights;a&&(a.setFlying(t.airborne),a.setBatteryLevel(t.batteryPercent),a.setStatusPattern(this.lightOverride??Qc(t)),a.update(e),this.rig&&this.rig.armFold<.005&&a.attachStatusToArms(this.rig.getArmFoldNode(`RearLeft`),this.rig.getArmFoldNode(`RearRight`)),a.syncStatusToArms());let o=t.homePosition;this.world?.setHome(o.x,o.z);let s=this.world;if(s){let e=this.buildMissionSignature();e!==this.missionSignature&&(this.missionSignature=e,s.setMissionWaypoints(t.mission.map(e=>({x:e.x,z:e.z,altitude:e.altitude})),o),s.setMissionVisible(this.missionVisible),s.setMissionWaypointsVisible(this.missionMarkersVisible),s.setMissionPathVisible(this.missionPathVisible),s.setMissionSelection(this.missionEditSelected));let n=t.missionIndex>=0?t.mission[t.missionIndex]??null:null;s.setMissionActive(n?t.missionIndex:-1,n?{x:n.x,z:n.z,altitude:n.altitude}:null)}this.missionEditor?.update(),this.radar&&this.world&&this.model&&this.radar.update(this.model,this.world,e,t.phase!==`powerOff`)}getRadarSnapshot(){return this.radar?.getSnapshot()??{detecting:!1,left:null,right:null,range:18,upLeft:null,upRight:null,upRange:15,aim:`forward`}}setRadarAim(e){this.radar?.setAim(e)}setRadarBeamsVisible(e){this.radarBeamsVisible=e,this.radar?.setVisible(e)}isRadarBeamsVisible(){return this.radar?.isBeamsVisible()??this.radarBeamsVisible}setAuxBeamVisible(e){this.auxBeamVisible=e,this.lights?.setBeamVisible(e)}isAuxBeamVisible(){return this.lights?.isBeamVisible()??this.auxBeamVisible}pushTrail(){let e=this.sim;this.world&&e.airborne&&this.world.pushTrail(e.position.x,this.groundOffsetY+e.position.y,e.position.z)}setCameraMode(e){let t=this.cameraMode;this.cameraMode=e,this.controls&&(this.controls.enabled=e===`orbit`),this.camera&&e===`fpv`&&t!==`fpv`&&(this.savedZoom=this.camera.zoom),e===`fpv`&&(this.fpvQuatReady=!1),this.camera&&e!==`fpv`&&t===`fpv`&&(this.camera.zoom=this.savedZoom??1,this.camera.updateProjectionMatrix(),this.savedZoom=null),e===`orbit`&&(this.cameraTarget.set(this.sim.position.x,this.groundOffsetY+this.sim.position.y,this.sim.position.z),this.controls?.target.copy(this.cameraTarget))}get isOrbitView(){return this.cameraMode===`orbit`}flyTo(e){let t={...this.sim.position};e.x!==void 0&&(t.x=e.x),e.y!==void 0&&(t.y=Math.max(0,e.y)),e.z!==void 0&&(t.z=e.z),this.sim.position.x=t.x,this.sim.position.y=t.y,this.sim.position.z=t.z,e.heading!==void 0&&(this.sim.heading=e.heading),e.pitch!==void 0&&(this.sim.tiltPitch=vd(e.pitch,-45,45)),e.roll!==void 0&&(this.sim.tiltRoll=vd(e.roll,-45,45)),this.cameraTarget.set(this.sim.position.x,this.groundOffsetY+this.sim.position.y,this.sim.position.z),this.controls&&(this.controls.target.copy(this.cameraTarget),this.controls.update()),this.syncPose(0)}zoomTo(e){this.sim.setZoom(e),this.camera&&this.cameraMode!==`orbit`&&this.camera.zoom!==this.sim.cameraZoom&&(this.camera.zoom=this.sim.cameraZoom,this.camera.updateProjectionMatrix())}applyGimbalCameraPose(e,t={}){let n=this.rig;if(!(n?.getGimbalCameraTransform(this.cameraScratch)??!1)||!n)return!1;this.cameraScratch.updateMatrixWorld(!0);let r=n.getGimbalCameraClearance(),i=t.offset??(r==null?rd:r+id),a=this.gimbalStabilization===`full`,o=(t.live===!0?void 0:this.captureView?.pitch)??this.sim.gimbalPitch,s=this.sim.gimbalYaw,c=t.fixedCenter===!0&&a&&this.captureView!==null&&n.getGimbalCameraMount(this.captureCenter,0,0),l=!c&&a&&n.getGimbalCameraMount(e.position,i,o);c?e.position.set(this.sim.position.x,this.captureCenter.y,this.sim.position.z):l||(this.forwardVector.set(0,0,-1).applyQuaternion(this.cameraScratch.quaternion).normalize(),e.position.copy(this.cameraScratch.position).addScaledVector(this.forwardVector,i));let u=a&&n.getGimbalCameraOrientation(this.fpvTargetQuat,o,0,s)?this.fpvTargetQuat:this.cameraScratch.quaternion,d=t.delta??0,f=this.fpvSmoothing*ad;return!t.instant&&f>0&&d>0?(this.fpvQuatReady?this.fpvQuat.slerp(u,1-Math.exp(-d/f)):(this.fpvQuat.copy(u),this.fpvQuatReady=!0),e.quaternion.copy(this.fpvQuat)):(this.fpvQuat.copy(u),this.fpvQuatReady=!0,e.quaternion.copy(u)),t.zoom!==void 0&&Math.abs(e.zoom-t.zoom)>.001&&(e.zoom=t.zoom,e.updateProjectionMatrix()),!0}configureGimbal(e={}){e.stabilization&&(this.gimbalStabilization=e.stabilization),e.response!==void 0&&(this.gimbalResponse=Math.max(0,e.response),this.rig&&(this.rig.gimbalResponse=this.gimbalResponse)),e.smoothing!==void 0&&(this.fpvSmoothing=vd(e.smoothing,0,1))}setCaptureView(e){this.captureView=e??null}spinBodyTo(e){this.sim.spinTo(e)}getBodyHeading(){return this.sim.heading}snapshotCamera(){let e=this.camera;return e?{position:e.position.clone(),quaternion:e.quaternion.clone(),zoom:e.zoom}:null}restoreCamera(e){let t=this.camera;t&&(t.position.copy(e.position),t.quaternion.copy(e.quaternion),Math.abs(t.zoom-e.zoom)>.001&&(t.zoom=e.zoom,t.updateProjectionMatrix()),t.updateMatrixWorld(!0))}setCaptureFrameVisible(e){this.world?.setCaptureHelpersVisible(e),this.model&&(this.model.visible=e),this.radar&&this.radar.setVisible(e?this.radarBeamsVisible:!1)}captureRecordingFrame(){let e=this.captureTrack,t=this.recordContext,n=this.camera,r=this.renderer?.domElement;if(!e||!t||!n||!r||!this.renderer||!this.scene)return;if((t.canvas.width!==r.width||t.canvas.height!==r.height)&&(t.canvas.width=r.width,t.canvas.height=r.height),this.cameraMode===`fpv`){this.setCaptureFrameVisible(!1),this.renderer.render(this.scene,n),this.setCaptureFrameVisible(!0),t.drawImage(r,0,0),e.requestFrame();return}let i=this.snapshotCamera();this.applyGimbalCameraPose(n,{zoom:this.sim.cameraZoom,delta:this.lastFrameDelta,live:!0})&&(n.updateMatrixWorld(!0),this.setCaptureFrameVisible(!1),this.renderer.render(this.scene,n),this.setCaptureFrameVisible(!0),t.drawImage(r,0,0),e.requestFrame(),i&&this.restoreCamera(i))}requestPhoto(){return!this.renderer||!this.camera||!this.rig||this.photoRequest?Promise.resolve(null):new Promise(e=>{let t=window.setTimeout(()=>{this.photoRequest&&(this.photoRequest=null,e(null))},dd);this.photoRequest={resolve:e,timer:t,restore:null,captureCamera:null}})}getCaptureCamera(){let e=this.rig,t=this.camera,n=this.renderer;if(!e||!t||!n)return null;let r=this.captureCamera;if(!this.applyGimbalCameraPose(r,{zoom:this.sim.cameraZoom,delta:0,fixedCenter:!0}))return null;let i=n.domElement,a=i.width,o=i.height;if(!a||!o)return null;let s=this.sim.cameraZoom>0?this.sim.cameraZoom:1,c=2*Math.atan(Math.tan(t.fov*Math.PI/360)/s),l=o/2/Math.tan(c/2),u=l,d=2*Math.atan(a/(2*u)),f=new It().setFromRotationMatrix(new W().makeBasis(new U(1,0,0),new U(0,0,-1),new U(0,1,0))).invert(),p=r.quaternion.clone().premultiply(f),m=this.sim,h=(e,t,n)=>[e,-n,t],g=e=>e*180/Math.PI;return{pose:{position:h(r.position.x,r.position.y,r.position.z),rotation:[p.x,p.y,p.z,p.w],coordinateFrame:`local-enu`},intrinsics:{width:a,height:o,fx:u,fy:l,cx:a/2,cy:o/2,horizontalFovDeg:g(d),verticalFovDeg:g(c),calibrationSource:`known`},frame:{width:a,height:o},drone:{position:h(m.position.x,m.position.y,m.position.z),heading:m.heading,tiltPitch:m.tiltPitch,tiltRoll:m.tiltRoll,gimbalPitch:m.gimbalPitch,gimbalYaw:m.gimbalYaw}}}onBeforeRender(){let e=this.photoRequest,t=this.camera;e&&t&&(e.restore=this.snapshotCamera(),this.setCaptureFrameVisible(!1),this.applyGimbalCameraPose(t,{zoom:this.sim.cameraZoom,delta:this.lastFrameDelta,fixedCenter:!0,instant:!0}),t.updateMatrixWorld(!0),e.captureCamera=this.getCaptureCamera())}onAfterRender(){let e=this.photoRequest;if(!e)return;this.photoRequest=null,window.clearTimeout(e.timer);let t=this.grabCanvas();t&&e.captureCamera&&(t.camera=e.captureCamera),t&&this.sim.takePhoto(),e.restore&&this.restoreCamera(e.restore),this.setCaptureFrameVisible(!0),this.scene&&this.renderer&&this.camera&&this.renderer.render(this.scene,this.camera),e.resolve(t)}grabCanvas(){let e=this.renderer?.domElement;if(!e||!e.width||!e.height)return null;let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);return n?(n.drawImage(e,0,0),{dataUrl:t.toDataURL(`image/png`),width:t.width,height:t.height}):null}get isRecording(){return this.recorder!==null}startRecording(){if(this.recorder)return!0;let e=this.renderer?.domElement;if(!e||typeof MediaRecorder>`u`||typeof e.captureStream!=`function`)return!1;let t=document.createElement(`canvas`);t.width=e.width||1,t.height=e.height||1;let n=t.getContext(`2d`);if(!n)return!1;let r,i;try{i=t.captureStream(0);let e=i.getVideoTracks()[0];e&&typeof e.requestFrame==`function`?this.captureTrack=e:(i.getTracks().forEach(e=>e.stop()),i=t.captureStream(fd),this.captureTrack=null);let n=_d();r=n?new MediaRecorder(i,{mimeType:n,videoBitsPerSecond:pd}):new MediaRecorder(i)}catch{return this.captureTrack=null,!1}return this.recordContext=n,this.recordChunks=[],this.recordStream=i,r.ondataavailable=e=>{e.data&&e.data.size>0&&this.recordChunks.push(e.data)},r.start(md),this.recorder=r,this.sim.setRecordingState(!0),!0}stopRecording(){let e=this.recorder;if(!e)return this.sim.setRecordingState(!1),Promise.resolve(null);this.recorder=null;let t=this.sim.recordSeconds;return this.sim.setRecordingState(!1),new Promise(n=>{let r=!1,i=()=>{if(r)return;r=!0,window.clearTimeout(a);let i=this.recordChunks;this.recordChunks=[],this.recordStream?.getTracks().forEach(e=>e.stop()),this.recordStream=null,this.captureTrack=null,this.recordContext=null;let o=i.length?new Blob(i,{type:e.mimeType||`video/webm`}):null;o&&this.onRecordingReady?.(o,t),n(o)},a=window.setTimeout(i,hd);e.onstop=i;try{e.stop()}catch{i()}})}updateCamera(e){let t=this.camera;if(!t)return;let n=this.sim,r=this.dronePosition.set(n.position.x,this.groundOffsetY+n.position.y,n.position.z);if(this.cameraMode===`fpv`)this.applyGimbalCameraPose(t,{zoom:this.sim.cameraZoom,delta:e,live:!0});else if(this.cameraMode===`follow`){let i=n.heading*Math.PI/180;this.forwardVector.set(Math.sin(i),0,-Math.cos(i)),this.followPosition.copy(r).addScaledVector(this.forwardVector,-7.5),this.followPosition.y+=nd,t.position.lerp(this.followPosition,Math.min(1,e*4)),this.followLookAt.copy(r),this.followLookAt.y+=.6,t.lookAt(this.followLookAt)}else this.cameraAutoFollow?(this.cameraTarget.lerp(r,Math.min(1,e*2.2)),this.controls&&(this.cameraShift.subVectors(this.cameraTarget,this.controls.target),this.controls.target.add(this.cameraShift),t.position.add(this.cameraShift))):this.controls&&this.cameraTarget.copy(this.controls.target)}resetCamera(){if(!this.camera||!this.controls)return;this.setCameraMode(`orbit`),this.cameraAutoFollow=!0,this.camera.zoom!==1&&(this.camera.zoom=1,this.camera.updateProjectionMatrix());let e=new U(this.sim.position.x,this.groundOffsetY+this.sim.position.y,this.sim.position.z);this.camera.position.set(e.x+6,e.y+3.5,e.z+7),this.controls.target.copy(e),this.cameraTarget.copy(e)}frameMission(){let e=this.camera,t=this.controls;if(!e||!t)return!1;let n=this.sim.homePosition,r=this.sim.mission[0],i=n.x,o=n.x,s=r?Math.max(1,r.altitude):a.takeoffAltitude,c=s,l=n.z,u=n.z,d=(e,t,n)=>{i=Math.min(i,e),o=Math.max(o,e),s=Math.min(s,t),c=Math.max(c,t),l=Math.min(l,n),u=Math.max(u,n)};for(let e of this.sim.mission)d(e.x,e.altitude,e.z);d(i,0,l),d(o,0,u);let f=new U((i+o)/2,(s+c)/2,(l+u)/2);f.y+=this.groundOffsetY;let p=Math.max(12,.5*Math.hypot(o-i,c-s,u-l)),m=Ft.degToRad(e.fov/2),h=Math.atan(Math.tan(m)*Math.max(.2,e.aspect)),g=Math.max(p/Math.tan(m),p/Math.tan(h))*1.35;this.setCameraMode(`orbit`),this.cameraAutoFollow=!1,e.zoom!==1&&(e.zoom=1,e.updateProjectionMatrix());let _=new U(-.42,.55,.72).normalize();return e.position.copy(f).addScaledVector(_,g),t.target.copy(f),this.cameraTarget.copy(f),e.lookAt(f),e.updateMatrixWorld(!0),t.update(),!0}get phase(){return this.sim.phase}get airborne(){return this.sim.airborne}get flightMode(){return this.sim.mode}get altitude(){return this.sim.position.y}get preflightChecks(){return this.sim.checklist}powerOn(){this.sim.powerOn()}takeOff(){return this.sim.autoTakeOff()}land(){return this.sim.startLanding()}returnHome(e=`用户触发返航`){return this.sim.startRth(e)}setStick(e){this.sim.setStick(e)}resetStick(){this.sim.setStick({...h})}setMoveDirection(e){this.sim.setStick({pitch:e===`up`?1:e===`down`?-1:0,roll:e===`right`?1:e===`left`?-1:0})}setVerticalDirection(e){this.sim.setStick({throttle:e===`up`?1:e===`down`?-1:0})}setRotationDirection(e){this.sim.setStick({yaw:e===`right`?1:e===`left`?-1:0})}setMode(e){this.sim.setMode(e)}setConfig(e){this.sim.setConfig(e)}setFaults(e){this.sim.faults={...this.sim.faults,...e}}setArmFoldTarget(e){this.armFoldTarget=+(e>.5)}get armFoldTargetValue(){return this.armFoldTarget}setArmsFolded(e){this.setArmFoldTarget(+!!e)}get armsFolded(){return this.armFoldTargetValue>.5}get legsDeployed(){return(this.rig?.legDeploy??1)>.5}setGimbalPitch(e){this.sim.setGimbalPitch(e)}nudgeGimbal(e,t=0){this.sim.nudgeGimbal(e,t)}clearTrail(){this.world?.clearTrail()}startMission(){return this.sim.startMission()}pauseMission(e){return this.sim.pauseMission(e)}resumeMission(){return this.sim.resumeMission()}stopMission(e){return this.sim.stopMission(e)}setMission(e){return this.sim.setMission(e)}setMissionConfig(e){this.sim.setMissionConfig(e)}resetMissionToDefault(){this.sim.resetMissionToDefault()}getMissionSnapshot(){return this.sim.snapshot().mission}getMissionExport(){return E(this.sim.mission.map(e=>({...e})),{...this.sim.missionConfig},this.sim.homePosition)}exportMission(e=`json`){return O(this.getMissionExport(),e)}setMissionVisible(e){this.missionVisible=e,this.world?.setMissionVisible(e)}isMissionVisible(){return this.world?.isMissionVisible()??this.missionVisible}setMissionWaypointsVisible(e){this.missionMarkersVisible=e,this.world?.setMissionWaypointsVisible(e)}isMissionWaypointsVisible(){return this.world?.isMissionWaypointsVisible()??this.missionMarkersVisible}setMissionPathVisible(e){this.missionPathVisible=e,this.world?.setMissionPathVisible(e)}isMissionPathVisible(){return this.world?.isMissionPathVisible()??this.missionPathVisible}supportsGeoCoordinates(){return!1}getWaypointGeo(e){return null}setWaypointGeo(e,t){return!1}buildMissionSignature(){let e=this.sim.homePosition;return`${e.x}|${e.z}#${this.sim.mission.map(e=>`${e.x}|${e.z}|${e.altitude}`).join(`;`)}`}canMissionSceneEdit(){return this.isOrbitView&&this.sim.missionStatus===`idle`&&!this.sim.missionPendingStart}setMissionEditEnabled(e){this.missionEditEnabled=e,this.missionEditor?.setEnabled(e),e?this.canMissionSceneEdit()?this.sim.mission.length>0&&this.frameMission():this.sim.pushEvent(`warn`,`场景编辑需要先切到观察者视角,且航线未在执行`):this.setMissionSelected(-1)}isMissionEditEnabled(){return this.missionEditEnabled}setMissionSelected(e){this.missionEditSelected=e,this.world?.setMissionSelection(e)}getMissionSelected(){return this.missionEditSelected}getMissionEditState(){let e=this.missionEditor;return e?{...e.getState(),selectedIndex:this.missionEditSelected}:{enabled:this.missionEditEnabled,active:!1,selectedIndex:this.missionEditSelected,hoverIndex:-1,dragging:!1,mode:null}}updateMissionWaypoint(e,t){let n=this.sim.updateMissionWaypoint(e,t);return n?(this.world?.updateMissionWaypoint(e,{x:n.x,z:n.z,altitude:n.altitude}),this.missionSignature=this.buildMissionSignature(),n):null}deleteMissionWaypoint(e){return!this.canMissionSceneEdit()||!this.sim.removeMissionWaypoint(e)?!1:(this.setMissionSelected(Math.min(e,this.sim.mission.length-1)),this.sim.pushEvent(`info`,`场景编辑:已删除航点 ${e+1}`),!0)}addMissionWaypointAtDrone(){if(!this.canMissionSceneEdit())return-1;let e=this.sim.position,t=this.sim.addMissionWaypoint({x:Math.round(e.x),z:Math.round(e.z),altitude:Math.max(1,Math.round(e.y)),speed:this.sim.missionConfig.autoSpeed});return t<0?-1:(this.setMissionSelected(t),this.sim.pushEvent(`info`,`场景编辑:已在飞机当前位置新增航点 ${t+1}`),t)}newWaypointTemplate(e){let t=this.sim.mission,n=t[Math.min(e,t.length-1)]??t[t.length-1];return{altitude:n?.altitude??30,speed:n?.speed??this.sim.missionConfig.autoSpeed,hoverSeconds:n?.hoverSeconds??0}}getRigReport(){return this.rig?.parts??[]}getSnapshot(){return this.sim.snapshot()}getLightsSnapshot(){return this.lights?.getSnapshot()??null}getTelemetry(){return{speedMetersPerSecond:Math.hypot(this.sim.velocity.x,this.sim.velocity.z),altitudeMeters:this.sim.position.y,isFlying:this.sim.airborne}}setStatusLightPattern(e){this.lightOverride=e,this.lights?.setStatusPattern(e)}clearStatusLightOverride(){this.lightOverride=null,this.lights?.setStatusPattern(Qc(this.sim))}get statusLightOverride(){return this.lightOverride}setBatteryLightMode(e){this.lights?.setBatteryMode(e)}setBatteryLightLevel(e){this.sim.forceBatteryLevel(e),this.lights?.setBatteryLevel(e)}setAuxLightMode(e){this.lights?.setAuxLightMode(e)}destroy(){if(this.destroyed=!0,this.recorder){try{this.recorder.stop()}catch{}this.recorder=null}this.recordStream?.getTracks().forEach(e=>e.stop()),this.recordStream=null,this.captureTrack=null,this.recordContext=null,this.recordChunks=[],this.onRecordingReady=null,this.missionEditor?.destroy(),this.missionEditor=null,this.rig?.destroy(),this.rig=null,this.lights?.destroy(),this.lights=null,this.world?.destroy(),this.world=null,this.radar?.destroy(),this.radar=null,this.model&&(this.disposeModel(this.model),this.scene?.remove(this.model)),this.model=null}normalizeModel(e){let t=new Yn().setFromObject(e).getSize(new U),n=Math.max(t.x,t.y,t.z);n>0&&e.scale.setScalar(Zu/n);let r=new Yn().setFromObject(e),i=r.getCenter(new U);e.position.x-=i.x,e.position.z-=i.z,e.position.y-=r.min.y}disposeModel(e){e.traverse(e=>{let t=e;t.isMesh&&(t.geometry.dispose(),(Array.isArray(t.material)?t.material:[t.material]).forEach(e=>e.dispose()))})}},bd=[`FrontLeft`,`FrontRight`,`RearLeft`,`RearRight`];function xd(e,t){let n=new e.Cartesian4;e.Matrix4.getColumn(t,1,n);let r=e.Cartesian3.fromCartesian4(n,new e.Cartesian3);return e.Cartesian3.magnitude(r)<1e-9?null:e.Cartesian3.normalize(r,r)}var Sd={statusLeft:{center:[-8.64,.912,9.765],radius:.5},statusRight:{center:[8.643,.911,9.767],radius:.5},battery:[{center:[-.527,2.085,4.811],radius:.1},{center:[-.176,2.084,4.813],radius:.1},{center:[.178,2.084,4.813],radius:.1},{center:[.53,2.085,4.812],radius:.1}],aux:{center:[0,-2.445,-.927],radius:.37}},Cd=10485707,wd=16771520,Td=8;function Ed(e,t,n){return e%(t+n)<t}function Dd(e){e.spinning&&(e.node.matrix=void 0,e.spinning=!1);let t=e.bell;t?.spinning&&(t.node.matrix=void 0,t.spinning=!1)}var Od=class{constructor(e,t){i(this,`sim`,void 0),i(this,`C`,void 0),i(this,`joints`,[]),i(this,`lightShader`,null),i(this,`modelRef`,null),i(this,`enabled`,!1),i(this,`timeMs`,0),this.sim=e;let n=t??window.Cesium;if(!n)throw Error(`[drone-camera] CesiumDroneRig 需要 Cesium 命名空间(请先加载 Cesium.js)`);this.C=n}attach(e){this.detach();let t=this.C;if(this.enabled=typeof e.getNode==`function`&&!!e.getNode(`PROP_FrontLeft_Spin_Bone`),this.enabled){this.modelRef=e,this.joints=[];for(let n of bd){let r=e.getNode(`PROP_${n}_Spin_Bone`),i=e.getNode(`CTRL_Prop_${n}_Spin`);if(!r||!i)continue;let a=xd(t,i.originalMatrix);if(!a)continue;let o=e.getNode(`ROTOR_${n}`),s=e.getNode(`MOTOR_${n}_RotorBell`),c=null;if(o&&s){let e=t.Matrix4.multiply(i.originalMatrix,o.originalMatrix,new t.Matrix4);c={node:s,original:s.originalMatrix,chain:e,invChain:t.Matrix4.inverse(e,new t.Matrix4),inv:new t.Matrix4,conj:new t.Matrix4,kernel:new t.Matrix4,product:new t.Matrix4,spinning:!1}}this.joints.push({position:n,node:r,original:r.originalMatrix,trs:new t.Matrix4,product:new t.Matrix4,axis:a,angle:0,spinning:!1,bell:c})}this.attachLightShader(e)}}attachLightShader(e){let t=this.C,n=Sd,r=()=>({type:t.UniformType.VEC3,value:new t.Cartesian3(0,0,0)}),i=e=>`vec3(${e[0]}, ${e[1]}, ${e[2]})`;this.lightShader=new t.CustomShader({lightingModel:t.LightingModel.PBR,uniforms:{u_statusL:r(),u_statusR:r(),u_batt0:r(),u_batt1:r(),u_batt2:r(),u_batt3:r(),u_aux:r()},fragmentShaderText:`
|
|
9
|
+
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
|
|
10
|
+
vec3 p = fsInput.attributes.positionMC;
|
|
11
|
+
vec3 e = vec3(0.0);
|
|
12
|
+
float t = 0.0; // 0 = 灯区中心,1 = 灯区边缘(供亮度梯度用)
|
|
13
|
+
if (distance(p, ${i(n.statusLeft.center)}) < ${n.statusLeft.radius}) { e = u_statusL; t = distance(p, ${i(n.statusLeft.center)}) / ${n.statusLeft.radius}; }
|
|
14
|
+
else if (distance(p, ${i(n.statusRight.center)}) < ${n.statusRight.radius}) { e = u_statusR; t = distance(p, ${i(n.statusRight.center)}) / ${n.statusRight.radius}; }
|
|
15
|
+
else if (distance(p, ${i(n.battery[0].center)}) < ${n.battery[0].radius}) { e = u_batt0; t = distance(p, ${i(n.battery[0].center)}) / ${n.battery[0].radius}; }
|
|
16
|
+
else if (distance(p, ${i(n.battery[1].center)}) < ${n.battery[1].radius}) { e = u_batt1; t = distance(p, ${i(n.battery[1].center)}) / ${n.battery[1].radius}; }
|
|
17
|
+
else if (distance(p, ${i(n.battery[2].center)}) < ${n.battery[2].radius}) { e = u_batt2; t = distance(p, ${i(n.battery[2].center)}) / ${n.battery[2].radius}; }
|
|
18
|
+
else if (distance(p, ${i(n.battery[3].center)}) < ${n.battery[3].radius}) { e = u_batt3; t = distance(p, ${i(n.battery[3].center)}) / ${n.battery[3].radius}; }
|
|
19
|
+
else if (distance(p, ${i(n.aux.center)}) < ${n.aux.radius}) { e = u_aux; t = distance(p, ${i(n.aux.center)}) / ${n.aux.radius}; }
|
|
20
|
+
// 点亮时只留自发光:必须同时关掉底色(diffuse)与高光(specular)——
|
|
21
|
+
// Cesium PBR 的最终色 = 底色×光照 + 高光 + emissive,灯珠网格底图是灰白灯罩
|
|
22
|
+
// (且被太阳照亮),红色 emissive 叠上去就被冲成粉色(观感"不够红")。
|
|
23
|
+
// three 版是整颗换成"底黑 + emissive"的自发光材质,这里等价地把两项清零。
|
|
24
|
+
//
|
|
25
|
+
// 亮度梯度(发光感的来源):边缘保持纯灯色(强度 1.0,深红不发粉),
|
|
26
|
+
// 中心按 core² 过曝到 ~3.2 倍形成亮核 —— 均匀提亮只会整块变粉,
|
|
27
|
+
// "深色边缘 + 过曝亮核"的径向梯度才是 LED 点亮的观感。
|
|
28
|
+
if (any(greaterThan(e, vec3(0.0)))) {
|
|
29
|
+
float core = 1.0 - clamp(t, 0.0, 1.0);
|
|
30
|
+
material.diffuse = vec3(0.0);
|
|
31
|
+
material.specular = vec3(0.0);
|
|
32
|
+
material.emissive = e * (1.0 + 2.2 * core * core);
|
|
33
|
+
}
|
|
34
|
+
}`}),e.customShader=this.lightShader}detach(){for(let e of this.joints)Dd(e);if(this.joints=[],this.modelRef&&this.lightShader)try{this.modelRef.customShader=void 0}catch{}this.lightShader=null,this.modelRef=null,this.enabled=!1}dispose(){this.detach()}update(e){if(!this.enabled)return;let t=Math.max(0,Math.min(e,.1));this.timeMs+=t*1e3,this.updateProps(t),this.updateLights()}updateProps(e){let t=this.C,n=this.sim.motorSpeeds;for(let r of this.joints){let i=Math.min(1.15,Math.max(0,n[r.position]??0));if(i<=.01){Dd(r);continue}r.angle=(r.angle+(3.8+i*7)*e*bc[r.position]*Math.PI*2)%(Math.PI*2);let a=t.Matrix3.fromQuaternion(t.Quaternion.fromAxisAngle(r.axis,r.angle));t.Matrix4.fromRotationTranslation(a,t.Cartesian3.ZERO,r.trs),r.node.matrix=t.Matrix4.multiply(r.original,r.trs,r.product),r.spinning=!0;let o=r.bell;o&&(t.Matrix4.inverseTransformation(r.trs,o.inv),t.Matrix4.multiply(o.invChain,o.inv,o.conj),t.Matrix4.multiply(o.conj,o.chain,o.kernel),o.node.matrix=t.Matrix4.multiply(o.kernel,o.original,o.product),o.spinning=!0)}}updateLights(){let e=Jc[Qc(this.sim)],t=e.steps.reduce((e,t)=>e+t.onMs+t.offMs,0),n=t>0?this.timeMs%t:0,r=e.steps[0]?.colors??[0],i=!1;for(let t of e.steps){if(n<t.onMs){r=t.colors,i=!0;break}if(n<t.onMs+t.offMs){r=t.colors,i=!1;break}n-=t.onMs+t.offMs}let a=[r[0]??0,r[1]??r[0]??0],o=Xc(this.sim.batteryPercent),s=[0,1,2,3].map(e=>e<o.lit||o.blinkIndex!==null&&e===o.blinkIndex&&Ed(this.timeMs,240,240)),c=this.sim.airborne&&this.sim.position.y<=Td,l=this.lightShader?.uniforms;if(l){let e=(e,t,n)=>{let r=l[e].value;n?(r.x=kd((t>>16&255)/255),r.y=kd((t>>8&255)/255),r.z=kd((t&255)/255)):(r.x=0,r.y=0,r.z=0)};e(`u_statusL`,a[0],i),e(`u_statusR`,a[1],i),s.forEach((t,n)=>e(`u_batt${n}`,Cd,t)),e(`u_aux`,wd,c)}}};function kd(e){return e<=.04045?e/12.92:((e+.055)/1.055)**2.4}var Ad=`dc-mission-wp-`,jd=`dc-mission-path`,Md=`dc-mission-home`,Nd=3,Pd=14,Fd=1,Id=.2,Ld=`#38bdf8`,Rd=`#04121f`,zd=`#ffc53d`,Bd=`#ff5f5f`,Vd=`#38bdf8`,Hd=`#3ddc97`,Ud=`#e9eff9`,Wd=`rgba(4, 18, 31, 0.62)`,Gd=`#bfe9d6`;function Kd(e,t){try{let n=e.setPointerCapture(t);n&&typeof n.catch==`function`&&n.catch(()=>{})}catch{}}function qd(e,t){try{let n=e.releasePointerCapture(t);n&&typeof n.catch==`function`&&n.catch(()=>{})}catch{}}function Jd(e,t,n){return Math.min(n,Math.max(t,e))}function Yd(e,t){return Math.round(e/t)*t}function Xd(e,t){return e.Color.fromCssColorString(t)}var Zd=class{constructor(e,t,n){i(this,`host`,void 0),i(this,`C`,void 0),i(this,`viewer`,void 0),i(this,`container`,void 0),i(this,`canvas`,void 0),i(this,`enabled`,!1),i(this,`hoverIndex`,-1),i(this,`drag`,null),i(this,`emptyClick`,null),i(this,`waypointSignature`,``),i(this,`homeKey`,``),i(this,`lastSelected`,-2),i(this,`lastActive`,-2),i(this,`lastHover`,-2),i(this,`disposed`,!1),i(this,`onPointerDown`,e=>{if(!this.editable()||e.button!==0)return;let t=this.pickWaypoint(e);if(t<0){this.emptyClick={x:e.clientX,y:e.clientY};return}let n=this.host.getWaypoints()[t];n&&(this.emptyClick=null,this.host.setSelected(t),this.drag=this.createDrag(e,t,n),this.host.setCameraInputEnabled(!1),this.canvas.style.cursor=e.shiftKey?`ns-resize`:`grabbing`,Kd(this.canvas,e.pointerId),e.stopPropagation(),e.preventDefault())}),i(this,`onPointerMove`,e=>{if(!this.enabled)return;let t=this.drag;if(t){if(!t.moved){if(Math.hypot(e.clientX-t.startClientX,e.clientY-t.startClientY)<Nd)return;t.moved=!0}this.applyDrag(e,t)}else{let t=this.editable()?this.pickWaypoint(e):-1;t!==this.hoverIndex&&(this.hoverIndex=t,this.canvas.style.cursor=t>=0?`grab`:``)}}),i(this,`onPointerUp`,e=>{qd(this.canvas,e.pointerId);let t=this.emptyClick;this.emptyClick=null;let n=this.drag;if(!n){t&&Math.hypot(e.clientX-t.x,e.clientY-t.y)<Nd&&this.host.setSelected(-1);return}if(this.drag=null,this.host.setCameraInputEnabled(!0),this.canvas.style.cursor=this.hoverIndex>=0?`grab`:``,!n.moved)return;let r=this.host.getWaypoints()[n.index];r&&this.host.log(`info`,`场景编辑:航点 ${n.index+1} 已更新为 E ${r.x.toFixed(0)} / S ${r.z.toFixed(0)} / 高度 ${r.altitude.toFixed(1)} m`)}),i(this,`onPointerLeave`,()=>{!this.drag&&this.hoverIndex!==-1&&(this.hoverIndex=-1,this.canvas.style.cursor=``)}),i(this,`onDoubleClick`,e=>{if(!this.editable()||e.button!==0||this.pickWaypoint(e)>=0)return;let t=this.pickEllipsoid(e),n=t?this.host.worldToLocalXZ(t):null;if(!n)return;let r=this.host.getLimits(),i=n.x-r.homeX,a=n.z-r.homeZ,o=Math.hypot(i,a),s=n.x,c=n.z;if(o>r.maxDistance){let e=r.maxDistance/o;s=r.homeX+i*e,c=r.homeZ+a*e}s=Yd(s,Fd),c=Yd(c,Fd);let l=this.host.getWaypoints(),u=k(l,s,c,r.homeX,r.homeZ),d=this.host.newWaypointTemplate(u),f=l.map(e=>({...e}));f.splice(u,0,{...d,x:s,z:c}),this.host.commitWaypoints(f,u),this.host.log(`info`,`场景编辑:在 E ${s.toFixed(0)} / S ${c.toFixed(0)} 新增航点 ${u+1}(双击地面新增)`),e.stopPropagation(),e.preventDefault()}),i(this,`onKeyDown`,e=>{if(!this.enabled)return;let t=e.target;if(t&&[`INPUT`,`SELECT`,`TEXTAREA`].includes(t.tagName))return;if(e.key===`Escape`){this.host.setSelected(-1);return}if(e.key!==`Delete`&&e.key!==`Backspace`)return;let n=this.host.getSelected();n<0||(e.preventDefault(),this.deleteWaypoint(n))}),this.host=e,this.C=t,this.viewer=n,this.container=n.container,this.canvas=n.canvas,this.container.addEventListener(`pointerdown`,this.onPointerDown,{capture:!0}),this.container.addEventListener(`pointermove`,this.onPointerMove,{capture:!0}),this.container.addEventListener(`pointerup`,this.onPointerUp,{capture:!0}),this.container.addEventListener(`pointercancel`,this.onPointerUp,{capture:!0}),this.container.addEventListener(`pointerleave`,this.onPointerLeave,{capture:!0}),this.container.addEventListener(`dblclick`,this.onDoubleClick,{capture:!0}),window.addEventListener(`keydown`,this.onKeyDown)}get isEnabled(){return this.enabled}setEnabled(e){this.enabled!==e&&(this.enabled=e,e||(this.cancelDrag(),this.hoverIndex=-1,this.canvas.style.cursor=``))}getEditState(){return{enabled:this.enabled,active:this.editable(),selectedIndex:this.host.getSelected(),hoverIndex:this.hoverIndex,dragging:this.drag!==null,mode:this.drag?.mode??null}}editable(){return this.enabled&&this.host.canEdit()}update(){this.disposed||(this.syncEntities(),this.syncStateVisuals())}syncEntities(){let e=this.host.getWaypoints(),t=e.map(e=>`${e.x.toFixed(2)},${e.z.toFixed(2)},${e.altitude.toFixed(2)}`).join(`;`),n=this.host.sim.homePosition,r=`${n.x.toFixed(2)},${n.z.toFixed(2)}`;(t!==this.waypointSignature||r!==this.homeKey)&&(this.waypointSignature=t,this.homeKey=r,this.rebuildWaypointEntities(e),this.rebuildPathEntity(e),this.rebuildHomeEntity(n),this.lastSelected=-2,this.lastActive=-2,this.lastHover=-2)}rebuildWaypointEntities(e){for(let t=e.length;;t+=1){let e=this.viewer.entities.getById(Ad+t);if(!e)break;this.viewer.entities.remove(e)}e.forEach((e,t)=>{let n=Ad+t,r=this.host.localToWorld(e.x,e.altitude,e.z),i=this.viewer.entities.getById(n);i?i.position=r:this.viewer.entities.add({id:n,position:r,point:{pixelSize:9,color:Xd(this.C,Ld),outlineColor:Xd(this.C,Rd),outlineWidth:2,disableDepthTestDistance:1/0},label:{text:String(t+1),font:`12px sans-serif`,pixelOffset:{x:12,y:-12},fillColor:Xd(this.C,Ud),showBackground:!0,backgroundColor:Xd(this.C,Wd),disableDepthTestDistance:1/0}})})}rebuildPathEntity(e){let t=this.viewer.entities.getById(jd);if(e.length<2){t&&this.viewer.entities.remove(t);return}let n=e.map(e=>this.host.localToWorld(e.x,e.altitude,e.z));t?t.polyline.positions=n:this.viewer.entities.add({id:jd,polyline:{positions:n,width:2,material:new this.C.PolylineGlowMaterialProperty({glowPower:.25,color:Xd(this.C,Vd)}),disableDepthTestDistance:1/0}})}rebuildHomeEntity(e){let t=this.viewer.entities.getById(Md),n=this.host.localToWorld(e.x,0,e.z);t?t.position=n:this.viewer.entities.add({id:Md,position:n,point:{pixelSize:7,color:Xd(this.C,Hd),outlineColor:Xd(this.C,Rd),outlineWidth:2,disableDepthTestDistance:1/0},label:{text:`返航点`,font:`11px sans-serif`,pixelOffset:{x:10,y:-10},fillColor:Xd(this.C,Gd),showBackground:!0,backgroundColor:Xd(this.C,Wd),disableDepthTestDistance:1/0}})}syncStateVisuals(){let e=this.host.getSelected(),t=this.host.sim.missionStatus===`idle`?-1:this.host.sim.missionIndex;if(e===this.lastSelected&&t===this.lastActive&&this.hoverIndex===this.lastHover)return;this.lastSelected=e,this.lastActive=t,this.lastHover=this.hoverIndex;let n=this.host.getWaypoints().length;for(let r=0;r<n;r+=1){let n=this.viewer.entities.getById(Ad+r);n?.point&&(r===t?(n.point.color=Xd(this.C,Bd),n.point.pixelSize=12):r===e?(n.point.color=Xd(this.C,zd),n.point.pixelSize=12):r===this.hoverIndex?(n.point.color=Xd(this.C,Ld),n.point.pixelSize=11):(n.point.color=Xd(this.C,Ld),n.point.pixelSize=9))}}setVisible(e){let t=this.host.getWaypoints().length;for(let n=0;n<t;n+=1){let t=this.viewer.entities.getById(Ad+n);t&&(t.show=e)}let n=this.viewer.entities.getById(jd);n&&(n.show=e);let r=this.viewer.entities.getById(Md);r&&(r.show=e)}setWaypointsVisible(e){let t=this.host.getWaypoints().length;for(let n=0;n<t;n+=1){let t=this.viewer.entities.getById(Ad+n);t&&(t.show=e)}}setPathVisible(e){let t=this.viewer.entities.getById(jd);t&&(t.show=e)}deleteWaypoint(e){if(!this.host.canEdit())return!1;let t=this.host.getWaypoints();if(e<0||e>=t.length)return!1;let n=t.filter((t,n)=>n!==e).map(e=>({...e}));return this.host.commitWaypoints(n,Math.min(e,n.length-1)),this.host.log(`info`,`场景编辑:已删除航点 ${e+1}`),!0}createDrag(e,t,n){let r=this.C,i=r.Cartesian3.subtract(this.host.localToWorld(1,0,0),this.host.localToWorld(0,0,0),new r.Cartesian3),a=r.Cartesian3.subtract(this.host.localToWorld(0,0,-1),this.host.localToWorld(0,0,0),new r.Cartesian3);return{index:t,mode:e.shiftKey?`altitude`:`move`,pointerId:e.pointerId,startClientX:e.clientX,startClientY:e.clientY,startX:n.x,startZ:n.z,startAltitude:n.altitude,moved:!1,east:i,north:a}}applyDrag(e,t){let n=e.altKey?Id:Fd,r=this.host.getLimits();if(t.mode===`altitude`){let i=t.startAltitude-(e.clientY-t.startClientY)*this.metersPerPixel(t);this.host.moveWaypoint(t.index,{altitude:Jd(Yd(i,n),1,r.maxAltitude)});return}let i=this.screenDeltaToLocal(e.clientX-t.startClientX,e.clientY-t.startClientY,t);i&&this.host.moveWaypoint(t.index,{x:Yd(i.x,n),z:Yd(i.z,n)})}screenDeltaToLocal(e,t,n){let r=this.C,i=this.viewer.camera,a=this.metersPerPixel(n),o=e=>{let t=r.Cartesian3.dot(e,n.east),i=r.Cartesian3.dot(e,n.north),a=Math.hypot(t,i);return a<1e-6?null:{e:t/a,n:i/a}},s=o(i.rightWC),c=o(i.directionWC);if(!s||!c)return null;let l=(s.e*e-c.e*t)*a,u=(s.n*e-c.n*t)*a;return{x:n.startX+l,z:n.startZ-u}}metersPerPixel(e){let t=this.C,n=this.viewer.camera,r=this.host.localToWorld(e.startX,e.startAltitude,e.startZ),i=t.Cartesian3.distance(n.positionWC,r),a=2*Math.tan(n.frustum.fovy/2)*i,o=this.canvas.getBoundingClientRect();return o.height>0?a/o.height:.2}pickWaypoint(e){let t=this.canvas.getBoundingClientRect();if(t.width<=0||t.height<=0)return-1;let n=e.clientX-t.left,r=e.clientY-t.top,i=this.host.getWaypoints(),a=-1,o=Pd;for(let e=0;e<i.length;e+=1){let t=i[e],s=this.viewer.scene.cartesianToCanvasCoordinates(this.host.localToWorld(t.x,t.altitude,t.z));if(!s)continue;let c=Math.hypot(s.x-n,s.y-r);c<o&&(o=c,a=e)}return a}pickEllipsoid(e){return this.viewer.camera.pickEllipsoid(this.toWindowPosition(e))}toWindowPosition(e){let t=this.canvas.getBoundingClientRect();return new this.C.Cartesian2(e.clientX-t.left,e.clientY-t.top)}cancelDrag(){this.drag&&(this.drag=null,this.host.setCameraInputEnabled(!0))}destroy(){if(this.disposed)return;this.disposed=!0,this.container.removeEventListener(`pointerdown`,this.onPointerDown,{capture:!0}),this.container.removeEventListener(`pointermove`,this.onPointerMove,{capture:!0}),this.container.removeEventListener(`pointerup`,this.onPointerUp,{capture:!0}),this.container.removeEventListener(`pointercancel`,this.onPointerUp,{capture:!0}),this.container.removeEventListener(`pointerleave`,this.onPointerLeave,{capture:!0}),this.container.removeEventListener(`dblclick`,this.onDoubleClick,{capture:!0}),window.removeEventListener(`keydown`,this.onKeyDown),this.cancelDrag();let e=this.host.getWaypoints().length;for(let t=0;t<e;t+=1){let e=this.viewer.entities.getById(Ad+t);e&&this.viewer.entities.remove(e)}for(let e of[jd,Md]){let t=this.viewer.entities.getById(e);t&&this.viewer.entities.remove(t)}this.waypointSignature=``,this.homeKey=``}},Qd={semiMajorAxis:6378137,inverseFlattening:298.257223563,get flattening(){return 1/this.inverseFlattening},get eccentricitySquared(){let e=this.flattening;return e*(2-e)}},$d=Math.PI/180,ef=180/Math.PI;function tf(e){return Number.isFinite(e)}function nf(e,t){if(!e.every(tf))throw RangeError(`${t} must contain finite numbers`)}function rf(e){let t=Math.hypot(e[0],e[1],e[2]);if(!(t>0)||!tf(t))throw RangeError(`Cannot normalize a zero vector`);return[e[0]/t,e[1]/t,e[2]/t]}function af(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}function of(e){let{longitude:t,latitude:n}=e,r=e.altitude??0;if(![t,n,r].every(tf))throw RangeError(`Geodetic coordinates must contain finite numbers`);if(n<-90||n>90)throw RangeError(`Latitude must be in [-90, 90]`);let i=t*$d,a=n*$d,o=Math.sin(a),s=Math.cos(a),c=Qd.semiMajorAxis/Math.sqrt(1-Qd.eccentricitySquared*o*o);return[(c+r)*s*Math.cos(i),(c+r)*s*Math.sin(i),(c*(1-Qd.eccentricitySquared)+r)*o]}function sf(e){nf(e,`ECEF position`);let[t,n,r]=e,i=Math.atan2(n,t)*ef,a=Math.hypot(t,n),o=Qd.semiMajorAxis,s=Qd.eccentricitySquared,c=o*Math.sqrt(1-s);if(t===0&&n===0&&r===0)throw RangeError(`The ECEF origin has no defined geodetic coordinate`);if(a<1e-12)return{longitude:0,latitude:Math.sign(r)*90,altitude:Math.abs(r)-c};let l=Math.atan2(r*o,a*c),u=Math.sin(l),d=Math.cos(l),f=Math.atan2(r+s*c*u*u*u/(1-s),a-s*o*d*d*d);for(let e=0;e<8;e+=1){let e=Math.sin(f),t=o/Math.sqrt(1-s*e*e),n=a/Math.cos(f)-t,i=Math.atan2(r,a*(1-s*t/(t+n)));if(Math.abs(i-f)<1e-13){f=i;break}f=i}let p=Math.sin(f),m=o/Math.sqrt(1-s*p*p),h=a/Math.cos(f)-m;return{longitude:i,latitude:f*ef,altitude:h}}function cf(e){if(![e.longitude,e.latitude,e.altitude??0].every(tf))throw RangeError(`ENU origin must contain finite numbers`);let t=e.longitude*$d,n=e.latitude*$d,r=Math.sin(t),i=Math.cos(t),a=Math.sin(n),o=Math.cos(n),s=[-r,i,0],c=[-a*i,-a*r,o],l=[o*i,o*r,a];return{origin:{longitude:e.longitude,latitude:e.latitude,altitude:e.altitude??0},ecefOrigin:of(e),east:s,north:c,up:l,enuToEcefRotation:mf([s,c,l])}}function lf(e,t){nf(e,`ECEF position`);let n=[e[0]-t.ecefOrigin[0],e[1]-t.ecefOrigin[1],e[2]-t.ecefOrigin[2]];return[af(n,t.east),af(n,t.north),af(n,t.up)]}function uf(e,t){return nf(e,`ENU position`),[t.ecefOrigin[0]+t.east[0]*e[0]+t.north[0]*e[1]+t.up[0]*e[2],t.ecefOrigin[1]+t.east[1]*e[0]+t.north[1]*e[1]+t.up[1]*e[2],t.ecefOrigin[2]+t.east[2]*e[0]+t.north[2]*e[1]+t.up[2]*e[2]]}function df(e){let t=Math.hypot(e[0],e[1],e[2],e[3]);if(!(t>0)||!tf(t))throw RangeError(`Quaternion must be finite and non-zero`);return[e[0]/t,e[1]/t,e[2]/t,e[3]/t]}function ff(e,t){return[e[3]*t[0]+e[0]*t[3]+e[1]*t[2]-e[2]*t[1],e[3]*t[1]-e[0]*t[2]+e[1]*t[3]+e[2]*t[0],e[3]*t[2]+e[0]*t[1]-e[1]*t[0]+e[2]*t[3],e[3]*t[3]-e[0]*t[0]-e[1]*t[1]-e[2]*t[2]]}function pf(e){return[-e[0],-e[1],-e[2],e[3]]}function mf(e){let[t,n,r]=e,i=t[0],a=n[0],o=r[0],s=t[1],c=n[1],l=r[1],u=t[2],d=n[2],f=r[2],p=i+c+f,m;if(p>0){let e=Math.sqrt(p+1)*2;m=[(d-l)/e,(o-u)/e,(s-a)/e,e/4]}else if(i>c&&i>f){let e=Math.sqrt(1+i-c-f)*2;m=[e/4,(a+s)/e,(o+u)/e,(d-l)/e]}else if(c>f){let e=Math.sqrt(1+c-i-f)*2;m=[(a+s)/e,e/4,(l+d)/e,(o-u)/e]}else{let e=Math.sqrt(1+f-i-c)*2;m=[(o+u)/e,(l+d)/e,e/4,(s-a)/e]}return df(m)}function hf(e,t){return df(ff(t.enuToEcefRotation,df(e)))}function gf(e,t){return df(ff(pf(t.enuToEcefRotation),df(e)))}var _f={colmap:[[1,0,0],[0,1,0],[0,0,1]],opencv:[[1,0,0],[0,1,0],[0,0,1]],three:[[1,0,0],[0,-1,0],[0,0,-1]],cesium:[[1,0,0],[0,-1,0],[0,0,-1]]};function vf(e,t=`three`){nf(e.right,`camera right`),nf(e.up,`camera up`),nf(e.forward,`camera forward`);let n=rf(e.right),r=rf(e.up),i=rf(e.forward);return mf(t===`colmap`||t===`opencv`?[n,[-r[0],-r[1],-r[2]],i]:[n,r,[-i[0],-i[1],-i[2]]])}function yf(e,t){let n=[[0,0,0],[0,0,0],[0,0,0]];for(let r=0;r<3;r+=1){let i=t[r];i&&(n[r]=[af(e[0]??[0,0,0],i),af(e[1]??[0,0,0],i),af(e[2]??[0,0,0],i)])}return n}function bf(e,t,n){let r=_f[t],i=_f[n];if(!r||!i)throw RangeError(`Unknown camera axis convention: ${String(t)} → ${String(n)}`);if(t===n)return df(e);let a=yf(r,i);return df(ff(df(e),mf(a)))}function xf(e,t={}){nf(e.position,`camera position`);let n=t.sourceCameraConvention??`cesium`,r,i=df(e.rotation);if(e.coordinateFrame===`ecef`){if(!t.enuFrame)throw RangeError(`enuFrame is required to convert an ECEF camera pose`);r=lf(e.position,t.enuFrame),i=gf(i,t.enuFrame)}else{if(e.coordinateFrame!==`local-enu`&&e.coordinateFrame!==`project-local`)throw RangeError(`Unsupported camera coordinate frame: ${e.coordinateFrame}`);r=[...e.position]}let a=bf(i,n,`colmap`),o=pf(a),s=ff(ff(o,[r[0],r[1],r[2],0]),a);return{position:r,rotation:a,qvec:[o[3],o[0],o[1],o[2]],tvec:[-s[0],-s[1],-s[2]],coordinateFrame:e.coordinateFrame===`project-local`?`project-local`:`local-enu`,rotationConvention:`camera-local-to-world; COLMAP +X right, +Y down, +Z forward`}}function Sf(e,t){return Array.isArray(e)&&e.length===t&&e.every(e=>typeof e==`number`&&tf(e))}function Cf(e,t,n){if(!e||typeof e!=`object`){n.errors.push(`${t}.boundingVolume is required`);return}let r=[`box`,`region`,`sphere`].filter(t=>Object.prototype.hasOwnProperty.call(e,t));if(r.length!==1){n.errors.push(`${t}.boundingVolume must contain exactly one of box, region, sphere`);return}let i=r[0],a={box:12,region:6,sphere:4};Sf(e[i],a[i])?n.stats.boundingVolumes+=1:n.errors.push(`${t}.boundingVolume.${i} must contain ${a[i]} finite numbers`)}function wf(e){let t={valid:!1,errors:[],warnings:[],stats:{nodes:0,contentUris:0,boundingVolumes:0,maxDepth:0}};if(!e||typeof e!=`object`)return t.errors.push(`tileset must be an object`),t;let n=e,r=n.asset?.version;if((typeof r!=`string`||!/^1(?:\.0|\.1)$/.test(r))&&t.errors.push(`asset.version must be "1.0" or "1.1"`),(typeof n.geometricError!=`number`||!tf(n.geometricError)||n.geometricError<0)&&t.errors.push(`geometricError must be a finite non-negative number`),!n.root||typeof n.root!=`object`||Array.isArray(n.root))t.errors.push(`root is required`);else{let e=(n,r,i)=>{if(!n||typeof n!=`object`||Array.isArray(n)){t.errors.push(`${r} must be an object`);return}t.stats.nodes+=1,t.stats.maxDepth=Math.max(t.stats.maxDepth,i),(typeof n.geometricError!=`number`||!tf(n.geometricError)||n.geometricError<0)&&t.errors.push(`${r}.geometricError must be a finite non-negative number`),Cf(n.boundingVolume,r,t),n.transform!==void 0&&!Sf(n.transform,16)&&t.errors.push(`${r}.transform must contain 16 finite numbers`);let a=n.content?.uri??n.content?.url;a!==void 0&&(typeof a!=`string`||!a.trim()?t.errors.push(`${r}.content.uri must be a non-empty string`):t.stats.contentUris+=1),n.contents!==void 0&&(Array.isArray(n.contents)?n.contents.forEach((e,n)=>{let i=e?.uri??e?.url;typeof i!=`string`||!i.trim()?t.errors.push(`${r}.contents[${n}].uri must be a non-empty string`):t.stats.contentUris+=1}):t.errors.push(`${r}.contents must be an array`)),n.children!==void 0&&(Array.isArray(n.children)?n.children.forEach((t,n)=>e(t,`${r}.children[${n}]`,i+1)):t.errors.push(`${r}.children must be an array`))};e(n.root,`root`,0),t.stats.contentUris===0&&t.warnings.push(`tileset has no content URI; it may contain only external children`)}return t.valid=t.errors.length===0,t}async function Tf(e,t,n={}){if(typeof e!=`string`||!e.trim())throw TypeError(`A non-empty tileset URL is required`);let r=n.validate?await n.validate(e):void 0;if(r&&!r.valid)throw Error(`Invalid 3D Tiles tileset: ${r.errors.join(`; `)}`);return{url:e,tileset:await(typeof t==`function`?t:t.load.bind(t))(e),validation:r}}var Ef=Tf;function Df(...e){let t=e[0]??``,n=/^[\\/]/.test(t),r=e.filter(e=>e.length>0).join(`/`).replace(/\\/g,`/`).replace(/\/+/g,`/`),i=/^[A-Za-z]:\//.test(r);return n&&!i&&!r.startsWith(`/`)?`/${r}`:r.replace(/\/$/,``)}function Of(e,t,n={}){if(!t||/[\\/]/.test(t))throw TypeError(`captureId must be a non-empty path segment`);let r=Df(e,`captures`,t),i=Df(e,`reconstruction`,t),a=Df(e,`outputs`,t);return{captureId:t,createdAt:n.createdAt??new Date().toISOString(),coordinateFrame:n.coordinateFrame??`local-enu`,status:`created`,paths:{captureDir:r,imagesDir:Df(r,`images`),manifestPath:Df(r,`manifest.json`),validationPath:Df(r,`image-validation.json`),reconstructionDir:i,colmapDir:Df(i,`colmap`),sparseDir:Df(i,`sparse`),denseDir:Df(i,`dense`),meshDir:Df(i,`mesh`),outputDir:a,tilesetPath:Df(a,`tileset.json`),reportPath:Df(i,`reconstruction-report.json`)}}}function kf(e){let t=[];if(!e||typeof e!=`object`)return[`report must be an object`];let n=e;return(!n.captureId||typeof n.captureId!=`string`)&&t.push(`captureId is required`),[`succeeded`,`failed`,`partial`].includes(n.status??``)||t.push(`status is invalid`),(!n.startedAt||typeof n.startedAt!=`string`)&&t.push(`startedAt is required`),Array.isArray(n.errors)||t.push(`errors must be an array`),Array.isArray(n.warnings)||t.push(`warnings must be an array`),n.registeredImages!==void 0&&(!Number.isInteger(n.registeredImages)||n.registeredImages<0)&&t.push(`registeredImages must be a non-negative integer`),n.totalImages!==void 0&&(!Number.isInteger(n.totalImages)||n.totalImages<0)&&t.push(`totalImages must be a non-negative integer`),n.registeredImages!==void 0&&n.totalImages!==void 0&&n.registeredImages>n.totalImages&&t.push(`registeredImages cannot exceed totalImages`),t}var Af=2.4,jf=[{key:`dji`,label:`DJI Mini 4 Pro`,url:`/models/dji_mini4_pro.glb`,scale:Af/31.758,yawOffsetDeg:90,lift:Af/31.758*5.034,gimbalOffsetM:.64,gimbalLiftM:-.03},{key:`cesium`,label:`Cesium 默认无人机`,url:`/Cesium/SampleData/models/CesiumDrone/CesiumDrone.glb`,scale:Af/4.668,yawOffsetDeg:0,lift:Af/4.668*.171,gimbalOffsetM:1.15,gimbalLiftM:.19}],Mf=.1,Nf=7.5,Pf=.6,Ff=5e3,If=30,Lf=8e6,Rf=500,zf=1500,Bf=1313821514,Vf=5130562,Hf=[`KHR_lights_punctual`];function Uf(e,t=Hf){if(t.length===0||e.byteLength<20)return null;let n=new DataView(e);if(n.getUint32(0,!0)!==1179937895||n.getUint32(4,!0)!==2)return null;let r=n.getUint32(8,!0),i=-1,a=0,o=-1,s=0,c=12,l=Math.min(r,e.byteLength);for(;c+8<=l;){let e=n.getUint32(c,!0),t=n.getUint32(c+4,!0),r=c+8;if(r+e>l)break;t===Bf&&i<0?(i=r,a=e):t===Vf&&o<0&&(o=r,s=e),c=r+e}if(i<0)return null;let u=new TextDecoder(`utf-8`).decode(new Uint8Array(e,i,a)),d;try{d=JSON.parse(u)}catch{return null}let f=d.extensionsRequired;if(!Array.isArray(f))return null;let p=f.filter(e=>!t.includes(e));if(p.length===f.length)return null;p.length>0?d.extensionsRequired=p:delete d.extensionsRequired;let m=new TextEncoder().encode(JSON.stringify(d)),h=m.byteLength+3&-4,g=o>=0?s:0,_=20+h+(g?8+g:0),v=new Uint8Array(_),y=new DataView(v.buffer);if(y.setUint32(0,1179937895,!0),y.setUint32(4,2,!0),y.setUint32(8,_,!0),y.setUint32(12,h,!0),y.setUint32(16,Bf,!0),v.fill(32,20,20+h),v.set(m,20),g){let t=20+h;y.setUint32(t,g,!0),y.setUint32(t+4,Vf,!0),v.set(new Uint8Array(e,o,g),t+8)}return v.buffer}var Wf=null;function Gf(e=`/Cesium/Cesium.js`){return typeof window>`u`?Promise.reject(Error(`[drone-camera] loadCesiumScript 只能在浏览器里调用`)):window.Cesium?Promise.resolve():Wf||(Wf=new Promise((t,n)=>{let r=document.createElement(`script`);r.src=e,r.onload=()=>t(),r.onerror=()=>{Wf=null,n(Error(`[drone-camera] Cesium 静态资源加载失败:${e}`))},document.head.appendChild(r)}),Wf)}var Kf=class{constructor(e){if(i(this,`sim`,new _e),i(this,`engine`,`cesium`),i(this,`cameraMode`,`orbit`),i(this,`C`,void 0),i(this,`viewer`,void 0),i(this,`enuToFixed`,void 0),i(this,`origin`,void 0),i(this,`groundClearance`,void 0),i(this,`followRange`,void 0),i(this,`stripExtensions`,void 0),i(this,`sanitizedBlobUrl`,null),i(this,`model`,null),i(this,`rig`,void 0),i(this,`missionEditor`,null),i(this,`loadToken`,0),i(this,`worldMatrix`,void 0),i(this,`modelIndex`,void 0),i(this,`armFoldTarget`,0),i(this,`missionEditEnabled`,!1),i(this,`missionEditSelected`,-1),i(this,`missionVisible`,!0),i(this,`missionMarkersVisible`,!0),i(this,`missionPathVisible`,!0),i(this,`recorder`,null),i(this,`recordChunks`,[]),i(this,`recordContext`,null),i(this,`captureTrack`,null),i(this,`recordStream`,null),i(this,`photoPending`,null),i(this,`photoCameraRestore`,null),i(this,`onRecordingReady`,null),i(this,`rafId`,null),i(this,`lastTime`,0),i(this,`disposed`,!1),i(this,`terrainSamplingDisabled`,!1),i(this,`cameraLocked`,!1),i(this,`captureView`,null),i(this,`captureFrameActive`,!1),i(this,`onModelChange`,null),i(this,`loop`,e=>{if(this.disposed)return;let t=this.lastTime===0?0:Math.min(Mf,(e-this.lastTime)/1e3);this.lastTime=e,this.sim.step(t),this.syncModelMatrix(),this.rig.update(t),this.missionEditor?.update(),this.applyCamera(),this.captureGimbalFrame(),this.rafId=requestAnimationFrame(this.loop)}),typeof window>`u`)throw Error(`[drone-camera] CesiumDroneAdapter 需要浏览器环境`);let t=e.cesium??window.Cesium;if(!t)throw Error(`[drone-camera] 未找到 Cesium:请先 await loadCesiumScript("/Cesium/Cesium.js"),或在 options 里显式传入 cesium 命名空间`);this.C=t,this.viewer=e.viewer,this.groundClearance=e.groundClearance??.05,this.followRange=e.followRange??Nf,this.modelIndex=e.modelIndex??0,this.stripExtensions=e.stripRequiredExtensions??Hf,this.origin={lon:e.lon??116.391,lat:e.lat??39.906,height:e.height??0},this.enuToFixed=t.Transforms.eastNorthUpToFixedFrame(t.Cartesian3.fromDegrees(this.origin.lon,this.origin.lat,this.origin.height)),this.worldMatrix=new t.Matrix4,this.rig=new Od(this.sim,t),this.installArmCheck()}async start(){let e=this.C,t=this.viewer.terrainProvider;if(this.canSampleTerrain(t))try{let n=e.Cartographic.fromDegrees(this.origin.lon,this.origin.lat),[r]=await e.sampleTerrainMostDetailed(t,[n]);r&&Number.isFinite(r.height)&&(this.origin.height=r.height)}catch(e){this.handleTerrainError(e)}this.rebuildEnuFrame(),this.loadModel(),this.missionEditor=new Zd(this,this.C,this.viewer),this.missionEditor.setEnabled(this.missionEditEnabled),this.applyMissionVisibility(),this.loop(performance.now())}destroy(){if(!this.disposed){if(this.disposed=!0,this.rafId!==null&&cancelAnimationFrame(this.rafId),this.rafId=null,this.recorder){try{this.recorder.stop()}catch{}this.recorder=null}if(this.photoPending){window.clearTimeout(this.photoPending.timer);let e=this.photoPending;this.photoPending=null,e.resolve(null)}this.photoCameraRestore?.camera&&this.restoreCamera(this.photoCameraRestore.camera),this.photoCameraRestore=null,this.captureFrameActive=!1,this.recordStream?.getTracks().forEach(e=>e.stop()),this.recordStream=null,this.captureTrack=null,this.recordContext=null,this.releaseCamera(),this.rig.dispose(),this.missionEditor?.destroy(),this.missionEditor=null,this.model&&(this.viewer.scene.primitives.remove(this.model),this.model=null),this.releaseSanitizedUrl(),this.recordChunks=[]}}releaseSanitizedUrl(){this.sanitizedBlobUrl&&typeof URL<`u`&&URL.revokeObjectURL(this.sanitizedBlobUrl),this.sanitizedBlobUrl=null}async resolveModelUrl(e,t){if(this.releaseSanitizedUrl(),this.stripExtensions.length===0||typeof fetch!=`function`)return e;try{let n=await fetch(e);if(!n.ok)return e;let r=Uf(await n.arrayBuffer(),this.stripExtensions);return this.disposed||t!==this.loadToken||!r?e:(this.sanitizedBlobUrl=URL.createObjectURL(new Blob([r],{type:`model/gltf-binary`})),this.sanitizedBlobUrl)}catch{return e}}get modelSpec(){return jf[this.modelIndex]??jf[0]}get modelLoaded(){return this.model!==null}setModel(e){let t=typeof e==`number`?e:jf.findIndex(t=>t.key===e);return t<0||t>=jf.length||(this.modelIndex=t,this.loadModel(),this.onModelChange?.(this.modelSpec)),this.modelSpec}cycleModel(){return this.setModel((this.modelIndex+1)%jf.length)}async loadModel(){let e=this.C,t=this.modelSpec,n=++this.loadToken,r=await this.resolveModelUrl(t.url,n);if(this.disposed||n!==this.loadToken)return;let i;try{i=await e.Model.fromGltfAsync({url:r,scale:t.scale,minimumPixelSize:0})}catch{return}if(this.disposed||n!==this.loadToken){i.isDestroyed()||i.destroy();return}this.model&&this.viewer.scene.primitives.remove(this.model),this.model=i,this.viewer.scene.primitives.add(i),this.syncModelMatrix();let a=()=>{!this.disposed&&this.model===i&&this.rig.attach(i)};i.ready?a():i.readyEvent.addEventListener(()=>a())}rebuildEnuFrame(){let e=this.C,t=e.Transforms.eastNorthUpToFixedFrame(e.Cartesian3.fromDegrees(this.origin.lon,this.origin.lat,this.origin.height));e.Matrix4.clone(t,this.enuToFixed)}computeWorldPosition(){let e=this.C,t=this.sim,n=e.Cartesian3.fromElements(t.position.x,-t.position.z,t.position.y+this.groundClearance+this.modelSpec.lift);return e.Matrix4.multiplyByPoint(this.enuToFixed,n,new e.Cartesian3)}syncModelMatrix(){if(!this.model)return;let e=this.C,t=this.sim,n=new e.HeadingPitchRoll(e.Math.toRadians(t.heading+this.modelSpec.yawOffsetDeg),e.Math.toRadians(-t.tiltPitch),e.Math.toRadians(t.tiltRoll));this.model.modelMatrix=e.Transforms.headingPitchRollToFixedFrame(this.computeWorldPosition(),n,void 0,void 0,this.worldMatrix)}getGeo(){let e=this.C,t=e.Cartographic.fromCartesian(this.computeWorldPosition());return{lon:e.Math.toDegrees(t.longitude),lat:e.Math.toDegrees(t.latitude),height:t.height}}setCameraMode(e){e!==this.cameraMode&&(this.cameraMode=e,e===`orbit`&&this.releaseCamera())}releaseCamera(){this.cameraLocked&&(this.viewer.camera.lookAtTransform(this.C.Matrix4.IDENTITY),this.cameraLocked=!1)}applyCamera(){if(this.cameraMode===`orbit`){this.releaseCamera();return}let e=this.C,t=this.viewer.camera,n=this.computeWorldPosition(),r=this.sim;if(this.cameraMode===`follow`){let i=2.1999999999999997,a=e.Cartesian3.add(n,e.Matrix4.multiplyByPointAsVector(this.enuToFixed,new e.Cartesian3(0,0,Pf),new e.Cartesian3),new e.Cartesian3);t.lookAt(a,new e.HeadingPitchRange(e.Math.toRadians(r.heading),-Math.atan2(i,this.followRange),Math.hypot(this.followRange,i))),this.cameraLocked=!0}else this.releaseCamera(),this.applyGimbalCameraPose()}applyGimbalCameraPose(){let{destination:e,heading:t,pitch:n,roll:r}=this.gimbalCameraView();this.viewer.camera.setView({destination:e,orientation:{heading:t,pitch:n,roll:r}})}gimbalCameraView(){let e=this.C,t=this.sim,n=this.modelSpec,r=this.captureView?.pitch??t.gimbalPitch,i=t.gimbalYaw,a=e.Math.toRadians(r),o=e.Math.toRadians(t.heading),s;return s=this.captureView?new e.Cartesian3(0,0,n.gimbalLiftM):new e.Cartesian3(Math.sin(o)*n.gimbalOffsetM*Math.cos(a),Math.cos(o)*n.gimbalOffsetM*Math.cos(a),n.gimbalOffsetM*Math.sin(a)+n.gimbalLiftM),{destination:e.Cartesian3.add(this.computeWorldPosition(),e.Matrix4.multiplyByPointAsVector(this.enuToFixed,s,new e.Cartesian3),new e.Cartesian3),heading:e.Math.toRadians(t.heading-i),pitch:a,roll:0}}getCaptureCamera(){if(this.disposed||!this.modelLoaded)return null;let e=this.C,t=this.viewer.canvas,n=t?.width??0,r=t?.height??0;if(!n||!r)return null;let{destination:i,heading:a,pitch:o,roll:s}=this.gimbalCameraView(),c=this.captureFrameActive?this.viewer.camera:new e.Camera(this.viewer.scene);this.captureFrameActive||c.setView({destination:i,orientation:{heading:a,pitch:o,roll:s}});let l=c.rightWC,u=c.upWC,d=c.directionWC,f=vf({right:[l.x,l.y,l.z],up:[u.x,u.y,u.z],forward:[d.x,d.y,d.z]},`cesium`),p=c.positionWC,m=e.Cartographic.fromCartesian(p),h=this.viewer.camera.frustum?.projectionMatrix;if(!h||Math.abs(h[11]+1)>1e-8)return null;let g=h[0]*n/2,_=h[5]*r/2,v=2*Math.atan(r/(2*_)),y=2*Math.atan(n/(2*g)),b=this.sim,x=e=>e*180/Math.PI;return{pose:{position:[p.x,p.y,p.z],rotation:f,coordinateFrame:`ecef`},intrinsics:{width:n,height:r,fx:g,fy:_,cx:n*(1-h[8])/2,cy:r*(1+h[9])/2,horizontalFovDeg:x(y),verticalFovDeg:x(v),calibrationSource:`known`},frame:{width:n,height:r},drone:{position:[b.position.x,-b.position.z,b.position.y],heading:b.heading,tiltPitch:b.tiltPitch,tiltRoll:b.tiltRoll,gimbalPitch:b.gimbalPitch,gimbalYaw:b.gimbalYaw},geo:{longitude:x(m.longitude),latitude:x(m.latitude),altitude:m.height}}}snapshotCamera(){let e=this.C,t=this.viewer.camera;return{position:e.Cartesian3.clone(t.positionWC),direction:e.Cartesian3.clone(t.directionWC),up:e.Cartesian3.clone(t.upWC),transform:e.Matrix4.clone(t.transform)}}restoreCamera(e){let t=this.C,n=this.viewer.camera;n.lookAtTransform(t.Matrix4.IDENTITY),n.setView({destination:e.position,orientation:{direction:e.direction,up:e.up}}),n.lookAtTransform(e.transform)}setCaptureFrameVisible(e){this.model&&(this.model.show=e),e?this.applyMissionVisibility():this.missionEditor?.setVisible(!1)}captureGimbalFrame(){let e=this.photoPending,t=this.recorder!==null,n=!1;if(!e&&this.photoCameraRestore&&(this.photoCameraRestore.camera&&this.restoreCamera(this.photoCameraRestore.camera),this.photoCameraRestore=null,this.captureFrameActive=!1,this.setCaptureFrameVisible(!0),n=!0),!e&&!t){n&&this.viewer.render();return}let r=this.cameraMode===`fpv`,i=r?null:e?this.photoCameraRestore?.camera??this.snapshotCamera():this.snapshotCamera();if(e&&!this.photoCameraRestore&&(this.photoCameraRestore={camera:i}),r||this.applyGimbalCameraPose(),this.setCaptureFrameVisible(!1),e&&(this.captureFrameActive=!0),this.viewer.render(),e&&(e.captureCamera=this.getCaptureCamera()),t&&this.pushRecordFrame(),e&&!e.forceCapture&&this.viewer.scene.globe?.tilesLoaded===!1)e.settledFrames=0;else if(e&&e.settledFrames<2)e.settledFrames+=1;else{if(e){this.photoPending=null,window.clearTimeout(e.timer);let t=this.grabCanvas();t&&e.captureCamera&&(t.camera=e.captureCamera),t&&this.sim.takePhoto(),e.resolve(t)}this.setCaptureFrameVisible(!0),e&&(this.photoCameraRestore=null,this.captureFrameActive=!1),i&&this.restoreCamera(i),this.viewer.render()}}pushRecordFrame(){let e=this.recordContext,t=this.viewer.canvas;e&&t&&((e.canvas.width!==t.width||e.canvas.height!==t.height)&&(e.canvas.width=t.width,e.canvas.height=t.height),e.drawImage(t,0,0),this.captureTrack?.requestFrame())}grabCanvas(){let e=this.viewer.canvas;if(!e||!e.width||!e.height)return null;let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);return n?(n.drawImage(e,0,0),{dataUrl:t.toDataURL(`image/png`),width:t.width,height:t.height}):null}resetCamera(){let e=this.C;this.releaseCamera(),this.cameraMode=`orbit`;let t=this.computeWorldPosition();this.viewer.camera.flyToBoundingSphere(new e.BoundingSphere(t,6),{duration:.8,offset:new e.HeadingPitchRange(0,e.Math.toRadians(-28),16)})}get phase(){return this.sim.phase}get airborne(){return this.sim.airborne}get flightMode(){return this.sim.mode}get altitude(){return this.sim.position.y}get preflightChecks(){return this.sim.checklist}get armsFolded(){return this.armFoldTarget>.5}get isRecording(){return this.recorder!==null}powerOn(){this.sim.powerOn()}takeOff(){return this.sim.autoTakeOff()}land(){return this.sim.startLanding()}returnHome(e=`用户触发返航`){return this.sim.startRth(e)}setStick(e){this.sim.setStick(e)}setMode(e){this.sim.setMode(e)}setGimbalPitch(e){this.sim.setGimbalPitch(e)}flyTo(e){let t=e.x??this.sim.position.x,n=e.y??this.sim.position.y,r=e.z??this.sim.position.z;this.sim.position.x=t,this.sim.position.y=Math.max(0,n),this.sim.position.z=r,e.heading!==void 0&&(this.sim.heading=e.heading),e.pitch!==void 0&&(this.sim.tiltPitch=Math.max(-45,Math.min(45,e.pitch))),e.roll!==void 0&&(this.sim.tiltRoll=Math.max(-45,Math.min(45,e.roll))),this.ensureAltitudeAboveTerrain()}zoomTo(e){if(this.sim.setZoom(e),this.cameraMode===`follow`){let e=Math.max(1.5,this.followRange/this.sim.cameraZoom);this.viewer.camera.lookAt(this.computeWorldPosition(),new this.C.HeadingPitchRange(this.C.Math.toRadians(this.sim.heading),-Math.atan2(2.1999999999999997,e),e))}}async ensureAltitudeAboveTerrain(){let e=this.viewer.terrainProvider;if(!this.canSampleTerrain(e))return;let t=this.C,n=t.Cartesian3.fromElements(this.sim.position.x,-this.sim.position.z,0),r=t.Matrix4.multiplyByPoint(this.enuToFixed,n,new t.Cartesian3),i=t.Cartographic.fromCartesian(r);try{let[n]=await t.sampleTerrainMostDetailed(e,[i]);if(!n||!Number.isFinite(n.height))return;let r=n.height-this.origin.height-this.groundClearance-this.modelSpec.lift+.25;this.sim.position.y<r&&(this.sim.position.y=r)}catch(e){this.handleTerrainError(e)}}canSampleTerrain(e){return!(this.disposed||this.terrainSamplingDisabled||!e||!e.availability||typeof e.requestTileGeometry!=`function`)}handleTerrainError(e){let t=e,n=t?.statusCode??t?.response?.status,r=String(t?.message??e??``);if(n===401||n===403||/\b(?:401|403)\b/.test(r)){this.terrainSamplingDisabled=!0;try{this.viewer.terrainProvider=new this.C.EllipsoidTerrainProvider}catch{}}}setCaptureView(e){this.captureView=e??null}spinBodyTo(e){this.sim.spinTo(e)}getBodyHeading(){return this.sim.heading}setArmsFolded(e){this.armFoldTarget=+!!e,this.refreshArmCheck()}installArmCheck(){this.sim.externalChecks.some(e=>e.id===`arms`)||this.sim.externalChecks.push({id:`arms`,label:`机臂`,ok:!1,detail:`机臂处于收纳状态`,blocking:!0})}refreshArmCheck(){let e=this.sim.externalChecks.find(e=>e.id===`arms`);e&&(e.ok=this.armFoldTarget<=.5,e.detail=e.ok?`已展开`:`机臂处于收纳状态`)}get isOrbitView(){return this.cameraMode===`orbit`}startMission(){return this.sim.startMission()}pauseMission(e){return this.sim.pauseMission(e)}resumeMission(){return this.sim.resumeMission()}stopMission(e){return this.sim.stopMission(e)}setMission(e){return this.sim.setMission(e)}setMissionConfig(e){this.sim.setMissionConfig(e)}resetMissionToDefault(){this.sim.resetMissionToDefault()}getMissionSnapshot(){return this.sim.snapshot().mission}getSnapshot(){return this.sim.snapshot()}getMissionExport(){return E(this.sim.mission.map(e=>({...e})),{...this.sim.missionConfig},this.sim.homePosition)}exportMission(e=`json`){return O(this.getMissionExport(),e)}getMissionEditState(){return this.missionEditor?.getEditState()??{enabled:this.missionEditEnabled,active:!1,selectedIndex:this.missionEditSelected,hoverIndex:-1,dragging:!1,mode:null}}setMissionEditEnabled(e){this.missionEditEnabled=e,this.missionEditor?.setEnabled(e),e?this.sim.mission.length>0&&this.canMissionSceneEdit()&&this.frameMission():this.setMissionSelected(-1)}isMissionEditEnabled(){return this.missionEditEnabled}getMissionSelected(){return this.missionEditSelected}setMissionSelected(e){this.missionEditSelected=e}updateMissionWaypoint(e,t){return this.sim.updateMissionWaypoint(e,t)}deleteMissionWaypoint(e){return!this.canMissionSceneEdit()||!this.sim.removeMissionWaypoint(e)?!1:(this.setMissionSelected(Math.min(e,this.sim.mission.length-1)),this.sim.pushEvent(`info`,`场景编辑:已删除航点 ${e+1}`),!0)}addMissionWaypointAtDrone(){if(!this.canMissionSceneEdit())return-1;let e=this.sim.position,t=this.sim.addMissionWaypoint({x:Math.round(e.x),z:Math.round(e.z),altitude:Math.max(1,Math.round(e.y)),speed:this.sim.missionConfig.autoSpeed});return t<0?-1:(this.setMissionSelected(t),this.sim.pushEvent(`info`,`场景编辑:已在飞机当前位置新增航点 ${t+1}`),t)}newWaypointTemplate(e){let t=this.sim.mission,n=t[Math.min(e,t.length-1)]??t[t.length-1];return{altitude:n?.altitude??30,speed:n?.speed??this.sim.missionConfig.autoSpeed,hoverSeconds:n?.hoverSeconds??0}}setMissionVisible(e){this.missionVisible=e,this.missionEditor?.setVisible(e)}isMissionVisible(){return this.missionVisible}setMissionWaypointsVisible(e){this.missionMarkersVisible=e,this.missionEditor?.setWaypointsVisible(e)}isMissionWaypointsVisible(){return this.missionMarkersVisible}setMissionPathVisible(e){this.missionPathVisible=e,this.missionEditor?.setPathVisible(e)}isMissionPathVisible(){return this.missionPathVisible}supportsGeoCoordinates(){return!0}getWaypointGeo(e){let t=this.sim.mission[e];if(!t)return null;let n=this.localToWorld(t.x,t.altitude,t.z),r=this.C.Cartographic.fromCartesian(n);return!r||!Number.isFinite(r.longitude)||!Number.isFinite(r.latitude)?null:{lon:this.C.Math.toDegrees(r.longitude),lat:this.C.Math.toDegrees(r.latitude),height:r.height}}setWaypointGeo(e,t){if(!this.sim.mission[e]||![t.lon,t.lat,t.height].every(e=>Number.isFinite(e)))return!1;let n=this.C.Cartesian3.fromDegrees(t.lon,t.lat,t.height),r=this.worldToLocalXZ(n);if(!r)return!1;let i=Math.min(500,Math.max(1,t.height-this.origin.height));return this.updateMissionWaypoint(e,{x:r.x,z:r.z,altitude:i})!==null}applyMissionVisibility(){this.missionEditor?.setVisible(this.missionVisible),this.missionEditor?.setWaypointsVisible(this.missionMarkersVisible),this.missionEditor?.setPathVisible(this.missionPathVisible)}frameMission(){if(!this.isOrbitView)return!1;let e=this.C,t=this.sim.homePosition,n=this.sim.mission[0],r=t.x,i=t.x,a=n?Math.max(1,n.altitude):1,o=a,s=t.z,c=t.z,l=(e,t,n)=>{r=Math.min(r,e),i=Math.max(i,e),a=Math.min(a,t),o=Math.max(o,t),s=Math.min(s,n),c=Math.max(c,n)};for(let e of this.sim.mission)l(e.x,e.altitude,e.z);l(r,0,s),l(i,0,c);let u={x:(r+i)/2,y:(a+o)/2,z:(s+c)/2},d=Math.max(12,.5*Math.hypot(i-r,o-a,c-s)),f=this.localToWorld(u.x,u.y,u.z),p=this.viewer.camera,m=this.viewer.canvas,h=p.frustum.fovy/2,g=m.clientWidth>0?m.clientWidth/m.clientHeight:1.6,_=Math.atan(Math.tan(h)*Math.max(.2,g)),v=Math.max(d/Math.tan(h),d/Math.tan(_))*1.35;return this.releaseCamera(),this.viewer.camera.flyToBoundingSphere(new e.BoundingSphere(f,d),{duration:.6,offset:new e.HeadingPitchRange(0,e.Math.toRadians(-32),v)}),!0}canMissionSceneEdit(){return this.isOrbitView&&this.sim.missionStatus===`idle`&&!this.sim.missionPendingStart}canEdit(){return this.canMissionSceneEdit()}getWaypoints(){return this.sim.mission.map(e=>({...e}))}getSelected(){return this.missionEditSelected}setSelected(e){this.setMissionSelected(e)}commitWaypoints(e,t){this.sim.setMission(e)&&this.setMissionSelected(t)}moveWaypoint(e,t){return this.updateMissionWaypoint(e,t)}getLimits(){return{maxAltitude:this.sim.altitudeCeiling,maxDistance:this.sim.distanceCeiling,homeX:this.sim.homePosition.x,homeZ:this.sim.homePosition.z}}localToWorld(e,t,n){let r=this.C,i=r.Cartesian3.fromElements(e,-n,t+this.origin.height);return r.Matrix4.multiplyByPoint(this.enuToFixed,i,new r.Cartesian3)}worldToLocalXZ(e){let t=this.C,n=t.Matrix4.inverse(this.enuToFixed,new t.Matrix4);if(!n)return null;let r=t.Matrix4.multiplyByPoint(n,e,new t.Cartesian3);return!r||!Number.isFinite(r.x)||!Number.isFinite(r.y)?null:{x:r.x,z:-r.y}}setCameraInputEnabled(e){let t=this.viewer.scene?.screenSpaceCameraController;t&&`enableInputs`in t&&(t.enableInputs=e)}log(e,t){this.sim.pushEvent(e,t)}async requestPhoto(){return this.disposed||this.photoPending?null:new Promise(e=>{let t={resolve:e,timer:0,settledFrames:0,forceCapture:!1,captureCamera:null};t.timer=window.setTimeout(()=>{this.photoPending===t&&(t.forceCapture=!0)},Ff),this.photoPending=t})}startRecording(){if(this.recorder)return!0;let e=this.viewer.canvas;if(!e||typeof MediaRecorder>`u`||typeof e.captureStream!=`function`)return!1;let t=document.createElement(`canvas`);t.width=e.width||1,t.height=e.height||1;let n=t.getContext(`2d`);if(!n)return!1;let r,i;try{i=t.captureStream(0);let e=i.getVideoTracks()[0];e&&typeof e.requestFrame==`function`?this.captureTrack=e:(i.getTracks().forEach(e=>e.stop()),i=t.captureStream(If),this.captureTrack=null);let n=MediaRecorder.isTypeSupported(`video/webm;codecs=vp9`)?`video/webm;codecs=vp9`:`video/webm`;r=new MediaRecorder(i,{mimeType:n,videoBitsPerSecond:Lf})}catch{return this.captureTrack=null,!1}return this.recordContext=n,this.recordStream=i,this.recordChunks=[],r.ondataavailable=e=>{e.data&&e.data.size>0&&this.recordChunks.push(e.data)},r.start(Rf),this.recorder=r,this.sim.setRecordingState(!0),!0}stopRecording(){let e=this.recorder;this.recorder=null;let t=this.sim.recordSeconds;if(this.sim.setRecordingState(!1),!e)return Promise.resolve(null);let n=this.recordChunks;return this.recordChunks=[],new Promise(r=>{let i=!1,a=()=>{if(i)return;i=!0,window.clearTimeout(o),this.recordStream?.getTracks().forEach(e=>e.stop()),this.recordStream=null,this.captureTrack=null,this.recordContext=null;let a=n.length?new Blob(n,{type:e.mimeType||`video/webm`}):null;a&&this.onRecordingReady?.(a,t),r(a)},o=window.setTimeout(a,zf);e.onstop=a;try{e.stop()}catch{a()}})}resetAll(){this.setStick({...h}),this.sim.reset()}};async function qf(e){if(e.engine===`cesium`){let t=new Kf(e);return await t.start(),t}let{engine:t,scene:n,camera:r,renderer:i,controls:a,...o}=e,s=new yd(n,r,i,a??null);return await s.initialize(o),s}var Jf=24,Yf=.6,Xf={"pano-wide":Qf(`pano-wide`,`广角`,{bodyYawStart:-30,cols:3,bodyYawStep:30,rowPitches:[20,0,-20],finalBodyYaw:30}),"pano-180":Qf(`pano-180`,`180° 全景`,{bodyYawStart:-90,cols:7,bodyYawStep:30,rowPitches:[20,-15,-50],finalBodyYaw:90}),"pano-360":Qf(`pano-360`,`360° 全景`,{bodyYawStart:0,cols:8,bodyYawStep:45,rowPitches:sp(Jf),finalBodyYaw:0,poles:!0})},Zf=[`pano-wide`,`pano-180`,`pano-360`];function Qf(e,t,n){let r=[];n.poles&&r.push({index:r.length+1,row:0,col:0,bodyYaw:0,pitch:90});for(let e=0;e<n.cols;e+=1){let t=$f(n.bodyYawStart+e*n.bodyYawStep);n.rowPitches.forEach((i,a)=>{r.push({index:r.length+1,row:a+ +!!n.poles,col:e,bodyYaw:t,pitch:i})})}return n.poles&&r.push({index:r.length+1,row:n.rowPitches.length+1,col:0,bodyYaw:0,pitch:-90}),{mode:e,label:t,rows:n.rowPitches.length+(n.poles?2:0),cols:n.cols,rowPitches:[...n.rowPitches],bodyYawStart:n.bodyYawStart,bodyYawStep:n.bodyYawStep,finalBodyYaw:n.finalBodyYaw,shots:r,total:r.length}}function $f(e){let t=(e+180)%360-180;return t===-180?180:t}function ep(e){return(e%360+360)%360}function tp(e,t){return Math.abs((e-t+540)%360-180)}var np=.5,rp=16,ip=8e3;function ap(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}`}function op(e){return new Promise(t=>setTimeout(t,e))}function sp(e){let t=Math.max(2,Math.ceil(180/((Number.isFinite(e)?Math.max(1,Math.min(179,e)):Jf)*Yf))),n=180/t;return Array.from({length:t-1},(e,t)=>90-n*(t+1))}function cp(e){return Qf(`pano-360`,`360° 全景`,{bodyYawStart:0,cols:8,bodyYawStep:45,rowPitches:sp(e),finalBodyYaw:0,poles:!0})}var lp=class{constructor(e,t={}){i(this,`capture`,void 0),i(this,`listeners`,new Set),i(this,`options`,void 0),i(this,`token`,0),i(this,`current`,null),this.capture=e,this.options={...t}}get running(){return this.current?.state===`running`}get progress(){return this.current?{...this.current}:null}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}setStitcher(e){this.options={...this.options,stitcher:e}}static preset(e,t){return e===`pano-360`&&t!==void 0?cp(t):Xf[e]}async start(e,t){if(this.running||!this.capture.getSession(e))return null;let n=this.capture.getCaptureIntrinsics()?.verticalFovDeg,r=t===`pano-360`?cp(n??Jf):Xf[t],i=`${t}-${ap()}`,a=this.token+=1,o=0,s=r.shots[0]??{index:0,row:0,col:0,bodyYaw:0,pitch:0};this.setProgress({state:`running`,mode:t,index:0,total:r.total,row:s.row,col:s.col,bodyYaw:s.bodyYaw,pitch:s.pitch,group:i});let c=e=>(this.capture.spinBodyTo(null),this.setProgress({state:`failed`,mode:t,index:o,total:r.total,row:s.row,col:s.col,bodyYaw:s.bodyYaw,pitch:s.pitch,group:i,message:e}),{group:i,mode:t,total:r.total,captured:o,cancelled:!1,error:e}),l=this.capture.getBodyHeading();if(!this.capture.canSpinBody||l===null)return c(`当前渲染后端不支持机体原地自转,无法完成全景水平网格`);let u=-1;for(let n of r.shots){if(this.token!==a)break;if(n.col!==u){u=n.col;let e=ep(l+n.bodyYaw);this.capture.spinBodyTo(e);let t=await this.awaitHeading(e,a);if(this.token!==a)break;if(!t)return c(`机身未能转到 ${e.toFixed(0)}°(需定点悬停中再拍)`)}if(s=n,this.setProgress({state:`running`,mode:t,index:o,total:r.total,row:n.row,col:n.col,bodyYaw:n.bodyYaw,pitch:n.pitch,group:i}),await this.capture.captureVirtualImage(e,{view:{pitch:n.pitch},panorama:up(i,t,n,r.total)})&&(o+=1),this.token!==a)break;this.options.shotIntervalMs&&this.options.shotIntervalMs>0&&await op(this.options.shotIntervalMs)}let d=this.token!==a,f={group:i,mode:t,total:r.total,captured:o,cancelled:d};if(!d){let e=ep(l+r.finalBodyYaw),t=this.capture.getBodyHeading();(t===null||tp(t,e)>np)&&(this.capture.spinBodyTo(e),await this.awaitHeading(e,a))}if(this.capture.spinBodyTo(null),!d){let n=this.options.stitcher;if(n){let a=this.buildGroup(e,i,t);if(a&&a.images.length){try{f.stitched=await n.stitch(a)}catch(e){return this.setProgress({state:`done`,mode:t,index:o,total:r.total,row:s.row,col:s.col,bodyYaw:s.bodyYaw,pitch:s.pitch,group:i,message:`拼接失败:${e.message}`}),f}this.options.onStitched?.(f.stitched??null,a)}}}return this.setProgress({state:d?`cancelled`:`done`,mode:t,index:o,total:r.total,row:s.row,col:s.col,bodyYaw:s.bodyYaw,pitch:s.pitch,group:i,message:d?`已取消(完成 ${o}/${r.total})`:`完成 ${o}/${r.total}`}),f}cancel(){this.running&&(this.token+=1,this.setProgress({...this.current,state:`cancelled`}))}buildGroup(e,t,n){let r=this.capture.getSession(e);return r?{id:t,mode:n,sessionId:e,images:r.images.filter(e=>e.metadata.panorama?.group===t).sort((e,t)=>(e.metadata.panorama?.index??0)-(t.metadata.panorama?.index??0))}:null}async awaitHeading(e,t){let n=this.options.spinTimeoutMs??ip,r=Date.now()+n;for(;;){let n=this.capture.getBodyHeading();if(n!==null&&tp(n,e)<=np)return!0;if(this.token!==t||Date.now()>=r)return!1;await op(rp)}}setProgress(e){this.current=e;for(let t of this.listeners)t({...e})}};function up(e,t,n,r){return{group:e,mode:t,index:n.index,total:r,row:n.row,col:n.col,bodyYaw:n.bodyYaw,pitch:n.pitch}}var dp=120,fp=`drone-control-panel-styles`,pp=[-90,-30,-10,0],mp=.5,hp=[{value:.5,label:`0.5×`},{value:1,label:`1×`},{value:2,label:`2×`},{value:5,label:`5×`},{value:10,label:`10×`}],gp=-90,_p=60,vp=.06,yp=.14,bp=.55,xp=.6,Sp=.45,Cp=.18,wp=16,Tp=[`throttle`,`yaw`,`pitch`,`roll`],Ep={KeyW:{channel:`throttle`,sign:1},KeyS:{channel:`throttle`,sign:-1},KeyA:{channel:`yaw`,sign:-1},KeyD:{channel:`yaw`,sign:1},ArrowUp:{channel:`pitch`,sign:1},ArrowDown:{channel:`pitch`,sign:-1},ArrowLeft:{channel:`roll`,sign:-1},ArrowRight:{channel:`roll`,sign:1},KeyQ:{channel:`yaw`,sign:-1},KeyE:{channel:`yaw`,sign:1}},Dp={KeyK:`photo`,KeyL:`record`};function Op(e){let t=e;if(!t)return!1;let n=t.tagName;return n===`INPUT`||n===`TEXTAREA`||n===`SELECT`||t.isContentEditable}function kp(e){return Number.isFinite(e)?String(Number.isInteger(e)?e:Number(e.toFixed(2))):`1`}var Ap=`
|
|
35
|
+
.dcp, .dcp-sticks-float {
|
|
36
|
+
--dcp-bg: rgba(15, 19, 27, 0.84);
|
|
37
|
+
--dcp-border: rgba(255, 255, 255, 0.12);
|
|
38
|
+
--dcp-text: #e9eff9;
|
|
39
|
+
--dcp-muted: rgba(233, 239, 249, 0.58);
|
|
40
|
+
--dcp-accent: #35a7ff;
|
|
41
|
+
--dcp-on-accent: #04121f;
|
|
42
|
+
--dcp-danger: #ff5f5f;
|
|
43
|
+
--dcp-radius: 10px;
|
|
44
|
+
/* 摇杆底盘直径与杆帽直径(杆帽按底盘等比缩放,横屏/小屏会整体调) */
|
|
45
|
+
--dcp-stick: 92px;
|
|
46
|
+
--dcp-knob: calc(var(--dcp-stick) * 0.42);
|
|
47
|
+
/* 技能钮(拍照/录像)直径:跟着底盘等比缩放,但夹在可点范围内 */
|
|
48
|
+
--dcp-skill: clamp(30px, calc(var(--dcp-stick) * 0.38), 38px);
|
|
49
|
+
font: 12px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
50
|
+
user-select: none;
|
|
51
|
+
-webkit-user-select: none;
|
|
52
|
+
-webkit-tap-highlight-color: transparent;
|
|
53
|
+
overscroll-behavior: contain;
|
|
54
|
+
}
|
|
55
|
+
.dcp {
|
|
56
|
+
z-index: 20;
|
|
57
|
+
/* 264px ≈ 任务面板(dmp 262px)同宽:230px 时预设行(0.5x/1x/2x/5x/10x 五连)、
|
|
58
|
+
四联分段控件挤到文字贴边;加宽只动行内空间,高度与块间距不变 */
|
|
59
|
+
width: 264px;
|
|
60
|
+
/* 高度封顶:面板加了拍摄模式区后内容超过 HUD 安全线(右下技能钮顶边距底 215px、
|
|
61
|
+
768 高的窗口里摇杆顶边距底 169px),必须让面板在矮视口里内部滚动,而不是压住摇杆 */
|
|
62
|
+
max-height: min(66vh, 640px);
|
|
63
|
+
box-sizing: border-box;
|
|
64
|
+
display: flex;
|
|
65
|
+
flex-direction: column;
|
|
66
|
+
padding: 10px 12px 12px;
|
|
67
|
+
border: 1px solid var(--dcp-border);
|
|
68
|
+
border-radius: var(--dcp-radius);
|
|
69
|
+
background: var(--dcp-bg);
|
|
70
|
+
color: var(--dcp-text);
|
|
71
|
+
-webkit-backdrop-filter: blur(10px);
|
|
72
|
+
backdrop-filter: blur(10px);
|
|
73
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
|
|
74
|
+
}
|
|
75
|
+
/* 悬浮摇杆层:铺满容器但自身不接指针,只留轮盘/技能可点,不挡场景拖拽 */
|
|
76
|
+
.dcp-sticks-float { inset: 0; z-index: 21; pointer-events: none; }
|
|
77
|
+
.dcp[data-position="top-left"] { top: 12px; left: 12px; }
|
|
78
|
+
.dcp[data-position="top-right"] { top: 12px; right: 12px; }
|
|
79
|
+
.dcp[data-position="bottom-left"] { bottom: 12px; left: 12px; }
|
|
80
|
+
.dcp[data-position="bottom-right"] { bottom: 12px; right: 12px; }
|
|
81
|
+
.dcp button, .dcp input, .dcp-sticks-float button { touch-action: manipulation; }
|
|
82
|
+
.dcp-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
|
83
|
+
.dcp-title { flex: 1; font-weight: 600; letter-spacing: 0.02em; }
|
|
84
|
+
.dcp-icon {
|
|
85
|
+
width: 20px; height: 20px; padding: 0; line-height: 18px;
|
|
86
|
+
border: 1px solid var(--dcp-border); border-radius: 6px;
|
|
87
|
+
background: transparent; color: var(--dcp-text); cursor: pointer; font-size: 12px;
|
|
88
|
+
}
|
|
89
|
+
.dcp-icon:hover { border-color: var(--dcp-accent); color: var(--dcp-accent); }
|
|
90
|
+
.dcp-label { display: flex; justify-content: space-between; align-items: baseline; color: var(--dcp-muted); margin-bottom: 6px; }
|
|
91
|
+
.dcp-label em { font-style: normal; color: var(--dcp-text); font-variant-numeric: tabular-nums; }
|
|
92
|
+
/* 速度倍率:读数位放一个可直接输入的数字框(0~1000 的行程光靠拖滑杆到不了精确值) */
|
|
93
|
+
.dcp-speed-val { display: inline-flex; align-items: center; gap: 2px; color: var(--dcp-text); }
|
|
94
|
+
.dcp-speed-val i { font-style: normal; }
|
|
95
|
+
.dcp-num {
|
|
96
|
+
width: 56px; padding: 1px 4px; border-radius: 5px; text-align: right;
|
|
97
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.06);
|
|
98
|
+
color: var(--dcp-text); font: inherit; font-variant-numeric: tabular-nums;
|
|
99
|
+
/* 微调按钮在窄面板里太挤,且方向键已能微调,隐掉它 */
|
|
100
|
+
-moz-appearance: textfield; appearance: textfield;
|
|
101
|
+
}
|
|
102
|
+
.dcp-num:focus { outline: none; border-color: var(--dcp-accent); }
|
|
103
|
+
.dcp-num::-webkit-outer-spin-button,
|
|
104
|
+
.dcp-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
|
105
|
+
.dcp-segmented { display: flex; gap: 4px; }
|
|
106
|
+
.dcp-seg {
|
|
107
|
+
flex: 1; min-width: 0; padding: 6px 0; border-radius: 7px; cursor: pointer;
|
|
108
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.04);
|
|
109
|
+
color: var(--dcp-muted); font-size: 12px;
|
|
110
|
+
}
|
|
111
|
+
.dcp-seg:hover { color: var(--dcp-text); }
|
|
112
|
+
.dcp-seg.is-active { background: var(--dcp-accent); border-color: var(--dcp-accent); color: var(--dcp-on-accent); font-weight: 600; }
|
|
113
|
+
.dcp-wide {
|
|
114
|
+
width: 100%; margin-top: 6px; padding: 6px 0; border-radius: 7px; cursor: pointer;
|
|
115
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.04); color: var(--dcp-text); font-size: 12px;
|
|
116
|
+
}
|
|
117
|
+
.dcp-wide:hover { border-color: var(--dcp-accent); color: var(--dcp-accent); }
|
|
118
|
+
.dcp-range { width: 100%; margin: 2px 0 6px; accent-color: var(--dcp-accent); cursor: pointer; }
|
|
119
|
+
.dcp-presets { display: flex; gap: 4px; }
|
|
120
|
+
.dcp-preset {
|
|
121
|
+
flex: 1; padding: 4px 0; border-radius: 6px; cursor: pointer; font-variant-numeric: tabular-nums;
|
|
122
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.04); color: var(--dcp-muted); font-size: 11px;
|
|
123
|
+
}
|
|
124
|
+
.dcp-preset:hover { color: var(--dcp-text); border-color: var(--dcp-accent); }
|
|
125
|
+
.dcp-actions { display: flex; gap: 6px; }
|
|
126
|
+
.dcp-flight-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
|
|
127
|
+
.dcp-flight {
|
|
128
|
+
padding: 7px 0; border-radius: 7px; cursor: pointer; font-size: 12px;
|
|
129
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.06); color: var(--dcp-text);
|
|
130
|
+
}
|
|
131
|
+
.dcp-flight:hover:not(:disabled) { border-color: var(--dcp-accent); color: var(--dcp-accent); }
|
|
132
|
+
.dcp-flight:disabled { opacity: 0.32; cursor: not-allowed; }
|
|
133
|
+
.dcp-takeoff { border-color: rgba(53, 167, 255, 0.55); }
|
|
134
|
+
.dcp-rth { border-color: rgba(255, 159, 67, 0.5); }
|
|
135
|
+
.dcp-hint { margin: 6px 0 0; color: var(--dcp-muted); font-size: 11px; line-height: 1.4; }
|
|
136
|
+
.dcp-hint:empty { display: none; }
|
|
137
|
+
.dcp-note { min-height: 16px; margin: 8px 0 0; color: var(--dcp-muted); font-size: 11px; order: 7; }
|
|
138
|
+
/* 键盘键位提示(手机横屏没键盘,媒体查询里会藏掉) */
|
|
139
|
+
.dcp-keys { margin: 4px 0 0; color: var(--dcp-muted); font-size: 10px; line-height: 1.4; opacity: 0.72; order: 8; }
|
|
140
|
+
.dcp-keys:empty { display: none; }
|
|
141
|
+
.dcp-btn {
|
|
142
|
+
flex: 1; padding: 7px 0; border-radius: 7px; cursor: pointer; font-size: 12px;
|
|
143
|
+
border: 1px solid var(--dcp-border); background: rgba(255, 255, 255, 0.06); color: var(--dcp-text);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* ── 主体:竖屏纵向流式;横屏(见媒体查询)改成两列网格 ── */
|
|
147
|
+
.dcp-body {
|
|
148
|
+
display: flex;
|
|
149
|
+
flex-direction: column;
|
|
150
|
+
flex: 1;
|
|
151
|
+
min-height: 0;
|
|
152
|
+
overflow-y: auto;
|
|
153
|
+
-webkit-overflow-scrolling: touch;
|
|
154
|
+
overscroll-behavior: contain;
|
|
155
|
+
}
|
|
156
|
+
/* display:contents 让各个控制块直接成为 .dcp-body 的 flex item */
|
|
157
|
+
.dcp-mid { display: contents; }
|
|
158
|
+
.dcp-blk { display: block; }
|
|
159
|
+
.dcp-blk + .dcp-blk { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--dcp-border); }
|
|
160
|
+
|
|
161
|
+
/* ── 悬浮双轮盘(仿王者荣耀:左下移动轮盘 + 右下技能轮盘) ── */
|
|
162
|
+
.dcp-stick {
|
|
163
|
+
position: absolute; pointer-events: auto;
|
|
164
|
+
display: flex; flex-direction: column; align-items: center; gap: 4px;
|
|
165
|
+
}
|
|
166
|
+
.dcp-stick[data-stick="left"] { left: 30px; bottom: 40px; }
|
|
167
|
+
.dcp-stick[data-stick="right"] { right: 30px; bottom: 40px; }
|
|
168
|
+
.dcp-stick-base {
|
|
169
|
+
position: relative;
|
|
170
|
+
width: var(--dcp-stick); height: var(--dcp-stick);
|
|
171
|
+
border-radius: 50%;
|
|
172
|
+
border: 1px solid var(--dcp-border);
|
|
173
|
+
background: radial-gradient(circle at 50% 32%, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02) 62%, rgba(0, 0, 0, 0.22));
|
|
174
|
+
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.42), 0 6px 18px rgba(0, 0, 0, 0.3);
|
|
175
|
+
cursor: grab;
|
|
176
|
+
touch-action: none;
|
|
177
|
+
-webkit-tap-highlight-color: transparent;
|
|
178
|
+
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
179
|
+
}
|
|
180
|
+
/* 十字刻度:让"中心 / 行程极限"一眼可见 */
|
|
181
|
+
.dcp-stick-base::before,
|
|
182
|
+
.dcp-stick-base::after { content: ''; position: absolute; left: 50%; top: 50%; background: var(--dcp-border); pointer-events: none; }
|
|
183
|
+
.dcp-stick-base::before { width: calc(100% - 20px); height: 1px; transform: translate(-50%, -50%); }
|
|
184
|
+
.dcp-stick-base::after { width: 1px; height: calc(100% - 20px); transform: translate(-50%, -50%); }
|
|
185
|
+
.dcp-stick-base.is-active { cursor: grabbing; border-color: var(--dcp-accent); box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.42), inset 0 0 0 1px var(--dcp-accent), 0 6px 18px rgba(0, 0, 0, 0.3); }
|
|
186
|
+
.dcp-stick-arrow { position: absolute; color: var(--dcp-muted); font-size: 9px; line-height: 1; pointer-events: none; }
|
|
187
|
+
.dcp-stick-arrow[data-dir="up"] { top: 3px; left: 50%; transform: translateX(-50%); }
|
|
188
|
+
.dcp-stick-arrow[data-dir="down"] { bottom: 3px; left: 50%; transform: translateX(-50%); }
|
|
189
|
+
.dcp-stick-arrow[data-dir="left"] { left: 3px; top: 50%; transform: translateY(-50%); }
|
|
190
|
+
.dcp-stick-arrow[data-dir="right"] { right: 3px; top: 50%; transform: translateY(-50%); }
|
|
191
|
+
.dcp-stick-knob {
|
|
192
|
+
position: absolute; left: 50%; top: 50%;
|
|
193
|
+
width: var(--dcp-knob); height: var(--dcp-knob);
|
|
194
|
+
margin: calc(var(--dcp-knob) / -2) 0 0 calc(var(--dcp-knob) / -2);
|
|
195
|
+
border-radius: 50%;
|
|
196
|
+
background: linear-gradient(180deg, #7b8798, #414b59);
|
|
197
|
+
border: 1px solid rgba(255, 255, 255, 0.24);
|
|
198
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
|
|
199
|
+
transition: transform 0.14s ease-out;
|
|
200
|
+
will-change: transform;
|
|
201
|
+
}
|
|
202
|
+
/* 按住时去掉回中动画,否则跟手会有一帧迟滞 */
|
|
203
|
+
.dcp-stick-base.is-active .dcp-stick-knob { transition: none; }
|
|
204
|
+
/* 键盘驱动:行程每 ~16ms 刷一次,过渡会拖在键位后面,同样去掉 */
|
|
205
|
+
.dcp-stick.is-keyboard .dcp-stick-knob { transition: none; }
|
|
206
|
+
.dcp-stick-cap { color: var(--dcp-muted); font-size: 10px; line-height: 1.25; text-align: center; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }
|
|
207
|
+
.dcp-stick-read { color: var(--dcp-muted); font-size: 10px; font-variant-numeric: tabular-nums; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }
|
|
208
|
+
.dcp-stick.is-active .dcp-stick-cap { color: var(--dcp-text); }
|
|
209
|
+
.dcp-stick.is-active .dcp-stick-read { color: var(--dcp-accent); }
|
|
210
|
+
|
|
211
|
+
/* ── 技能按钮(拍照/录像):坐在右轮盘正上方的技能位,不压盘面 ── */
|
|
212
|
+
/* 技能容器:贴着底盘上沿(底边 = 底盘顶边 + 7px 间距),整体居中,两枚按钮左右排开。
|
|
213
|
+
用 bottom:100% 而不是负 top 偏移 —— 无论底盘放大到 100px 还是缩到 56px,
|
|
214
|
+
按钮永远在轮盘外,不会再盖住盘面;容器自身不接指针,点击只落在按钮上 */
|
|
215
|
+
.dcp-skills {
|
|
216
|
+
position: absolute; left: 50%; bottom: 100%;
|
|
217
|
+
transform: translateX(-50%);
|
|
218
|
+
margin-bottom: 7px;
|
|
219
|
+
display: flex; align-items: flex-end; gap: 7px;
|
|
220
|
+
pointer-events: none;
|
|
221
|
+
}
|
|
222
|
+
.dcp-skill {
|
|
223
|
+
position: relative; z-index: 2;
|
|
224
|
+
width: var(--dcp-skill); height: var(--dcp-skill); padding: 0;
|
|
225
|
+
border-radius: 50%; cursor: pointer; pointer-events: auto;
|
|
226
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
|
|
227
|
+
border: 1.5px solid rgba(53, 167, 255, 0.6);
|
|
228
|
+
background: radial-gradient(circle at 50% 30%, rgba(53, 167, 255, 0.32), rgba(8, 18, 30, 0.92) 72%);
|
|
229
|
+
color: var(--dcp-text);
|
|
230
|
+
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.42);
|
|
231
|
+
transition: transform 0.1s ease, border-color 0.15s ease;
|
|
232
|
+
}
|
|
233
|
+
.dcp-skill:hover { border-color: var(--dcp-accent); }
|
|
234
|
+
.dcp-skill:active { transform: scale(0.92); }
|
|
235
|
+
/* 错开一格高度,斜向弧形排布(拍照左下 / 录像右上),不靠 transform 免得和按下态打架 */
|
|
236
|
+
.dcp-skill-rec {
|
|
237
|
+
margin-bottom: 5px;
|
|
238
|
+
border-color: rgba(255, 159, 67, 0.6); background: radial-gradient(circle at 50% 30%, rgba(255, 159, 67, 0.3), rgba(26, 16, 6, 0.92) 72%);
|
|
239
|
+
}
|
|
240
|
+
.dcp-skill-rec:hover { border-color: #ffb267; }
|
|
241
|
+
.dcp-skill-ico { font-size: 13px; line-height: 1; }
|
|
242
|
+
.dcp-skill-lbl { font-size: 8px; line-height: 1.1; letter-spacing: 0.02em; }
|
|
243
|
+
.dcp-skill-badge {
|
|
244
|
+
position: absolute; right: -5px; top: -5px;
|
|
245
|
+
min-width: 15px; padding: 0 3px; border-radius: 8px;
|
|
246
|
+
background: var(--dcp-accent); color: var(--dcp-on-accent);
|
|
247
|
+
font-size: 8px; line-height: 13px; font-weight: 700; font-variant-numeric: tabular-nums;
|
|
248
|
+
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
|
|
249
|
+
display: none;
|
|
250
|
+
}
|
|
251
|
+
.dcp-skill-badge:not(:empty) { display: block; }
|
|
252
|
+
.dcp-skill-rec .dcp-skill-badge { background: #ff9f43; color: #241300; }
|
|
253
|
+
.dcp-ico-rec { width: 10px; height: 10px; border-radius: 50%; background: #ff5f5f; box-shadow: 0 0 0 2px rgba(255, 95, 95, 0.28); }
|
|
254
|
+
.dcp-skill-rec.is-recording { border-color: var(--dcp-danger); }
|
|
255
|
+
.dcp-skill-rec.is-recording .dcp-ico-rec { animation: dcp-rec-pulse 1s ease-in-out infinite; }
|
|
256
|
+
@keyframes dcp-rec-pulse {
|
|
257
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
258
|
+
50% { opacity: 0.45; transform: scale(0.8); }
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* ── 手机横屏:面板贴底居中、嵌在左右轮盘之间(上方画面全留给取景),紧凑两列卡片 ── */
|
|
262
|
+
@media (orientation: landscape) and (max-height: 620px) {
|
|
263
|
+
/* 面板与悬浮轮盘共用同一杆径基准:面板左右偏移按它算,才能刚好让开轮盘和技能 */
|
|
264
|
+
.dcp[data-adaptive="true"],
|
|
265
|
+
.dcp-sticks-float[data-adaptive="true"] { --dcp-stick: clamp(64px, 22vh, 100px); }
|
|
266
|
+
.dcp[data-adaptive="true"][data-position] {
|
|
267
|
+
top: auto; bottom: 8px;
|
|
268
|
+
left: calc(var(--dcp-stick) + 62px);
|
|
269
|
+
right: calc(var(--dcp-stick) + 62px);
|
|
270
|
+
width: auto; max-width: none;
|
|
271
|
+
padding: 5px 9px 6px;
|
|
272
|
+
font-size: 11px;
|
|
273
|
+
}
|
|
274
|
+
.dcp[data-adaptive="true"] .dcp-head { margin-bottom: 3px; }
|
|
275
|
+
.dcp[data-adaptive="true"] .dcp-title { font-size: 11px; }
|
|
276
|
+
.dcp[data-adaptive="true"] .dcp-body {
|
|
277
|
+
display: grid;
|
|
278
|
+
grid-template-columns: 1fr 1fr;
|
|
279
|
+
gap: 4px 10px;
|
|
280
|
+
align-content: start;
|
|
281
|
+
max-height: 52vh;
|
|
282
|
+
overflow-y: auto;
|
|
283
|
+
-webkit-overflow-scrolling: touch;
|
|
284
|
+
}
|
|
285
|
+
/* 横屏藏提示条(技能角标已承载拍照/录像反馈),把高度让给场景 */
|
|
286
|
+
.dcp[data-adaptive="true"] .dcp-note,
|
|
287
|
+
.dcp[data-adaptive="true"] .dcp-keys { display: none; }
|
|
288
|
+
.dcp[data-adaptive="true"] .dcp-blk {
|
|
289
|
+
margin-top: 0; padding: 4px 6px; border-top: none;
|
|
290
|
+
background: rgba(255, 255, 255, 0.03); border-radius: 8px;
|
|
291
|
+
}
|
|
292
|
+
/* 触控热区在横屏适度收窄:34px 会顶满屏高,28px 仍大于手指容差 */
|
|
293
|
+
.dcp[data-adaptive="true"] .dcp-seg,
|
|
294
|
+
.dcp[data-adaptive="true"] .dcp-wide,
|
|
295
|
+
.dcp[data-adaptive="true"] .dcp-flight,
|
|
296
|
+
.dcp[data-adaptive="true"] .dcp-btn,
|
|
297
|
+
.dcp[data-adaptive="true"] .dcp-preset { min-height: 28px; padding: 4px 0; font-size: 11px; }
|
|
298
|
+
.dcp[data-adaptive="true"] .dcp-label { margin-bottom: 3px; white-space: nowrap; }
|
|
299
|
+
.dcp[data-adaptive="true"] .dcp-label em { min-width: 0; overflow: hidden; }
|
|
300
|
+
.dcp[data-adaptive="true"] .dcp-seg,
|
|
301
|
+
.dcp[data-adaptive="true"] .dcp-wide { white-space: nowrap; overflow: hidden; }
|
|
302
|
+
.dcp[data-adaptive="true"] .dcp-flight-grid { grid-template-columns: repeat(3, 1fr); gap: 4px; }
|
|
303
|
+
.dcp[data-adaptive="true"] .dcp-segmented { gap: 3px; }
|
|
304
|
+
.dcp[data-adaptive="true"] .dcp-presets { gap: 3px; }
|
|
305
|
+
.dcp[data-adaptive="true"] .dcp-hint { margin: 3px 0 0; font-size: 10px; }
|
|
306
|
+
.dcp[data-adaptive="true"] .dcp-range { margin: 0 0 4px; }
|
|
307
|
+
|
|
308
|
+
.dcp-sticks-float[data-adaptive="true"] .dcp-stick[data-stick="left"] { left: 20px; bottom: 26px; }
|
|
309
|
+
.dcp-sticks-float[data-adaptive="true"] .dcp-stick[data-stick="right"] { right: 20px; bottom: 26px; }
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* ── 小屏横屏(如 iPhone SE):列宽吃紧,再降一档字号与杆径 ── */
|
|
313
|
+
@media (orientation: landscape) and (max-height: 620px) and (max-width: 700px) {
|
|
314
|
+
.dcp[data-adaptive="true"],
|
|
315
|
+
.dcp-sticks-float[data-adaptive="true"] { --dcp-stick: clamp(56px, 20vh, 84px); }
|
|
316
|
+
.dcp[data-adaptive="true"] .dcp-seg,
|
|
317
|
+
.dcp[data-adaptive="true"] .dcp-wide,
|
|
318
|
+
.dcp[data-adaptive="true"] .dcp-flight,
|
|
319
|
+
.dcp[data-adaptive="true"] .dcp-btn,
|
|
320
|
+
.dcp[data-adaptive="true"] .dcp-preset { font-size: 10px; }
|
|
321
|
+
.dcp[data-adaptive="true"] .dcp-label { font-size: 10px; }
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* ── 手机竖屏:面板收一点宽度,轮盘略缩 ── */
|
|
325
|
+
@media (max-width: 560px) and (orientation: portrait) {
|
|
326
|
+
.dcp[data-adaptive="true"] { width: min(86vw, 246px); }
|
|
327
|
+
.dcp-sticks-float[data-adaptive="true"] { --dcp-stick: 84px; }
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/* ── 触控设备:把点击热区抬到 34px 以上,避免误触(技能钮只放到上限,不再撑大) ── */
|
|
331
|
+
@media (pointer: coarse) {
|
|
332
|
+
.dcp-seg, .dcp-wide, .dcp-flight, .dcp-btn, .dcp-preset { min-height: 34px; }
|
|
333
|
+
.dcp, .dcp-sticks-float { --dcp-skill: clamp(34px, calc(var(--dcp-stick) * 0.4), 40px); }
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* 折叠 / 展开放最后:横屏那条 .dcp-body{display:grid} 与它同权重,靠源码顺序压过去 */
|
|
337
|
+
.dcp[data-collapsed="true"] .dcp-body { display: none; }
|
|
338
|
+
`;function jp(){if(typeof document>`u`||document.getElementById(fp))return;let e=document.createElement(`style`);e.id=fp,e.textContent=Ap,document.head.appendChild(e)}function Mp(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return e.replace(/[&<>"']/g,e=>t[e]??e)}function Np(e,t){let n=document.createElement(`a`);n.href=e,n.download=t,n.rel=`noopener`,document.body.appendChild(n),n.click(),n.remove()}function Pp(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}`}function Fp(e,t){return t<=0?e:Math.abs(e)<=t?0:(e-Math.sign(e)*t)/(1-t)}function Ip(e,t){if(t<=0)return e;let n=Math.min(.95,Math.max(0,t)),r=Math.abs(e);return Math.sign(e)*(n*r**3+(1-n)*r)}function Lp(e){return Math.max(-1,Math.min(1,e))}function Rp(e,t){if(Math.abs(e)<.005&&Math.abs(t)<.005)return`居中`;let n=(e,t,n)=>Math.abs(e)<.005?`·0.00`:`${e>0?t:n}${Math.abs(e).toFixed(2)}`;return`${n(e,`↑`,`↓`)} ${n(t,`→`,`←`)}`}var zp=class{constructor(e,t={}){if(i(this,`root`,void 0),i(this,`hudLayer`,void 0),i(this,`fly`,void 0),i(this,`opts`,void 0),i(this,`presets`,void 0),i(this,`container`,void 0),i(this,`abort`,new AbortController),i(this,`deadzone`,void 0),i(this,`lateralDeadzone`,void 0),i(this,`expo`,void 0),i(this,`yawRateScale`,void 0),i(this,`keyboardEnabled`,void 0),i(this,`keyboardRise`,void 0),i(this,`keyboardFall`,void 0),i(this,`pressedKeys`,new Set),i(this,`keyboardStick`,{throttle:0,yaw:0,pitch:0,roll:0}),i(this,`keyboardTimer`,null),i(this,`lastKeyboardTick`,0),i(this,`sticks`,[]),i(this,`refs`,void 0),i(this,`timer`,null),i(this,`pitchDragging`,!1),i(this,`speedDragging`,!1),i(this,`photoBusy`,!1),i(this,`visible`,void 0),i(this,`collapsed`,!1),i(this,`destroyed`,!1),i(this,`lastRecordSeconds`,0),i(this,`panorama`,null),i(this,`panoramaUnsub`,null),i(this,`shootMode`,`single`),i(this,`panoProgress`,null),typeof document>`u`)throw Error(`[drone-camera] DroneControlPanel 需要浏览器环境(document),Node 侧请勿实例化`);this.fly=e,this.opts=t,this.presets=t.pitchPresets??pp,this.deadzone=t.stickDeadzone??vp,this.lateralDeadzone=t.stickLateralDeadzone??yp,this.expo=t.stickExpo??bp,this.yawRateScale=Math.max(0,Math.min(1,t.yawRateScale??xp)),this.keyboardEnabled=t.keyboard!==!1,this.keyboardRise=Math.max(.02,t.keyboardRiseSeconds??Sp),this.keyboardFall=Math.max(.02,t.keyboardFallSeconds??Cp),this.container=t.container??document.body,this.visible=t.visible??!0,t.injectStyles!==!1&&jp(),t.captureService&&t.panorama!==!1&&(this.panorama=new lp(t.captureService,{shotIntervalMs:t.panoramaShotIntervalMs??dp}));let n=t.container??null;n&&getComputedStyle(n).position===`static`&&(n.style.position=`relative`);let r=n?`absolute`:`fixed`;this.root=document.createElement(`div`),this.root.className=`dcp`,this.root.dataset.position=t.position??`top-right`,this.root.dataset.adaptive=String(t.adaptive!==!1),this.root.style.position=r,this.root.innerHTML=this.template(),this.visible||(this.root.style.display=`none`),this.hudLayer=document.createElement(`div`),this.hudLayer.className=`dcp-sticks-float`,this.hudLayer.dataset.adaptive=this.root.dataset.adaptive,this.hudLayer.style.position=r,this.hudLayer.innerHTML=this.hudTemplate(),this.visible||(this.hudLayer.style.display=`none`),this.refs={modeLabel:this.query(`[data-role="mode-label"]`),flightState:this.query(`[data-role="flight-state"]`),powerButton:this.query(`[data-role="power"]`),takeoffButton:this.query(`[data-role="takeoff"]`),landButton:this.query(`[data-role="land"]`),rthButton:this.query(`[data-role="rth"]`),armDeployButton:this.query(`[data-role="arm-deploy"]`),armFoldButton:this.query(`[data-role="arm-fold"]`),flightModeLabel:this.query(`[data-role="flight-mode-label"]`),speedSlider:this.query(`[data-role="speed-scale"]`),speedInput:this.query(`[data-role="speed-scale-input"]`),preflight:this.query(`[data-role="preflight"]`),pitchSlider:this.query(`[data-role="pitch"]`),pitchValue:this.query(`[data-role="pitch-value"]`),photoCount:this.queryIn(this.hudLayer,`[data-role="photo-count"]`),recordButton:this.queryIn(this.hudLayer,`[data-role="toggle-record"]`),recTime:this.queryIn(this.hudLayer,`[data-role="rec-time"]`),note:this.query(`[data-role="note"]`),shootLabel:this.root.querySelector(`[data-role="shoot-label"]`)},this.sticks=this.collectSticks(),this.panorama&&(this.panoramaUnsub=this.panorama.subscribe(e=>{this.panoProgress=e,this.syncShootMode(),this.syncHudBadge()})),this.bind(),this.sync(),this.mount()}mount(){return!this.destroyed&&!this.root.isConnected&&this.container.appendChild(this.root),!this.destroyed&&!this.hudLayer.isConnected&&this.container.appendChild(this.hudLayer),this}unmount(){return this.root.remove(),this.hudLayer.remove(),this}setVisible(e){return this.visible=e,this.root.style.display=e?``:`none`,this.hudLayer.style.display=e?``:`none`,this}isVisible(){return this.visible}setCollapsed(e){return this.collapsed=e,this.root.dataset.collapsed=String(e),this}destroy(){this.destroyed||(this.destroyed=!0,this.stopKeyboard(),this.releaseKeyboard(),this.releaseSticks(),this.abort.abort(),this.stopTimer(),this.panorama?.cancel(),this.panoramaUnsub?.(),this.panoramaUnsub=null,this.root.remove(),this.hudLayer.remove())}static removeInjectedStyles(){typeof document<`u`&&document.getElementById(fp)?.remove()}sync(){if(this.destroyed)return;let e=this.fly,t=e.phase;this.refs.flightState.textContent=`${p[t]??t} · ${e.altitude.toFixed(1)} m`;let n=t===`powerOff`||t===`stopped`;this.refs.powerButton.disabled=!n,this.refs.takeoffButton.disabled=t!==`standby`&&t!==`motorsOn`,this.refs.landButton.disabled=!(e.airborne||t===`takingOff`),this.refs.rthButton.disabled=!(e.airborne&&t!==`rth`);let r=e.armsFolded;this.refs.armDeployButton.disabled=!r,this.refs.armFoldButton.disabled=r||e.airborne;let i=e.preflightChecks.filter(e=>e.blocking&&!e.ok);this.refs.preflight.textContent=i.length?`待通过:${i.map(e=>e.label).join(`、`)}`:``,this.refs.preflight.title=i.map(e=>`${e.label}:${e.detail}`).join(`
|
|
339
|
+
`);let a=e.flightMode;this.refs.flightModeLabel.textContent=s.find(e=>e.key===a)?.label??a,this.root.querySelectorAll(`[data-action="set-flight-mode"]`).forEach(e=>{e.classList.toggle(`is-active`,e.dataset.mode===a)}),this.renderSpeedScale(e.sim.speedScale);let o=e.cameraMode;if(this.refs.modeLabel.textContent=$u.find(e=>e.key===o)?.label??o,this.root.querySelectorAll(`[data-action="set-mode"]`).forEach(e=>{e.classList.toggle(`is-active`,e.dataset.mode===o)}),!this.pitchDragging){let t=Math.round(e.sim.gimbalPitch);this.refs.pitchSlider.value=String(t),this.renderPitch(t)}this.syncStickReadout(),this.syncShootMode(),this.syncHudBadge()}syncHudBadge(){let e=this.fly,t=this.panoProgress;this.refs.photoCount.textContent=t?.state===`running`?`${t.index}/${t.total}`:e.sim.photoCount>0?String(e.sim.photoCount):``;let n=e.isRecording;this.refs.recordButton.classList.toggle(`is-recording`,n),this.refs.recTime.textContent=n?`${e.sim.recordSeconds.toFixed(0)}s`:``}syncShootMode(){if(!this.panorama)return;let e=this.panorama.running;this.root.querySelectorAll(`[data-action="set-shoot-mode"]`).forEach(t=>{let n=t.dataset.mode===this.shootMode;t.classList.toggle(`is-active`,n),t.toggleAttribute(`disabled`,e&&!n)});let t=this.refs.shootLabel;if(!t)return;let n=this.panoProgress,r=this.shootMode===`single`?null:lp.preset(this.shootMode,this.opts.captureService?.getCaptureIntrinsics()?.verticalFovDeg);t.textContent=n&&n.mode===this.shootMode&&n.state!==`idle`?`${n.state===`running`?`扫描中`:n.state===`done`?`完成`:n.state===`failed`?`未完成`:`已停止`} ${n.index}/${n.total}`:r?`${r.total} 张`:`单张`}query(e){return this.queryIn(this.root,e)}queryIn(e,t){let n=e.querySelector(t);if(!n)throw Error(`[drone-camera] 面板结构缺失:${t}`);return n}template(){let e=$u.map(e=>`<button type="button" class="dcp-seg" data-action="set-mode" data-mode="${e.key}">${e.label}</button>`).join(``),t=this.presets.map(e=>`<button type="button" class="dcp-preset" data-action="preset-pitch" data-pitch="${e}">${e}°</button>`).join(``),n=s.map(e=>`<button type="button" class="dcp-seg" data-action="set-flight-mode" data-mode="${e.key}">${e.label}</button>`).join(``),r=hp.map(e=>`<button type="button" class="dcp-preset" data-action="preset-speed" data-scale="${e.value}">${e.label}</button>`).join(``),i=this.panorama?`<section class="dcp-blk" data-blk="shoot">
|
|
340
|
+
<div class="dcp-label">拍摄模式<em data-role="shoot-label">单张</em></div>
|
|
341
|
+
<div class="dcp-segmented">
|
|
342
|
+
<button type="button" class="dcp-seg is-active" data-action="set-shoot-mode" data-mode="single">单张</button>
|
|
343
|
+
${Zf.map(e=>`<button type="button" class="dcp-seg" data-action="set-shoot-mode" data-mode="${e}">${Xf[e].label}</button>`).join(``)}
|
|
344
|
+
</div>
|
|
345
|
+
<p class="dcp-hint">悬停中拍摄:广角 3×3、180° 分层扫描、球形 360° 另补天顶/天底。</p>
|
|
346
|
+
</section>`:``;return`
|
|
347
|
+
<div class="dcp-head">
|
|
348
|
+
<span class="dcp-title">${Mp(this.opts.title??`无人机`)}</span>
|
|
349
|
+
<button type="button" class="dcp-icon" data-action="toggle-collapse" title="收起 / 展开" aria-label="收起或展开">–</button>
|
|
350
|
+
</div>
|
|
351
|
+
<div class="dcp-body">
|
|
352
|
+
<div class="dcp-mid">
|
|
353
|
+
<section class="dcp-blk" data-blk="flight">
|
|
354
|
+
<div class="dcp-label">飞行状态<em data-role="flight-state">--</em></div>
|
|
355
|
+
<div class="dcp-flight-grid">
|
|
356
|
+
<button type="button" class="dcp-flight" data-action="power-on" data-role="power">上电</button>
|
|
357
|
+
<button type="button" class="dcp-flight dcp-takeoff" data-action="takeoff" data-role="takeoff">起飞</button>
|
|
358
|
+
<button type="button" class="dcp-flight" data-action="land" data-role="land">降落</button>
|
|
359
|
+
<button type="button" class="dcp-flight dcp-rth" data-action="rth" data-role="rth">返航</button>
|
|
360
|
+
<button type="button" class="dcp-flight" data-action="arm-deploy" data-role="arm-deploy">展开机臂</button>
|
|
361
|
+
<button type="button" class="dcp-flight" data-action="arm-fold" data-role="arm-fold">收拢机臂</button>
|
|
362
|
+
</div>
|
|
363
|
+
<p class="dcp-hint" data-role="preflight"></p>
|
|
364
|
+
</section>
|
|
365
|
+
|
|
366
|
+
<section class="dcp-blk" data-blk="mode">
|
|
367
|
+
<div class="dcp-label">飞行模式<em data-role="flight-mode-label">--</em></div>
|
|
368
|
+
<div class="dcp-segmented">${n}</div>
|
|
369
|
+
</section>
|
|
370
|
+
|
|
371
|
+
<section class="dcp-blk" data-blk="speed">
|
|
372
|
+
<div class="dcp-label">
|
|
373
|
+
速度倍率
|
|
374
|
+
<span class="dcp-speed-val">
|
|
375
|
+
<input class="dcp-num" type="number" data-role="speed-scale-input"
|
|
376
|
+
min="0" max="${l}" step="${mp}"
|
|
377
|
+
value="${kp(1)}" title="0 ~ ${l},数值即倍数(1 = 真机原速)" />
|
|
378
|
+
<i>×</i>
|
|
379
|
+
</span>
|
|
380
|
+
</div>
|
|
381
|
+
<input class="dcp-range" type="range" data-role="speed-scale"
|
|
382
|
+
min="0" max="${l}" step="${mp}"
|
|
383
|
+
value="${kp(1)}" title="左右拖动;0 = 机体不动,1 = 真机原速" />
|
|
384
|
+
<div class="dcp-presets">${r}</div>
|
|
385
|
+
</section>
|
|
386
|
+
|
|
387
|
+
<section class="dcp-blk" data-blk="camera">
|
|
388
|
+
<div class="dcp-label">相机视角<em data-role="mode-label">--</em></div>
|
|
389
|
+
<div class="dcp-segmented">${e}</div>
|
|
390
|
+
<button type="button" class="dcp-wide" data-action="reset-camera">复位观察视角</button>
|
|
391
|
+
</section>
|
|
392
|
+
|
|
393
|
+
<section class="dcp-blk" data-blk="gimbal">
|
|
394
|
+
<div class="dcp-label">云台俯仰<em data-role="pitch-value">--</em></div>
|
|
395
|
+
<input class="dcp-range" type="range" data-role="pitch" min="${gp}" max="${_p}" step="1" value="-10" />
|
|
396
|
+
<div class="dcp-presets">${t}</div>
|
|
397
|
+
</section>
|
|
398
|
+
|
|
399
|
+
${i}
|
|
400
|
+
</div>
|
|
401
|
+
<p class="dcp-note" data-role="note"></p>
|
|
402
|
+
<p class="dcp-keys">${this.keyboardEnabled?`键盘 W/S 升降 · A/D 转向 · ↑/↓ 前后 · ←/→ 横滚 · Ctrl+K 拍照 · Ctrl+L 录像`:``}</p>
|
|
403
|
+
</div>
|
|
404
|
+
`}hudTemplate(){return`
|
|
405
|
+
${this.stickTemplate(`left`,`左杆 · 升降/偏航`,[[`up`,`升`],[`down`,`降`],[`left`,`左转`],[`right`,`右转`]])}
|
|
406
|
+
<div class="dcp-stick" data-stick="right" title="右杆:上下前后、左右横滚(美国手 Mode 2),松杆自动回中">
|
|
407
|
+
<div class="dcp-stick-base">
|
|
408
|
+
<span class="dcp-stick-arrow" data-dir="up">前</span>
|
|
409
|
+
<span class="dcp-stick-arrow" data-dir="down">后</span>
|
|
410
|
+
<span class="dcp-stick-arrow" data-dir="left">左移</span>
|
|
411
|
+
<span class="dcp-stick-arrow" data-dir="right">右移</span>
|
|
412
|
+
<div class="dcp-stick-knob"></div>
|
|
413
|
+
<div class="dcp-skills">
|
|
414
|
+
<button type="button" class="dcp-skill dcp-skill-photo" data-action="photo" title="拍照">
|
|
415
|
+
<span class="dcp-skill-ico">📷</span>
|
|
416
|
+
<span class="dcp-skill-lbl">拍照</span>
|
|
417
|
+
<span class="dcp-skill-badge" data-role="photo-count"></span>
|
|
418
|
+
</button>
|
|
419
|
+
<button type="button" class="dcp-skill dcp-skill-rec" data-action="toggle-record" data-role="toggle-record" title="开始 / 停止录像">
|
|
420
|
+
<span class="dcp-skill-ico dcp-ico-rec"></span>
|
|
421
|
+
<span class="dcp-skill-lbl">录像</span>
|
|
422
|
+
<span class="dcp-skill-badge" data-role="rec-time"></span>
|
|
423
|
+
</button>
|
|
424
|
+
</div>
|
|
425
|
+
</div>
|
|
426
|
+
<span class="dcp-stick-cap">右杆 · 前后/横滚</span>
|
|
427
|
+
<span class="dcp-stick-read" data-role="stick-read">居中</span>
|
|
428
|
+
</div>
|
|
429
|
+
`}stickTemplate(e,t,n){let r=n.map(([e,t])=>`<span class="dcp-stick-arrow" data-dir="${e}">${t}</span>`).join(``);return`
|
|
430
|
+
<div class="dcp-stick" data-stick="${e}" title="${e===`left`?`左杆:上下升降、左右偏航(美国手 Mode 2),松杆自动回中`:`右杆:上下前后、左右横滚(美国手 Mode 2),松杆自动回中`}">
|
|
431
|
+
<div class="dcp-stick-base">
|
|
432
|
+
${r}
|
|
433
|
+
<div class="dcp-stick-knob"></div>
|
|
434
|
+
</div>
|
|
435
|
+
<span class="dcp-stick-cap">${t}</span>
|
|
436
|
+
<span class="dcp-stick-read" data-role="stick-read">居中</span>
|
|
437
|
+
</div>
|
|
438
|
+
`}collectSticks(){return Array.from(this.hudLayer.querySelectorAll(`.dcp-stick`)).map(e=>{let t=e.querySelector(`.dcp-stick-base`),n=e.querySelector(`.dcp-stick-knob`),r=e.querySelector(`[data-role="stick-read"]`);if(!t||!n||!r)throw Error(`[drone-camera] 面板摇杆结构缺失`);return{side:e.dataset.stick,root:e,base:t,knob:n,read:r,pointerId:null,vertical:0,lateral:0,radius:0,radiusSpan:0}})}bindActionDelegate(e){e.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-action]`);t&&this.handleAction(t.dataset.action??``,t)},{signal:this.abort.signal})}bind(){let{signal:e}=this.abort;this.bindActionDelegate(this.root),this.bindActionDelegate(this.hudLayer);let t=this.refs.pitchSlider;t.addEventListener(`input`,()=>{let e=Number(t.value);this.fly.setGimbalPitch(e),this.renderPitch(e)},{signal:e}),t.addEventListener(`pointerdown`,()=>this.pitchDragging=!0,{signal:e}),window.addEventListener(`pointerup`,()=>this.pitchDragging=!1,{signal:e});let n=this.refs.speedSlider;n.addEventListener(`input`,()=>this.applySpeedScale(n.value),{signal:e}),n.addEventListener(`pointerdown`,()=>this.speedDragging=!0,{signal:e}),window.addEventListener(`pointerup`,()=>this.speedDragging=!1,{signal:e});let r=this.refs.speedInput;r.addEventListener(`input`,()=>{r.value.trim()!==``&&this.applySpeedScale(r.value)},{signal:e}),r.addEventListener(`change`,()=>{r.value=kp(this.fly.sim.speedScale),this.sync()},{signal:e}),this.hudLayer.addEventListener(`pointerdown`,e=>this.startStick(e),{signal:e}),window.addEventListener(`pointermove`,e=>this.moveStick(e),{signal:e}),window.addEventListener(`pointerup`,e=>this.endStick(e),{signal:e}),window.addEventListener(`pointercancel`,e=>this.endStick(e),{signal:e}),this.bindKeyboard(),this.opts.syncIntervalMs!==0&&(this.timer=window.setInterval(()=>this.sync(),this.opts.syncIntervalMs??200))}startStick(e){let t=e.target;if(t?.closest(`.dcp-skill`))return;let n=t?.closest(`.dcp-stick-base`);if(!n)return;let r=this.sticks.find(e=>e.base===n);if(r){e.preventDefault(),r.pointerId=e.pointerId,r.root.classList.add(`is-active`);try{r.base.setPointerCapture(e.pointerId)}catch{}this.updateStick(r,e.clientX,e.clientY)}}moveStick(e){let t=this.sticks.find(t=>t.pointerId===e.pointerId);t&&(e.preventDefault(),this.updateStick(t,e.clientX,e.clientY))}endStick(e){let t=this.sticks.find(t=>t.pointerId===e.pointerId);t&&this.resetStick(t)}updateStick(e,t,n){let r=e.base.getBoundingClientRect(),i=Math.max(1,(r.width-e.knob.offsetWidth)/2),a=t-(r.left+r.width/2),o=n-(r.top+r.height/2),s=Math.hypot(a,o);if(s>i){let e=i/s;a*=e,o*=e}e.knob.style.transform=`translate(${a.toFixed(1)}px, ${o.toFixed(1)}px)`;let c=Ip(Fp(-o/i,this.deadzone),this.expo),l=Ip(Fp(a/i,this.lateralDeadzone),this.expo);e.vertical=c,e.lateral=l,this.applyStick(),e.read.textContent=Rp(c,l)}resetStick(e){e.pointerId=null,e.root.classList.remove(`is-active`,`is-keyboard`),e.knob.style.transform=``,e.vertical=0,e.lateral=0,this.applyStick(),e.read.textContent=Rp(0,0),this.syncKeyboardVisuals()}syncKeyboardVisuals(){if(this.destroyed)return;let e=this.keyboardStick;for(let t of this.sticks){if(t.pointerId!==null)continue;let n=t.side===`left`?e.throttle:e.pitch,r=t.side===`left`?e.yaw:e.roll,i=Math.abs(n)>.005||Math.abs(r)>.005;this.paintStick(t,n,r,i)}}paintStick(e,t,n,r){let i=e.base.offsetWidth;i!==e.radiusSpan&&(e.radiusSpan=i,e.radius=Math.max(1,(i-e.knob.offsetWidth)/2));let a=Lp(n)*e.radius,o=-Lp(t)*e.radius;e.knob.style.transform=`translate(${a.toFixed(1)}px, ${o.toFixed(1)}px)`,e.root.classList.toggle(`is-keyboard`,r),e.root.classList.toggle(`is-active`,r),e.read.textContent=Rp(t,n)}applyStick(){if(this.destroyed)return;let e=this.sticks.find(e=>e.side===`left`),t=this.sticks.find(e=>e.side===`right`),n=e=>e!=null&&e.pointerId!==null,r=this.keyboardStick,i=n(e)?e.vertical:r.throttle,a=n(e)?e.lateral:r.yaw,o=n(t)?t.vertical:r.pitch,s=n(t)?t.lateral:r.roll;this.fly.setStick({throttle:Lp(i),pitch:Lp(o),roll:Lp(s),yaw:Lp(a)*this.yawRateScale})}bindKeyboard(){if(!this.keyboardEnabled)return;let{signal:e}=this.abort;window.addEventListener(`keydown`,e=>this.onKey(e,!0),{signal:e}),window.addEventListener(`keyup`,e=>this.onKey(e,!1),{signal:e}),window.addEventListener(`blur`,()=>this.releaseKeyboard(),{signal:e}),this.lastKeyboardTick=performance.now(),this.keyboardTimer=window.setInterval(()=>this.tickKeyboard(),wp)}onKey(e,t){if(!Op(e.target)){if(e.ctrlKey||e.metaKey){let n=Dp[e.code];if(!n||(e.preventDefault(),!t||e.repeat||e.altKey))return;this.runShortcut(n)}else Ep[e.code]&&(e.altKey||(t?this.pressedKeys.add(e.code):this.pressedKeys.delete(e.code),e.preventDefault()))}}runShortcut(e){this.destroyed||(e===`photo`?this.takePhoto():this.toggleRecording())}tickKeyboard(){if(this.destroyed)return;let e=performance.now(),t=Math.min(.1,Math.max(0,(e-this.lastKeyboardTick)/1e3));if(this.lastKeyboardTick=e,t<=0)return;let n={throttle:0,yaw:0,pitch:0,roll:0};for(let e of this.pressedKeys){let t=Ep[e];t&&(n[t.channel]=Lp(n[t.channel]+t.sign))}let r=!1;for(let e of Tp){let i=this.keyboardStick[e],a=n[e];if(i===a)continue;let o=t/(a===0?this.keyboardFall:this.keyboardRise),s=Math.abs(a-i)<=o?a:i+Math.sign(a-i)*o;this.keyboardStick[e]=s,r=!0}r&&(this.applyStick(),this.syncKeyboardVisuals())}releaseKeyboard(){this.pressedKeys.clear();let e=!1;for(let t of Tp)this.keyboardStick[t]!==0&&(this.keyboardStick[t]=0,e=!0);e&&(this.applyStick(),this.syncKeyboardVisuals())}stopKeyboard(){this.keyboardTimer!==null&&(window.clearInterval(this.keyboardTimer),this.keyboardTimer=null)}releaseSticks(){this.sticks.forEach(e=>this.resetStick(e))}syncStickReadout(){let e=this.fly.sim.stick;for(let t of this.sticks){if(t.pointerId!==null)continue;let n=t.side===`left`?e.throttle:e.pitch,r=t.side===`left`?e.yaw/(this.yawRateScale||1):e.roll;t.read.textContent=Rp(n,r)}}stopTimer(){this.timer!==null&&(window.clearInterval(this.timer),this.timer=null)}renderPitch(e){this.refs.pitchValue.textContent=`${Math.round(e)}°`}applySpeedScale(e){let t=typeof e==`number`?e:Number(e);if(!Number.isFinite(t))return;this.fly.sim.setSpeedScale(t);let n=this.fly.sim.speedScale;this.speedDragging||(this.refs.speedSlider.value=String(n)),document.activeElement!==this.refs.speedInput&&(this.refs.speedInput.value=kp(n)),this.setNote(n===0?`速度倍率 0×:机体不会移动(含自动起飞 / 降落)`:`速度倍率 ${kp(n)}×`)}renderSpeedScale(e){this.speedDragging||(this.refs.speedSlider.value=String(e)),document.activeElement!==this.refs.speedInput&&(this.refs.speedInput.value=kp(e))}setNote(e){this.refs.note.textContent=e}handleAction(e,t){if(!this.destroyed)switch(e){case`power-on`:this.fly.powerOn(),this.setNote(`已上电:自检 + 预热完成后(待机)即可起飞`),this.sync();break;case`takeoff`:this.fly.takeOff()?this.setNote(`起飞:自动上升至 1.2 米`):this.setNote(`起飞未受理:需等自检/预热到「地面待机」,且起飞前检查通过`),this.sync();break;case`land`:this.fly.land()?this.setNote(`开始自动降落`):this.setNote(`降落未受理:需在空中或起飞爬升中`),this.sync();break;case`rth`:this.fly.returnHome(`面板按钮`)?this.setNote(`已触发智能返航`):this.setNote(`返航未受理:需在空中(已在返航中也会被忽略)`),this.sync();break;case`arm-deploy`:this.fly.setArmsFolded(!1),this.setNote(`机臂展开中,桨叶随后张开`),this.sync();break;case`arm-fold`:this.fly.setArmsFolded(!0),this.setNote(`机臂收拢中`),this.sync();break;case`set-flight-mode`:{let e=t.dataset.mode;if(!e)return;this.fly.setMode(e),this.sync();break}case`set-mode`:{let e=t.dataset.mode;if(!e)return;this.fly.setCameraMode(e),this.sync();break}case`reset-camera`:this.fly.resetCamera(),this.sync();break;case`preset-pitch`:{let e=Number(t.dataset.pitch);if(!Number.isFinite(e))return;this.fly.setGimbalPitch(e),this.sync();break}case`preset-speed`:{let e=Number(t.dataset.scale);if(!Number.isFinite(e))return;this.applySpeedScale(e),this.sync();break}case`photo`:this.takePhoto();break;case`set-shoot-mode`:{if(this.panorama?.running)break;let e=t.dataset.mode;if(!e)break;this.shootMode=e,this.syncShootMode();break}case`toggle-record`:this.toggleRecording();break;case`toggle-collapse`:this.setCollapsed(!this.collapsed)}}async takePhoto(){if(!(this.photoBusy||this.destroyed)){if(this.shootMode!==`single`)await this.runPanorama();else{this.photoBusy=!0,this.setNote(`拍照中…`);try{let e=await this.fly.requestPhoto();if(!e){this.setNote(`拍照失败:相机未就绪`);return}this.opts.onPhoto?this.opts.onPhoto(e):this.opts.autoDownload!==!1&&Np(e.dataUrl,`drone-photo-${Pp()}.png`),this.setNote(`已拍摄 ${e.width}×${e.height}`)}catch(e){this.setNote(`拍照异常:${e.message}`)}finally{this.photoBusy=!1}}}}async runPanorama(){let e=this.panorama,t=this.opts.captureService;if(!e||!t)return;if(e.running){e.cancel(),this.setNote(`正在停止全景拍摄…`);return}let n=this.shootMode,r=lp.preset(n,t.getCaptureIntrinsics()?.verticalFovDeg);if(this.fly.phase!==`flying`){this.setNote(`全景需要定点悬停中拍摄(请先起飞并停止航线)`);return}let i=t.activeSession??t.createSession({source:`virtual-camera`,name:`全景-${Pp()}`});this.photoBusy=!0,this.setNote(`${r.label} 扫描中 0/${r.total}…`);try{let t=await e.start(i.id,n);t?t.error?this.setNote(`全景未完成:${t.error}`):t.cancelled?this.setNote(`全景已停止(${t.captured}/${t.total})`):this.setNote(`${r.label} 完成 ${t.captured}/${t.total}${t.stitched?` · 已拼接`:``}`):this.setNote(`全景启动失败(可能已有扫描在进行)`)}catch(e){this.setNote(`全景异常:${e.message}`)}finally{this.photoBusy=!1,this.sync()}}async toggleRecording(){if(!this.destroyed){if(this.fly.isRecording){this.setNote(`正在收尾…`),this.lastRecordSeconds=this.fly.sim.recordSeconds;let e=await this.fly.stopRecording();e?(this.opts.onRecording?this.opts.onRecording(e,this.lastRecordSeconds):this.opts.autoDownload!==!1&&Np(URL.createObjectURL(e),`drone-video-${Pp()}.webm`),this.setNote(`已保存 ${this.lastRecordSeconds.toFixed(1)}s`)):this.setNote(`录像为空,未保存`),this.sync()}else this.fly.startRecording()?(this.setNote(`录制中(云台取景),停止后自动保存`),this.sync()):this.setNote(`当前环境不支持录像(需要 MediaRecorder)`)}}},Bp=`drone-mission-panel-styles`,Vp=100,Hp=1,Up=16,Wp={x:{min:-2e3,max:2e3},z:{min:-2e3,max:2e3},altitude:{min:1,max:500},speed:{min:0,max:16},hoverSeconds:{min:0,max:60},gimbalPitch:{min:-90,max:60}},Gp=[{key:`none`,label:`无动作`},{key:`photo`,label:`拍照`}],Kp=[{key:`hover`,label:`原地悬停`},{key:`rth`,label:`自动返航`},{key:`land`,label:`自动降落`}],qp=[`standby`,`motorsOn`,`takingOff`,`flying`,`rth`];function Jp(e,t,n){return Math.min(n,Math.max(t,e))}function Yp(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return e.replace(/[&<>"']/g,e=>t[e]??e)}function Xp(){if(typeof document>`u`||document.getElementById(Bp))return;let e=document.createElement(`style`);e.id=Bp,e.textContent=em,document.head.appendChild(e)}var Zp=class{constructor(e,t={}){if(i(this,`root`,void 0),i(this,`fly`,void 0),i(this,`opts`,void 0),i(this,`container`,void 0),i(this,`abort`,new AbortController),i(this,`timer`,null),i(this,`destroyed`,!1),i(this,`visible`,void 0),i(this,`lastWaypointCount`,-1),i(this,`speedDragging`,!1),i(this,`coordMode`,`xyz`),i(this,`geoSupported`,void 0),i(this,`refs`,void 0),i(this,`scene`,void 0),typeof document>`u`)throw Error(`[drone-camera] MissionPanel 需要浏览器环境(document),Node 侧请勿实例化`);this.fly=e,this.opts=t,this.container=t.container??document.body,this.visible=t.visible??!0,this.geoSupported=e.supportsGeoCoordinates(),t.injectStyles!==!1&&Xp();let n=t.container??null;n&&getComputedStyle(n).position===`static`&&(n.style.position=`relative`);let r=n?`absolute`:`fixed`;this.root=document.createElement(`div`),this.root.className=`dmp`,this.root.dataset.position=t.position??`top-left`,this.root.dataset.adaptive=String(t.adaptive!==!1),this.root.style.position=r;let a=t.offset??{};if(a.y){let e=this.root.dataset.position.startsWith(`bottom`)?`marginBottom`:`marginTop`;this.root.style[e]=`${a.y}px`}if(a.x){let e=this.root.dataset.position.endsWith(`right`)?`marginRight`:`marginLeft`;this.root.style[e]=`${a.x}px`}this.root.innerHTML=this.template(),this.visible||(this.root.style.display=`none`),this.refs={status:this.query(`[data-role="mission-status"]`),progress:this.query(`[data-role="mission-progress"]`),block:this.query(`[data-role="mission-block"]`),start:this.query(`[data-action="mission-start"]`),pause:this.query(`[data-action="mission-pause"]`),resume:this.query(`[data-action="mission-resume"]`),stop:this.query(`[data-action="mission-stop"]`),total:this.query(`[data-role="mission-total"]`),speed:this.query(`[data-role="mission-speed"]`),speedValue:this.query(`[data-role="mission-speed-value"]`),loop:this.query(`[data-role="mission-loop"]`),count:this.query(`[data-role="waypoint-count"]`),fieldset:this.query(`[data-role="waypoint-fieldset"]`),list:this.query(`[data-role="waypoint-list"]`),add:this.query(`[data-action="waypoint-add"]`),preset:this.query(`[data-action="waypoint-preset"]`),clear:this.query(`[data-action="waypoint-clear"]`),exportJson:this.query(`[data-action="waypoint-export"][data-format="json"]`),exportCsv:this.query(`[data-action="waypoint-export"][data-format="csv"]`),lockHint:this.query(`[data-role="waypoint-lock"]`)};let o=this.root.querySelector(`[data-blk="scene-edit"]`);this.scene=o?{toggle:o.querySelector(`[data-role="scene-edit-toggle"]`),badge:o.querySelector(`[data-role="scene-edit-badge"]`),status:o.querySelector(`[data-role="scene-edit-status"]`),deleteBtn:o.querySelector(`[data-action="scene-delete"]`),addBtn:o.querySelector(`[data-action="scene-add"]`),selectFirst:o.querySelector(`[data-action="scene-select-first"]`),deselect:o.querySelector(`[data-action="scene-deselect"]`),showWaypoints:o.querySelector(`[data-role="toggle-waypoints"]`),showPath:o.querySelector(`[data-role="toggle-path"]`)}:null,this.bind(),this.sync(),this.mount()}mount(){return!this.destroyed&&!this.root.isConnected&&this.container.appendChild(this.root),this}unmount(){return this.root.remove(),this}setVisible(e){return this.visible=e,this.root.style.display=e?``:`none`,this}isVisible(){return this.visible}destroy(){this.destroyed||(this.destroyed=!0,this.abort.abort(),this.stopTimer(),this.root.remove())}static removeInjectedStyles(){typeof document<`u`&&document.getElementById(Bp)?.remove()}sync(){if(this.destroyed)return;let e=this.fly.getSnapshot(),t=e.mission,n=t.status===`idle`;this.refs.status.textContent=y[t.status]??t.status,this.refs.status.className=`dmp-badge${$p(t.status)}`,this.refs.progress.textContent=this.progressText(t),this.refs.block.textContent=this.blockReason(e,n);let r=t.status===`idle`&&t.total>0&&qp.includes(e.phase);this.refs.start.disabled=!r,this.refs.pause.disabled=t.status!==`running`,this.refs.resume.disabled=t.status!==`paused`,this.refs.stop.disabled=t.status===`idle`&&e.phase!==`takingOff`,this.refs.total.textContent=`${t.total} 个航点`,this.speedDragging||(this.refs.speed.value=String(t.config.autoSpeed),this.renderSpeed(t.config.autoSpeed)),this.writeChecked(this.refs.loop,t.config.loop),this.markActive(`[data-action="mission-heading"]`,t.config.headingMode),this.markActive(`[data-action="mission-path"]`,t.config.pathMode),this.markActive(`[data-action="mission-finish"]`,t.config.finishAction),t.waypoints.length!==this.lastWaypointCount&&(this.buildRows(t.waypoints),this.lastWaypointCount=t.waypoints.length),this.refs.count.textContent=`${t.waypoints.length} 个`,this.refs.fieldset.disabled=!n,this.refs.add.disabled=!n,this.refs.preset.disabled=!n,this.refs.clear.disabled=!n;let i=t.waypoints.length===0;this.refs.exportJson.disabled=i,this.refs.exportCsv.disabled=i,this.refs.lockHint.hidden=n,this.syncRows(t),this.scene&&this.syncScene(this.fly.getMissionEditState(),n)}query(e){let t=this.root.querySelector(e);if(!t)throw Error(`[drone-camera] 航线面板结构缺失:${e}`);return t}template(){let e=[{value:`auto`,label:`指向下一航点`},{value:`fixed`,label:`锁定起始航向`}].map(e=>`<button type="button" data-action="mission-heading" data-value="${e.value}">${e.label}</button>`).join(``),t=[{value:`straight`,label:`到点减速`},{value:`curved`,label:`曲线过点`}].map(e=>`<button type="button" data-action="mission-path" data-value="${e.value}">${e.label}</button>`).join(``),n=Kp.map(e=>`<button type="button" data-action="mission-finish" data-value="${e.key}">${e.label}</button>`).join(``);return`
|
|
439
|
+
<div class="dmp-head">
|
|
440
|
+
<span class="dmp-title">${Yp(this.opts.title??`航线规划`)}</span>
|
|
441
|
+
<button type="button" class="dmp-icon" data-action="toggle-collapse" title="收起 / 展开" aria-label="收起或展开">–</button>
|
|
442
|
+
</div>
|
|
443
|
+
<div class="dmp-body">
|
|
444
|
+
<section class="dmp-card">
|
|
445
|
+
<div class="dmp-card-head"><span>航线任务</span><em class="dmp-badge" data-role="mission-status">--</em></div>
|
|
446
|
+
<div class="dmp-btns">
|
|
447
|
+
<button type="button" class="dmp-btn dmp-primary" data-action="mission-start">执行航线</button>
|
|
448
|
+
<button type="button" class="dmp-btn" data-action="mission-pause">暂停</button>
|
|
449
|
+
<button type="button" class="dmp-btn" data-action="mission-resume">继续</button>
|
|
450
|
+
<button type="button" class="dmp-btn dmp-wide" data-action="mission-stop">停止任务(原地悬停)</button>
|
|
451
|
+
</div>
|
|
452
|
+
<p class="dmp-progress" data-role="mission-progress"></p>
|
|
453
|
+
<p class="dmp-block" data-role="mission-block" hidden></p>
|
|
454
|
+
<p class="dmp-fine">地面直接点「执行航线」会先自动起飞,到 1.2 米后自动接上航线;空中启动同样从首个航点走起。飞向首个航点与返航同款分段:先垂直调整到航点高度 → 水平飞过去 → 收到航点高度 → 机头对准航线方向,之后才开始执行航线。执行中拨动摇杆会暂停任务并交回手动控制。</p>
|
|
455
|
+
</section>
|
|
456
|
+
|
|
457
|
+
<section class="dmp-card">
|
|
458
|
+
<div class="dmp-card-head"><span>任务参数</span><em data-role="mission-total">0 个航点</em></div>
|
|
459
|
+
<label class="dmp-range-row">
|
|
460
|
+
<span>巡航速度</span>
|
|
461
|
+
<input type="range" data-role="mission-speed" min="${Hp}" max="${Up}" step="0.5" value="6" />
|
|
462
|
+
<strong data-role="mission-speed-value">6.0 m/s</strong>
|
|
463
|
+
</label>
|
|
464
|
+
<p class="dmp-row-label">机头朝向</p>
|
|
465
|
+
<div class="dmp-seg dmp-seg-2">${e}</div>
|
|
466
|
+
<p class="dmp-row-label">过点方式</p>
|
|
467
|
+
<div class="dmp-seg dmp-seg-2">${t}</div>
|
|
468
|
+
<p class="dmp-row-label">全部完成后</p>
|
|
469
|
+
<div class="dmp-seg dmp-seg-3">${n}</div>
|
|
470
|
+
<label class="dmp-switch"><input type="checkbox" data-role="mission-loop" /><span>循环执行(完成后回到第 1 个航点)</span></label>
|
|
471
|
+
<p class="dmp-fine">曲线过点保持巡航速度、距航点 3 米就切向下一点,所以会忽略航点悬停;直线模式按刹车距离提前收油,过点更稳。</p>
|
|
472
|
+
</section>
|
|
473
|
+
|
|
474
|
+
<section class="dmp-card">
|
|
475
|
+
<div class="dmp-card-head"><span>航点列表</span><em data-role="waypoint-count">0 个</em></div>
|
|
476
|
+
${this.coordModeTemplate()}
|
|
477
|
+
<fieldset class="dmp-wp-fieldset" data-role="waypoint-fieldset">
|
|
478
|
+
<ul class="dmp-wp-list" data-role="waypoint-list"></ul>
|
|
479
|
+
</fieldset>
|
|
480
|
+
<div class="dmp-seg dmp-seg-3">
|
|
481
|
+
<button type="button" data-action="waypoint-add">添加航点</button>
|
|
482
|
+
<button type="button" data-action="waypoint-preset">示例航线</button>
|
|
483
|
+
<button type="button" data-action="waypoint-clear">清空</button>
|
|
484
|
+
</div>
|
|
485
|
+
<div class="dmp-seg dmp-seg-2">
|
|
486
|
+
<button type="button" data-action="waypoint-export" data-format="json" title="完整存档:航点 + 任务参数 + 概览统计,可再次载入">导出 JSON</button>
|
|
487
|
+
<button type="button" data-action="waypoint-export" data-format="csv" title="纯航点表,Excel / WPS 可直接打开">导出 CSV</button>
|
|
488
|
+
</div>
|
|
489
|
+
<p class="dmp-fine">导出内容为当前航点与任务参数,坐标与列表一致(相对返航点的东 / 南向偏移)。</p>
|
|
490
|
+
<p class="dmp-fine" data-role="waypoint-lock" hidden>任务执行中:停止任务之后才能修改航点(与真机「航线上传后不可改」一致)。</p>
|
|
491
|
+
</section>
|
|
492
|
+
|
|
493
|
+
${this.sceneEditTemplate()}
|
|
494
|
+
</div>
|
|
495
|
+
`}coordModeTemplate(){return this.geoSupported?`
|
|
496
|
+
<div class="dmp-seg dmp-seg-2 dmp-coord-mode" data-blk="coord-mode">
|
|
497
|
+
<button type="button" data-action="coord-mode" data-value="xyz" class="is-active">XYZ</button>
|
|
498
|
+
<button type="button" data-action="coord-mode" data-value="geo">经纬度</button>
|
|
499
|
+
</div>`:``}sceneEditTemplate(){return this.opts.sceneEdit===!1?``:`
|
|
500
|
+
<section class="dmp-card" data-blk="scene-edit">
|
|
501
|
+
<div class="dmp-card-head"><span>场景内编辑</span><em class="dmp-badge" data-role="scene-edit-badge">已关闭</em></div>
|
|
502
|
+
<label class="dmp-switch"><input type="checkbox" data-role="scene-edit-toggle" /><span>在三维场景里直接编辑航点</span></label>
|
|
503
|
+
<ul class="dmp-gesture">
|
|
504
|
+
<li><b>拖拽航点</b><span>在它当前高度的水平面内移动</span></li>
|
|
505
|
+
<li><b>Shift + 拖拽</b><span>改高度(按住 Alt 可关掉 1 米吸附)</span></li>
|
|
506
|
+
<li><b>双击地面</b><span>在该处插入一个航点</span></li>
|
|
507
|
+
<li><b>Delete</b><span>删除当前选中的航点,Esc 取消选中</span></li>
|
|
508
|
+
</ul>
|
|
509
|
+
<div class="dmp-status" data-role="scene-edit-status"></div>
|
|
510
|
+
<div class="dmp-seg dmp-seg-3">
|
|
511
|
+
<button type="button" data-action="scene-delete">删除选中</button>
|
|
512
|
+
<button type="button" data-action="scene-add">飞机位置新增</button>
|
|
513
|
+
<button type="button" data-action="scene-frame">框住航线</button>
|
|
514
|
+
</div>
|
|
515
|
+
<div class="dmp-seg dmp-seg-2">
|
|
516
|
+
<button type="button" data-action="scene-select-first">选中第 1 个航点</button>
|
|
517
|
+
<button type="button" data-action="scene-deselect">取消选中</button>
|
|
518
|
+
</div>
|
|
519
|
+
<div class="dmp-switch-row">
|
|
520
|
+
<label class="dmp-switch"><input type="checkbox" data-role="toggle-waypoints" /><span>显示航点</span></label>
|
|
521
|
+
<label class="dmp-switch"><input type="checkbox" data-role="toggle-path" /><span>显示航线</span></label>
|
|
522
|
+
</div>
|
|
523
|
+
<p class="dmp-fine">隐藏只是不画,不影响任务执行;编辑航点则要求航线未在执行,且处于观察者视角(机载视角下屏幕里没有可点的目标)。</p>
|
|
524
|
+
</section>
|
|
525
|
+
`}rowTemplate(e){let t=Gp.map(e=>`<option value="${e.key}">${e.label}</option>`).join(``),n=this.coordMode===`geo`?`<div class="dmp-wp-row dmp-wp-row-geo">
|
|
526
|
+
<label class="dmp-wp-field"><span>经度</span><input class="dmp-wp-input" type="number" step="0.00000001" data-field="lon" /></label>
|
|
527
|
+
<label class="dmp-wp-field"><span>纬度</span><input class="dmp-wp-input" type="number" step="0.00000001" data-field="lat" /></label>
|
|
528
|
+
<label class="dmp-wp-field dmp-wp-geo-h"><span>高度</span><input class="dmp-wp-input" type="number" step="0.1" data-field="geoHeight" /></label>
|
|
529
|
+
</div>`:`<div class="dmp-wp-row">
|
|
530
|
+
<label class="dmp-wp-field"><span>X</span><input class="dmp-wp-input" type="number" step="2" data-field="x" /></label>
|
|
531
|
+
<label class="dmp-wp-field"><span>Z</span><input class="dmp-wp-input" type="number" step="2" data-field="z" /></label>
|
|
532
|
+
<label class="dmp-wp-field"><span>高度</span><input class="dmp-wp-input" type="number" step="1" min="1" data-field="altitude" /></label>
|
|
533
|
+
</div>`;return`
|
|
534
|
+
<li class="dmp-wp" data-index="${e}" data-action="waypoint-select">
|
|
535
|
+
<div class="dmp-wp-head">
|
|
536
|
+
<span class="dmp-wp-index">${e+1}</span>
|
|
537
|
+
<span class="dmp-wp-coord" data-role="wp-coord"></span>
|
|
538
|
+
<button type="button" class="dmp-mini" data-action="waypoint-remove">删除</button>
|
|
539
|
+
</div>
|
|
540
|
+
${n}
|
|
541
|
+
<div class="dmp-wp-row">
|
|
542
|
+
<label class="dmp-wp-field"><span>速度</span><input class="dmp-wp-input" type="number" step="1" min="0" max="16" data-field="speed" /></label>
|
|
543
|
+
<label class="dmp-wp-field"><span>悬停</span><input class="dmp-wp-input" type="number" step="1" min="0" max="60" data-field="hoverSeconds" /></label>
|
|
544
|
+
<label class="dmp-wp-field dmp-wp-gimbal">
|
|
545
|
+
<input type="checkbox" data-field="gimbalOn" />
|
|
546
|
+
<span>云台</span>
|
|
547
|
+
<input class="dmp-wp-input" type="number" step="5" min="-90" max="60" data-field="gimbalPitch" />
|
|
548
|
+
</label>
|
|
549
|
+
<label class="dmp-wp-field"><span>动作</span><select class="dmp-wp-select" data-field="action">${t}</select></label>
|
|
550
|
+
</div>
|
|
551
|
+
<em class="dmp-wp-flag" data-role="wp-flag" hidden>当前目标</em>
|
|
552
|
+
</li>
|
|
553
|
+
`}buildRows(e){this.refs.list.innerHTML=e.length?e.map((e,t)=>this.rowTemplate(t)).join(``):`<li class="dmp-wp-empty">暂无航点</li>`}syncRows(e){let t=this.refs.list.querySelectorAll(`li.dmp-wp`),n=this.fly.getMissionSelected();t.forEach((t,r)=>{let i=e.waypoints[r];if(!i)return;t.classList.toggle(`is-active`,e.status!==`idle`&&e.index===r),t.classList.toggle(`is-selected`,n===r);let a=t.querySelector(`[data-role="wp-coord"]`);a&&(a.textContent=this.waypointCoordText(i,r));let o=e=>{let n=t.querySelector(`[data-field="${e}"]`);n&&this.writeValue(n,String(i[e]))};if(this.coordMode===`geo`){let e=this.fly.getWaypointGeo(r);if(e){let n=t.querySelector(`[data-field="lon"]`);n&&this.writeValue(n,e.lon.toFixed(8));let r=t.querySelector(`[data-field="lat"]`);r&&this.writeValue(r,e.lat.toFixed(8));let i=t.querySelector(`[data-field="geoHeight"]`);i&&this.writeValue(i,e.height.toFixed(1))}}else o(`x`),o(`z`),o(`altitude`);o(`speed`),o(`hoverSeconds`);let s=t.querySelector(`[data-field="gimbalOn"]`);s&&this.writeChecked(s,i.gimbalPitch!==null);let c=t.querySelector(`[data-field="gimbalPitch"]`);c&&(this.writeValue(c,String(i.gimbalPitch??-45)),c.disabled=i.gimbalPitch===null);let l=t.querySelector(`[data-field="action"]`);l&&this.writeValue(l,i.action);let u=t.querySelector(`[data-role="wp-flag"]`);u&&(u.hidden=e.status===`idle`||e.index!==r)})}bind(){let{signal:e}=this.abort;this.root.addEventListener(`click`,e=>{let t=e.target?.closest(`[data-action]`);t&&this.handleAction(t.dataset.action??``,t)},{signal:e}),this.refs.list.addEventListener(`input`,e=>this.handleRowInput(e),{signal:e}),this.refs.list.addEventListener(`change`,e=>this.handleRowInput(e),{signal:e}),this.refs.speed.addEventListener(`input`,()=>{let e=Number(this.refs.speed.value);Number.isFinite(e)&&(this.fly.setMissionConfig({autoSpeed:e}),this.renderSpeed(e))},{signal:e}),this.refs.speed.addEventListener(`pointerdown`,()=>this.speedDragging=!0,{signal:e}),window.addEventListener(`pointerup`,()=>this.speedDragging=!1,{signal:e}),this.refs.loop.addEventListener(`change`,()=>this.fly.setMissionConfig({loop:this.refs.loop.checked}),{signal:e}),this.scene&&(this.scene.toggle.addEventListener(`change`,()=>{this.fly.setMissionEditEnabled(this.scene?.toggle.checked??!1),this.sync()},{signal:e}),this.scene.showWaypoints.addEventListener(`change`,()=>this.fly.setMissionWaypointsVisible(this.scene?.showWaypoints.checked??!0),{signal:e}),this.scene.showPath.addEventListener(`change`,()=>this.fly.setMissionPathVisible(this.scene?.showPath.checked??!0),{signal:e})),this.opts.syncIntervalMs!==0&&(this.timer=window.setInterval(()=>this.sync(),this.opts.syncIntervalMs??Vp))}handleAction(e,t){let n=this.fly,r=()=>Number(t.closest(`.dmp-wp`)?.dataset.index??-1);switch(e){case`toggle-collapse`:this.root.dataset.collapsed=String(this.root.dataset.collapsed!==`true`);break;case`mission-start`:n.startMission();break;case`mission-pause`:n.pauseMission(`用户暂停`);break;case`mission-resume`:n.resumeMission();break;case`mission-stop`:n.stopMission(`用户停止`);break;case`mission-heading`:n.setMissionConfig({headingMode:t.dataset.value});break;case`mission-path`:n.setMissionConfig({pathMode:t.dataset.value});break;case`mission-finish`:n.setMissionConfig({finishAction:t.dataset.value});break;case`waypoint-add`:this.addWaypoint();break;case`waypoint-preset`:this.selectWaypoint(-1),n.resetMissionToDefault();break;case`waypoint-clear`:this.selectWaypoint(-1),n.setMission([]);break;case`waypoint-export`:this.exportMission(t.dataset.format===`csv`?`csv`:`json`,t);break;case`waypoint-select`:this.selectWaypoint(r());break;case`waypoint-remove`:this.removeWaypoint(r());break;case`scene-delete`:this.deleteSelected();break;case`scene-add`:this.addAtDrone();break;case`scene-frame`:n.frameMission();break;case`scene-select-first`:this.selectWaypoint(0);break;case`scene-deselect`:this.selectWaypoint(-1);break;case`coord-mode`:this.setCoordMode(t.dataset.value===`geo`?`geo`:`xyz`);break;default:return}this.sync()}handleRowInput(e){let t=e.target?.closest(`[data-field]`),n=Number((t?.closest(`.dmp-wp`))?.dataset.index??-1);if(!t||n<0)return;let r=t.dataset.field??``;if(r===`gimbalOn`){let e=t.checked;this.patchWaypoint(n,{gimbalPitch:e?-45:null});return}if(r===`action`){let e=t.value===`photo`?`photo`:`none`;this.patchWaypoint(n,{action:e});return}if(r===`lon`||r===`lat`||r===`geoHeight`){let t=e.target.value.trim();this.patchWaypointGeo(n,r,t);return}if(!(r in Wp))return;let i=r,a=e.target.value.trim();if(a===``)return;let o=Number(a);if(!Number.isFinite(o))return;let s=Wp[i];this.patchWaypoint(n,{[i]:Jp(o,s.min,s.max)})}waypoints(){return this.fly.sim.mission.map(e=>({...e}))}patchWaypoint(e,t){let n=this.waypoints().map((n,r)=>r===e?{...n,...t}:n);this.fly.setMission(n)}patchWaypointGeo(e,t,n){if(n===``)return;let r=this.fly.getWaypointGeo(e);if(!r)return;let i=Number(n);if(!Number.isFinite(i))return;let a={lon:r.lon,lat:r.lat,height:r.height};t===`lon`?a.lon=Math.min(180,Math.max(-180,i)):t===`lat`?a.lat=Math.min(90,Math.max(-90,i)):t===`geoHeight`&&(a.height=Math.min(9e3,Math.max(0,i))),this.fly.setWaypointGeo(e,a)}addWaypoint(){let e=this.waypoints(),t=e[e.length-1],n=t?{x:t.x+12,z:t.z,altitude:t.altitude,speed:t.speed}:{x:0,z:-30,altitude:30,speed:0,hoverSeconds:0,gimbalPitch:null,action:`none`};this.fly.setMission([...e,n]),this.revealRow(this.fly.sim.mission.length-1)}removeWaypoint(e){e<0||(this.fly.setMission(this.waypoints().filter((t,n)=>n!==e)),this.selectWaypoint(-1))}exportMission(e,t){let n=this.fly.exportMission(e),r=Qp(e),i=e===`csv`?`text/csv;charset=utf-8`:`application/json`;if(this.opts.onExport){this.opts.onExport({format:e,text:n,filename:r,mime:i}),this.flashButton(t,`已交给宿主`);return}let a=new Blob([e===`csv`?`\ufeff${n}`:n],{type:i}),o=URL.createObjectURL(a),s=document.createElement(`a`);s.href=o,s.download=r,s.rel=`noopener`,document.body.appendChild(s),s.click(),s.remove(),window.setTimeout(()=>URL.revokeObjectURL(o),2e3),this.flashButton(t,`已导出`)}flashButton(e,t){e.dataset.label||(e.dataset.label=e.textContent??``),e.textContent=t,window.setTimeout(()=>{e.dataset.label&&(e.textContent=e.dataset.label)},1400)}selectWaypoint(e){this.fly.setMissionSelected(e),e>=0&&this.revealRow(e)}deleteSelected(){let e=this.fly.getMissionSelected();e<0||this.fly.deleteMissionWaypoint(e)}addAtDrone(){let e=this.fly.addMissionWaypointAtDrone();e>=0&&this.revealRow(e)}revealRow(e){this.refs.list.querySelector(`[data-index="${e}"]`)?.scrollIntoView({block:`nearest`})}renderSpeed(e){this.refs.speedValue.textContent=`${e.toFixed(1)} m/s`}markActive(e,t){this.root.querySelectorAll(e).forEach(e=>{e.classList.toggle(`is-active`,e.dataset.value===t)})}writeValue(e,t){document.activeElement!==e&&e.value!==t&&(e.value=t)}writeChecked(e,t){document.activeElement!==e&&e.checked!==t&&(e.checked=t)}progressText(e){if(e.status===`idle`)return e.total?`待执行 · 共 ${e.total} 个航点`:`暂无航线`;let t=x(e.stage)?`启航(航点 1/${e.total}) · ${this.stageLabel(e.stage)}`:`第 ${e.index+1}/${e.total} 个航点 · ${this.stageLabel(e.stage)}`,n=`${Math.round(e.progress*100)}%`,r=e.etaSeconds;return`${t} · ${n} · 剩余 ${r>=60?`${Math.floor(r/60)} 分 ${Math.round(r%60)} 秒`:`${r.toFixed(0)} 秒`}`}stageLabel(e){return{idle:`待执行`,"depart-climb":`垂直调整到首航点高度`,"depart-cruise":`水平飞向首个航点`,"depart-settle":`调整到航点高度`,"depart-align":`对准航线方向`,goto:`飞向航点`,hover:`航点悬停`}[e]??e}blockReason(e,t){return t?e.mission.total===0?`航线为空:先「添加航点」或「示例航线」`:e.positionSource===`atti`?`当前无定位(姿态模式),航点任务需要 GNSS`:qp.includes(e.phase)?``:`当前阶段(${e.phaseLabel})无法启动航线`:``}syncScene(e,t){let n=this.scene;if(!n)return;this.writeChecked(n.toggle,e.enabled);let r=e.enabled?e.dragging?{label:`拖动中`,tone:` is-warn`}:e.active?{label:`编辑中`,tone:` is-ok`}:{label:`待切换视角`,tone:` is-warn`}:{label:`已关闭`,tone:``};n.badge.textContent=r.label,n.badge.className=`dmp-badge${r.tone}`;let i=e.selectedIndex>=0?this.fly.sim.mission[e.selectedIndex]:null,a;a=i?this.sceneCoordText(e.selectedIndex,i):`未选中航点(在场景里点一下航点光柱)`,e.dragging?a+=` · ${e.mode===`altitude`?`调整高度中`:`移动中`}`:e.enabled&&!e.active&&(a+=` · ${this.sceneBlockReason(t)}`),n.status.textContent=a,n.deleteBtn.disabled=e.selectedIndex<0||!t,n.addBtn.disabled=!t,n.selectFirst.disabled=this.fly.sim.mission.length===0,n.deselect.disabled=e.selectedIndex<0,this.writeChecked(n.showWaypoints,this.fly.isMissionWaypointsVisible()),this.writeChecked(n.showPath,this.fly.isMissionPathVisible())}sceneBlockReason(e){return e?this.fly.isOrbitView?`当前不可编辑`:`需切到观察者视角`:`任务执行中不可编辑`}setCoordMode(e){e!==this.coordMode&&(this.coordMode=e,this.root.querySelectorAll(`[data-action="coord-mode"]`).forEach(t=>t.classList.toggle(`is-active`,t.dataset.value===e)),this.lastWaypointCount=-1,this.sync())}waypointCoordText(e,t){if(this.coordMode===`geo`){let e=this.fly.getWaypointGeo(t);if(e)return`经度 ${e.lon.toFixed(8)} / 纬度 ${e.lat.toFixed(8)}`}return`E ${e.x} / S ${e.z}`}sceneCoordText(e,t){if(this.coordMode===`geo`){let t=this.fly.getWaypointGeo(e);if(t)return`已选中 航点 ${e+1} · 经度 ${t.lon.toFixed(8)} / 纬度 ${t.lat.toFixed(8)} / ${t.height.toFixed(1)} m`}return`已选中 航点 ${e+1} · E ${t.x} / S ${t.z} / ${t.altitude.toFixed(0)} m`}stopTimer(){this.timer!==null&&(window.clearInterval(this.timer),this.timer=null)}};function Qp(e){let t=new Date,n=e=>String(e).padStart(2,`0`);return`mission-${`${t.getFullYear()}${n(t.getMonth()+1)}${n(t.getDate())}-${n(t.getHours())}${n(t.getMinutes())}${n(t.getSeconds())}`}.${e}`}function $p(e){return e===`running`?` is-ok`:e===`paused`?` is-warn`:``}var em=`
|
|
554
|
+
.dmp {
|
|
555
|
+
--dmp-bg: rgba(15, 19, 27, 0.84);
|
|
556
|
+
--dmp-card: rgba(255, 255, 255, 0.04);
|
|
557
|
+
--dmp-border: rgba(255, 255, 255, 0.12);
|
|
558
|
+
--dmp-text: #e9eff9;
|
|
559
|
+
--dmp-muted: rgba(233, 239, 249, 0.58);
|
|
560
|
+
--dmp-accent: #35a7ff;
|
|
561
|
+
--dmp-on-accent: #04121f;
|
|
562
|
+
--dmp-warn: #ffc53d;
|
|
563
|
+
--dmp-danger: #ff5f5f;
|
|
564
|
+
--dmp-ok: #3ddc97;
|
|
565
|
+
--dmp-radius: 10px;
|
|
566
|
+
/* 面板底部留出的避让高度:这套 HUD 布局里画面两下角是虚拟摇杆(底盘 92px + 上下留白),
|
|
567
|
+
面板别压上去 —— 摇杆悬浮层 z-index 更高、仍可点,但叠着既难看又容易误触。
|
|
568
|
+
宿主没有摇杆时可自行改小(例如 --dmp-clear-bottom: 24px) */
|
|
569
|
+
--dmp-clear-bottom: 188px;
|
|
570
|
+
font: 12px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
571
|
+
user-select: none;
|
|
572
|
+
-webkit-user-select: none;
|
|
573
|
+
-webkit-tap-highlight-color: transparent;
|
|
574
|
+
overscroll-behavior: contain;
|
|
575
|
+
z-index: 20;
|
|
576
|
+
width: 300px;
|
|
577
|
+
box-sizing: border-box;
|
|
578
|
+
padding: 10px 12px 12px;
|
|
579
|
+
border: 1px solid var(--dmp-border);
|
|
580
|
+
border-radius: var(--dmp-radius);
|
|
581
|
+
background: var(--dmp-bg);
|
|
582
|
+
color: var(--dmp-text);
|
|
583
|
+
-webkit-backdrop-filter: blur(10px);
|
|
584
|
+
backdrop-filter: blur(10px);
|
|
585
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
|
|
586
|
+
max-height: calc(100% - var(--dmp-clear-bottom));
|
|
587
|
+
display: flex;
|
|
588
|
+
flex-direction: column;
|
|
589
|
+
}
|
|
590
|
+
.dmp[data-position="top-left"] { top: 12px; left: 12px; }
|
|
591
|
+
.dmp[data-position="top-right"] { top: 12px; right: 12px; }
|
|
592
|
+
.dmp[data-position="bottom-left"] { bottom: 12px; left: 12px; }
|
|
593
|
+
.dmp[data-position="bottom-right"] { bottom: 12px; right: 12px; }
|
|
594
|
+
.dmp button, .dmp input, .dmp select { touch-action: manipulation; font: inherit; }
|
|
595
|
+
.dmp-hidden, .dmp [hidden] { display: none !important; }
|
|
596
|
+
|
|
597
|
+
.dmp-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
|
|
598
|
+
.dmp-title { flex: 1; font-weight: 600; letter-spacing: 0.4px; }
|
|
599
|
+
.dmp-icon {
|
|
600
|
+
width: 22px; height: 22px; flex: none; line-height: 1;
|
|
601
|
+
border: 1px solid var(--dmp-border); border-radius: 6px;
|
|
602
|
+
background: transparent; color: var(--dmp-text); cursor: pointer;
|
|
603
|
+
}
|
|
604
|
+
.dmp-icon:hover { background: rgba(255, 255, 255, 0.08); }
|
|
605
|
+
.dmp[data-collapsed="true"] .dmp-body { display: none; }
|
|
606
|
+
|
|
607
|
+
.dmp-body { overflow-y: auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; padding-right: 2px; }
|
|
608
|
+
.dmp-body::-webkit-scrollbar { width: 6px; }
|
|
609
|
+
.dmp-body::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.16); border-radius: 3px; }
|
|
610
|
+
|
|
611
|
+
.dmp-card {
|
|
612
|
+
padding: 8px 9px 9px;
|
|
613
|
+
border: 1px solid var(--dmp-border);
|
|
614
|
+
border-radius: 8px;
|
|
615
|
+
background: var(--dmp-card);
|
|
616
|
+
}
|
|
617
|
+
.dmp-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
|
|
618
|
+
.dmp-card-head > span { flex: 1; font-weight: 600; }
|
|
619
|
+
.dmp-card-head em { font-style: normal; font-size: 11px; color: var(--dmp-muted); }
|
|
620
|
+
|
|
621
|
+
.dmp-badge {
|
|
622
|
+
flex: none; padding: 1px 7px; border-radius: 999px;
|
|
623
|
+
border: 1px solid var(--dmp-border);
|
|
624
|
+
background: rgba(255, 255, 255, 0.06);
|
|
625
|
+
color: var(--dmp-muted); font-size: 11px;
|
|
626
|
+
}
|
|
627
|
+
.dmp-badge.is-ok { color: var(--dmp-ok); border-color: rgba(61, 220, 151, 0.4); }
|
|
628
|
+
.dmp-badge.is-warn { color: var(--dmp-warn); border-color: rgba(255, 197, 61, 0.4); }
|
|
629
|
+
|
|
630
|
+
.dmp-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
|
|
631
|
+
.dmp-btn {
|
|
632
|
+
padding: 6px 8px; border-radius: 7px; cursor: pointer;
|
|
633
|
+
border: 1px solid var(--dmp-border);
|
|
634
|
+
background: rgba(255, 255, 255, 0.06);
|
|
635
|
+
color: var(--dmp-text);
|
|
636
|
+
}
|
|
637
|
+
.dmp-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.12); }
|
|
638
|
+
.dmp-btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
639
|
+
.dmp-btn.dmp-primary { background: var(--dmp-accent); border-color: var(--dmp-accent); color: var(--dmp-on-accent); font-weight: 600; }
|
|
640
|
+
.dmp-btn.dmp-primary:hover:not(:disabled) { filter: brightness(1.08); }
|
|
641
|
+
.dmp-btn.dmp-wide { grid-column: 1 / -1; }
|
|
642
|
+
|
|
643
|
+
.dmp-progress { margin: 7px 0 0; color: var(--dmp-accent); font-size: 11px; }
|
|
644
|
+
.dmp-block { margin: 5px 0 0; padding: 5px 7px; border-radius: 6px; background: rgba(255, 95, 95, 0.12); color: #ffb3b3; font-size: 11px; }
|
|
645
|
+
.dmp-fine { margin: 6px 0 0; color: var(--dmp-muted); font-size: 11px; line-height: 1.45; }
|
|
646
|
+
.dmp-row-label { margin: 7px 0 4px; color: var(--dmp-muted); font-size: 11px; }
|
|
647
|
+
|
|
648
|
+
.dmp-range-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 8px; }
|
|
649
|
+
.dmp-range-row > span { color: var(--dmp-muted); font-size: 11px; }
|
|
650
|
+
.dmp-range-row strong { font-variant-numeric: tabular-nums; font-size: 11px; }
|
|
651
|
+
.dmp-range-row input[type="range"] { width: 100%; accent-color: var(--dmp-accent); }
|
|
652
|
+
|
|
653
|
+
.dmp-seg { display: grid; gap: 4px; }
|
|
654
|
+
.dmp-seg-2 { grid-template-columns: 1fr 1fr; }
|
|
655
|
+
.dmp-seg-3 { grid-template-columns: repeat(3, 1fr); }
|
|
656
|
+
.dmp-seg button {
|
|
657
|
+
padding: 5px 4px; border-radius: 6px; cursor: pointer; font-size: 11px;
|
|
658
|
+
border: 1px solid var(--dmp-border);
|
|
659
|
+
background: rgba(255, 255, 255, 0.05);
|
|
660
|
+
color: var(--dmp-text);
|
|
661
|
+
}
|
|
662
|
+
.dmp-seg button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.11); }
|
|
663
|
+
.dmp-seg button:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
664
|
+
.dmp-seg button.is-active { background: var(--dmp-accent); border-color: var(--dmp-accent); color: var(--dmp-on-accent); font-weight: 600; }
|
|
665
|
+
.dmp-coord-mode { margin-bottom: 7px; }
|
|
666
|
+
.dmp-coord-mode button { font-variant-numeric: tabular-nums; }
|
|
667
|
+
|
|
668
|
+
.dmp-switch { display: flex; align-items: center; gap: 6px; margin-top: 7px; cursor: pointer; }
|
|
669
|
+
.dmp-switch input { flex: none; accent-color: var(--dmp-accent); }
|
|
670
|
+
.dmp-switch > span { font-size: 11px; }
|
|
671
|
+
.dmp-switch-row { display: flex; gap: 14px; }
|
|
672
|
+
|
|
673
|
+
.dmp-wp-fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
|
|
674
|
+
.dmp-wp-fieldset:disabled { opacity: 0.55; }
|
|
675
|
+
.dmp-wp-list { list-style: none; margin: 0; padding: 0; max-height: 240px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
|
|
676
|
+
.dmp-wp-list::-webkit-scrollbar { width: 6px; }
|
|
677
|
+
.dmp-wp-list::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.16); border-radius: 3px; }
|
|
678
|
+
.dmp-wp-empty { color: var(--dmp-muted); font-size: 11px; padding: 6px 2px; }
|
|
679
|
+
.dmp-wp {
|
|
680
|
+
position: relative; padding: 6px 6px 7px; border-radius: 7px; cursor: pointer;
|
|
681
|
+
border: 1px solid var(--dmp-border);
|
|
682
|
+
background: rgba(255, 255, 255, 0.03);
|
|
683
|
+
}
|
|
684
|
+
.dmp-wp.is-selected, .dmp-wp:hover { border-color: rgba(53, 167, 255, 0.5); }
|
|
685
|
+
.dmp-wp.is-active { border-color: var(--dmp-ok); box-shadow: 0 0 0 1px rgba(61, 220, 151, 0.35) inset; }
|
|
686
|
+
.dmp-wp-head { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
|
|
687
|
+
.dmp-wp-index {
|
|
688
|
+
flex: none; width: 18px; height: 18px; border-radius: 50%;
|
|
689
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
690
|
+
background: rgba(53, 167, 255, 0.2); color: var(--dmp-accent); font-size: 11px; font-weight: 600;
|
|
691
|
+
}
|
|
692
|
+
.dmp-wp-coord { flex: 1; color: var(--dmp-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
|
|
693
|
+
.dmp-mini {
|
|
694
|
+
flex: none; padding: 2px 7px; border-radius: 5px; cursor: pointer; font-size: 11px;
|
|
695
|
+
border: 1px solid var(--dmp-border);
|
|
696
|
+
background: transparent; color: var(--dmp-danger);
|
|
697
|
+
}
|
|
698
|
+
.dmp-mini:hover { background: rgba(255, 95, 95, 0.14); }
|
|
699
|
+
.dmp-wp-row { display: grid; grid-template-columns: 1fr 1fr 1.25fr; gap: 5px; margin-bottom: 5px; }
|
|
700
|
+
.dmp-wp-row:last-of-type { margin-bottom: 0; grid-template-columns: repeat(2, 1fr); }
|
|
701
|
+
/* geo 首行:经纬度各占半宽(8 位小数约 10 字符,半宽输入框放得下),高度独占整行 */
|
|
702
|
+
.dmp-wp-row-geo { grid-template-columns: 1fr 1fr; }
|
|
703
|
+
.dmp-wp-row-geo .dmp-wp-geo-h { grid-column: 1 / -1; }
|
|
704
|
+
.dmp-wp-field { display: flex; align-items: center; gap: 4px; min-width: 0; }
|
|
705
|
+
.dmp-wp-field > span { flex: none; color: var(--dmp-muted); font-size: 11px; }
|
|
706
|
+
.dmp-wp-gimbal { grid-column: span 2; }
|
|
707
|
+
.dmp-wp-input {
|
|
708
|
+
width: 100%; min-width: 0; box-sizing: border-box;
|
|
709
|
+
padding: 3px 4px; border-radius: 5px;
|
|
710
|
+
border: 1px solid var(--dmp-border);
|
|
711
|
+
background: rgba(0, 0, 0, 0.28); color: var(--dmp-text); font-size: 11px;
|
|
712
|
+
font-variant-numeric: tabular-nums;
|
|
713
|
+
}
|
|
714
|
+
/* Chrome/Edge 的数字框默认带上下调节箭头,窄格里能吃掉十几像素 —— 藏掉它,
|
|
715
|
+
否则"500"这种三位数会裁得只剩"5",看起来就像列表高度和场景对不上 */
|
|
716
|
+
.dmp-wp-input::-webkit-outer-spin-button,
|
|
717
|
+
.dmp-wp-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
|
718
|
+
.dmp-wp-input[type='number'] { -moz-appearance: textfield; appearance: textfield; }
|
|
719
|
+
.dmp-wp-input:focus { outline: none; border-color: var(--dmp-accent); }
|
|
720
|
+
.dmp-wp-input:disabled { opacity: 0.45; }
|
|
721
|
+
.dmp-wp-select {
|
|
722
|
+
width: 100%; min-width: 0; box-sizing: border-box;
|
|
723
|
+
padding: 3px 4px; border-radius: 5px;
|
|
724
|
+
border: 1px solid var(--dmp-border);
|
|
725
|
+
background: rgba(0, 0, 0, 0.28); color: var(--dmp-text); font-size: 11px;
|
|
726
|
+
}
|
|
727
|
+
.dmp-wp-flag {
|
|
728
|
+
position: absolute; top: -6px; right: 8px;
|
|
729
|
+
padding: 0 6px; border-radius: 999px; font-style: normal; font-size: 10px;
|
|
730
|
+
background: var(--dmp-ok); color: #03231a; font-weight: 600;
|
|
731
|
+
}
|
|
732
|
+
.dmp-gesture { list-style: none; margin: 7px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
|
|
733
|
+
.dmp-gesture li { display: flex; gap: 8px; font-size: 11px; }
|
|
734
|
+
.dmp-gesture b { flex: none; width: 74px; color: var(--dmp-text); font-weight: 600; }
|
|
735
|
+
.dmp-gesture span { color: var(--dmp-muted); }
|
|
736
|
+
.dmp-status { margin: 7px 0; padding: 5px 7px; border-radius: 6px; background: rgba(255, 255, 255, 0.05); font-size: 11px; color: var(--dmp-muted); }
|
|
737
|
+
|
|
738
|
+
@media (max-height: 620px) {
|
|
739
|
+
.dmp[data-adaptive="true"] { width: 232px; padding: 8px 9px 9px; }
|
|
740
|
+
.dmp[data-adaptive="true"] .dmp-wp-list { max-height: 168px; }
|
|
741
|
+
.dmp[data-adaptive="true"] .dmp-fine { display: none; }
|
|
742
|
+
.dmp[data-adaptive="true"] .dmp-gesture { display: none; }
|
|
743
|
+
}
|
|
744
|
+
`,tm=`drone-minimap-styles`,nm=Math.PI/180,rm=10,im=[40,60,80,100,150,200,300],am=3.4,om=.55,sm=[2,5,10,25,50,100,200],cm=16,lm=`"Inter", "HarmonyOS Sans SC", system-ui, -apple-system, "Segoe UI", sans-serif`,um=`
|
|
745
|
+
.dcm {
|
|
746
|
+
--dcm-size: 186px;
|
|
747
|
+
--dcm-offset-x: 0px;
|
|
748
|
+
--dcm-offset-y: 0px;
|
|
749
|
+
--dcm-bg: rgba(9, 17, 22, 0.62);
|
|
750
|
+
--dcm-border: rgba(255, 255, 255, 0.16);
|
|
751
|
+
--dcm-grid: rgba(255, 255, 255, 0.06);
|
|
752
|
+
--dcm-ring: rgba(255, 255, 255, 0.17);
|
|
753
|
+
--dcm-obstacle: rgba(186, 188, 183, 0.32);
|
|
754
|
+
--dcm-obstacle-edge: rgba(214, 216, 210, 0.6);
|
|
755
|
+
--dcm-mission: #39d0b0;
|
|
756
|
+
--dcm-mission-done: rgba(57, 208, 176, 0.3);
|
|
757
|
+
--dcm-mission-active: #ffc53d;
|
|
758
|
+
--dcm-trail: rgba(93, 202, 165, 0.5);
|
|
759
|
+
--dcm-home: #35e08a;
|
|
760
|
+
--dcm-drone: #7fe3ff;
|
|
761
|
+
--dcm-fov: rgba(127, 227, 255, 0.13);
|
|
762
|
+
--dcm-text: rgba(226, 240, 246, 0.82);
|
|
763
|
+
position: absolute;
|
|
764
|
+
z-index: 5;
|
|
765
|
+
width: var(--dcm-size);
|
|
766
|
+
height: var(--dcm-size);
|
|
767
|
+
border-radius: 12px;
|
|
768
|
+
border: 0.5px solid var(--dcm-border);
|
|
769
|
+
background: var(--dcm-bg);
|
|
770
|
+
overflow: hidden;
|
|
771
|
+
pointer-events: none;
|
|
772
|
+
user-select: none;
|
|
773
|
+
}
|
|
774
|
+
.dcm[data-position="top-left"] { left: calc(14px + var(--dcm-offset-x)); top: calc(14px + var(--dcm-offset-y)); }
|
|
775
|
+
.dcm[data-position="top-right"] { right: calc(14px + var(--dcm-offset-x)); top: calc(14px + var(--dcm-offset-y)); }
|
|
776
|
+
.dcm[data-position="bottom-left"] { left: calc(14px + var(--dcm-offset-x)); bottom: calc(14px + var(--dcm-offset-y)); }
|
|
777
|
+
.dcm[data-position="bottom-right"] { right: calc(14px + var(--dcm-offset-x)); bottom: calc(14px + var(--dcm-offset-y)); }
|
|
778
|
+
.dcm[data-position="bottom-center"] { left: 50%; transform: translateX(-50%); bottom: calc(14px + var(--dcm-offset-y)); }
|
|
779
|
+
.dcm-canvas { display: block; width: 100%; height: 100%; }
|
|
780
|
+
`;function dm(){if(typeof document>`u`||document.getElementById(tm))return;let e=document.createElement(`style`);e.id=tm,e.textContent=um,document.head.appendChild(e)}function fm(e,t,n,r,i,a){let o=Math.min(a,r/2,i/2);e.beginPath(),e.moveTo(t+o,n),e.arcTo(t+r,n,t+r,n+i,o),e.arcTo(t+r,n+i,t,n+i,o),e.arcTo(t,n+i,t,n,o),e.arcTo(t,n,t+r,n,o),e.closePath()}function pm(e,t,n){let r=e.getPropertyValue(t).trim();return r.length>0?r:n}var mm=class{constructor(e,t={}){if(i(this,`fly`,void 0),i(this,`container`,void 0),i(this,`root`,void 0),i(this,`canvas`,void 0),i(this,`ctx`,void 0),i(this,`size`,void 0),i(this,`minRange`,void 0),i(this,`maxRange`,void 0),i(this,`showObstacles`,void 0),i(this,`showMission`,void 0),i(this,`showTrail`,void 0),i(this,`showFov`,void 0),i(this,`showGrid`,void 0),i(this,`colors`,void 0),i(this,`visible`,void 0),i(this,`destroyed`,!1),i(this,`manualRange`,null),i(this,`rangeCurrent`,120),i(this,`rangeTarget`,120),i(this,`rangeReady`,!1),i(this,`scale`,1),i(this,`originX`,0),i(this,`originZ`,0),i(this,`raf`,null),i(this,`lastTime`,0),i(this,`frameDrawn`,!1),typeof document>`u`)throw Error(`[drone-camera] DroneMiniMap 需要浏览器环境(document),Node 侧请勿实例化`);this.fly=e,this.size=Math.max(96,t.size??186),this.manualRange=t.range===void 0?null:t.range,this.minRange=Math.max(10,t.minRange??40),this.maxRange=Math.max(this.minRange,t.maxRange??300),this.showObstacles=t.showObstacles!==!1,this.showMission=t.showMission!==!1,this.showTrail=t.showTrail!==!1,this.showFov=t.showFov!==!1,this.showGrid=t.showGrid!==!1,this.visible=t.visible??!0,t.injectStyles!==!1&&dm(),this.container=t.container??document.body;let n=t.container??null;n&&getComputedStyle(n).position===`static`&&(n.style.position=`relative`),this.root=document.createElement(`div`),this.root.className=t.className?`dcm ${t.className}`:`dcm`,this.root.dataset.position=t.position??`bottom-right`,this.root.style.position=n?`absolute`:`fixed`,this.root.style.setProperty(`--dcm-size`,`${this.size}px`),t.offset?.x&&this.root.style.setProperty(`--dcm-offset-x`,`${Math.max(0,t.offset.x)}px`),t.offset?.y&&this.root.style.setProperty(`--dcm-offset-y`,`${Math.max(0,t.offset.y)}px`),this.visible||(this.root.style.display=`none`),this.canvas=document.createElement(`canvas`),this.canvas.className=`dcm-canvas`,this.root.appendChild(this.canvas),this.container.appendChild(this.root);let r=this.canvas.getContext(`2d`);if(!r)throw Error(`[drone-camera] DroneMiniMap 无法获取 2D 绘图上下文`);this.ctx=r;let a=Math.min(2,typeof window>`u`?1:window.devicePixelRatio||1);this.canvas.width=Math.round(this.size*a),this.canvas.height=Math.round(this.size*a),this.ctx.scale(a,a),this.colors=this.resolveColors(),this.lastTime=typeof performance>`u`?0:performance.now(),this.render(),this.start()}render(){this.destroyed||(this.frameDrawn=!0,this.drawFrame())}setVisible(e){this.visible=e,this.root.style.display=e?``:`none`}isVisible(){return this.visible}setRange(e){this.manualRange=e===null?null:Math.max(5,e),this.rangeReady=!1}getRange(){return this.rangeCurrent}refreshTheme(){this.colors=this.resolveColors(),this.drawFrame()}getStats(){let e=this.fly.sim;return{range:this.rangeCurrent,scale:this.scale,obstacleCount:this.showObstacles?e.obstacles.length:0,waypointCount:this.showMission?e.mission.length:0,trailPoints:this.fly.world?.getTrail().count??0,fovDeg:this.horizontalFov(),centerX:this.originX,centerZ:this.originZ}}hasDrawn(){return this.frameDrawn}stop(){this.raf!==null&&(cancelAnimationFrame(this.raf),this.raf=null)}destroy(){this.destroyed||(this.destroyed=!0,this.stop(),this.root.parentNode?.removeChild(this.root),this.container.childElementCount===0&&this.container.style.removeProperty(`position`),typeof document<`u`&&document.getElementById(tm)?.remove())}start(){if(typeof requestAnimationFrame!=`function`)return;let e=t=>{if(this.destroyed)return;this.raf=requestAnimationFrame(e);let n=Math.min(.25,Math.max(0,(t-this.lastTime)/1e3));this.lastTime=t,this.visible&&this.drawFrame(n)};this.raf=requestAnimationFrame(e)}resolveColors(){let e=getComputedStyle(this.root);return{grid:pm(e,`--dcm-grid`,`rgba(255,255,255,0.06)`),ring:pm(e,`--dcm-ring`,`rgba(255,255,255,0.17)`),obstacle:pm(e,`--dcm-obstacle`,`rgba(186,188,183,0.32)`),obstacleEdge:pm(e,`--dcm-obstacle-edge`,`rgba(214,216,210,0.6)`),mission:pm(e,`--dcm-mission`,`#39d0b0`),missionDone:pm(e,`--dcm-mission-done`,`rgba(57,208,176,0.3)`),missionActive:pm(e,`--dcm-mission-active`,`#ffc53d`),trail:pm(e,`--dcm-trail`,`rgba(93,202,165,0.5)`),home:pm(e,`--dcm-home`,`#35e08a`),drone:pm(e,`--dcm-drone`,`#7fe3ff`),fov:pm(e,`--dcm-fov`,`rgba(127,227,255,0.13)`),text:pm(e,`--dcm-text`,`rgba(226,240,246,0.82)`)}}horizontalFov(){let e=this.fly.camera;if(!e||this.fly.cameraMode!==`fpv`)return null;let t=Math.max(.001,e.zoom||1),n=e.fov*nm,r=2*Math.atan(Math.tan(n/2)/t),i=e.aspect||1;return 2*Math.atan(Math.tan(r/2)*i)/nm}updateRange(e,t){if(this.manualRange!==null){this.rangeCurrent=this.manualRange,this.rangeTarget=this.manualRange,this.rangeReady=!0;return}let n=e.position.x,r=e.position.z,i=this.minRange*.7;if(e.homeReady){let t=e.homePosition;i=Math.max(i,Math.hypot(n-t.x,r-t.z)+12)}for(let t of e.mission)i=Math.max(i,Math.hypot(n-t.x,r-t.z)+12);if(this.rangeTarget=Math.min(this.maxRange,Math.max(this.minRange,im.find(e=>e>=i)??this.maxRange)),!this.rangeReady){this.rangeCurrent=this.rangeTarget,this.rangeReady=!0;return}let a=Math.min(1,Math.max(0,t)*am);Math.abs(this.rangeCurrent-this.rangeTarget)<.001?this.rangeCurrent=this.rangeTarget:this.rangeCurrent+=(this.rangeTarget-this.rangeCurrent)*a}drawFrame(e=1/60){let t=this.ctx,n=this.size,r=this.fly.sim;t.clearRect(0,0,n,n),t.save(),fm(t,0,0,n,n,12),t.clip(),this.updateRange(r,e);let i=n/2;this.scale=(i-rm)/this.rangeCurrent,this.originX=r.position.x,this.originZ=r.position.z,this.showGrid&&this.drawGrid(),this.drawRings(),this.showObstacles&&this.drawObstacles(r.obstacles),this.showMission&&this.drawMission(r),this.showTrail&&this.drawTrail(),this.drawHome(r),this.showFov&&this.drawFov(r.heading),this.drawDrone(r.heading),this.drawCompass(),this.drawScaleLabel(),t.restore()}toX(e){return this.size/2+(e-this.originX)*this.scale}toY(e){return this.size/2+(e-this.originZ)*this.scale}gridStep(){for(let e of sm)if(e*this.scale>=cm)return e;return sm[sm.length-1]??200}drawGrid(){let e=this.ctx,t=this.gridStep(),n=this.rangeCurrent,r=Math.ceil((this.originX-n)/t),i=Math.floor((this.originX+n)/t),a=Math.ceil((this.originZ-n)/t),o=Math.floor((this.originZ+n)/t);e.strokeStyle=this.colors.grid,e.lineWidth=.5,e.beginPath();for(let n=r;n<=i;n+=1){let r=this.toX(n*t);e.moveTo(r,0),e.lineTo(r,this.size)}for(let n=a;n<=o;n+=1){let r=this.toY(n*t);e.moveTo(0,r),e.lineTo(this.size,r)}e.stroke()}drawRings(){let e=this.ctx,t=this.size/2,n=t-rm;e.strokeStyle=this.colors.ring,e.lineWidth=.5,e.setLineDash([3,4]);for(let r of[n,n*.5])e.beginPath(),e.arc(t,t,r,0,Math.PI*2),e.stroke();e.setLineDash([])}drawObstacles(e){if(e.length===0)return;let t=this.ctx;t.fillStyle=this.colors.obstacle,t.strokeStyle=this.colors.obstacleEdge,t.lineWidth=.5;for(let n of e){let e=this.toX(n.minX),r=this.toY(n.minZ),i=(n.maxX-n.minX)*this.scale,a=(n.maxZ-n.minZ)*this.scale;e+i<-10||e>this.size+rm||r+a<-10||r>this.size+rm||(t.beginPath(),t.rect(e,r,Math.max(2,i),Math.max(2,a)),t.fill(),t.stroke())}}drawMission(e){let t=e.mission;if(t.length===0)return;let n=this.ctx,r=e.missionStatus!==`idle`,i=r?e.missionIndex:-1,a=[],o=e.homeReady;if(o){let t=e.homePosition;a.push({x:this.toX(t.x),y:this.toY(t.z)})}for(let e of t)a.push({x:this.toX(e.x),y:this.toY(e.z)});let s=+!!o;n.save(),n.globalAlpha=r?1:.72,n.lineWidth=1.5,n.lineJoin=`round`;for(let e=0;e<a.length-1;e+=1){let t=a[e],r=a[e+1];if(!t||!r)continue;let o=e+1-s,c=i>=0&&o<=i;n.strokeStyle=c?this.colors.missionDone:this.colors.mission,c?n.setLineDash([3,3]):n.setLineDash([]),n.beginPath(),n.moveTo(t.x,t.y),n.lineTo(r.x,r.y),n.stroke()}n.setLineDash([]);let c=this.rangeCurrent<=150;n.font=`600 9px ${lm}`,n.textAlign=`center`,n.textBaseline=`middle`;for(let e=0;e<t.length;e+=1){let r=t[e];if(!r)continue;let a=this.toX(r.x),o=this.toY(r.z),s=e===i,l=i>=0&&e<i;n.beginPath(),n.arc(a,o,s?5.5:3.6,0,Math.PI*2),n.fillStyle=s?this.colors.missionActive:l?this.colors.missionDone:this.colors.mission,n.fill(),s&&(n.strokeStyle=this.colors.missionActive,n.lineWidth=1,n.beginPath(),n.arc(a,o,8.5,0,Math.PI*2),n.stroke()),c&&(n.fillStyle=this.colors.text,n.fillText(String(e+1),a,o-9))}n.restore()}drawTrail(){let e=this.fly.world?.getTrail();if(!e||e.count<2)return;let t=this.ctx,n=e.positions,r=Math.max(1,Math.floor(e.count/600));t.strokeStyle=this.colors.trail,t.lineWidth=1.5,t.lineJoin=`round`,t.beginPath();let i=!1;for(let a=0;a<e.count;a+=r){let e=n[a*3],r=n[a*3+2];if(e===void 0||r===void 0)continue;let o=this.toX(e),s=this.toY(r);i?t.lineTo(o,s):(t.moveTo(o,s),i=!0)}let a=n[(e.count-1)*3],o=n[(e.count-1)*3+2];i&&a!==void 0&&o!==void 0&&t.lineTo(this.toX(a),this.toY(o)),t.stroke()}drawHome(e){if(!e.homeReady)return;let t=this.ctx,n=e.homePosition,r=this.toX(n.x),i=this.toY(n.z);t.strokeStyle=this.colors.home,t.lineWidth=1.5,t.beginPath(),t.arc(r,i,8,0,Math.PI*2),t.stroke(),t.fillStyle=this.colors.home,t.font=`600 10px ${lm}`,t.textAlign=`center`,t.textBaseline=`middle`,t.fillText(`H`,r,i+.5)}drawFov(e){let t=this.horizontalFov();if(t===null)return;let n=this.ctx,r=this.rangeCurrent*om*this.scale,i=t/2*nm;n.save(),n.translate(this.size/2,this.size/2),n.rotate(e*nm),n.beginPath(),n.moveTo(0,0),n.arc(0,0,r,-Math.PI/2-i,-Math.PI/2+i),n.closePath(),n.fillStyle=this.colors.fov,n.fill(),n.restore()}drawDrone(e){let t=this.ctx;t.save(),t.translate(this.size/2,this.size/2),t.rotate(e*nm),t.beginPath(),t.moveTo(0,-9),t.lineTo(6.2,7),t.lineTo(0,3.8),t.lineTo(-6.2,7),t.closePath(),t.fillStyle=this.colors.drone,t.fill(),t.restore()}drawCompass(){let e=this.ctx,t=this.size-17;e.fillStyle=this.colors.drone,e.beginPath(),e.moveTo(t,6),e.lineTo(t-3.5,13),e.lineTo(t+3.5,13),e.closePath(),e.fill(),e.fillStyle=this.colors.text,e.font=`600 10px ${lm}`,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(`N`,t,20)}drawScaleLabel(){let e=this.ctx;e.fillStyle=this.colors.text,e.font=`500 10px ${lm}`,e.textAlign=`left`,e.textBaseline=`alphabetic`,e.fillText(`${Math.round(this.rangeCurrent)} m`,10,this.size-9)}},hm=271,gm=272,_m=274,vm=306,ym=34665,bm=34853,xm=33434,Sm=33437,Cm=34855,wm=36867,Tm=37386,Em=40962,Dm=40963,Om=41989,km=42036,Am=1,jm=2,Mm=3,Nm=4,Pm=5,Fm=6,Im={1:1,2:1,3:2,4:4,5:8,6:1,7:1,8:2,9:4,10:8,11:4,12:8};function Lm(e,t,n){return e.getUint16(t,n)}function Rm(e,t,n){return e.getUint32(t,n)}function zm(e,t,n,r){let i=new Map,a=t+n;if(a+2>e.byteLength)return i;let o=Lm(e,a,r);for(let t=0;t<o;t+=1){let n=a+2+t*12;if(n+12>e.byteLength)break;let o=Lm(e,n,r),s=Lm(e,n+2,r),c=Rm(e,n+4,r);i.set(o,{type:s,count:c,offset:n})}return i}function Bm(e,t,n,r){let i=Im[n.type];if(!i)return null;if(i*n.count<=4)return n.offset+8;let a=t+Rm(e,n.offset+8,r);return a<e.byteLength?a:null}function Vm(e,t,n,r,i){let a=Im[n.type],o=Bm(e,t,n,r);if(!a||o===null)return;let s=o+i*a;if(!(s+a>e.byteLength))switch(n.type){case 1:case 2:case 6:case 7:return e.getUint8(s);case 3:return Lm(e,s,r);case 8:return e.getInt16(s,r);case 4:return Rm(e,s,r);case 9:return e.getInt32(s,r);case 11:return e.getFloat32(s,r);case 12:return e.getFloat64(s,r);default:return}}function Hm(e,t,n,r,i=0){if(!n)return;if(n.type===11||n.type===12)return Vm(e,t,n,r,i);let a=Im[n.type],o=Bm(e,t,n,r);if(o===null)return;let s=o+i*(a??8);if(s+8>e.byteLength)return;let c=n.type===10?e.getInt32(s,r):Rm(e,s,r),l=n.type===10?e.getInt32(s+4,r):Rm(e,s+4,r);if(l!==0)return c/l}function Um(e,t,n,r){if(!n)return;let i=Bm(e,t,n,r);if(i===null)return;let a=``;for(let t=0;t<n.count;t+=1){let n=i+t;if(n>=e.byteLength)break;let r=e.getUint8(n);if(r===0)break;a+=String.fromCharCode(r)}let o=a.trim();return o.length?o:void 0}function Wm(e,t,n,r){if(n)return n.type===5||n.type===10?Hm(e,t,n,r):Vm(e,t,n,r,0)}function Gm(e,t,n,r){if(!n||n.count<3)return;let i=Hm(e,t,n,r,0),a=Hm(e,t,n,r,1),o=Hm(e,t,n,r,2);if(i!==void 0&&a!==void 0&&o!==void 0)return i+a/60+o/3600}function Km(e){if(!e)return;let t=/^(\d{4}):(\d{2}):(\d{2})[ T](\d{2}):(\d{2}):(\d{2})/.exec(e);if(!t)return;let[,n,r,i,a,o,s]=t;return`${n}-${r}-${i}T${a}:${o}:${s}`}function qm(e,t){if(t+8>e.byteLength)return null;let n=Lm(e,t,!1),r;if(n===18761)r=!0;else if(n===19789)r=!1;else return null;if(Lm(e,t+2,r)!==42)return null;let i=[],a=Rm(e,t+4,r);if(a===0)return null;let o=zm(e,t,a,r);if(o.size===0)return null;let s={warnings:i};s.make=Um(e,t,o.get(hm),r),s.model=Um(e,t,o.get(gm),r),s.orientation=Wm(e,t,o.get(_m),r),s.dateTime=Km(Um(e,t,o.get(vm),r));let c=Wm(e,t,o.get(ym),r),l=c===void 0?null:zm(e,t,c,r);l?(s.lensModel=Um(e,t,l.get(km),r),s.dateTimeOriginal=Km(Um(e,t,l.get(wm),r)),s.exposureTimeSeconds=Hm(e,t,l.get(xm),r),s.fNumber=Hm(e,t,l.get(Sm),r),s.isoSpeed=Wm(e,t,l.get(Cm),r),s.focalLengthMm=Hm(e,t,l.get(Tm),r),s.focalLength35mm=Wm(e,t,l.get(Om),r),s.pixelXDimension=Wm(e,t,l.get(Em),r),s.pixelYDimension=Wm(e,t,l.get(Dm),r)):i.push(`缺少 Exif 子 IFD(焦距 / 原始拍摄时间等字段不可得)`);let u=Wm(e,t,o.get(bm),r),d=u===void 0?null:zm(e,t,u,r);if(d){let n={},i=Gm(e,t,d.get(jm),r),a=Um(e,t,d.get(Am),r);i!==void 0&&(n.latitude=a?.toUpperCase()===`S`?-i:i);let o=Gm(e,t,d.get(Nm),r),c=Um(e,t,d.get(Mm),r);o!==void 0&&(n.longitude=c?.toUpperCase()===`W`?-o:o);let l=Hm(e,t,d.get(Fm),r),u=Wm(e,t,d.get(Pm),r);u!==void 0&&(n.altitudeRef=u),l!==void 0&&(n.altitude=u===1?-l:l),Object.keys(n).length&&(s.gps=n)}else i.push(`照片不含 GPS 信息(无法做地理定位,只能当作局部坐标成果)`);return s}function Jm(e){if(e.byteLength<4)return null;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(Lm(t,0,!1)!==65496)return null;let n=2;for(;n+4<=t.byteLength;){if(t.getUint8(n)!==255){n+=1;continue}let e=t.getUint8(n+1);if(e===255||e===1||e>=208&&e<=217){n+=2;continue}if(e===218)break;let r=Lm(t,n+2,!1);if(r<2)break;let i=n+4;if(e===225&&i+6<=t.byteLength&&Rm(t,i,!1)===1165519206&&Lm(t,i+4,!1)===0)return qm(t,i+6);n=i+r-2}return null}async function Ym(e,t=262144){let n=e.slice(0,Math.min(t,e.size)),r;try{r=new Uint8Array(await n.arrayBuffer())}catch{return null}try{return Jm(r)}catch{return null}}var Xm=1,Zm=`quaternion [x,y,z,w]; active camera-local-to-world rotation; camera forward=-Z, right=+X, up=+Y`;function Qm(e){return typeof e==`number`&&Number.isFinite(e)}function $m(e,t){return Array.isArray(e)&&e.length===t&&e.every(Qm)}function eh(e){return e.slice()}function th(e,t){let n=e;return{model:t.cameraModel??(n?.fx!==void 0||n?.fy!==void 0?`PINHOLE`:`UNKNOWN`),width:n?.width??0,height:n?.height??0,...n?.fx===void 0?{}:{fx:n.fx},...n?.fy===void 0?{}:{fy:n.fy},...n?.cx===void 0?{}:{cx:n.cx},...n?.cy===void 0?{}:{cy:n.cy},...n?.horizontalFovDeg===void 0?{}:{horizontalFovDeg:n.horizontalFovDeg},...n?.verticalFovDeg===void 0?{}:{verticalFovDeg:n.verticalFovDeg},...n?.distortion===void 0?{}:{distortion:[...n.distortion]},projection:t.projection??`perspective`}}function nh(e,t,n){if(e.model!==t.model||e.projection!==t.projection||![`width`,`height`,`fx`,`fy`,`cx`,`cy`,`horizontalFovDeg`,`verticalFovDeg`,`zoom`].every(r=>{let i=e[r],a=t[r];if(typeof i!=`number`||typeof a!=`number`)return i===a;let o=Math.max(1,Math.abs(i),Math.abs(a));return Math.abs(i-a)<=n*o}))return!1;let r=e.distortion??[],i=t.distortion??[];return r.length===i.length&&r.every((e,t)=>{let r=i[t];return Qm(r)&&Math.abs(e-r)<=n*Math.max(1,Math.abs(e),Math.abs(r))})}function rh(e,t){let n=e.replace(/\\/g,`/`),r=t.replace(/\\/g,`/`).replace(/\/+$/,``);return!r||n.startsWith(`${r}/`)?n:`${r}/${n.replace(/^\/+/,``)}`}function ih(e){switch(e){case`ecef`:return`Cesium ECEF`;case`local-enu`:return`ENU`;case`project-local`:return`project-local`;default:return`unknown`}}function ah(e,t,n){let r=[...new Set(t.map(e=>e.cameraPose?.coordinateFrame).filter(Boolean))],i=r.length===1?ih(r[0]):r.length>1?`mixed`:`unknown`,a=e.options.georeference,o=i===`Cesium ECEF`&&a?cf(a):null,s=o?lf([0,0,0],o):null,c={source:i,target:i===`Cesium ECEF`?`ENU`:i,...i!==`unknown`&&i!==`mixed`&&(i!==`Cesium ECEF`||o!==null)?{translation:[0,0,0],rotation:[0,0,0,1],scale:1}:{parametersAvailable:!1},...a?{origin:{longitude:a.longitude,latitude:a.latitude,altitude:a.altitude??0}}:{},...o&&s?{parametersAvailable:!0,translation:s,rotation:[-o.enuToEcefRotation[0],-o.enuToEcefRotation[1],-o.enuToEcefRotation[2],o.enuToEcefRotation[3]],ecefOrigin:[...o.ecefOrigin],basis:{east:[...o.east],north:[...o.north],up:[...o.up]},enuToEcefRotation:[...o.enuToEcefRotation],matrix:[o.east[0],o.east[1],o.east[2],s[0],o.north[0],o.north[1],o.north[2],s[1],o.up[0],o.up[1],o.up[2],s[2],0,0,0,1],matrixOrder:`row-major`}:{},...n?.transform??{}};return{world:n?.world??(i===`Cesium ECEF`?`Cesium ECEF`:i),local:n?.local??(i===`Cesium ECEF`?`ENU`:i),units:n?.units??`meters`,transform:c}}function oh(e){return e.validation.status===`invalid`?`failed`:e.validation.status===`pending`?`pending`:`success`}function sh(e,t,n){let r=e.cameraPose,i=e.cameraIntrinsics?th(e.cameraIntrinsics,{}):void 0;return{id:e.id,file:rh(e.fileName,n),timestamp:e.capturedAt,...r?{position:eh(r.position),rotation:eh(r.rotation),coordinateFrame:r.coordinateFrame}:{},rotationConvention:Zm,captureStatus:oh(e),source:e.source,mimeType:e.mimeType,sizeBytes:e.sizeBytes,width:e.cameraIntrinsics?.width??t.width,height:e.cameraIntrinsics?.height??t.height,...i?{intrinsics:i}:{},...e.metadata.cameraModel?{cameraModel:e.metadata.cameraModel}:{},...e.metadata.engine?{engine:e.metadata.engine}:{},...e.metadata.sceneId?{sceneId:e.metadata.sceneId}:{},...e.metadata.sceneVersion?{sceneVersion:e.metadata.sceneVersion}:{},...e.imageUrl?{contentHash:ch(e.imageUrl)}:{},validation:{status:e.validation.status,messages:[...e.validation.messages]}}}function ch(e){let t=2166136261;for(let n=0;n<e.length;n+=1)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return`fnv1a32-${(t>>>0).toString(16).padStart(8,`0`)}`}function lh(e,t={}){let n=e.images.find(e=>e.cameraIntrinsics)?.cameraIntrinsics,r=th(n,t);return{schemaVersion:1,captureId:t.captureId??e.id,createdAt:t.createdAt??e.createdAt,coordinateFrame:ah(e,e.images,t.coordinateFrame),camera:r,images:e.images.map(e=>sh(e,r,t.imageDirectory??`images`))}}var uh=lh,dh=lh;function fh(e,t=2){return JSON.stringify(e,null,t)}function ph(e){let t=typeof e==`string`?JSON.parse(e):e;if(!t||t.schemaVersion!==1)throw Error(`Unsupported capture manifest schema version: ${String(t?.schemaVersion)}`);if(!Array.isArray(t.images))throw Error(`Capture manifest images must be an array`);return t}function Q(e,t,n,r){return{severity:e,code:t,message:n,...r?{imageId:r}:{}}}function mh(e,t={}){let n=[],r=[],i=e=>{e.severity===`error`?n.push(e):r.push(e)},a=t.requirePose??!0,o=t.requireIntrinsics??!0,s=t.checkBlankImages??!0,c=t.rejectDuplicates??!0,l=t.intrinsicsTolerance??.001,u=Array.isArray(e?.images)?e.images:[],d=[];(!e||e.schemaVersion!==1)&&i(Q(`error`,`schema-version`,`Unsupported or missing manifest schemaVersion`)),e?.captureId||i(Q(`error`,`capture-id`,`captureId is required`)),(!e?.createdAt||Number.isNaN(Date.parse(e.createdAt)))&&i(Q(`error`,`created-at`,`createdAt must be a valid ISO timestamp`)),(!e?.coordinateFrame?.world||!e.coordinateFrame.local)&&i(Q(`error`,`coordinate-frame`,`coordinateFrame.world and local are required`)),(!e?.coordinateFrame?.transform?.source||!e.coordinateFrame.transform.target)&&i(Q(`error`,`coordinate-transform`,`coordinateFrame.transform must declare source and target`)),e?.coordinateFrame?.transform?.parametersAvailable===!1&&i(Q(`error`,`coordinate-transform`,`Coordinate transform parameters are unavailable`));let f=e?.camera;(!f||!f.model||!Qm(f.width)||!Qm(f.height)||f.width<=0||f.height<=0)&&i(Q(`error`,`camera-intrinsics`,`camera model and positive image dimensions are required`)),o&&(!f||!Qm(f.fx)||!Qm(f.fy)||!Qm(f.cx)||!Qm(f.cy))&&i(Q(`error`,`camera-intrinsics`,`camera fx/fy/cx/cy must be finite`));let p=new Set,m=new Map,h=new Map,g=new Map,_=0;for(let e of u){_+=1,e?.id||i(Q(`error`,`image-id`,`Image id is required`)),e?.id&&p.has(e.id)&&i(Q(`error`,`duplicate-id`,`Duplicate image id: ${e.id}`,e.id)),e?.id&&p.add(e.id),e?.captureStatus!==`success`&&i(Q(`error`,`capture-status`,`Image captureStatus must be success`,e?.id)),e?.file||i(Q(`error`,`image-file`,`Image file path is required`,e?.id)),(!e?.timestamp||Number.isNaN(Date.parse(e.timestamp)))&&i(Q(`error`,`timestamp`,`Image timestamp must be valid`,e?.id)),e?.mimeType?.startsWith(`image/`)||i(Q(`error`,`mime-type`,`Image MIME type must start with image/`,e?.id)),(!Qm(e?.sizeBytes)||(e?.sizeBytes??0)<=0)&&i(Q(`error`,`empty-file`,`Image file is empty or size is unknown`,e?.id));let n=e?.width??f?.width,r=e?.height??f?.height;!Qm(n)||!Qm(r)||n<=0||r<=0?i(Q(`error`,`image-dimensions`,`Image dimensions must be positive`,e?.id)):f&&(n!==f.width||r!==f.height)&&i(Q(`error`,`image-dimensions-mismatch`,`Image dimensions do not match the manifest camera`,e?.id));let o=t.imageQuality?.[e?.id]??t.imageQuality?.[e?.file]??e?.quality;o?.decodable===!1&&i(Q(`error`,`decode`,`Image cannot be decoded`,e?.id)),s&&(o?.blank===!0||o?.uniform===!0)&&i(Q(`error`,`blank-image`,`Image is uniformly black/white or otherwise blank`,e?.id)),s&&Qm(o?.variance)&&o.variance<=1e-6&&i(Q(`error`,`blank-image`,`Image has no measurable pixel variation`,e?.id)),s&&Qm(o?.meanLuma)&&(o.meanLuma<=1||o.meanLuma>=254)&&(!Qm(o.variance)||o.variance<=1)&&i(Q(`error`,`blank-image`,`Image is effectively pure black or white`,e?.id)),e?.rotationConvention||i(Q(`error`,`rotation-convention`,`rotationConvention is required`,e?.id)),a&&(!$m(e?.position,3)||!$m(e?.rotation,4))&&i(Q(`error`,`pose`,`Image position and quaternion must contain finite values`,e?.id)),$m(e?.rotation,4)&&Math.hypot(...e.rotation)<1e-9&&i(Q(`error`,`pose-quaternion`,`Image rotation quaternion has zero length`,e.id));let u=e?.file;if(u&&m.has(u)){let t=m.get(u);d.push([t,e.id]),c&&i(Q(`error`,`duplicate-file`,`Duplicate image file: ${u}`,e.id)),c&&i(Q(`error`,`duplicate-content`,`Duplicate image content (same file path)`,e.id))}else u&&m.set(u,e.id);let v=e?.contentHash;if(v&&h.has(v)){let t=h.get(v);d.push([t,e.id]),c&&i(Q(`error`,`duplicate-content`,`Duplicate image content hash`,e.id))}else v&&h.set(v,e.id);if($m(e?.position,3)&&$m(e?.rotation,4)){let t=`${e.position.join(`,`)}|${e.rotation.join(`,`)}`;if(g.has(t)){let n=g.get(t);d.push([n,e.id]),c&&i(Q(`error`,`duplicate-pose`,`Duplicate camera pose`,e.id))}else g.set(t,e.id)}e?.intrinsics&&f&&!nh(f,e.intrinsics,l)&&i(Q(`error`,`intrinsics-mismatch`,`Image camera intrinsics do not match the manifest camera`,e.id))}u.length===0&&i(Q(`error`,`no-images`,`Manifest contains no images`)),u.length===1&&r.push(Q(`warning`,`single-image`,`A single image cannot provide photogrammetric coverage`));let v=[...n,...r],y=n.length?`invalid`:r.length?`warning`:`valid`;return{valid:n.length===0,passed:n.length===0,status:y,imageCount:u.length,checkedImages:_,errors:n,warnings:r,issues:v,duplicateImageIds:d}}function hh(e,t={},n={}){return mh(lh(e,n),t)}var gh=class{constructor(e={}){i(this,`options`,void 0),this.options={...e}}validate(e,t={}){return e.schemaVersion===1?mh(e,this.options):hh(e,this.options,t)}static validate(e,t={},n={}){return e.schemaVersion===1?mh(e,t):hh(e,t,n)}},_h=`drone-camera/capture-session`,vh=1,yh=200;function bh(e){let t=[],n=`valid`,r=e=>{t.push(e),n===`valid`&&(n=`warning`)},i=e=>{t.push(e)},a=e=>{t.push(e),n=`invalid`};e.mimeType.startsWith(`image/`)||a(`不是图像类型(${e.mimeType||`未知`})`),e.sizeBytes<=0&&a(`文件为空`),!e.cameraPose&&e.source===`virtual-camera`&&r(`缺少相机位姿(无法参与 SfM 相机解算)`),(!e.cameraIntrinsics||e.cameraIntrinsics.calibrationSource===`unknown`)&&r(`相机内参未知(SfM 需自行估计,精度受限)`),e.source===`real-camera`?((e.metadata.latitude===void 0||e.metadata.longitude===void 0)&&r(`缺少 GPS 经纬度(无法地理配准)`),e.metadata.cameraModel||r(`缺少相机型号信息`),e.metadata.exif||r(`未读到 EXIF 元数据`)):e.metadata.sceneId||i(`未记录场景标识(成果无法与特定场景版本对应)`);let{width:o,height:s}=e.cameraIntrinsics??{width:0,height:0};return(o<=0||s<=0)&&a(`图像尺寸无效`),o>0&&s>0&&Math.min(o,s)<200&&r(`图像过小(${o}×${s}),对重建几乎没有贡献`),{status:n,messages:t}}function xh(e){let t={total:e.images.length,valid:0,warning:0,invalid:0,pending:0,withGps:0,withPose:0};for(let n of e.images)t[n.validation.status]+=1,n.metadata.latitude!==void 0&&n.metadata.longitude!==void 0&&(t.withGps+=1),n.cameraPose&&(t.withPose+=1);return t}function Sh(e,t,n){let r={width:t,height:n,calibrationSource:`unknown`},i=e?.focalLength35mm;if(!i||i<=0||t<=0||n<=0)return r;let a=2*Math.atan(36/(2*i)),o=t/(2*Math.tan(a/2)),s=o,c=2*Math.atan(n/(2*s));return{width:t,height:n,fx:o,fy:s,cx:t/2,cy:n/2,horizontalFovDeg:a*180/Math.PI,verticalFovDeg:c*180/Math.PI,calibrationSource:`exif`}}function Ch(){return`img-${Math.random().toString(36).slice(2,10)}`}function wh(){return`cap-${Math.random().toString(36).slice(2,10)}`}function Th(e,t){return Math.hypot(e[0]-t[0],e[1]-t[1],e[2]-t[2])}var Eh=class{constructor(e={}){i(this,`sessions`,new Map),i(this,`listeners`,new Set),i(this,`now`,void 0),i(this,`createId`,void 0),i(this,`provider`,void 0),i(this,`auto`,new Map),this.provider=e.provider??null,this.now=e.now??(()=>new Date),this.createId=e.createId??Ch}setProvider(e){this.provider=e}getCaptureIntrinsics(){let e=this.provider?.getCaptureCamera()?.intrinsics;return e?{...e}:null}buildManifest(e,t={}){let n=this.sessions.get(e);return n?lh(n,t):null}exportManifest(e,t={},n=2){let r=this.buildManifest(e,t);return r?fh(r,n):``}validateSession(e,t={}){let n=this.buildManifest(e,t);return n?mh(n,t):null}createSession(e){let t=this.now().toISOString(),n={id:wh(),options:{includeCameraMetadata:!0,...e},status:`created`,images:[],createdAt:t,updatedAt:t,engine:this.provider?.engine,autoCapturing:!1};return this.sessions.set(n.id,n),this.emit(n),n}getSession(e){return this.sessions.get(e)??null}listSessions(){return[...this.sessions.values()]}get activeSession(){let e=null;for(let t of this.sessions.values())(!e||t.updatedAt>=e.updatedAt)&&(e=t);return e}pauseSession(e){let t=this.sessions.get(e);t&&(this.stopAutoCapture(e),t.status=`paused`,this.touch(t))}resumeSession(e){let t=this.sessions.get(e);t&&(t.status=`capturing`,this.touch(t))}finishSession(e){let t=this.sessions.get(e);return t?(this.stopAutoCapture(e),t.status=`finished`,this.touch(t),t):null}removeSession(e){this.stopAutoCapture(e),this.sessions.delete(e)}removeImage(e,t){let n=this.sessions.get(e);if(!n)return!1;let r=n.images.findIndex(e=>e.id===t);if(r<0)return!1;let[i]=n.images.splice(r,1);if(i?.localBlob&&i.imageUrl?.startsWith(`blob:`))try{URL.revokeObjectURL(i.imageUrl)}catch{}return this.touch(n),!0}clearImages(e){let t=this.sessions.get(e);if(t){for(let e of t.images)if(e.imageUrl?.startsWith(`blob:`))try{URL.revokeObjectURL(e.imageUrl)}catch{}t.images=[],this.touch(t)}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}async captureVirtualImage(e,t={}){let n=this.sessions.get(e);if(!n||n.status===`finished`||n.status===`failed`)return null;let r=this.provider;if(!r)return null;let i=t.view??null,a=r.setCaptureView?.bind(r);i&&a&&a(i);try{let e=await r.requestPhoto();if(!e)return null;let i=e.camera??r.getCaptureCamera(),a=this.buildVirtualImage(n,e,i,t.panorama);return n.images.push(a),n.status===`created`&&(n.status=`capturing`),this.touch(n),a}finally{i&&a&&a(null)}}get canSpinBody(){return typeof this.provider?.spinBodyTo==`function`}getBodyHeading(){let e=this.provider?.getBodyHeading?.();return typeof e==`number`&&Number.isFinite(e)?e:null}spinBodyTo(e){this.provider?.spinBodyTo?.(e)}buildVirtualImage(e,t,n,r){let i=this.now().toISOString(),{width:a,height:o}={width:t.width,height:t.height},s=n?{...n.intrinsics,width:a,height:o}:{width:a,height:o,calibrationSource:`unknown`},c=n?.geo??(n&&n.pose.coordinateFrame===`local-enu`&&e.options.georeference?Ah(n.pose.position,e.options.georeference):void 0),l={id:this.createId(),source:`virtual-camera`,fileName:`virtual-${i.replace(/[:.]/g,`-`)}.png`,mimeType:`image/png`,sizeBytes:Dh(t.dataUrl),capturedAt:i,imageUrl:t.dataUrl,cameraIntrinsics:s,cameraPose:n?.pose,metadata:{latitude:c?.latitude,longitude:c?.longitude,altitude:c?.altitude,cameraModel:`虚拟相机(场景渲染)`,sceneId:n?.scene?.id??e.options.sceneId,sceneVersion:n?.scene?.version??e.options.sceneVersion,engine:n?this.provider?.engine:void 0,panorama:r},validation:{status:`pending`,messages:[]}};return l.validation=bh(l),l}startAutoCapture(e,t={}){let n=this.sessions.get(e);if(!n)return!1;let r=Math.max(0,t.intervalMs??n.options.captureIntervalMs??0),i=Math.max(0,t.distanceMeters??n.options.distanceIntervalMeters??0);if(r<=0&&i<=0)return!1;this.stopAutoCapture(e),n.options.captureIntervalMs=r,n.options.distanceIntervalMeters=i;let a={timer:setInterval(()=>void this.tickAuto(e),yh),intervalMs:r,distanceMeters:i,lastShotAt:0,lastPosition:null,busy:!1};return this.auto.set(e,a),n.autoCapturing=!0,(n.status===`created`||n.status===`paused`)&&(n.status=`capturing`),this.touch(n),this.tickAuto(e,!0),!0}async tickAuto(e,t=!1){let n=this.sessions.get(e),r=this.auto.get(e);if(!n||!r||r.busy)return;let i=this.provider?.getCaptureCamera()?.pose.position??null,a=this.now().getTime()-r.lastShotAt,o=i&&r.lastPosition?Th(i,r.lastPosition):1/0,s=r.intervalMs>0&&a>=r.intervalMs,c=r.distanceMeters>0&&o>=r.distanceMeters;if(t||s||c){r.busy=!0;try{if(!await this.captureVirtualImage(e))return;r.lastShotAt=this.now().getTime();let t=this.provider?.getCaptureCamera()?.pose.position??i;r.lastPosition=t?[...t]:null}finally{r.busy=!1}}}stopAutoCapture(e){let t=this.auto.get(e);if(!t)return;clearInterval(t.timer),this.auto.delete(e);let n=this.sessions.get(e);n&&(n.autoCapturing=!1,this.touch(n))}isAutoCapturing(e){return this.auto.has(e)}async importRealImages(e,t){let n=this.sessions.get(e);if(!n)return[];let r=Array.from(t),i=[];for(let e of r){let t=await this.buildRealImage(e);n.images.push(t),i.push(t)}return n.status===`created`&&(n.status=`capturing`),this.touch(n),i}async buildRealImage(e){let t=await Ym(e),n=/jpe?g$/i.test(e.type)||/\.jpe?g$/i.test(e.name),r=await kh(e,t),i=Sh(t,r.width,r.height),a=Oh(t?.dateTimeOriginal)??this.now().toISOString(),o=t?.gps,s=o?.latitude!==void 0&&o?.longitude!==void 0,c={id:this.createId(),source:`real-camera`,fileName:e.name,mimeType:e.type||(n?`image/jpeg`:``),sizeBytes:e.size,capturedAt:a,localBlob:e,cameraIntrinsics:i,metadata:{latitude:s?o?.latitude:void 0,longitude:s?o?.longitude:void 0,altitude:o?.altitude,cameraModel:[t?.make,t?.model].filter(Boolean).join(` `)||void 0,exif:t??void 0,rtkFixed:void 0},validation:{status:`pending`,messages:[]}};return typeof URL<`u`&&typeof URL.createObjectURL==`function`&&(c.imageUrl=URL.createObjectURL(e)),c.validation=bh(c),c}exportSession(e,t=`json`){let n=this.sessions.get(e);return n?t===`manifest`?this.exportManifest(e):t===`csv`?this.toCsv(n):this.toJson(n):t===`csv`?``:`{}`}toJson(e){return JSON.stringify({format:_h,version:1,exportedAt:this.now().toISOString(),frame:{virtual:`local-enu: 原点 = 起飞点(返航点),x 东 / y 北 / z 上,单位米`,real:`metadata.longitude / latitude 为 WGS84 十进制度,altitude 为 GPS 海拔(米)`,quaternion:`[x, y, z, w]`},session:{...e,images:void 0},summary:xh(e),images:e.images.map(e=>this.toExportImage(e))},null,2)}toExportImage(e){let{localBlob:t,imageUrl:n,...r}=e;return r}toCsv(e){let t=e=>{if(e==null)return``;let t=String(e);return/[",\r\n]/.test(t)?`"${t.replace(/"/g,`""`)}"`:t},n=`序号.来源.引擎.文件名.采集时间.图像宽.图像高.fx.fy.水平视场角(度).内参来源.坐标系.相机X.相机Y.相机Z.四元数x.四元数y.四元数z.四元数w.经度.纬度.高度(m).相机型号.场景.全景组.全景模式.全景序号.机身偏航(度).取景俯仰(度).校验.备注`.split(`.`),r=e.images.map((e,n)=>{let r=e.cameraPose,i=e.cameraIntrinsics;return[n+1,e.source,e.metadata.engine,e.fileName,e.capturedAt,i?.width,i?.height,i?.fx===void 0?void 0:Number(i.fx.toFixed(3)),i?.fy===void 0?void 0:Number(i.fy.toFixed(3)),i?.horizontalFovDeg===void 0?void 0:Number(i.horizontalFovDeg.toFixed(3)),i?.calibrationSource,r?.coordinateFrame,r?.position[0],r?.position[1],r?.position[2],r?.rotation[0],r?.rotation[1],r?.rotation[2],r?.rotation[3],e.metadata.longitude,e.metadata.latitude,e.metadata.altitude,e.metadata.cameraModel,e.metadata.sceneId,e.metadata.panorama?.group,e.metadata.panorama?.mode,e.metadata.panorama?`${e.metadata.panorama.index}/${e.metadata.panorama.total}`:void 0,e.metadata.panorama?.bodyYaw,e.metadata.panorama?.pitch,e.validation.status,e.validation.messages.join(` / `)].map(t)});return[n.join(`,`),...r.map(e=>e.join(`,`))].join(`\r
|
|
781
|
+
`)}touch(e){e.updatedAt=this.now().toISOString(),this.emit(e)}emit(e){for(let t of this.listeners)t(e)}};function Dh(e){let t=e.indexOf(`,`);if(t<0)return 0;let n=e.length-t-1;return Math.round(n*3/4)}function Oh(e){if(!e)return;let t=new Date(e);return Number.isNaN(t.getTime())?void 0:t.toISOString()}async function kh(e,t){let n={width:t?.pixelXDimension??0,height:t?.pixelYDimension??0},r=globalThis.createImageBitmap;if(typeof r!=`function`)return n;try{let t=await r(e),i={width:t.width,height:t.height};return typeof t.close==`function`&&t.close(),i.width&&i.height?i:n}catch{return n}}function Ah(e,t){let n=111320,r=n*Math.cos(t.latitude*Math.PI/180);return{longitude:t.longitude+(r>0?e[0]/r:0),latitude:t.latitude+e[1]/n,altitude:(t.altitude??0)+e[2]}}function $(e){let t={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};return e.replace(/[&<>"']/g,e=>t[e]??e)}function jh(e){return!Number.isFinite(e)||e<=0?`–`:e<1024?`${e}B`:e<1048576?`${(e/1024).toFixed(0)}KB`:`${(e/1024/1024).toFixed(1)}MB`}function Mh(e,t){let n=document.createElement(`a`);n.href=e,n.download=t,n.rel=`noopener`,document.body.appendChild(n),n.click(),n.remove()}async function Nh(e){if(e.length===0)throw Error(`当前会话没有可打包的图片`);if(e.length>65535)throw RangeError(`图片数量超过 ZIP 格式支持的上限`);let t=new TextEncoder,n=[],r=[],i=new Set,a=0,o=new Date,s=o.getHours()<<11|o.getMinutes()<<5|Math.floor(o.getSeconds()/2),c=Math.max(1980,o.getFullYear())-1980<<9|o.getMonth()+1<<5|o.getDate();for(let[o,l]of e.entries()){let e;if(l.localBlob)e=l.localBlob;else if(l.imageUrl){let t=await fetch(l.imageUrl);if(!t.ok)throw Error(`读取图片失败(${l.fileName}):HTTP ${t.status}`);e=await t.blob()}else throw Error(`图片缺少原始数据:${l.fileName}`);let u=Ph(l.fileName),d=u;if(i.has(d)){let e=u.lastIndexOf(`.`),t=e>0?u.slice(0,e):u,n=e>0?u.slice(e):``;for(d=`${t}-${String(o+1).padStart(3,`0`)}${n}`;i.has(d);)d=`${t}-${String(o+1).padStart(3,`0`)}-${i.size}${n}`}i.add(d);let f=t.encode(d);if(f.length>65535)throw RangeError(`图片文件名过长:${l.fileName}`);if(e.size>4294967295)throw RangeError(`图片超过 ZIP 单文件大小上限:${l.fileName}`);let p=await Fh(e),m=new Uint8Array(new ArrayBuffer(30+f.length)),h=new DataView(m.buffer);h.setUint32(0,67324752,!0),h.setUint16(4,20,!0),h.setUint16(6,2048,!0),h.setUint16(8,0,!0),h.setUint16(10,s,!0),h.setUint16(12,c,!0),h.setUint32(14,p,!0),h.setUint32(18,e.size,!0),h.setUint32(22,e.size,!0),h.setUint16(26,f.length,!0),m.set(f,30),n.push(m,e);let g=new Uint8Array(new ArrayBuffer(46+f.length)),_=new DataView(g.buffer);if(_.setUint32(0,33639248,!0),_.setUint16(4,20,!0),_.setUint16(6,20,!0),_.setUint16(8,2048,!0),_.setUint16(10,0,!0),_.setUint16(12,s,!0),_.setUint16(14,c,!0),_.setUint32(16,p,!0),_.setUint32(20,e.size,!0),_.setUint32(24,e.size,!0),_.setUint16(28,f.length,!0),_.setUint32(42,a,!0),g.set(f,46),r.push(g),a+=m.length+e.size,a>4294967295)throw RangeError(`图片总大小超过 ZIP 格式支持的上限`)}let l=r.reduce((e,t)=>e+t.length,0);if(l>4294967295||a+l>4294967295)throw RangeError(`图片总大小超过 ZIP 格式支持的上限`);let u=new Uint8Array(new ArrayBuffer(22)),d=new DataView(u.buffer);d.setUint32(0,101010256,!0),d.setUint16(8,e.length,!0),d.setUint16(10,e.length,!0),d.setUint32(12,l,!0),d.setUint32(16,a,!0);for(let e of r)n.push(e);return n.push(u),new Blob(n,{type:`application/zip`})}function Ph(e){return e.replace(/[\\/:*?"<>|\u0000-\u001f]/g,`_`).replace(/^\.+/,``).trim()||`image`}async function Fh(e){let t=new Uint32Array(256);for(let e=0;e<t.length;e+=1){let n=e;for(let e=0;e<8;e+=1)n=n&1?3988292384^n>>>1:n>>>1;t[e]=n>>>0}let n=4294967295,r=new Uint8Array(await e.arrayBuffer());for(let e of r)n=t[(n^e)&255]^n>>>8;return(n^4294967295)>>>0}var Ih={valid:`有效`,warning:`警告`,invalid:`无效`,pending:`待检`},Lh={valid:`✓`,warning:`!`,invalid:`×`,pending:`·`};function Rh(e){return e===`pano-wide`?`广角`:e===`pano-180`?`180° 全景`:e===`pano-360`?`360° 全景`:e}var zh=`__ungrouped__`;function Bh(e){let t=[],n={key:zh,kind:`single`,label:`单张影像`,images:[],indexes:[],complete:!1},r=new Map;e.forEach((e,i)=>{let a=e.metadata.panorama?.group;if(!a){n.images.push(e),n.indexes.push(i+1);return}let o=r.get(a);o||(o=[],r.set(a,o),t.push(a)),o.push({image:e,sequence:i+1})});let i=[];for(let e of t){let t=r.get(e);if(!t?.length)continue;let n=t[0]?.image.metadata.panorama;if(!n)continue;t.sort((e,t)=>(e.image.metadata.panorama?.index??0)-(t.image.metadata.panorama?.index??0));let a=n.total??t.length;i.push({key:e,kind:`panorama`,mode:n.mode,label:Rh(n.mode),images:t.map(e=>e.image),indexes:t.map(e=>e.sequence),total:a,complete:a>0&&t.length>=a})}return n.images.length&&i.push(n),i}function Vh(e,t){let n=e.metadata.panorama;return n?`#${t} · ${n.bodyYaw}°/${n.pitch}°`:`#${t}`}function Hh(e,t){let n=e.cameraPose,r=e.cameraIntrinsics,i=[];if(i.push(`<b>#${t+1} ${$(e.fileName)}</b>`),i.push(`来源 ${e.source} · ${$(e.mimeType||`未知类型`)} · ${jh(e.sizeBytes)} · ${$(e.capturedAt)}`),r){let e=e=>e===void 0?`–`:e.toFixed(2);i.push(`内参 [${r.calibrationSource}] ${r.width}×${r.height} · fx ${e(r.fx)} / fy ${e(r.fy)}`+(r.horizontalFovDeg===void 0?``:` · 水平 FOV ${r.horizontalFovDeg.toFixed(2)}°`))}n?i.push(`位姿 [${n.coordinateFrame}] 位置 (${n.position.map(e=>e.toFixed(3)).join(`, `)}) 四元数 (${n.rotation.map(e=>e.toFixed(4)).join(`, `)})`):i.push(`位姿 – (无相机位置/朝向记录)`);let a=e.metadata,o=a.longitude!==void 0&&a.latitude!==void 0?`${a.longitude.toFixed(7)}, ${a.latitude.toFixed(7)}`+(a.altitude===void 0?``:` @ ${a.altitude.toFixed(1)}m`):`无`;i.push(`经纬高 ${o}`),a.cameraModel&&i.push(`相机 ${$(a.cameraModel)}`),a.sceneId&&i.push(`场景 ${$(a.sceneId)}`),a.engine&&i.push(`产出后端 ${$(a.engine)}`);let s=a.panorama;return s&&i.push(`<b>全景</b> ${$(s.mode)} · 组 ${$(s.group)} · 第 ${s.index}/${s.total} 张 · 网格 第 ${s.col+1} 方位 / 第 ${s.row+1} 层 · 机身偏航 ${s.bodyYaw}° / 取景俯仰 ${s.pitch}°`),i.push(`<b>校验</b> ${Ih[e.validation.status]}`+(e.validation.messages.length?`\n<span class="is-warn">${e.validation.messages.map($).join(`
|
|
782
|
+
`)}</span>`:``)),i.join(`
|
|
783
|
+
`)}var Uh=`drone-image-viewer-styles`,Wh=1e3,Gh=48,Kh=`
|
|
784
|
+
.dview {
|
|
785
|
+
--dview-text: #e9eff9;
|
|
786
|
+
--dview-muted: rgba(233, 239, 249, 0.58);
|
|
787
|
+
--dview-border: rgba(255, 255, 255, 0.12);
|
|
788
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
789
|
+
user-select: none;
|
|
790
|
+
-webkit-user-select: none;
|
|
791
|
+
-webkit-tap-highlight-color: transparent;
|
|
792
|
+
}
|
|
793
|
+
.dview {
|
|
794
|
+
position: fixed; inset: 0; z-index: ${Wh};
|
|
795
|
+
display: flex; align-items: center; justify-content: center;
|
|
796
|
+
padding: max(10px, env(safe-area-inset-top)) 10px max(10px, env(safe-area-inset-bottom));
|
|
797
|
+
color: var(--dview-text);
|
|
798
|
+
outline: none;
|
|
799
|
+
}
|
|
800
|
+
.dview[hidden] { display: none; }
|
|
801
|
+
.dview-mask {
|
|
802
|
+
position: absolute; inset: 0; background: rgba(6, 9, 14, 0.86);
|
|
803
|
+
-webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
|
|
804
|
+
}
|
|
805
|
+
.dview-frame {
|
|
806
|
+
position: relative; z-index: 1;
|
|
807
|
+
display: flex; flex-direction: column;
|
|
808
|
+
width: min(100%, 1280px); height: 100%; overflow: hidden;
|
|
809
|
+
/* height 必须给定:大图是 absolute(不占流内高度),若 frame 高度由内容撑起,
|
|
810
|
+
stage 的 flex:1 会分到 0 高,整块取景区塌掉 */
|
|
811
|
+
border: 1px solid var(--dview-border); border-radius: 12px;
|
|
812
|
+
background: rgba(15, 19, 27, 0.94);
|
|
813
|
+
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
|
|
814
|
+
}
|
|
815
|
+
.dview-bar {
|
|
816
|
+
display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
|
|
817
|
+
padding: 8px 10px; border-bottom: 1px solid var(--dview-border);
|
|
818
|
+
}
|
|
819
|
+
.dview-idx { font-weight: 600; font-variant-numeric: tabular-nums; }
|
|
820
|
+
.dview[data-status="warning"] .dview-idx { color: #f5a623; }
|
|
821
|
+
.dview[data-status="invalid"] .dview-idx { color: #ff5f5f; }
|
|
822
|
+
.dview-name {
|
|
823
|
+
flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
824
|
+
color: var(--dview-muted);
|
|
825
|
+
}
|
|
826
|
+
.dview-icon {
|
|
827
|
+
flex: 0 0 auto; width: 26px; height: 26px; padding: 0; cursor: pointer;
|
|
828
|
+
border: 1px solid var(--dview-border); border-radius: 7px;
|
|
829
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dview-text);
|
|
830
|
+
font: inherit; line-height: 1;
|
|
831
|
+
}
|
|
832
|
+
.dview-icon:hover { background: rgba(255, 255, 255, 0.14); }
|
|
833
|
+
.dview-icon[hidden] { display: none; }
|
|
834
|
+
.dview-stage {
|
|
835
|
+
position: relative; flex: 1; min-height: 0;
|
|
836
|
+
display: flex; align-items: center; justify-content: center;
|
|
837
|
+
/* 不裁剪的话,大图会按固有比例溢出 stage、顶栏直接被图盖住 */
|
|
838
|
+
overflow: hidden; background: #05070b; touch-action: pan-y;
|
|
839
|
+
}
|
|
840
|
+
.dview-img {
|
|
841
|
+
/* 绝对定位 + margin auto:最可靠的"适应窗口"写法,不依赖 flex 高度的百分比解析 */
|
|
842
|
+
position: absolute; inset: 0; margin: auto;
|
|
843
|
+
max-width: 100%; max-height: 100%; display: block; object-fit: contain;
|
|
844
|
+
}
|
|
845
|
+
.dview-img[hidden] { display: none; }
|
|
846
|
+
.dview-empty { margin: 0; padding: 20px; color: var(--dview-muted); text-align: center; }
|
|
847
|
+
.dview-empty[hidden] { display: none; }
|
|
848
|
+
.dview-nav {
|
|
849
|
+
position: absolute; top: 50%; transform: translateY(-50%);
|
|
850
|
+
width: 38px; height: 58px; padding: 0; cursor: pointer;
|
|
851
|
+
border: 1px solid var(--dview-border); border-radius: 10px;
|
|
852
|
+
background: rgba(10, 14, 20, 0.6); color: var(--dview-text);
|
|
853
|
+
font: 22px/1 inherit;
|
|
854
|
+
}
|
|
855
|
+
.dview-nav:hover { background: rgba(53, 167, 255, 0.28); }
|
|
856
|
+
.dview-nav[hidden] { display: none; }
|
|
857
|
+
.dview-prev { left: 8px; }
|
|
858
|
+
.dview-next { right: 8px; }
|
|
859
|
+
.dview-meta {
|
|
860
|
+
flex: 0 0 auto; max-height: 26vh; overflow-y: auto; overscroll-behavior: contain;
|
|
861
|
+
padding: 8px 10px; border-top: 1px solid var(--dview-border);
|
|
862
|
+
font-size: 11px; line-height: 1.6; color: var(--dview-muted);
|
|
863
|
+
white-space: pre-wrap; word-break: break-all;
|
|
864
|
+
}
|
|
865
|
+
.dview-meta b { color: var(--dview-text); font-weight: 600; }
|
|
866
|
+
.dview-meta .is-warn { color: #f5a623; }
|
|
867
|
+
.dview-hint {
|
|
868
|
+
flex: 0 0 auto; padding: 5px 10px; border-top: 1px solid var(--dview-border);
|
|
869
|
+
color: var(--dview-muted); font-size: 10px;
|
|
870
|
+
}
|
|
871
|
+
@media (max-height: 520px) {
|
|
872
|
+
.dview-meta { max-height: 38vh; font-size: 10px; }
|
|
873
|
+
.dview-nav { height: 44px; }
|
|
874
|
+
}
|
|
875
|
+
@media (pointer: coarse) {
|
|
876
|
+
.dview-icon { width: 32px; height: 32px; }
|
|
877
|
+
.dview-nav { width: 44px; }
|
|
878
|
+
}
|
|
879
|
+
`;function qh(){if(typeof document>`u`||document.getElementById(Uh))return;let e=document.createElement(`style`);e.id=Uh,e.textContent=Kh,document.head.appendChild(e)}var Jh=class{constructor(e,t={}){i(this,`service`,void 0),i(this,`options`,void 0),i(this,`root`,null),i(this,`refs`,null),i(this,`unsubscribe`,null),i(this,`sessionId`,null),i(this,`imageId`,null),i(this,`lastIndex`,0),i(this,`bodyOverflow`,``),i(this,`swipeStart`,null),i(this,`suppressClick`,!1),i(this,`destroyed`,!1),i(this,`onClick`,e=>{if(this.suppressClick){this.suppressClick=!1;return}let t=e.target;switch((t?.closest(`[data-action]`))?.dataset.action){case`close`:this.close();return;case`prev`:this.step(-1);return;case`next`:this.step(1);return;case`download`:this.download();return}let n=this.refs;n&&(t===this.root||t===n.mask||t===n.stage)&&this.close()}),i(this,`onPointerDown`,e=>{if(!e.target?.closest(`[data-action]`)){this.swipeStart={x:e.clientX,y:e.clientY,pointerId:e.pointerId};try{this.refs?.stage.setPointerCapture(e.pointerId)}catch{}}}),i(this,`onPointerUp`,e=>{let t=this.swipeStart;if(this.swipeStart=null,!t||t.pointerId!==e.pointerId)return;let n=e.clientX-t.x,r=e.clientY-t.y;Math.abs(n)<Gh||Math.abs(n)<Math.abs(r)||(this.suppressClick=!0,this.step(n<0?1:-1))}),i(this,`onPointerCancel`,()=>{this.swipeStart=null}),i(this,`onImageError`,()=>{let e=this.refs;e&&(e.img.hidden=!0,e.empty.hidden=!1,e.empty.textContent=`影像地址已失效(可能已被移除或回收)。`)}),i(this,`onKeyDown`,e=>{if(!(this.destroyed||!this.root||this.root.hidden)&&!(e.ctrlKey||e.metaKey||e.altKey)){switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowLeft`:e.preventDefault(),this.step(-1);break;case`ArrowRight`:e.preventDefault(),this.step(1);break;case`Home`:e.preventDefault(),this.jump(0);break;case`End`:e.preventDefault(),this.jump(-1)}e.stopPropagation()}}),this.service=e,this.options=t}get isOpen(){return this.root!==null&&!this.root.hidden}get current(){let e=this.resolveSession()?.images??[];return this.imageId?e.find(e=>e.id===this.imageId)??null:null}open(e,t){this.destroyed||(this.sessionId=t??this.service.activeSession?.id??null,this.imageId=e,this.mount(),this.root&&this.refs&&(this.root.hidden=!1,this.lockScroll(),this.render(),this.root.focus()))}close(){if(!this.root)return;let e=!this.root.hidden;this.unmount(),e&&this.options.onClose?.()}step(e){let t=this.resolveSession()?.images??[];if(t.length<2||!this.imageId)return;let n=t.findIndex(e=>e.id===this.imageId);if(n<0)return;let r=t[(n+e+t.length)%t.length];r&&(this.imageId=r.id,this.render())}jump(e){let t=this.resolveSession()?.images??[];if(!t.length)return;let n=t[e<0?t.length-1:Math.min(e,t.length-1)];n&&(this.imageId=n.id,this.render())}download(){let e=this.current;e?.imageUrl&&Mh(e.imageUrl,e.fileName||`capture-${this.lastIndex+1}.png`)}destroy(){this.destroyed||(this.destroyed=!0,this.unmount(),this.options.injectStyles!==!1&&document.getElementById(Uh)?.remove())}resolveSession(){if(this.sessionId){let e=this.service.getSession(this.sessionId);if(e)return e}return this.service.activeSession}mount(){if(this.root||typeof document>`u`)return;this.options.injectStyles!==!1&&qh();let e=document.createElement(`div`);e.className=`dview`,e.hidden=!0,e.tabIndex=-1,e.setAttribute(`role`,`dialog`),e.setAttribute(`aria-modal`,`true`),e.setAttribute(`aria-label`,`影像查看`),this.options.zIndex&&this.options.zIndex!==Wh&&(e.style.zIndex=String(this.options.zIndex)),e.innerHTML=this.template(),document.body.appendChild(e),this.root=e,this.refs={mask:this.query(`[data-role="mask"]`),stage:this.query(`[data-role="stage"]`),img:this.query(`[data-role="img"]`),empty:this.query(`[data-role="empty"]`),idx:this.query(`[data-role="idx"]`),name:this.query(`[data-role="name"]`),meta:this.query(`[data-role="meta"]`),prev:this.query(`[data-action="prev"]`),next:this.query(`[data-action="next"]`),download:this.query(`[data-action="download"]`)},e.addEventListener(`click`,this.onClick),this.refs.stage.addEventListener(`pointerdown`,this.onPointerDown),this.refs.stage.addEventListener(`pointerup`,this.onPointerUp),this.refs.stage.addEventListener(`pointercancel`,this.onPointerCancel),this.refs.img.addEventListener(`error`,this.onImageError),window.addEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.unsubscribe=this.service.subscribe(()=>{this.root&&!this.root.hidden&&this.render()})}unmount(){window.removeEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.unsubscribe?.(),this.unsubscribe=null,this.root?.remove(),this.root=null,this.refs=null,this.swipeStart=null,this.unlockScroll()}render(){let e=this.root,t=this.refs;if(!e||!t)return;let n=this.resolveSession()?.images??[];if(!n.length){this.close();return}let r=this.imageId?n.findIndex(e=>e.id===this.imageId):-1;r<0&&(r=Math.max(0,Math.min(this.lastIndex,n.length-1)));let i=n[r];if(!i){this.close();return}this.imageId=i.id;let a=r!==this.lastIndex;this.lastIndex=r,e.dataset.status=i.validation.status,t.idx.textContent=`#${r+1} / ${n.length}`,t.name.textContent=i.fileName||`(未命名)`,t.name.title=i.fileName,t.meta.innerHTML=Hh(i,r);let o=n.length<2;t.prev.hidden=o,t.next.hidden=o,t.download.hidden=this.options.downloadable===!1||!i.imageUrl,i.imageUrl?(t.img.hidden=!1,t.empty.hidden=!0,t.img.getAttribute(`src`)!==i.imageUrl&&(t.img.src=i.imageUrl)):(t.img.hidden=!0,t.img.removeAttribute(`src`),t.empty.hidden=!1,t.empty.textContent=`这张影像没有可用的预览地址。`),a&&this.options.onNavigate?.(i,r)}lockScroll(){typeof document<`u`&&(this.bodyOverflow=document.body.style.overflow,document.body.style.overflow=`hidden`)}unlockScroll(){typeof document<`u`&&(document.body.style.overflow=this.bodyOverflow)}query(e){let t=this.root;if(!t)throw Error(`[DroneImageViewer] 弹窗尚未挂载`);let n=t.querySelector(e);if(!n)throw Error(`[DroneImageViewer] 缺少节点:${e}`);return n}template(){return`
|
|
880
|
+
<div class="dview-mask" data-role="mask" data-action="close"></div>
|
|
881
|
+
<div class="dview-frame">
|
|
882
|
+
<div class="dview-bar">
|
|
883
|
+
<span class="dview-idx" data-role="idx">–</span>
|
|
884
|
+
<span class="dview-name" data-role="name">–</span>
|
|
885
|
+
<button type="button" class="dview-icon" data-action="download" title="下载原图" aria-label="下载原图">↓</button>
|
|
886
|
+
<button type="button" class="dview-icon" data-action="close" title="关闭 (Esc)" aria-label="关闭">×</button>
|
|
887
|
+
</div>
|
|
888
|
+
<div class="dview-stage" data-role="stage">
|
|
889
|
+
<img class="dview-img" data-role="img" alt="">
|
|
890
|
+
<p class="dview-empty" data-role="empty" hidden></p>
|
|
891
|
+
<button type="button" class="dview-nav dview-prev" data-action="prev" title="上一张 (←)" aria-label="上一张">‹</button>
|
|
892
|
+
<button type="button" class="dview-nav dview-next" data-action="next" title="下一张 (→)" aria-label="下一张">›</button>
|
|
893
|
+
</div>
|
|
894
|
+
<div class="dview-meta" data-role="meta"></div>
|
|
895
|
+
<div class="dview-hint">← / → 翻页 · Esc 关闭 · 触屏可左右滑动</div>
|
|
896
|
+
</div>
|
|
897
|
+
`}},Yh=Math.PI/180,Xh=180/Math.PI,Zh=10,Qh=4096,$h=2048,eg=.22,tg=.05,ng=Math.tan(30*Yh),rg=Math.tan(20*Yh),ig={thetaStart:-180,spanTheta:360,phiTop:90,spanPhi:180},ag=class{constructor(e={}){i(this,`onProgress`,null),i(this,`pixelsPerDegree`,void 0),i(this,`maxWidth`,void 0),i(this,`maxHeight`,void 0),i(this,`projection`,void 0),i(this,`fill`,void 0),i(this,`feather`,void 0),i(this,`background`,void 0),i(this,`mimeType`,void 0),i(this,`quality`,void 0),this.pixelsPerDegree=Ag(e.pixelsPerDegree,1,40,Zh),this.maxWidth=Ag(e.maxWidth,64,16384,Qh),this.maxHeight=Ag(e.maxHeight,64,16384,$h),this.projection=e.projection,this.fill=e.fill===`none`?`none`:`edge`,this.feather=Ag(e.feather,0,.9,eg),this.background=e.background??null,this.mimeType=e.mimeType??`image/png`,this.quality=Ag(e.quality,0,1,.9)}async stitch(e){if(typeof document>`u`)return null;let t=cg(e);if(this.onProgress?.(0,t.length),t.length<2)return null;let n=this.projection??(e.mode===`pano-360`?`sphere`:`band`),r=mg(t),i=n===`sphere`?ig:e.mode===`pano-180`&&r?{...r,thetaStart:-90,spanTheta:180}:r;if(!i)return null;let a=Math.max(2,Math.round(i.spanTheta*this.pixelsPerDegree)),o=Math.max(2,Math.round(i.spanPhi*this.pixelsPerDegree)),s=Math.min(1,this.maxWidth/a,this.maxHeight/o);s<1&&(a=Math.max(2,Math.round(a*s)),o=Math.max(2,Math.round(o*s)));let c=hg(i,a,o,this.feather),l=document.createElement(`canvas`),u=l.getContext(`2d`,{willReadFrequently:!0});if(!u)return null;let d=0;for(let e=0;e<t.length;e+=1){let n=t[e];if(!n)continue;let r=await Tg(n.image.imageUrl);if(r){let e=wg(l,u,r);e&&(gg(c,n,e.data,e.width,e.height),d+=1)}this.onProgress?.(e+1,t.length),await Eg()}if(!d)return null;let f=vg(c,this.fill),p=document.createElement(`canvas`);p.width=a,p.height=o;let m=p.getContext(`2d`);if(!m)return null;if(this.background){m.fillStyle=this.background,m.fillRect(0,0,a,o);let e=document.createElement(`canvas`);e.width=a,e.height=o,e.getContext(`2d`)?.putImageData(f.image,0,0),m.drawImage(e,0,0)}else m.putImageData(f.image,0,0);let h=og(c);return{url:p.toDataURL(this.mimeType,this.quality),diagnosticUrl:h.url,diagnosticCoverage:h.coverage,width:a,height:o,name:`${e.id}.png`,coverage:f.covered/(a*o),equirectangular:{...i,wrapsTheta:c.wrapsTheta}}}};function og(e){let t=document.createElement(`canvas`);t.width=e.width,t.height=e.height;let n=t.getContext(`2d`);if(!n)throw Error(`[EquirectStitcher] 无法创建覆盖诊断画布`);let r=n.createImageData(e.width,e.height),i=0,a=0,o=0;for(let t=0;t<e.coverageCount.length;t+=1){let n=e.coverageCount[t]??0,s=t*4;n===0?(r.data[s]=239,r.data[s+1]=68,r.data[s+2]=68,i+=1):n===1?(r.data[s]=250,r.data[s+1]=204,r.data[s+2]=21,a+=1):(r.data[s]=34,r.data[s+1]=197,r.data[s+2]=94,o+=1),r.data[s+3]=255}n.putImageData(r,0,0);let s=e.width*e.height;return{url:t.toDataURL(`image/png`),coverage:{uncovered:i/s,single:a/s,overlap:o/s}}}function sg(e={}){return new ag(e)}function cg(e){let t=[];for(let n of e.images){let e=n.metadata.panorama;if(!e||!n.imageUrl)continue;let r=e.bodyYaw,i=e.pitch,{tanH:a,tanV:o}=fg(n),s=lg(r,i),c=ug(r,i),l=dg(s,c),u=pg(r,i,l,c,s,a,o);t.push({image:n,theta:r,phi:i,tanH:a,tanV:o,right:l,up:c,forward:s,...u})}return t.sort((e,t)=>(e.image.metadata.panorama?.index??0)-(t.image.metadata.panorama?.index??0)),t}function lg(e,t){let n=e*Yh,r=t*Yh,i=Math.cos(r);return[Math.sin(n)*i,Math.sin(r),-Math.cos(n)*i]}function ug(e,t){let n=e*Yh,r=t*Yh,i=Math.sin(r);return[-Math.sin(n)*i,Math.cos(r),Math.cos(n)*i]}function dg(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function fg(e){let t=e.cameraIntrinsics,n=ng,r=rg;return t&&(typeof t.horizontalFovDeg==`number`&&t.horizontalFovDeg>0?n=Math.tan(t.horizontalFovDeg/2*Yh):typeof t.fx==`number`&&t.fx>0&&t.width>0&&(n=t.width/2/t.fx),typeof t.verticalFovDeg==`number`&&t.verticalFovDeg>0?r=Math.tan(t.verticalFovDeg/2*Yh):typeof t.fy==`number`&&t.fy>0&&t.height>0&&(r=t.height/2/t.fy)),{tanH:Math.max(1e-4,n),tanV:Math.max(1e-4,r)}}function pg(e,t,n,r,i,a,o){let s=[[0,0],[-a,-o],[a,-o],[-a,o],[a,o],[0,-o],[0,o],[-a,0],[a,0]],c=0,l=0;for(let a of s){let o=a[0],s=a[1],u=o*n[0]+s*r[0]+i[0],d=o*n[1]+s*r[1]+i[1],f=o*n[2]+s*r[2]+i[2],p=Math.hypot(u,d,f)||1,m=Og(Math.atan2(u/p,-f/p)*Xh-e),h=Math.asin(Math.max(-1,Math.min(1,d/p)))*Xh;Math.abs(m)>c&&(c=Math.abs(m)),l=Math.max(l,Math.abs(h-t))}return{halfTheta:Math.max(c,.5),halfPhi:Math.max(l,.5)}}function mg(e){if(!e.length)return null;let t=-1/0,n=1/0;for(let r of e)t=Math.max(t,r.phi+r.halfPhi),n=Math.min(n,r.phi-r.halfPhi);let r=Math.max(1,t-n),i=[];for(let n of e){if(n.halfTheta*2>=360)return{thetaStart:0,spanTheta:360,phiTop:t,spanPhi:r};let e=Dg(n.theta-n.halfTheta,360),a=e+n.halfTheta*2;a>360?(i.push({lo:e,hi:360}),i.push({lo:0,hi:a-360})):i.push({lo:e,hi:a})}i.sort((e,t)=>e.lo-t.lo);let a=[];for(let e of i){let t=a[a.length-1];t&&e.lo<=t.hi?t.hi=Math.max(t.hi,e.hi):a.push({lo:e.lo,hi:e.hi})}if(!a.length)return null;let o=a[0];if(a.length===1&&o&&o.hi-o.lo>=360-1e-6)return{thetaStart:o.lo,spanTheta:360,phiTop:t,spanPhi:r};let s=-1/0,c=0,l=0;for(let e=0;e<a.length;e+=1){let t=a[e],n=a[(e+1)%a.length];if(!t||!n)continue;let r=e===a.length-1?n.lo+360-t.hi:n.lo-t.hi;r>s&&(s=r,c=(e+1)%a.length,l=e)}let u=a[c],d=a[l];if(!u||!d)return null;let f=u.lo;return{thetaStart:f,spanTheta:Math.min(360,Math.max(1,d.hi+(l<c?360:0)-f)),phiTop:t,spanPhi:r}}function hg(e,t,n,r){let i=new Float32Array(t),a=new Float32Array(t),o=e.spanTheta/t;for(let n=0;n<t;n+=1){let t=(e.thetaStart+(n+.5)*o)*Yh;i[n]=Math.sin(t),a[n]=Math.cos(t)}let s=new Float32Array(n),c=new Float32Array(n),l=e.spanPhi/n;for(let t=0;t<n;t+=1){let n=(e.phiTop-(t+.5)*l)*Yh;s[t]=Math.sin(n),c[t]=Math.cos(n)}return{width:t,height:n,thetaStart:e.thetaStart,spanTheta:e.spanTheta,wrapsTheta:e.spanTheta>=360-1e-6,phiTop:e.phiTop,spanPhi:e.spanPhi,sinTheta:i,cosTheta:a,sinPhi:s,cosPhi:c,acc:new Float32Array(t*n*3),wsum:new Float32Array(t*n),coverageCount:new Uint8Array(t*n),feather:r,colsPerDeg:t/e.spanTheta,rowsPerDeg:n/e.spanPhi}}function gg(e,t,n,r,i){let a=Dg(t.theta-e.thetaStart,360);if(a>=e.spanTheta)return;let o=Math.floor((a-t.halfTheta)*e.colsPerDeg)-1,s=Math.ceil((a+t.halfTheta)*e.colsPerDeg)+1,c=e.wrapsTheta?o:Math.max(0,o),l=e.wrapsTheta?s:Math.min(e.width-1,s),u=Math.max(0,Math.floor((e.phiTop-(t.phi+t.halfPhi))*e.rowsPerDeg)-1),d=Math.min(e.height-1,Math.ceil((e.phiTop-(t.phi-t.halfPhi))*e.rowsPerDeg)+1);if(u>d)return;let[f,p,m]=t.right,[h,g,_]=t.up,[v,y,b]=t.forward,x=t.tanH,S=t.tanV,C=1-e.feather,w=r-1,T=i-1;for(let t=u;t<=d;t+=1){let i=e.sinPhi[t]??0,a=e.cosPhi[t]??1,o=t*e.width;for(let t=c;t<=l;t+=1){let s=Dg(t,e.width),c=e.sinTheta[s]??0,l=e.cosTheta[s]??1,u=c*a,d=i,E=-l*a,D=u*f+d*p+E*m,O=u*h+d*g+E*_,k=u*v+d*y+E*b;if(k<=1e-6)continue;let A=D/k,j=O/k;if(A<-x||A>x||j<-S||j>S)continue;let M=A/x,N=j/S,P=_g(Math.abs(M),C)*_g(Math.abs(N),C);if(P<=0)continue;let ee=(M*.5+.5)*w,F=(.5-N*.5)*T,te=ee|0,ne=F|0,re=te<w?te+1:w,ie=ne<T?ne+1:T,ae=ee-te,oe=F-ne,se=(1-ae)*(1-oe),ce=ae*(1-oe),le=(1-ae)*oe,ue=ae*oe,de=(ne*r+te)*4,I=(ne*r+re)*4,L=(ie*r+te)*4,fe=(ie*r+re)*4,pe=(o+s)*3;for(let t=0;t<3;t+=1){let r=(n[de+t]??0)*se+(n[I+t]??0)*ce+(n[L+t]??0)*le+(n[fe+t]??0)*ue;e.acc[pe+t]=(e.acc[pe+t]??0)+r*P}e.wsum[o+s]=(e.wsum[o+s]??0)+P,(e.coverageCount[o+s]??0)<255&&(e.coverageCount[o+s]=(e.coverageCount[o+s]??0)+1)}}}function _g(e,t){if(e<=t)return 1;let n=1-t;if(n<=1e-6)return tg;let r=(e-t)/n,i=1-r*r;return i<tg?tg:i}function vg(e,t){let n=e.width,r=e.height,i=new ImageData(n,r),a=i.data,o=0;for(let t=0;t<r;t+=1){let r=t*n;for(let t=0;t<n;t+=1){let n=r+t,i=e.wsum[n]??0,s=n*4;if(i>1e-6){let t=1/i;a[s]=kg((e.acc[n*3]??0)*t),a[s+1]=kg((e.acc[n*3+1]??0)*t),a[s+2]=kg((e.acc[n*3+2]??0)*t),a[s+3]=255,o+=1}else a[s+3]=0}}return t===`edge`&&bg(n,r,a,e.wrapsTheta),e.wrapsTheta&&yg(e,a),{image:i,covered:o}}function yg(e,t){let{width:n,height:r,colsPerDeg:i}=e,a=Math.min(Math.floor(n/2),Math.max(1,Math.round(i)));for(let e=0;e<r;e+=1){let r=e*n*4,i=r,o=r+(n-1)*4;if((t[i+3]??0)!==0&&(t[o+3]??0)!==0)for(let e=0;e<a;e+=1){let i=r+e*4,o=r+(n-1-e)*4,s=e/a,c=1-s*s*(3-2*s);for(let e=0;e<3;e+=1){let n=t[i+e]??0,r=t[o+e]??0,a=(n+r)/2;t[i+e]=kg(n+(a-n)*c),t[o+e]=kg(r+(a-r)*c)}}}}function bg(e,t,n,r){xg(e,t,n,r),Sg(e,t,n)}function xg(e,t,n,r){let i=e*4,a=new Uint8Array(e),o=new Int32Array(e),s=new Int32Array(e);for(let c=0;c<t;c+=1){let t=c*i,l=-1,u=-1;for(let r=0;r<e;r+=1)a[r]=+((n[t+r*4+3]??0)>0),(a[r]??0)!==0&&(l<0&&(l=r),u=r);if(l<0)continue;let d=-1;for(let t=0;t<e;t+=1)o[t]=a[t]?t:d,a[t]&&(d=t);d=-1;for(let t=e-1;t>=0;--t)s[t]=a[t]?t:d,a[t]&&(d=t);for(let i=0;i<e;i+=1){if((a[i]??0)!==0)continue;let c=o[i]??-1,d=s[i]??-1,f=-1,p=1/0;if(c>=0&&(f=c,p=i-c),d>=0&&d-i<p&&(f=d,p=d-i),r){if(u>=0){let t=i+e-u;t<p&&(f=u,p=t)}if(l>=0){let t=e-i+l;t<p&&(f=l,p=t)}}f>=0&&Cg(n,t+f*4,t+i*4)}}}function Sg(e,t,n){let r=e*4,i=new Int32Array(e).fill(-1),a=new Int32Array(e).fill(-1);for(let o=0;o<t;o+=1){let t=o*r;for(let r=0;r<e;r+=1)(n[t+r*4+3]??0)>0&&((i[r]??-1)<0&&(i[r]=o),a[r]=o)}let o=new Int32Array(t).fill(-1),s=new Int32Array(t).fill(-1);for(let c=0;c<e;c+=1){let e=i[c]??-1,l=a[c]??-1;if(e<0||l<0)continue;let u=c*4,d=e*r+u;for(let t=0;t<e;t+=1)Cg(n,d,t*r+u);let f=l*r+u;for(let e=l+1;e<t;e+=1)Cg(n,f,e*r+u);let p=-1;for(let t=e;t<=l;t+=1)(n[t*r+u+3]??0)>0&&(p=t),o[t]=p;p=-1;for(let t=l;t>=e;--t)(n[t*r+u+3]??0)>0&&(p=t),s[t]=p;for(let t=e;t<=l;t+=1){if((n[t*r+u+3]??0)>0)continue;let e=o[t]??-1,i=s[t]??-1,a=t*r+u;if(e>=0&&i>=0){let o=e*r+u,s=i*r+u,c=(t-e)/(i-e);for(let e=0;e<3;e+=1){let t=n[o+e]??0,r=n[s+e]??0;n[a+e]=kg(t+(r-t)*c)}n[a+3]=255}else{let t=e>=0?e:i;t>=0&&Cg(n,t*r+u,a)}}}}function Cg(e,t,n){e[n]=e[t]??0,e[n+1]=e[t+1]??0,e[n+2]=e[t+2]??0,e[n+3]=255}function wg(e,t,n){let r=n.naturalWidth||n.width,i=n.naturalHeight||n.height;if(!r||!i)return null;e.width=r,e.height=i,t.clearRect(0,0,r,i),t.drawImage(n,0,0,r,i);try{let e=t.getImageData(0,0,r,i);return{data:e.data,width:e.width,height:e.height}}catch{return null}}function Tg(e){return new Promise(t=>{if(!e){t(null);return}let n=new Image;n.decoding=`async`,n.onload=()=>t(n),n.onerror=()=>t(null),n.src=e})}function Eg(){return new Promise(e=>setTimeout(e,0))}function Dg(e,t){if(!(t>0))return 0;let n=e%t;return n<0?n+t:n}function Og(e){let t=(e+180)%360-180;return t===-180?180:t}function kg(e){return e>0?e>255?255:e:0}function Ag(e,t,n,r){return typeof e!=`number`||!Number.isFinite(e)?r:Math.max(t,Math.min(n,e))}var jg=`drone-panorama-viewer-styles`,Mg=1100,Ng=Math.PI/180,Pg=.0015,Fg=.9,Ig=.03,Lg=89,Rg=75,zg=25,Bg=110,Vg={thetaStart:-180,spanTheta:360,phiTop:90,spanPhi:180,wrapsTheta:!0},Hg=`
|
|
898
|
+
attribute vec2 aPos;
|
|
899
|
+
varying vec2 vUv;
|
|
900
|
+
void main() {
|
|
901
|
+
vUv = aPos * 0.5 + 0.5;
|
|
902
|
+
gl_Position = vec4(aPos, 0.0, 1.0);
|
|
903
|
+
}
|
|
904
|
+
`,Ug=`
|
|
905
|
+
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
|
906
|
+
precision highp float;
|
|
907
|
+
#else
|
|
908
|
+
precision mediump float;
|
|
909
|
+
#endif
|
|
910
|
+
varying vec2 vUv;
|
|
911
|
+
uniform sampler2D uTex;
|
|
912
|
+
uniform float uTanHalf;
|
|
913
|
+
uniform float uAspect;
|
|
914
|
+
uniform vec3 uRight;
|
|
915
|
+
uniform vec3 uUp;
|
|
916
|
+
uniform vec3 uForward;
|
|
917
|
+
uniform float uThetaStart;
|
|
918
|
+
uniform float uSpanTheta;
|
|
919
|
+
uniform float uPhiTop;
|
|
920
|
+
uniform float uSpanPhi;
|
|
921
|
+
uniform float uWrap;
|
|
922
|
+
uniform float uTextureWidth;
|
|
923
|
+
const float PI = 3.141592653589793;
|
|
924
|
+
|
|
925
|
+
vec4 sampleWrappedTexture(float u, float v) {
|
|
926
|
+
float texel = u * uTextureWidth - 0.5;
|
|
927
|
+
float texel0 = floor(texel);
|
|
928
|
+
float blend = fract(texel);
|
|
929
|
+
float x0 = mix(clamp(texel0, 0.0, uTextureWidth - 1.0), mod(texel0, uTextureWidth), uWrap);
|
|
930
|
+
float x1 = mix(clamp(texel0 + 1.0, 0.0, uTextureWidth - 1.0), mod(texel0 + 1.0, uTextureWidth), uWrap);
|
|
931
|
+
float u0 = (x0 + 0.5) / uTextureWidth;
|
|
932
|
+
float u1 = (x1 + 0.5) / uTextureWidth;
|
|
933
|
+
return mix(texture2D(uTex, vec2(u0, v)), texture2D(uTex, vec2(u1, v)), blend);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
void main() {
|
|
937
|
+
vec2 ndc = vUv * 2.0 - 1.0;
|
|
938
|
+
vec3 dir = normalize(uRight * (ndc.x * uTanHalf * uAspect) + uUp * (ndc.y * uTanHalf) + uForward);
|
|
939
|
+
float phi = asin(clamp(dir.y, -1.0, 1.0)) / PI * 180.0;
|
|
940
|
+
float theta = atan(dir.x, -dir.z) / PI * 180.0;
|
|
941
|
+
float u = (theta - uThetaStart) / uSpanTheta;
|
|
942
|
+
u = mix(clamp(u, 0.0, 1.0), fract(u), uWrap);
|
|
943
|
+
float v = clamp((uPhiTop - phi) / uSpanPhi, 0.0, 1.0);
|
|
944
|
+
gl_FragColor = sampleWrappedTexture(u, v);
|
|
945
|
+
}
|
|
946
|
+
`,Wg=`
|
|
947
|
+
.divp {
|
|
948
|
+
--divp-text: #e9eff9;
|
|
949
|
+
--divp-muted: rgba(233, 239, 249, 0.58);
|
|
950
|
+
--divp-border: rgba(255, 255, 255, 0.12);
|
|
951
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
952
|
+
user-select: none;
|
|
953
|
+
-webkit-user-select: none;
|
|
954
|
+
-webkit-tap-highlight-color: transparent;
|
|
955
|
+
}
|
|
956
|
+
.divp {
|
|
957
|
+
position: fixed; inset: 0; z-index: ${Mg};
|
|
958
|
+
display: flex; align-items: center; justify-content: center;
|
|
959
|
+
padding: max(8px, env(safe-area-inset-top)) 8px max(8px, env(safe-area-inset-bottom));
|
|
960
|
+
color: var(--divp-text);
|
|
961
|
+
outline: none;
|
|
962
|
+
}
|
|
963
|
+
.divp[hidden] { display: none; }
|
|
964
|
+
.divp-mask {
|
|
965
|
+
position: absolute; inset: 0; background: rgba(3, 5, 8, 0.96);
|
|
966
|
+
-webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
|
|
967
|
+
}
|
|
968
|
+
.divp-frame {
|
|
969
|
+
position: relative; z-index: 1;
|
|
970
|
+
display: flex; flex-direction: column;
|
|
971
|
+
width: min(100%, 1420px); height: 100%; overflow: hidden;
|
|
972
|
+
border: 1px solid var(--divp-border); border-radius: 12px;
|
|
973
|
+
background: rgba(10, 13, 19, 0.96);
|
|
974
|
+
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
|
|
975
|
+
}
|
|
976
|
+
.divp-bar {
|
|
977
|
+
flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
|
|
978
|
+
padding: 8px 10px; border-bottom: 1px solid var(--divp-border);
|
|
979
|
+
}
|
|
980
|
+
.divp-title { font-weight: 600; }
|
|
981
|
+
.divp-hud { color: var(--divp-muted); font-variant-numeric: tabular-nums; }
|
|
982
|
+
.divp-spacer { flex: 1; min-width: 4px; }
|
|
983
|
+
.divp-btn {
|
|
984
|
+
flex: 0 0 auto; min-height: 26px; padding: 3px 10px; cursor: pointer; white-space: nowrap;
|
|
985
|
+
border: 1px solid var(--divp-border); border-radius: 7px;
|
|
986
|
+
background: rgba(255, 255, 255, 0.06); color: var(--divp-text); font: inherit; font-size: 12px;
|
|
987
|
+
}
|
|
988
|
+
.divp-btn:hover { background: rgba(255, 255, 255, 0.14); }
|
|
989
|
+
.divp-btn[hidden] { display: none; }
|
|
990
|
+
.divp-icon {
|
|
991
|
+
flex: 0 0 auto; width: 26px; height: 26px; padding: 0; cursor: pointer;
|
|
992
|
+
border: 1px solid var(--divp-border); border-radius: 7px;
|
|
993
|
+
background: rgba(255, 255, 255, 0.06); color: var(--divp-text); font: inherit; line-height: 1;
|
|
994
|
+
}
|
|
995
|
+
.divp-icon:hover { background: rgba(255, 255, 255, 0.14); }
|
|
996
|
+
.divp-stage {
|
|
997
|
+
position: relative; flex: 1; min-height: 0; overflow: hidden;
|
|
998
|
+
background: radial-gradient(circle at 50% 45%, #0a1018, #04060a 70%);
|
|
999
|
+
touch-action: none; cursor: grab;
|
|
1000
|
+
}
|
|
1001
|
+
.divp-stage[data-dragging="true"] { cursor: grabbing; }
|
|
1002
|
+
.divp-canvas { display: block; width: 100%; height: 100%; }
|
|
1003
|
+
.divp-canvas[hidden] { display: none; }
|
|
1004
|
+
.divp-note {
|
|
1005
|
+
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
|
1006
|
+
margin: 0; padding: 14px 18px; max-width: 80%;
|
|
1007
|
+
border: 1px solid var(--divp-border); border-radius: 10px;
|
|
1008
|
+
background: rgba(10, 14, 20, 0.9); color: var(--divp-muted); text-align: center;
|
|
1009
|
+
}
|
|
1010
|
+
.divp-note[hidden] { display: none; }
|
|
1011
|
+
.divp-foot {
|
|
1012
|
+
flex: 0 0 auto; padding: 6px 10px; border-top: 1px solid var(--divp-border);
|
|
1013
|
+
color: var(--divp-muted); font-size: 11px;
|
|
1014
|
+
}
|
|
1015
|
+
@media (pointer: coarse) {
|
|
1016
|
+
.divp-icon { width: 32px; height: 32px; }
|
|
1017
|
+
.divp-btn { min-height: 32px; }
|
|
1018
|
+
}
|
|
1019
|
+
`;function Gg(){if(typeof document>`u`||document.getElementById(jg))return;let e=document.createElement(`style`);e.id=jg,e.textContent=Wg,document.head.appendChild(e)}function Kg(e,t){let n=e*Ng,r=t*Ng,i=Math.cos(n),a=Math.sin(n),o=Math.cos(r),s=Math.sin(r);return{forward:[a*o,s,-i*o],up:[-a*s,o,i*s],right:[i,0,a]}}function qg(e,t,n){return Math.min(n,Math.max(t,e))}function Jg(e,t,n,r){return Number.isFinite(e)?qg(e,t,n):r}function Yg(e){return(e%360+360)%360}var Xg=class{constructor(e={}){i(this,`options`,void 0),i(this,`minFov`,void 0),i(this,`maxFov`,void 0),i(this,`root`,null),i(this,`refs`,null),i(this,`program`,null),i(this,`gl`,null),i(this,`observer`,null),i(this,`source`,``),i(this,`fileName`,`panorama.png`),i(this,`importUrl`,null),i(this,`importName`,``),i(this,`image`,null),i(this,`projection`,{...Vg}),i(this,`loadSeq`,0),i(this,`ready`,!1),i(this,`yaw`,0),i(this,`pitch`,0),i(this,`fov`,Rg),i(this,`velocity`,{yaw:0,pitch:0}),i(this,`pointers`,new Map),i(this,`lastPointer`,null),i(this,`pinchDistance`,0),i(this,`rafId`,0),i(this,`dirty`,!0),i(this,`bodyOverflow`,``),i(this,`destroyed`,!1),i(this,`onContextLost`,e=>{e.preventDefault(),this.ready=!1}),i(this,`onContextRestored`,()=>{this.ready=!1,this.program=null,this.gl=null,this.createContext()&&this.image&&this.uploadTexture(this.image)}),i(this,`onFrame`,()=>{this.rafId=0;let e=this.velocity;Math.abs(e.yaw)>Ig||Math.abs(e.pitch)>Ig?(this.yaw+=e.yaw,this.pitch=qg(this.pitch+e.pitch,-89,Lg),e.yaw*=Fg,e.pitch*=Fg,this.dirty=!0,this.schedule()):(e.yaw=0,e.pitch=0),this.dirty&&(this.dirty=!1,this.draw())}),i(this,`onImportFile`,e=>{let t=e.target,n=t.files?.[0];t.value=``,n&&(this.importUrl&&URL.revokeObjectURL(this.importUrl),this.importUrl=URL.createObjectURL(n),this.importName=n.name,this.open(this.importUrl,n.name))}),i(this,`onClick`,e=>{let t=e.target;switch((t?.closest(`[data-action]`))?.dataset.action){case`close`:this.close();return;case`reset`:this.reset();return;case`download`:this.download();return;case`import`:this.refs?.file.click();return}(t===this.root||t===this.refs?.mask)&&this.close()}),i(this,`onPointerDown`,e=>{if(!e.target?.closest(`[data-action]`)){this.pointers.set(e.pointerId,{x:e.clientX,y:e.clientY});try{this.refs?.stage.setPointerCapture(e.pointerId)}catch{}this.velocity.yaw=0,this.velocity.pitch=0,this.pointers.size===1?this.lastPointer={x:e.clientX,y:e.clientY}:(this.lastPointer=null,this.pinchDistance=this.currentPinchDistance()),this.refs?.stage.setAttribute(`data-dragging`,`true`)}}),i(this,`onPointerMove`,e=>{if(!this.pointers.has(e.pointerId))return;let t=this.pointers.get(e.pointerId);if(this.pointers.set(e.pointerId,{x:e.clientX,y:e.clientY}),this.pointers.size>=2){let n=this.currentPinchDistance();this.pinchDistance>0&&n>0&&this.zoomBy(this.pinchDistance/n),this.pinchDistance=n,t&&this.rotateBy((e.clientX-t.x)*.5,(e.clientY-t.y)*.5,!0);return}let n=this.lastPointer;if(!n)return;let r=e.clientX-n.x,i=e.clientY-n.y;this.lastPointer={x:e.clientX,y:e.clientY},this.rotateBy(r,i,!1)}),i(this,`onPointerUp`,e=>{if(this.pointers.has(e.pointerId)){if(this.pointers.delete(e.pointerId),this.pointers.size===1){let e=this.pointers.values().next().value;this.lastPointer=e?{x:e.x,y:e.y}:null,this.pinchDistance=0}else this.pointers.size===0&&(this.lastPointer=null,this.pinchDistance=0,this.refs?.stage.removeAttribute(`data-dragging`))}}),i(this,`onWheel`,e=>{e.preventDefault(),this.velocity.yaw=0,this.velocity.pitch=0,this.zoomBy(Math.exp(e.deltaY*Pg))}),i(this,`onDoubleClick`,e=>{e.target?.closest(`[data-action]`)||this.reset()}),i(this,`onKeyDown`,e=>{if(this.destroyed||!this.root||this.root.hidden||e.ctrlKey||e.metaKey||e.altKey)return;let t=e.shiftKey?15:5;switch(e.key){case`Escape`:e.preventDefault(),this.close();break;case`ArrowLeft`:e.preventDefault(),this.yaw-=t,this.invalidate();break;case`ArrowRight`:e.preventDefault(),this.yaw+=t,this.invalidate();break;case`ArrowUp`:e.preventDefault(),this.pitch=qg(this.pitch+t,-89,Lg),this.invalidate();break;case`ArrowDown`:e.preventDefault(),this.pitch=qg(this.pitch-t,-89,Lg),this.invalidate();break;case`+`:case`=`:e.preventDefault(),this.zoomBy(.85);break;case`-`:case`_`:e.preventDefault(),this.zoomBy(1/.85);break;case`0`:case`Home`:e.preventDefault(),this.reset()}e.stopPropagation()}),this.options=e,this.minFov=Jg(e.minFovDeg??zg,5,170,zg),this.maxFov=Jg(e.maxFovDeg??Bg,this.minFov,170,Bg),this.yaw=e.initialYawDeg??0,this.pitch=qg(e.initialPitchDeg??0,-89,Lg),this.fov=qg(e.initialFovDeg??Rg,this.minFov,this.maxFov)}get isOpen(){return this.root!==null&&!this.root.hidden}get view(){return{yaw:this.yaw,pitch:this.pitch,fov:this.fov}}open(e,t){if(this.destroyed)return;this.mount();let n=this.root;if(!n||!this.refs)return;if(!e){if(this.importUrl){this.source=this.importUrl,this.projection={...Vg},this.refs.title.textContent=this.importName||`360° 全景`,n.hidden=!1,this.lockScroll(),this.reset(),this.loadImage(this.importUrl),n.focus();return}this.source=``,this.image=null,this.ready=!1,this.refs.title.textContent=t??`360° 全景`,n.hidden=!1,this.lockScroll(),this.reset(),this.invalidate(),this.setNote(`还没有全景图 —— 点右上「导入图片」,选一张等距柱状全景图(2:1 长条)。`),n.focus();return}let r=typeof e==`string`?e:e.url;if(!r)return;this.source=r,this.projection=typeof e==`string`?{...Vg}:{...Vg,...e.equirectangular};let i=typeof e==`string`?t:t??e.name;this.fileName=i&&/\.\w{2,5}$/.test(i)?i:`${this.slug(i??`panorama`)}.png`,this.refs.title.textContent=i??`全景图`,n.hidden=!1,this.lockScroll(),this.reset(),this.loadImage(r),n.focus()}close(){if(!this.root)return;let e=!this.root.hidden;this.unmount(),e&&this.options.onClose?.()}reset(){this.yaw=this.options.initialYawDeg??0,this.pitch=qg(this.options.initialPitchDeg??0,-89,Lg),this.fov=qg(this.options.initialFovDeg??Rg,this.minFov,this.maxFov),this.velocity.yaw=0,this.velocity.pitch=0,this.invalidate()}download(){this.source&&Mh(this.source,this.fileName)}destroy(){this.destroyed||(this.destroyed=!0,this.unmount(),this.importUrl&&(URL.revokeObjectURL(this.importUrl),this.importUrl=null),this.options.injectStyles!==!1&&document.getElementById(jg)?.remove())}mount(){if(this.root||typeof document>`u`)return;this.options.injectStyles!==!1&&Gg();let e=document.createElement(`div`);e.className=`divp`,e.hidden=!0,e.tabIndex=-1,e.setAttribute(`role`,`dialog`),e.setAttribute(`aria-modal`,`true`),e.setAttribute(`aria-label`,`全景查看`),this.options.zIndex&&this.options.zIndex!==Mg&&(e.style.zIndex=String(this.options.zIndex)),e.innerHTML=this.template(),document.body.appendChild(e),this.root=e,this.refs={mask:this.query(`[data-role="mask"]`),stage:this.query(`[data-role="stage"]`),canvas:this.query(`[data-role="canvas"]`),title:this.query(`[data-role="title"]`),hud:this.query(`[data-role="hud"]`),note:this.query(`[data-role="note"]`),download:this.query(`[data-action="download"]`),file:this.query(`[data-role="file"]`)},this.refs.file.addEventListener(`change`,this.onImportFile),e.addEventListener(`click`,this.onClick);let t=this.refs.stage;t.addEventListener(`pointerdown`,this.onPointerDown),t.addEventListener(`pointermove`,this.onPointerMove),t.addEventListener(`pointerup`,this.onPointerUp),t.addEventListener(`pointercancel`,this.onPointerUp),t.addEventListener(`wheel`,this.onWheel,{passive:!1}),t.addEventListener(`dblclick`,this.onDoubleClick),window.addEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.createContext()?typeof ResizeObserver<`u`&&(this.observer=new ResizeObserver(()=>this.syncSize()),this.observer.observe(t)):(this.refs.canvas.hidden=!0,this.setNote(`这个浏览器不支持 WebGL,没法把全景贴到球面上 —— 已回退成平面长图。`),this.fallbackImage())}unmount(){window.removeEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.rafId&&(window.cancelAnimationFrame(this.rafId),this.rafId=0),this.observer?.disconnect(),this.observer=null,this.image=null,this.pointers.clear(),this.lastPointer=null,this.pinchDistance=0,this.disposeGL(),this.root?.remove(),this.root=null,this.refs=null,this.ready=!1,this.unlockScroll()}createContext(){let e=this.refs?.canvas;if(!e)return null;let t=e.getContext(`webgl`,{alpha:!1,antialias:!1})??e.getContext(`experimental-webgl`);if(!t)return null;this.gl=t;let n=this.buildProgram(t);return n?(this.program=n,t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!1),t.clearColor(.02,.03,.05,1),e.addEventListener(`webglcontextlost`,this.onContextLost),e.addEventListener(`webglcontextrestored`,this.onContextRestored),this.syncSize(),t):(this.gl=null,null)}buildProgram(e){let t=Zg(e,e.VERTEX_SHADER,Hg),n=Zg(e,e.FRAGMENT_SHADER,Ug);if(!t||!n)return null;let r=e.createProgram(),i=e.createBuffer(),a=e.createTexture();if(!r||!i||!a)return null;if(e.attachShader(r,t),e.attachShader(r,n),e.linkProgram(r),e.deleteShader(t),e.deleteShader(n),!e.getProgramParameter(r,e.LINK_STATUS))return e.deleteProgram(r),null;e.useProgram(r);let o=new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]);e.bindBuffer(e.ARRAY_BUFFER,i),e.bufferData(e.ARRAY_BUFFER,o,e.STATIC_DRAW);let s=e.getAttribLocation(r,`aPos`);return e.enableVertexAttribArray(s),e.vertexAttribPointer(s,2,e.FLOAT,!1,0,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,a),e.uniform1i(e.getUniformLocation(r,`uTex`),0),{program:r,buffer:i,texture:a,uniforms:{texture:e.getUniformLocation(r,`uTex`),tanHalf:e.getUniformLocation(r,`uTanHalf`),aspect:e.getUniformLocation(r,`uAspect`),right:e.getUniformLocation(r,`uRight`),up:e.getUniformLocation(r,`uUp`),forward:e.getUniformLocation(r,`uForward`),thetaStart:e.getUniformLocation(r,`uThetaStart`),spanTheta:e.getUniformLocation(r,`uSpanTheta`),phiTop:e.getUniformLocation(r,`uPhiTop`),spanPhi:e.getUniformLocation(r,`uSpanPhi`),wrap:e.getUniformLocation(r,`uWrap`),textureWidth:e.getUniformLocation(r,`uTextureWidth`)}}}disposeGL(){let e=this.gl,t=this.program;this.program=null,this.gl=null,e&&(this.refs?.canvas.removeEventListener(`webglcontextlost`,this.onContextLost),this.refs?.canvas.removeEventListener(`webglcontextrestored`,this.onContextRestored),t&&(e.deleteTexture(t.texture),e.deleteBuffer(t.buffer),e.deleteProgram(t.program)),e.getExtension(`WEBGL_lose_context`)?.loseContext())}loadImage(e){this.ready=!1;let t=++this.loadSeq;this.gl&&(this.refs?.canvas.removeAttribute(`hidden`),this.setNote(`正在把全景图贴上球面…`));let n=new Image;n.decoding=`async`,n.onload=()=>{!this.destroyed&&this.root&&t===this.loadSeq&&(this.image=n,this.gl&&this.program?(this.uploadTexture(n),this.refs?.note.setAttribute(`hidden`,``)):this.fallbackImage())},n.onerror=()=>{t===this.loadSeq&&this.setNote(`全景图加载失败(地址可能已失效)。`)},n.src=e}uploadTexture(e){let t=this.gl,n=this.program;t&&n&&(t.bindTexture(t.TEXTURE_2D,n.texture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),t.useProgram(n.program),t.uniform1f(n.uniforms.textureWidth,e.naturalWidth||e.width),this.ready=!0,this.invalidate())}fallbackImage(){let e=this.refs;if(!e||!this.source)return;e.canvas.hidden=!0;let t=document.createElement(`img`);t.src=this.source,t.alt=`全景图`,t.style.cssText=`position:absolute;inset:0;margin:auto;max-width:100%;max-height:100%;object-fit:contain;`,e.stage.appendChild(t)}setNote(e){let t=this.refs;t&&(t.note.textContent=e,t.note.removeAttribute(`hidden`))}syncSize(){let e=this.refs?.canvas,t=this.refs?.stage;if(!e||!t)return;let n=Math.min(typeof window>`u`?1:window.devicePixelRatio||1,2),r=Math.max(1,Math.round(t.clientWidth*n)),i=Math.max(1,Math.round(t.clientHeight*n));(e.width!==r||e.height!==i)&&(e.width=r,e.height=i,this.invalidate())}invalidate(){this.dirty=!0,this.schedule()}schedule(){this.rafId||this.destroyed||this.refs&&this.root?.hidden||(this.rafId=window.requestAnimationFrame(this.onFrame))}draw(){let e=this.gl,t=this.program,n=this.refs?.canvas;if(!e||!t||!n||!n.width||!n.height)return;if(e.viewport(0,0,n.width,n.height),e.clear(e.COLOR_BUFFER_BIT),!this.ready){this.updateHud();return}let r=Kg(this.yaw,this.pitch),i=t.uniforms;e.uniform1f(i.tanHalf,Math.tan(this.fov*Ng/2)),e.uniform1f(i.aspect,n.width/n.height),e.uniform3f(i.right,r.right[0],r.right[1],r.right[2]),e.uniform3f(i.up,r.up[0],r.up[1],r.up[2]),e.uniform3f(i.forward,r.forward[0],r.forward[1],r.forward[2]),e.uniform1f(i.thetaStart,this.projection.thetaStart),e.uniform1f(i.spanTheta,this.projection.spanTheta),e.uniform1f(i.phiTop,this.projection.phiTop),e.uniform1f(i.spanPhi,this.projection.spanPhi),e.uniform1f(i.wrap,+!!this.projection.wrapsTheta),e.drawArrays(e.TRIANGLES,0,6),this.updateHud()}updateHud(){let e=this.refs?.hud;e&&(e.textContent=`方位 ${Math.round(Yg(this.yaw))}° · 仰角 ${Math.round(this.pitch)}° · 视野 ${Math.round(this.fov)}°`)}rotateBy(e,t,n){let r=this.refs?.stage.clientHeight??0;if(!r)return;let i=this.fov/r,a=-e*i,o=t*i;this.yaw+=a,this.pitch=qg(this.pitch+o,-89,Lg),n||(this.velocity.yaw=a,this.velocity.pitch=o),this.invalidate()}zoomBy(e){!Number.isFinite(e)||e<=0||(this.fov=qg(this.fov*e,this.minFov,this.maxFov),this.invalidate())}currentPinchDistance(){let e=[...this.pointers.values()];if(e.length<2)return 0;let[t,n]=e;return!t||!n?0:Math.hypot(t.x-n.x,t.y-n.y)}lockScroll(){typeof document<`u`&&(this.bodyOverflow=document.body.style.overflow,document.body.style.overflow=`hidden`)}unlockScroll(){typeof document<`u`&&(document.body.style.overflow=this.bodyOverflow)}slug(e){return e.replace(/[^\w.-]+/g,`-`).replace(/^-+|-+$/g,``)||`panorama`}query(e){let t=this.root;if(!t)throw Error(`[DronePanoramaViewer] 弹窗尚未挂载`);let n=t.querySelector(e);if(!n)throw Error(`[DronePanoramaViewer] 缺少节点:${e}`);return n}template(){let e=this.options.downloadable===!1?` hidden`:``;return`
|
|
1020
|
+
<div class="divp-mask" data-role="mask" data-action="close"></div>
|
|
1021
|
+
<div class="divp-frame">
|
|
1022
|
+
<div class="divp-bar">
|
|
1023
|
+
<span class="divp-title" data-role="title">全景图</span>
|
|
1024
|
+
<span class="divp-hud" data-role="hud"></span>
|
|
1025
|
+
<span class="divp-spacer"></span>
|
|
1026
|
+
<button type="button" class="divp-btn" data-action="reset" title="视角复位 (0)">复位</button>
|
|
1027
|
+
<button type="button" class="divp-btn" data-action="import" title="从本地导入等距柱状全景图"${this.options.importable?``:` hidden`}>导入图片</button>
|
|
1028
|
+
<button type="button" class="divp-btn" data-action="download" title="下载原图"${e}>下载原图</button>
|
|
1029
|
+
<button type="button" class="divp-icon" data-action="close" title="关闭 (Esc)" aria-label="关闭">×</button>
|
|
1030
|
+
</div>
|
|
1031
|
+
<div class="divp-stage" data-role="stage">
|
|
1032
|
+
<canvas class="divp-canvas" data-role="canvas"></canvas>
|
|
1033
|
+
<p class="divp-note" data-role="note" hidden></p>
|
|
1034
|
+
</div>
|
|
1035
|
+
<div class="divp-foot">拖动环视球面 · 滚轮 / 双指缩放 · 方向键微调(Shift 加速) · 双击或 0 复位 · Esc 关闭</div>
|
|
1036
|
+
</div>
|
|
1037
|
+
<input type="file" accept="image/*" data-role="file" hidden />
|
|
1038
|
+
`}};function Zg(e,t,n){let r=e.createShader(t);return r?(e.shaderSource(r,n),e.compileShader(r),e.getShaderParameter(r,e.COMPILE_STATUS)?r:(console.warn(`[DronePanoramaViewer] 着色器编译失败:`,e.getShaderInfoLog(r)),e.deleteShader(r),null)):null}var Qg=`drone-gallery-styles`,$g=900,e_=24,t_=205,n_=47,r_=`
|
|
1039
|
+
.dgallery {
|
|
1040
|
+
--dg-text: #e9eff9;
|
|
1041
|
+
--dg-muted: rgba(233, 239, 249, 0.58);
|
|
1042
|
+
--dg-border: rgba(255, 255, 255, 0.12);
|
|
1043
|
+
--dg-accent: #35a7ff;
|
|
1044
|
+
--dg-ok: #37d67a;
|
|
1045
|
+
--dg-warn: #f5a623;
|
|
1046
|
+
--dg-bad: #ff5f5f;
|
|
1047
|
+
font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
1048
|
+
user-select: none;
|
|
1049
|
+
-webkit-user-select: none;
|
|
1050
|
+
-webkit-tap-highlight-color: transparent;
|
|
1051
|
+
}
|
|
1052
|
+
.dgallery {
|
|
1053
|
+
position: fixed; inset: 0; z-index: ${$g};
|
|
1054
|
+
display: flex; align-items: center; justify-content: center;
|
|
1055
|
+
padding: max(10px, env(safe-area-inset-top)) 10px max(10px, env(safe-area-inset-bottom));
|
|
1056
|
+
color: var(--dg-text);
|
|
1057
|
+
outline: none;
|
|
1058
|
+
}
|
|
1059
|
+
.dgallery[hidden] { display: none; }
|
|
1060
|
+
.dgallery-mask {
|
|
1061
|
+
position: absolute; inset: 0; background: rgba(6, 9, 14, 0.86);
|
|
1062
|
+
-webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
|
|
1063
|
+
}
|
|
1064
|
+
.dgallery-frame {
|
|
1065
|
+
position: relative; z-index: 1;
|
|
1066
|
+
display: flex; flex-direction: column;
|
|
1067
|
+
width: min(100%, 1180px); height: 100%; overflow: hidden;
|
|
1068
|
+
border: 1px solid var(--dg-border); border-radius: 12px;
|
|
1069
|
+
background: rgba(15, 19, 27, 0.95);
|
|
1070
|
+
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.5);
|
|
1071
|
+
}
|
|
1072
|
+
.dgallery-bar {
|
|
1073
|
+
flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
|
|
1074
|
+
padding: 8px 10px; border-bottom: 1px solid var(--dg-border);
|
|
1075
|
+
}
|
|
1076
|
+
.dgallery-title { font-weight: 600; }
|
|
1077
|
+
.dgallery-session {
|
|
1078
|
+
max-width: 200px; min-height: 26px; padding: 2px 6px; cursor: pointer;
|
|
1079
|
+
border: 1px solid var(--dg-border); border-radius: 7px;
|
|
1080
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dg-text); font: inherit;
|
|
1081
|
+
}
|
|
1082
|
+
.dgallery-stats { color: var(--dg-muted); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1083
|
+
.dgallery-stats .is-ok { color: var(--dg-ok); }
|
|
1084
|
+
.dgallery-stats .is-warn { color: var(--dg-warn); }
|
|
1085
|
+
.dgallery-stats .is-bad { color: var(--dg-bad); }
|
|
1086
|
+
.dgallery-spacer { flex: 1; min-width: 4px; }
|
|
1087
|
+
.dgallery-icon {
|
|
1088
|
+
flex: 0 0 auto; width: 26px; height: 26px; padding: 0; cursor: pointer;
|
|
1089
|
+
border: 1px solid var(--dg-border); border-radius: 7px;
|
|
1090
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dg-text); font: inherit; line-height: 1;
|
|
1091
|
+
}
|
|
1092
|
+
.dgallery-icon:hover { background: rgba(255, 255, 255, 0.14); }
|
|
1093
|
+
.dgallery-chips {
|
|
1094
|
+
flex: 0 0 auto; display: flex; gap: 6px; align-items: center;
|
|
1095
|
+
padding: 6px 10px; overflow-x: auto; border-bottom: 1px solid var(--dg-border);
|
|
1096
|
+
}
|
|
1097
|
+
.dgallery-chips[hidden] { display: none; }
|
|
1098
|
+
.dgallery-chip {
|
|
1099
|
+
flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
|
|
1100
|
+
min-height: 24px; padding: 2px 8px; cursor: pointer; white-space: nowrap;
|
|
1101
|
+
border: 1px solid var(--dg-border); border-radius: 999px;
|
|
1102
|
+
background: rgba(255, 255, 255, 0.05); color: var(--dg-text); font: inherit; font-size: 12px;
|
|
1103
|
+
}
|
|
1104
|
+
.dgallery-chip:hover { background: rgba(255, 255, 255, 0.12); }
|
|
1105
|
+
.dgallery-chip i { width: 8px; height: 8px; border-radius: 50%; background: var(--dg-group, var(--dg-accent)); }
|
|
1106
|
+
.dgallery-body {
|
|
1107
|
+
flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
|
|
1108
|
+
padding: 10px; -webkit-overflow-scrolling: touch;
|
|
1109
|
+
}
|
|
1110
|
+
.dgallery-group { margin-bottom: 16px; }
|
|
1111
|
+
.dgallery-group:last-child { margin-bottom: 4px; }
|
|
1112
|
+
.dgallery-group-head {
|
|
1113
|
+
display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
|
|
1114
|
+
padding: 7px 9px; margin-bottom: 8px; border-radius: 9px;
|
|
1115
|
+
border: 1px solid var(--dg-border);
|
|
1116
|
+
border-left: 3px solid var(--dg-group, var(--dg-accent));
|
|
1117
|
+
background: rgba(255, 255, 255, 0.035);
|
|
1118
|
+
}
|
|
1119
|
+
.dgallery-group-title { font-weight: 600; }
|
|
1120
|
+
.dgallery-group-sub { color: var(--dg-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
|
|
1121
|
+
.dgallery-group-sub .is-warn { color: var(--dg-warn); }
|
|
1122
|
+
.dgallery-group-sub .is-ok { color: var(--dg-ok); }
|
|
1123
|
+
.dgallery-btn {
|
|
1124
|
+
min-height: 26px; padding: 3px 10px; cursor: pointer; white-space: nowrap;
|
|
1125
|
+
border: 1px solid var(--dg-border); border-radius: 8px;
|
|
1126
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dg-text); font: inherit; font-size: 12px;
|
|
1127
|
+
}
|
|
1128
|
+
.dgallery-btn:hover { background: rgba(255, 255, 255, 0.13); }
|
|
1129
|
+
.dgallery-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
|
|
1130
|
+
.dgallery-btn.dgallery-primary { background: var(--dg-accent); border-color: transparent; color: #04121f; font-weight: 600; }
|
|
1131
|
+
.dgallery-btn.dgallery-on { background: var(--dg-bad); border-color: transparent; color: #fff; font-weight: 600; }
|
|
1132
|
+
.dgallery-thumbs {
|
|
1133
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(94px, 1fr)); gap: 6px;
|
|
1134
|
+
}
|
|
1135
|
+
.dgallery-thumb {
|
|
1136
|
+
position: relative; aspect-ratio: 4 / 3; padding: 0; overflow: hidden; cursor: pointer;
|
|
1137
|
+
border: 1px solid var(--dg-border); border-radius: 7px; background: rgba(255, 255, 255, 0.04);
|
|
1138
|
+
}
|
|
1139
|
+
.dgallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
1140
|
+
.dgallery-thumb[data-selected="true"] { border-color: var(--dg-accent); box-shadow: 0 0 0 1px var(--dg-accent); }
|
|
1141
|
+
.dgallery-thumb[data-status="warning"] { border-color: var(--dg-warn); }
|
|
1142
|
+
.dgallery-thumb[data-status="invalid"] { border-color: var(--dg-bad); }
|
|
1143
|
+
.dgallery-badge {
|
|
1144
|
+
position: absolute; left: 3px; top: 3px; min-width: 14px; height: 14px; padding: 0 3px;
|
|
1145
|
+
border-radius: 4px; font-size: 10px; line-height: 14px; text-align: center; font-weight: 700;
|
|
1146
|
+
background: rgba(0, 0, 0, 0.6); color: #fff;
|
|
1147
|
+
}
|
|
1148
|
+
.dgallery-thumb[data-status="valid"] .dgallery-badge { background: var(--dg-ok); color: #04140a; }
|
|
1149
|
+
.dgallery-thumb[data-status="warning"] .dgallery-badge { background: var(--dg-warn); color: #241500; }
|
|
1150
|
+
.dgallery-thumb[data-status="invalid"] .dgallery-badge { background: var(--dg-bad); }
|
|
1151
|
+
.dgallery-tag {
|
|
1152
|
+
position: absolute; left: 0; right: 0; bottom: 0; padding: 1px 4px;
|
|
1153
|
+
font-size: 9px; line-height: 14px; color: #fff; font-variant-numeric: tabular-nums;
|
|
1154
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0));
|
|
1155
|
+
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
1156
|
+
}
|
|
1157
|
+
.dgallery-note { margin: 6px 0 0; color: var(--dg-muted); font-size: 11px; }
|
|
1158
|
+
.dgallery-note.is-warn { color: var(--dg-warn); }
|
|
1159
|
+
.dgallery-note[hidden] { display: none; }
|
|
1160
|
+
.dgallery-card {
|
|
1161
|
+
display: flex; gap: 10px; align-items: flex-start; margin-top: 8px; padding: 8px;
|
|
1162
|
+
border: 1px solid rgba(53, 167, 255, 0.5); border-radius: 9px;
|
|
1163
|
+
background: rgba(53, 167, 255, 0.08);
|
|
1164
|
+
}
|
|
1165
|
+
.dgallery-card[hidden] { display: none; }
|
|
1166
|
+
.dgallery-card-img {
|
|
1167
|
+
flex: 0 0 auto; max-width: 46%; max-height: 150px; min-width: 80px;
|
|
1168
|
+
border-radius: 6px; background: #05070b; object-fit: contain; display: block; cursor: zoom-in;
|
|
1169
|
+
}
|
|
1170
|
+
.dgallery-card-side { flex: 1; min-width: 0; }
|
|
1171
|
+
.dgallery-card-title { font-weight: 600; }
|
|
1172
|
+
.dgallery-card-meta { color: var(--dg-muted); font-size: 11px; margin: 2px 0 7px; }
|
|
1173
|
+
.dgallery-card-actions { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
1174
|
+
.dgallery-diagnostic { margin-top: 8px; border: 1px solid var(--dg-border); border-radius: 8px; }
|
|
1175
|
+
.dgallery-diagnostic summary { padding: 7px 9px; cursor: pointer; color: var(--dg-text); }
|
|
1176
|
+
.dgallery-diagnostic-content { padding: 0 9px 9px; }
|
|
1177
|
+
.dgallery-diagnostic-help { margin: 0 0 8px; color: var(--dg-muted); font-size: 12px; }
|
|
1178
|
+
.dgallery-diagnostic-img {
|
|
1179
|
+
display: block; width: 100%; max-height: 58vh; object-fit: contain;
|
|
1180
|
+
background: #080b10; border-radius: 6px;
|
|
1181
|
+
}
|
|
1182
|
+
.dgallery-diagnostic-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 8px 0 0; padding: 0; list-style: none; }
|
|
1183
|
+
.dgallery-diagnostic-legend li { display: flex; align-items: center; gap: 6px; color: var(--dg-muted); font-size: 11px; }
|
|
1184
|
+
.dgallery-diagnostic-swatch { width: 12px; height: 12px; flex: 0 0 auto; border-radius: 3px; background: var(--dg-shot-color); }
|
|
1185
|
+
.dgallery-foot {
|
|
1186
|
+
flex: 0 0 auto; padding: 6px 10px; border-top: 1px solid var(--dg-border);
|
|
1187
|
+
color: var(--dg-muted); font-size: 11px;
|
|
1188
|
+
}
|
|
1189
|
+
@media (max-height: 560px) {
|
|
1190
|
+
.dgallery-thumbs { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); }
|
|
1191
|
+
.dgallery-card-img { max-height: 96px; }
|
|
1192
|
+
}
|
|
1193
|
+
@media (pointer: coarse) {
|
|
1194
|
+
.dgallery-icon { width: 32px; height: 32px; }
|
|
1195
|
+
.dgallery-btn { min-height: 32px; }
|
|
1196
|
+
}
|
|
1197
|
+
`;function i_(){if(typeof document>`u`||document.getElementById(Qg))return;let e=document.createElement(`style`);e.id=Qg,e.textContent=r_,document.head.appendChild(e)}var a_=class{constructor(e,t={}){i(this,`service`,void 0),i(this,`options`,void 0),i(this,`stitcher`,void 0),i(this,`root`,null),i(this,`refs`,null),i(this,`unsubscribe`,null),i(this,`viewer`,null),i(this,`ownViewer`,!1),i(this,`panorama`,null),i(this,`ownPanorama`,!1),i(this,`sessionId`,null),i(this,`selectedId`,null),i(this,`stitches`,new Map),i(this,`progressKey`,null),i(this,`bodyOverflow`,``),i(this,`destroyed`,!1),i(this,`downloadInProgress`,!1),i(this,`onClick`,e=>{let t=e.target,n=t?.closest(`[data-action]`);if(!n)(t===this.root||t===this.refs?.mask)&&this.close();else switch(n.dataset.action??``){case`close`:this.close();break;case`jump`:{let e=n.dataset.key??``;(this.refs?.body.querySelector(`.dgallery-group[data-key="${c_(e)}"]`))?.scrollIntoView({block:`start`});break}case`select-image`:{let e=n.dataset.id??``;this.selectedId=e,this.syncSelection(),this.viewer?.open(e,this.resolveSession()?.id);break}case`stitch`:this.stitch(n.dataset.key??``);break;case`download-originals`:this.downloadOriginals();break;case`stitch-all`:this.stitchAll();break;case`view-panorama`:{let e=n.dataset.key??``,t=this.stitches.get(e)?.result;t?.url&&this.panorama?.open(t,`合成全景图`);break}case`download-stitch`:{let e=n.dataset.key??``,t=this.stitches.get(e)?.result;t?.url&&Mh(t.url,t.name??`${e}-pano.png`);break}}}),i(this,`onSessionChange`,()=>{let e=this.refs;if(!e)return;let t=this.service.getSession(e.sessionSelect.value);t&&(t.updatedAt=new Date().toISOString(),this.sessionId=t.id,this.selectedId=null,this.viewer?.close(),this.panorama?.close(),this.render())}),i(this,`onKeyDown`,e=>{this.destroyed||!this.root||this.root.hidden||this.panorama?.isOpen||this.viewer?.isOpen||e.ctrlKey||e.metaKey||e.altKey||(e.key===`Escape`&&(e.preventDefault(),this.close()),e.stopPropagation())}),this.service=e,this.options=t,this.stitcher=t.stitcher===void 0?sg():t.stitcher,this.stitcher&&(this.stitcher.onProgress=(e,t)=>{let n=this.progressKey;if(!n)return;let r=this.stitches.get(n);r&&r.status===`running`&&(r.done=e,r.total=t,this.renderStitch(n))})}get isOpen(){return this.root!==null&&!this.root.hidden}open(e){if(this.destroyed)return;this.sessionId=e??this.service.activeSession?.id??null,this.mount();let t=this.root;t&&(t.hidden=!1,this.lockScroll(),this.render(),t.focus())}close(){if(!this.root)return;let e=!this.root.hidden;this.panorama?.close(),this.viewer?.close(),this.unmount(),e&&this.options.onClose?.()}refresh(){this.isOpen&&this.render()}closePanorama(){this.panorama?.close()}async stitch(e){let t=this.resolveSession(),n=t?Bh(t.images).find(t=>t.key===e):null;if(!n||n.kind!==`panorama`||this.stitches.get(e)?.status===`running`||!this.stitcher)return null;this.stitches.set(e,{status:`running`,done:0,total:n.images.length}),this.progressKey=e,this.renderStitch(e);let r=null;try{r=await this.stitcher.stitch({id:n.key,mode:n.mode??`pano-180`,sessionId:t?.id??``,images:n.images})}catch(t){return this.stitches.set(e,{status:`error`,done:0,total:n.images.length,message:`合成失败:${t.message}`}),this.progressKey=null,this.renderStitch(e),this.options.onStitched?.(n,null),null}return this.progressKey=null,r?this.stitches.set(e,{status:`done`,done:n.images.length,total:n.images.length,result:r}):this.stitches.set(e,{status:`error`,done:0,total:n.images.length,message:`这组没法合成(可用影像不足,或图片没有可读的预览地址)`}),this.renderStitch(e),this.options.onStitched?.(n,r),r}async stitchAll(){let e=this.resolveSession();if(!e)return;let t=Bh(e.images).filter(e=>e.kind===`panorama`);for(let e of t)await this.stitch(e.key)}destroy(){this.destroyed||(this.destroyed=!0,this.panorama?.close(),this.viewer?.close(),this.ownPanorama&&this.panorama?.destroy(),this.ownViewer&&this.viewer?.destroy(),this.panorama=null,this.viewer=null,this.unmount(),this.options.injectStyles!==!1&&document.getElementById(Qg)?.remove())}resolveSession(){if(this.sessionId){let e=this.service.getSession(this.sessionId);if(e)return e}return this.service.activeSession}mount(){if(this.root||typeof document>`u`)return;this.options.injectStyles!==!1&&i_();let e=document.createElement(`div`);e.className=`dgallery`,e.hidden=!0,e.tabIndex=-1,e.setAttribute(`role`,`dialog`),e.setAttribute(`aria-modal`,`true`),e.setAttribute(`aria-label`,this.options.title??`影像集`),this.options.zIndex&&this.options.zIndex!==$g&&(e.style.zIndex=String(this.options.zIndex)),e.innerHTML=this.template(),document.body.appendChild(e),this.root=e,this.refs={mask:this.query(`[data-role="mask"]`),sessionSelect:this.query(`[data-role="session"]`),stats:this.query(`[data-role="stats"]`),chips:this.query(`[data-role="chips"]`),body:this.query(`[data-role="body"]`),downloadStatus:this.query(`[data-role="download-status"]`)},this.options.viewer?(this.viewer=this.options.viewer,this.ownViewer=!1):this.options.viewerEnabled!==!1&&(this.viewer=new Jh(this.service,{...this.options.viewerOptions,zIndex:(this.options.zIndex??$g)+100,onNavigate:(e,t)=>{this.selectedId=e.id,this.syncSelection(),this.options.viewerOptions?.onNavigate?.(e,t)}}),this.ownViewer=!0),this.options.panoramaViewer?(this.panorama=this.options.panoramaViewer,this.ownPanorama=!1):this.options.panoramaViewerEnabled!==!1&&(this.panorama=new Xg({...this.options.panoramaViewerOptions,zIndex:(this.options.zIndex??$g)+200}),this.ownPanorama=!0),e.addEventListener(`click`,this.onClick),this.refs.sessionSelect.addEventListener(`change`,this.onSessionChange),window.addEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.unsubscribe=this.service.subscribe(()=>this.render())}unmount(){window.removeEventListener(`keydown`,this.onKeyDown,{capture:!0}),this.unsubscribe?.(),this.unsubscribe=null,this.root?.remove(),this.root=null,this.refs=null,this.unlockScroll()}render(){let e=this.refs,t=this.root;if(!t||!e||t.hidden)return;let n=this.resolveSession(),r=this.service.listSessions(),i=r.map(e=>`${e.id}:${e.options.name}`).join(`|`);if(e.sessionSelect.dataset.signature!==i)e.sessionSelect.dataset.signature=i,e.sessionSelect.innerHTML=r.map(e=>`<option value="${$(e.id)}">${$(e.options.name)} · ${e.images.length}</option>`).join(``);else{let t=e.sessionSelect.options;r.forEach((e,n)=>{let r=t[n];if(!r)return;let i=`${e.options.name} · ${e.images.length}`;r.textContent!==i&&(r.textContent=i)})}n&&(e.sessionSelect.value=n.id);let a=n?.images??[],o=t.querySelector(`[data-action="download-originals"]`);o&&(o.disabled=a.length===0||this.downloadInProgress,o.textContent=this.downloadInProgress?`正在打包…`:`打包原图`);let s=Bh(a),c=a.filter(e=>e.validation.status===`valid`).length,l=a.filter(e=>e.validation.status===`warning`).length,u=a.filter(e=>e.validation.status===`invalid`).length;e.stats.innerHTML=n?`共 <b>${a.length}</b> 张 · ${s.length} 组 · <span class="is-ok">有效 ${c}</span> · <span class="is-warn">警告 ${l}</span> · <span class="is-bad">无效 ${u}</span>`:`未创建会话`,e.chips.hidden=s.length<2;let d=t.querySelector(`[data-action="stitch-all"]`);if(d&&(d.hidden=!s.some(e=>e.kind===`panorama`&&e.images.length>=2)),e.chips.innerHTML=s.map((e,t)=>`<button type="button" class="dgallery-chip" data-action="jump" data-key="${$(e.key)}"><i style="--dg-group:${o_(t)}"></i>${$(e.label)} · ${e.images.length}</button>`).join(``),!a.length){e.body.innerHTML=`<p class="dgallery-note">${n?`这个会话里还没有影像。`:`未创建会话。`}</p>`;return}let f=e.body.scrollTop;e.body.innerHTML=s.map((e,t)=>this.groupMarkup(e,t)).join(``),e.body.scrollTop=f;for(let e of s)this.renderStitch(e.key);this.syncSelection()}groupMarkup(e,t){let n=e.images.slice(0,e_),r=e.images.length-n.length,i=o_(t),a=[];a.push(`<section class="dgallery-group" data-key="${$(e.key)}" style="--dg-group:${i}">`),a.push(`<div class="dgallery-group-head">`),a.push(`<span class="dgallery-group-title">${$(e.label)}</span>`);let o=`<span class="dgallery-group-sub">${e.images.length} 张`;return e.kind===`panorama`&&(o+=` / ${e.total??e.images.length} 张`,o+=e.complete?` · <span class="is-ok">已拍完</span>`:` · <span class="is-warn">未拍完</span>`,o+=` · 组 ${$(e.key)}`),o+=`</span>`,a.push(o),a.push(`<span class="dgallery-spacer"></span>`),e.kind===`panorama`&&e.images.length>=2&&this.stitcher&&a.push(`<button type="button" class="dgallery-btn dgallery-primary" data-action="stitch" data-key="${$(e.key)}">一键合成</button>`),a.push(`</div>`),a.push(`<div class="dgallery-thumbs">`),n.forEach((t,n)=>{let r=e.indexes[n]??n+1;a.push(`<button type="button" class="dgallery-thumb" data-action="select-image" data-id="${$(t.id)}" data-status="${t.validation.status}" title="#${r} ${$(t.fileName)} · ${Ih[t.validation.status]}" aria-label="查看第 ${r} 张">`+(t.imageUrl?`<img src="${t.imageUrl}" alt="" loading="lazy">`:``)+`<span class="dgallery-badge">${Lh[t.validation.status]}</span><span class="dgallery-tag">${$(Vh(t,r))}</span></button>`)}),a.push(`</div>`),r>0&&a.push(`<p class="dgallery-note">还有 ${r} 张未在此列出(共 ${e.images.length} 张)。</p>`),a.push(`<div data-role="stitch" data-key="${$(e.key)}"></div>`),a.push(`</section>`),a.join(``)}renderStitch(e){let t=this.refs;if(!t)return;let n=t.body.querySelector(`[data-role="stitch"][data-key="${c_(e)}"]`);if(!n)return;let r=t.body.querySelector(`[data-action="stitch"][data-key="${c_(e)}"]`),i=this.stitches.get(e);if(!i){n.innerHTML=``,r&&(r.disabled=!1,r.textContent=`一键合成`,r.classList.remove(`dgallery-on`));return}if(i.status===`running`){r&&(r.disabled=!0,r.classList.add(`dgallery-on`),r.textContent=i.total>0?`合成中 ${i.done}/${i.total}`:`合成中 ${i.done}`),n.innerHTML=`<p class="dgallery-note">等距柱状拼接中,逐张反投影…</p>`;return}if(i.status===`error`){r&&(r.disabled=!1,r.classList.remove(`dgallery-on`),r.textContent=`重试合成`),n.innerHTML=`<p class="dgallery-note is-warn">${$(i.message??`合成失败`)}</p>`;return}let a=i.result;if(r&&(r.disabled=!1,r.classList.remove(`dgallery-on`),r.textContent=`重新合成`),!a?.url){n.innerHTML=`<p class="dgallery-note is-warn">合成完成,但没有可用的图片地址。</p>`;return}let o=[];a.width&&a.height&&o.push(`${a.width}×${a.height}`),typeof a.coverage==`number`&&o.push(`实拍覆盖 ${Math.round(a.coverage*100)}%`);let s=s_(a.url);s>0&&o.push(jh(s));let c=a.diagnosticUrl?`<details class="dgallery-diagnostic"><summary>拍摄覆盖检查(看颜色即可)</summary><div class="dgallery-diagnostic-content"><p class="dgallery-diagnostic-help">这不是照片,是拍摄覆盖地图:红色表示没有任何照片拍到,拼接只能猜着补;黄色表示只有一张照片拍到,容易出现接缝;绿色表示至少两张照片重叠。找墙出现的位置看颜色即可。</p><img class="dgallery-diagnostic-img" src="${a.diagnosticUrl}" alt="平面全景覆盖图"><ul class="dgallery-diagnostic-legend"><li><i class="dgallery-diagnostic-swatch" style="--dg-shot-color:#ef4444"></i><span>红:没拍到 ${Math.round((a.diagnosticCoverage?.uncovered??0)*100)}%</span></li><li><i class="dgallery-diagnostic-swatch" style="--dg-shot-color:#facc15"></i><span>黄:只拍到一次 ${Math.round((a.diagnosticCoverage?.single??0)*100)}%</span></li><li><i class="dgallery-diagnostic-swatch" style="--dg-shot-color:#22c55e"></i><span>绿:有照片重叠 ${Math.round((a.diagnosticCoverage?.overlap??0)*100)}%</span></li></ul></div></details>`:``;n.innerHTML=`<div class="dgallery-card"><img class="dgallery-card-img" data-action="view-panorama" data-key="${$(e)}" src="${a.url}" alt="合成全景"><div class="dgallery-card-side"><div class="dgallery-card-title">合成全景图</div><div class="dgallery-card-meta">等距柱状 360°×180° · ${o.map($).join(` · `)}</div><div class="dgallery-card-actions"><button type="button" class="dgallery-btn dgallery-primary" data-action="view-panorama" data-key="${$(e)}">360° 环视</button><button type="button" class="dgallery-btn" data-action="download-stitch" data-key="${$(e)}">下载</button></div></div></div>`+c}syncSelection(){let e=this.refs;if(e)for(let t of e.body.querySelectorAll(`.dgallery-thumb`))t.dataset.selected=String(t.dataset.id===this.selectedId)}async downloadOriginals(){if(this.downloadInProgress)return;let e=this.resolveSession();if(!e?.images.length)this.setDownloadStatus(`当前会话没有可下载的图片。`);else{this.downloadInProgress=!0,this.setDownloadStatus(`正在打包 ${e.images.length} 张原图…`),this.render();try{let t=await Nh(e.images),n=URL.createObjectURL(t);Mh(n,`${e.options.name.replace(/[\\/:*?"<>|\u0000-\u001f]/g,`_`).trim()||`影像集`}-原始图片.zip`),window.setTimeout(()=>URL.revokeObjectURL(n),6e4),this.setDownloadStatus(`已打包下载 ${e.images.length} 张原图。`)}catch(e){let t=e instanceof Error?e.message:String(e);this.setDownloadStatus(`打包下载失败:${t}`)}finally{this.downloadInProgress=!1,this.render()}}}setDownloadStatus(e){this.refs&&(this.refs.downloadStatus.textContent=e)}lockScroll(){typeof document<`u`&&(this.bodyOverflow=document.body.style.overflow,document.body.style.overflow=`hidden`)}unlockScroll(){typeof document<`u`&&(document.body.style.overflow=this.bodyOverflow)}query(e){let t=this.root;if(!t)throw Error(`[DroneGallery] 弹窗尚未挂载`);let n=t.querySelector(e);if(!n)throw Error(`[DroneGallery] 缺少节点:${e}`);return n}template(){return`
|
|
1198
|
+
<div class="dgallery-mask" data-role="mask" data-action="close"></div>
|
|
1199
|
+
<div class="dgallery-frame">
|
|
1200
|
+
<div class="dgallery-bar">
|
|
1201
|
+
<span class="dgallery-title">${$(this.options.title??`影像集`)}</span>
|
|
1202
|
+
<select class="dgallery-session" data-role="session" title="切换会话"></select>
|
|
1203
|
+
<span class="dgallery-stats" data-role="stats">–</span>
|
|
1204
|
+
<span class="dgallery-spacer"></span>
|
|
1205
|
+
${this.stitcher?`<button type="button" class="dgallery-btn" data-action="stitch-all" title="把当前会话里所有全景组依次合成">合成全部</button>`:``}
|
|
1206
|
+
<button type="button" class="dgallery-btn" data-action="download-originals" title="将当前会话的原图打包为 ZIP">打包原图</button>
|
|
1207
|
+
<button type="button" class="dgallery-icon" data-action="close" title="关闭 (Esc)" aria-label="关闭">×</button>
|
|
1208
|
+
</div>
|
|
1209
|
+
<div class="dgallery-chips" data-role="chips" hidden></div>
|
|
1210
|
+
<div class="dgallery-body" data-role="body"></div>
|
|
1211
|
+
<div class="dgallery-foot"><span>点缩略图看大图 · 全景组「一键合成」后可「360° 环视」拖动看四周 · Esc 关闭</span><span data-role="download-status" aria-live="polite"></span></div>
|
|
1212
|
+
</div>
|
|
1213
|
+
`}};function o_(e){return`hsl(${(t_+e*n_)%360} 78% 62%)`}function s_(e){if(!e.startsWith(`data:`))return 0;let t=e.indexOf(`,`);if(t<0)return 0;let n=e.length-t-1,r=e.endsWith(`==`)?2:+!!e.endsWith(`=`);return Math.max(0,Math.floor(n*3/4)-r)}function c_(e){return typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(e):e.replace(/["\\]/g,`\\$&`)}var l_=`drone-capture-panel-styles`,u_=1,d_=`
|
|
1214
|
+
.dcap {
|
|
1215
|
+
--dcap-bg: rgba(15, 19, 27, 0.86);
|
|
1216
|
+
--dcap-border: rgba(255, 255, 255, 0.12);
|
|
1217
|
+
--dcap-text: #e9eff9;
|
|
1218
|
+
--dcap-muted: rgba(233, 239, 249, 0.58);
|
|
1219
|
+
--dcap-accent: #35a7ff;
|
|
1220
|
+
--dcap-on-accent: #04121f;
|
|
1221
|
+
--dcap-ok: #37d67a;
|
|
1222
|
+
--dcap-warn: #f5a623;
|
|
1223
|
+
--dcap-danger: #ff5f5f;
|
|
1224
|
+
--dcap-radius: 10px;
|
|
1225
|
+
font: 12px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
1226
|
+
user-select: none;
|
|
1227
|
+
-webkit-user-select: none;
|
|
1228
|
+
-webkit-tap-highlight-color: transparent;
|
|
1229
|
+
}
|
|
1230
|
+
.dcap {
|
|
1231
|
+
z-index: 20;
|
|
1232
|
+
width: 316px;
|
|
1233
|
+
max-height: min(62vh, 580px);
|
|
1234
|
+
box-sizing: border-box;
|
|
1235
|
+
padding: 10px 12px 12px;
|
|
1236
|
+
display: flex;
|
|
1237
|
+
flex-direction: column;
|
|
1238
|
+
border: 1px solid var(--dcap-border);
|
|
1239
|
+
border-radius: var(--dcap-radius);
|
|
1240
|
+
background: var(--dcap-bg);
|
|
1241
|
+
color: var(--dcap-text);
|
|
1242
|
+
-webkit-backdrop-filter: blur(10px);
|
|
1243
|
+
backdrop-filter: blur(10px);
|
|
1244
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
|
|
1245
|
+
}
|
|
1246
|
+
.dcap[data-position="top-left"] { top: 12px; left: 12px; }
|
|
1247
|
+
.dcap[data-position="top-right"] { top: 12px; right: 12px; }
|
|
1248
|
+
.dcap[data-position="bottom-left"] { bottom: 12px; left: 12px; }
|
|
1249
|
+
.dcap[data-position="bottom-right"] { bottom: 12px; right: 12px; }
|
|
1250
|
+
.dcap-head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
|
|
1251
|
+
.dcap-title { font-size: 12px; font-weight: 600; }
|
|
1252
|
+
.dcap-count { margin-left: auto; color: var(--dcap-muted); font-variant-numeric: tabular-nums; }
|
|
1253
|
+
.dcap-icon {
|
|
1254
|
+
width: 20px; height: 20px; padding: 0; line-height: 1; cursor: pointer;
|
|
1255
|
+
border: 1px solid var(--dcap-border); border-radius: 6px;
|
|
1256
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dcap-text);
|
|
1257
|
+
}
|
|
1258
|
+
.dcap-body { flex: 1; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
|
|
1259
|
+
.dcap[data-collapsed="true"] .dcap-body { display: none; }
|
|
1260
|
+
.dcap-blk { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--dcap-border); }
|
|
1261
|
+
.dcap-blk:first-child { margin-top: 0; padding-top: 0; border-top: none; }
|
|
1262
|
+
.dcap-label {
|
|
1263
|
+
display: flex; justify-content: space-between; align-items: baseline;
|
|
1264
|
+
color: var(--dcap-muted); margin-bottom: 6px;
|
|
1265
|
+
}
|
|
1266
|
+
.dcap-label em { font-style: normal; color: var(--dcap-text); font-variant-numeric: tabular-nums; }
|
|
1267
|
+
.dcap-row { display: flex; gap: 6px; align-items: center; margin-bottom: 7px; }
|
|
1268
|
+
.dcap-row > .dcap-field { flex: 1; min-width: 0; }
|
|
1269
|
+
.dcap-btn {
|
|
1270
|
+
flex: 1; min-height: 28px; padding: 4px 8px; cursor: pointer; white-space: nowrap;
|
|
1271
|
+
border: 1px solid var(--dcap-border); border-radius: 8px;
|
|
1272
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dcap-text); font: inherit;
|
|
1273
|
+
}
|
|
1274
|
+
.dcap-btn:hover { background: rgba(255, 255, 255, 0.12); }
|
|
1275
|
+
.dcap-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
|
|
1276
|
+
.dcap-btn.dcap-primary { background: var(--dcap-accent); border-color: transparent; color: var(--dcap-on-accent); font-weight: 600; }
|
|
1277
|
+
.dcap-btn.dcap-on { background: var(--dcap-danger); border-color: transparent; color: #fff; font-weight: 600; }
|
|
1278
|
+
.dcap-select, .dcap-num, .dcap-text {
|
|
1279
|
+
box-sizing: border-box; width: 100%; min-height: 26px; padding: 2px 6px;
|
|
1280
|
+
border: 1px solid var(--dcap-border); border-radius: 7px;
|
|
1281
|
+
background: rgba(255, 255, 255, 0.06); color: var(--dcap-text); font: inherit;
|
|
1282
|
+
}
|
|
1283
|
+
.dcap-num { width: 62px; text-align: right; font-variant-numeric: tabular-nums; }
|
|
1284
|
+
.dcap-select:focus, .dcap-num:focus, .dcap-text:focus { outline: none; border-color: var(--dcap-accent); }
|
|
1285
|
+
.dcap-field { display: flex; align-items: center; gap: 5px; color: var(--dcap-muted); white-space: nowrap; }
|
|
1286
|
+
.dcap-hint { margin: 2px 0 0; color: var(--dcap-muted); font-size: 11px; }
|
|
1287
|
+
.dcap-note {
|
|
1288
|
+
margin: 6px 0 0; padding: 5px 7px; border-radius: 7px; font-size: 11px; line-height: 1.5;
|
|
1289
|
+
background: rgba(255, 255, 255, 0.05); color: var(--dcap-muted);
|
|
1290
|
+
}
|
|
1291
|
+
.dcap-note[hidden] { display: none; }
|
|
1292
|
+
.dcap-note.is-warn { color: var(--dcap-warn); }
|
|
1293
|
+
@media (pointer: coarse) { .dcap-btn { min-height: 34px; } }
|
|
1294
|
+
`;function f_(){if(typeof document>`u`||document.getElementById(l_))return;let e=document.createElement(`style`);e.id=l_,e.textContent=d_,document.head.appendChild(e)}function p_(){let e=new Date,t=e=>String(e).padStart(2,`0`);return`${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}-${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}`}var m_=class{constructor(e,t={}){if(i(this,`service`,void 0),i(this,`host`,void 0),i(this,`root`,void 0),i(this,`refs`,void 0),i(this,`options`,void 0),i(this,`viewer`,null),i(this,`gallery`,null),i(this,`unsubscribe`,null),i(this,`sessionSignature`,``),i(this,`noteTimer`,null),i(this,`destroyed`,!1),i(this,`onClick`,e=>{let t=e.target?.closest(`[data-action]`);t&&this.handleAction(t.dataset.action??``,t)}),i(this,`onChange`,e=>{let t=e.target;if(t&&t===this.refs.sessionSelect){let e=this.service.getSession(this.refs.sessionSelect.value);e&&(e.updatedAt=new Date().toISOString(),this.viewer?.close(),e.options.captureIntervalMs&&(this.refs.intervalInput.value=String(e.options.captureIntervalMs/1e3)),e.options.distanceIntervalMeters&&(this.refs.distanceInput.value=String(e.options.distanceIntervalMeters)),this.sync())}}),typeof document>`u`)throw Error(`[DroneCapturePanel] 需要 DOM 环境`);this.options=t,t.injectStyles!==!1&&f_(),this.service=t.service??new Eh({provider:e}),t.service||this.service.setProvider(e);let n=t.container??null;this.host=n??document.body,n&&getComputedStyle(n).position===`static`&&(n.style.position=`relative`),this.root=document.createElement(`div`),this.root.className=`dcap`,this.root.dataset.position=t.position??`bottom-left`,this.root.dataset.collapsed=`false`,this.root.style.position=n?`absolute`:`fixed`;let r=t.position??`bottom-left`,a=t.offset??{};if(a.y){let e=r.startsWith(`bottom`)?`marginBottom`:`marginTop`;this.root.style[e]=`${a.y}px`}if(a.x){let e=r.endsWith(`right`)?`marginRight`:`marginLeft`;this.root.style[e]=`${a.x}px`}t.visible===!1&&(this.root.style.display=`none`),this.root.innerHTML=this.template(),this.host.appendChild(this.root),this.refs={body:this.query(`[data-role="body"]`),count:this.query(`[data-role="count"]`),sessionSelect:this.query(`[data-role="session-select"]`),sessionName:this.query(`[data-role="session-name"]`),sourceSelect:this.query(`[data-role="source-select"]`),nameInput:this.query(`[data-role="name-input"]`),virtualBlock:this.query(`[data-blk="virtual"]`),realBlock:this.query(`[data-blk="real"]`),intervalInput:this.query(`[data-role="interval"]`),distanceInput:this.query(`[data-role="distance"]`),autoBtn:this.query(`[data-action="auto-toggle"]`),autoState:this.query(`[data-role="auto-state"]`),galleryCount:this.query(`[data-role="gallery-count"]`),galleryBtn:this.query(`[data-action="open-gallery"]`),note:this.query(`[data-role="note"]`),fileInput:this.query(`[data-role="file-input"]`),dirInput:this.query(`[data-role="dir-input"]`)},this.refs.nameInput.value=`虚拟采集-${p_()}`,this.refs.intervalInput.value=String(u_),this.refs.distanceInput.value=`0`,t.autoCreateSession!==!1&&this.service.listSessions().length===0&&this.service.createSession(this.newSessionOptions(`virtual-camera`,this.refs.nameInput.value)),this.root.addEventListener(`click`,this.onClick),this.root.addEventListener(`change`,this.onChange),this.refs.fileInput.addEventListener(`change`,()=>void this.onFiles(this.refs.fileInput)),this.refs.dirInput.addEventListener(`change`,()=>void this.onFiles(this.refs.dirInput)),this.unsubscribe=this.service.subscribe(()=>this.sync()),t.viewer!==!1&&(this.viewer=new Jh(this.service,{...t.viewerOptions})),t.gallery!==!1&&(this.gallery=new a_(this.service,{...t.galleryOptions,...this.viewer?{viewer:this.viewer}:{},viewerEnabled:t.viewer!==!1&&(t.galleryOptions?.viewerEnabled??!0)})),this.sync()}newSessionOptions(e,t){return{...this.options.sessionDefaults,source:e,name:t}}get session(){return this.service.activeSession}setVisible(e){this.root.style.display=e?``:`none`}openViewer(e){let t=this.session;if(!t||!this.viewer)return;let n=e??t.images[t.images.length-1]?.id;n&&this.viewer.open(n,t.id)}closeViewer(){this.viewer?.close()}openGallery(e){this.gallery?.open(e??this.session?.id)}closeGallery(){this.gallery?.close()}sync(){if(this.destroyed)return;let e=this.session;this.refs.count.textContent=e?`${e.images.length} 张`:`–`,this.refs.sessionName.textContent=e?`${e.options.name}`:`未创建`,this.syncSessionOptions();let t=!e||e.options.source===`virtual-camera`;this.refs.virtualBlock.style.display=t?``:`none`,this.refs.realBlock.style.display=t?`none`:``;let n=e?this.service.isAutoCapturing(e.id):!1;if(this.refs.autoBtn.textContent=n?`停止自动`:`自动采集`,this.refs.autoBtn.classList.toggle(`dcap-on`,n),this.refs.autoState.textContent=n?`自动中 · 每 ${this.refs.intervalInput.value}s / ${this.refs.distanceInput.value}m`:`空闲`,e){let t=Bh(e.images).filter(e=>e.kind===`panorama`).length;this.refs.galleryCount.textContent=t?`${t} 组全景 · 共 ${e.images.length} 张`:`共 ${e.images.length} 张`}else this.refs.galleryCount.textContent=`未创建会话`;this.refs.galleryBtn.disabled=!e||e.images.length===0,this.refs.galleryBtn.title=e?.images.length?`按组合浏览影像集,全景组可一键合成`:`还没有影像`,this.gallery?.refresh()}setNote(e,t=!1){this.destroyed||(this.refs.note.textContent=e,this.refs.note.classList.toggle(`is-warn`,t),this.refs.note.hidden=!e,this.noteTimer!==null&&clearTimeout(this.noteTimer),this.noteTimer=e?setTimeout(()=>{this.destroyed||(this.refs.note.hidden=!0),this.noteTimer=null},5e3):null)}syncSessionOptions(){let e=this.service.listSessions(),t=e.map(e=>`${e.id}:${e.options.name}:${e.options.source}`).join(`|`);if(t!==this.sessionSignature){this.sessionSignature=t;let n=this.session;this.refs.sessionSelect.innerHTML=e.map(e=>`<option value="${e.id}">${$(e.options.name)} · ${e.images.length}</option>`).join(``),n&&(this.refs.sessionSelect.value=n.id)}else{let t=this.session;t&&(this.refs.sessionSelect.value=t.id);let n=this.refs.sessionSelect.options;for(let t=0;t<n.length;t+=1){let r=e[t],i=n[t];if(!r||!i)continue;let a=`${r.options.name} · ${r.images.length}`;i.textContent!==a&&(i.textContent=a)}}}async handleAction(e,t){let n=this.session;switch(e){case`toggle-collapse`:{let e=this.root.dataset.collapsed===`true`;this.root.dataset.collapsed=e?`false`:`true`,this.query(`[data-action="toggle-collapse"]`).textContent=e?`–`:`+`;break}case`session-new`:{let e=this.refs.sourceSelect.value,t=this.refs.nameInput.value.trim()||`采集-${p_()}`;this.service.createSession(this.newSessionOptions(e,t)),this.sync();break}case`capture-one`:if(!n)break;t.setAttribute(`disabled`,`disabled`),await this.service.captureVirtualImage(n.id),t.removeAttribute(`disabled`);break;case`auto-toggle`:if(!n)break;if(this.service.isAutoCapturing(n.id))this.service.stopAutoCapture(n.id);else{let e=Number(this.refs.intervalInput.value),t=Number(this.refs.distanceInput.value);this.service.startAutoCapture(n.id,{intervalMs:Number.isFinite(e)&&e>0?e*1e3:0,distanceMeters:Number.isFinite(t)&&t>0?t:0})||this.setNote(`自动采集需要时间间隔或距离间隔至少填一个 > 0 的值。`)}this.sync();break;case`pick-files`:this.refs.fileInput.click();break;case`pick-dir`:this.refs.dirInput.click();break;case`open-gallery`:this.openGallery();break;case`clear-images`:if(!n)break;this.service.clearImages(n.id),this.sync();break;case`export`:n&&this.exportSession(n,t.dataset.format??`json`);break;case`finish`:n&&this.service.finishSession(n.id)}}async onFiles(e){let t=this.session;if(!t||!e.files?.length)return;let n=Array.from(e.files);e.value=``,this.setNote(`正在导入 ${n.length} 个文件…`),await this.service.importRealImages(t.id,n),this.sync(),this.setNote(`已导入 ${n.length} 个文件。`)}exportSession(e,t){let n=this.service.exportSession(e.id,t);if(this.options.downloadOnExport!==!1&&typeof document<`u`){let r=t===`csv`?`text/csv`:`application/json`,i=URL.createObjectURL(new Blob([n],{type:`${r};charset=utf-8`})),a=t===`manifest`?`json`:t;Mh(i,`capture-${e.options.name}-${p_()}${t===`manifest`?`-manifest`:``}.${a}`),URL.revokeObjectURL(i)}return n}destroy(){if(!this.destroyed){this.destroyed=!0,this.unsubscribe?.(),this.unsubscribe=null,this.noteTimer!==null&&clearTimeout(this.noteTimer),this.noteTimer=null,this.viewer?.destroy(),this.viewer=null,this.gallery?.destroy(),this.gallery=null;for(let e of this.service.listSessions())this.service.stopAutoCapture(e.id);this.root.remove(),this.options.injectStyles!==!1&&document.getElementById(l_)?.remove()}}query(e){let t=this.root.querySelector(e);if(!t)throw Error(`[DroneCapturePanel] 缺少节点:${e}`);return t}template(){return`
|
|
1295
|
+
<div class="dcap-head">
|
|
1296
|
+
<span class="dcap-title">${$(this.options.title??`影像采集`)}</span>
|
|
1297
|
+
<span class="dcap-count" data-role="count">–</span>
|
|
1298
|
+
<button type="button" class="dcap-icon" data-action="toggle-collapse" title="收起 / 展开" aria-label="收起或展开">–</button>
|
|
1299
|
+
</div>
|
|
1300
|
+
<div class="dcap-body" data-role="body">
|
|
1301
|
+
<section class="dcap-blk">
|
|
1302
|
+
<div class="dcap-label">采集会话<em data-role="session-name">–</em></div>
|
|
1303
|
+
<div class="dcap-row">
|
|
1304
|
+
<select class="dcap-select dcap-field" data-role="session-select" title="切换当前会话"></select>
|
|
1305
|
+
<button type="button" class="dcap-btn" style="flex:0 0 auto" data-action="finish" title="结束当前会话(保留影像集)">结束</button>
|
|
1306
|
+
</div>
|
|
1307
|
+
<div class="dcap-row">
|
|
1308
|
+
<input class="dcap-text dcap-field" data-role="name-input" type="text" placeholder="会话名称" title="新会话名称">
|
|
1309
|
+
<select class="dcap-select" data-role="source-select" style="flex:0 0 86px" title="影像来源">
|
|
1310
|
+
<option value="virtual-camera">场景虚拟</option>
|
|
1311
|
+
<option value="real-camera">真实照片</option>
|
|
1312
|
+
</select>
|
|
1313
|
+
<button type="button" class="dcap-btn dcap-primary" style="flex:0 0 auto" data-action="session-new">新建</button>
|
|
1314
|
+
</div>
|
|
1315
|
+
</section>
|
|
1316
|
+
|
|
1317
|
+
<section class="dcap-blk" data-blk="virtual">
|
|
1318
|
+
<div class="dcap-label">虚拟采集<em data-role="auto-state">空闲</em></div>
|
|
1319
|
+
<div class="dcap-row">
|
|
1320
|
+
<button type="button" class="dcap-btn dcap-primary" data-action="capture-one">拍一张</button>
|
|
1321
|
+
<button type="button" class="dcap-btn" data-action="auto-toggle">自动采集</button>
|
|
1322
|
+
</div>
|
|
1323
|
+
<div class="dcap-row">
|
|
1324
|
+
<label class="dcap-field">间隔(s)
|
|
1325
|
+
<input class="dcap-num" data-role="interval" type="number" min="0" step="0.5" value="1">
|
|
1326
|
+
</label>
|
|
1327
|
+
<label class="dcap-field">距离(m)
|
|
1328
|
+
<input class="dcap-num" data-role="distance" type="number" min="0" step="1" value="0">
|
|
1329
|
+
</label>
|
|
1330
|
+
</div>
|
|
1331
|
+
<p class="dcap-hint">与「拍照」同源,每张带取景相机位姿 / 内参 / 坐标系。</p>
|
|
1332
|
+
</section>
|
|
1333
|
+
|
|
1334
|
+
<section class="dcap-blk" data-blk="real">
|
|
1335
|
+
<div class="dcap-label">真实照片导入</div>
|
|
1336
|
+
<div class="dcap-row">
|
|
1337
|
+
<button type="button" class="dcap-btn" data-action="pick-files">选择照片</button>
|
|
1338
|
+
<button type="button" class="dcap-btn" data-action="pick-dir">选择文件夹</button>
|
|
1339
|
+
</div>
|
|
1340
|
+
<p class="dcap-hint">原图不压缩保存;缺 EXIF / GPS 标记为「警告」。</p>
|
|
1341
|
+
</section>
|
|
1342
|
+
|
|
1343
|
+
<section class="dcap-blk">
|
|
1344
|
+
<div class="dcap-label">影像集<em data-role="gallery-count">未创建会话</em></div>
|
|
1345
|
+
<div class="dcap-row">
|
|
1346
|
+
<button type="button" class="dcap-btn dcap-primary" data-action="open-gallery" disabled>打开影像集</button>
|
|
1347
|
+
</div>
|
|
1348
|
+
<p class="dcap-hint">按组合分组浏览;全景组可「一键合成」成一张等距柱状全景图。</p>
|
|
1349
|
+
<div class="dcap-row" style="margin-top:6px">
|
|
1350
|
+
<button type="button" class="dcap-btn" data-action="export" data-format="json">导出 JSON</button>
|
|
1351
|
+
<button type="button" class="dcap-btn" data-action="export" data-format="manifest">导出 Manifest</button>
|
|
1352
|
+
<button type="button" class="dcap-btn" data-action="export" data-format="csv">导出 CSV</button>
|
|
1353
|
+
<button type="button" class="dcap-btn" data-action="clear-images">清空</button>
|
|
1354
|
+
</div>
|
|
1355
|
+
</section>
|
|
1356
|
+
</div>
|
|
1357
|
+
<p class="dcap-note" data-role="note" hidden></p>
|
|
1358
|
+
<input type="file" data-role="file-input" accept="image/*" multiple style="display:none">
|
|
1359
|
+
<input type="file" data-role="dir-input" webkitdirectory directory multiple style="display:none">
|
|
1360
|
+
`}};function h_(e){return typeof e==`object`&&!!e}function g_(e){return h_(e)?e:null}function __(e,t){let n=g_(e);n&&(n.show=t)}function v_(e,t){Array.isArray(e)?e.forEach(e=>t(e)):e!==void 0&&t(e)}function y_(e){if(typeof e==`function`)return e;if(typeof e.fromUrl==`function`)return e.fromUrl.bind(e);if(typeof e.load==`function`)return e.load.bind(e);throw TypeError(`A tileset loader function, fromUrl, or load method is required`)}var b_=class{constructor(e){if(i(this,`viewer`,void 0),i(this,`loader`,void 0),i(this,`primitives`,void 0),i(this,`original`,void 0),i(this,`currentTileset`,null),i(this,`currentUrl`,null),i(this,`compareMode`,void 0),i(this,`visible`,void 0),i(this,`destroyed`,!1),i(this,`loadVersion`,0),i(this,`originalVisibility`,new Map),!e||!e.viewer)throw TypeError(`A viewer is required`);let t=e.viewer.scene?.primitives;if(!t||typeof t.add!=`function`||typeof t.remove!=`function`)throw TypeError(`viewer.scene.primitives with add/remove methods is required`);this.viewer=e.viewer,this.primitives=t,this.loader=y_(e.loader),this.original=e.original,this.compareMode=e.compareMode??`both`,this.visible=e.visible??!0,this.rememberOriginalVisibility(),this.applyVisibility()}get tileset(){return this.currentTileset}get url(){return this.currentUrl}get mode(){return this.compareMode}get isVisible(){return this.visible}get isDestroyed(){return this.destroyed}get state(){return{url:this.currentUrl,tileset:this.currentTileset,original:this.original,compareMode:this.compareMode,visible:this.visible,destroyed:this.destroyed}}async load(e){if(this.assertAlive(),typeof e!=`string`||!e.trim())throw TypeError(`A non-empty tileset URL is required`);let t=++this.loadVersion,n=await this.loader(e);if(n==null)throw Error(`Tileset loader returned no tileset`);if(this.destroyed||t!==this.loadVersion)throw n!==this.currentTileset&&this.destroyPrimitive(n),Error(this.destroyed?`ReconstructionPreview has been destroyed`:`Tileset load was superseded`);let r=this.currentTileset;if(n!==r){try{this.primitives.add(n)}catch(e){throw this.destroyPrimitive(n),e}this.currentTileset=n,this.currentUrl=e,r!==null&&this.unmount(r)}else this.currentUrl=e;return this.applyVisibility(),n}setCompareMode(e){if(this.assertAlive(),e!==`original`&&e!==`reconstructed`&&e!==`both`)throw RangeError(`Unknown reconstruction compare mode: ${String(e)}`);this.compareMode=e,this.applyVisibility()}setVisible(e){this.assertAlive(),this.visible=!!e,this.applyVisibility()}setOriginal(e){this.assertAlive(),this.restoreOriginalVisibility(),this.original=e,this.rememberOriginalVisibility(),this.applyVisibility()}destroy(){if(this.destroyed)return;this.destroyed=!0,this.loadVersion+=1;let e=this.currentTileset;this.currentTileset=null,this.currentUrl=null;try{e!==null&&this.unmount(e)}finally{this.restoreOriginalVisibility()}}assertAlive(){if(this.destroyed)throw Error(`ReconstructionPreview has been destroyed`)}rememberOriginalVisibility(){v_(this.original,e=>{let t=g_(e);t&&!this.originalVisibility.has(t)&&this.originalVisibility.set(t,{hadShow:`show`in t,show:t.show})})}restoreOriginalVisibility(){for(let[e,t]of this.originalVisibility)t.hadShow?e.show=t.show:delete e.show;this.originalVisibility.clear()}applyVisibility(){let e=this.visible&&(this.compareMode===`original`||this.compareMode===`both`),t=this.visible&&(this.compareMode===`reconstructed`||this.compareMode===`both`);v_(this.original,t=>__(t,e)),this.currentTileset!==null&&__(this.currentTileset,t)}unmount(e){__(e,!1);try{this.primitives.remove(e)}finally{this.destroyPrimitive(e)}}destroyPrimitive(e){if(!h_(e))return;let t=e.isDestroyed;if(typeof t==`function`&&t.call(e))return;let n=e.destroy;typeof n==`function`&&n.call(e)}};e.ARM_POSITIONS=vc,e.BODY_SPIN_RATE_DEG=d,e.BODY_SPIN_TOLERANCE_DEG=f,e.CAMERA_MODE_LIST=$u,e.CAPTURE_EXPORT_FORMAT=_h,e.CAPTURE_EXPORT_VERSION=vh,e.CAPTURE_MANIFEST_SCHEMA_VERSION=Xm,e.CaptureService=Eh,e.CaptureValidator=gh,e.CesiumDroneAdapter=Kf,e.CesiumDroneRig=Od,e.CesiumMissionEditor=Zd,e.DEFAULT_CONFIG=v,e.DEFAULT_MISSION=C,e.DEFAULT_MISSION_CONFIG=S,e.DEFAULT_OBSTACLES=uc,e.DEFAULT_SPEED_SCALE=u,e.DEFAULT_UNSUPPORTED_REQUIRED_EXTENSIONS=Hf,e.DRONE_MAX_SPEED_METERS_PER_SECOND=Qu,e.DRONE_MODELS=jf,e.DRONE_MODEL_URL=Xu,e.DRONE_SPEC=a,e.DroneCapturePanel=m_,e.DroneControlPanel=zp,e.DroneFly=yd,e.DroneGallery=a_,e.DroneImageViewer=Jh,e.DroneLights=al,e.DroneMiniMap=mm,e.DronePanoramaViewer=Xg,e.DroneRadar=kl,e.DroneRig=Vc,e.DroneSim=_e,e.DroneWorld=_c,e.EquirectStitcher=ag,e.FLIGHT_MODES=o,e.FLIGHT_MODE_LIST=s,e.GIMBAL_LIMITS=Dc,e.MISSION_ALTITUDE_HARD_LIMIT=w,e.MISSION_STAGE_LABELS=b,e.MISSION_STATUS_LABELS=y,e.MOTOR_POSITIONS=g,e.MissionEditor=Ll,e.MissionPanel=Zp,e.NEUTRAL_STICK=h,e.NO_FAULTS=_,e.PANORAMA_MODE_LIST=Zf,e.PANORAMA_PRESETS=Xf,e.PHASE_LABELS=p,e.POSITION_SOURCE_LABELS=m,e.PROP_SPIN_SIGN=bc,e.PanoramaCapture=lp,e.ReconstructionPreview=b_,e.SPEED_SCALE_MAX=l,e.SPEED_SCALE_MIN=c,e.STATUS_PATTERNS=Jc,e.STATUS_PATTERN_LIST=Yc,e.UNGROUPED_KEY=zh,e.VALIDATION_BADGES=Lh,e.VALIDATION_LABELS=Ih,e.WGS84=Qd,e.angularExtent=pg,e.batteryLedPlan=Xc,e.buildCaptureManifest=lh,e.buildMissionExport=E,e.cameraPoseToColmap=xf,e.cameraQuaternionFromBasis=vf,e.captureSessionToManifest=uh,e.convertCameraQuaternion=bf,e.createCaptureManifest=dh,e.createDroneControl=qf,e.createEcefEnuFrame=cf,e.createEquirectStitcher=sg,e.createOriginalImagesZip=Nh,e.createReconstructionTask=Of,e.describeBatteryLevel=Zc,e.describeImage=Hh,e.ecefQuaternionToEnu=gf,e.ecefToEnu=lf,e.ecefToGeodetic=sf,e.enuQuaternionToEcef=hf,e.enuToEcef=uf,e.escapeHtml=$,e.exportMissionText=O,e.findMissionInsertIndex=k,e.formatBytes=jh,e.geodeticToEcef=of,e.groupSessionImages=Bh,e.imageTileLabel=Vh,e.intrinsicsFromExif=Sh,e.isMissionDepartStage=x,e.loadCesiumScript=Gf,e.loadCesiumTileset=Tf,e.loadTilesetForCesium=Ef,e.missionToCsv=D,e.normalizeMissionWaypoint=T,e.panoramaModeLabel=Rh,e.parseCaptureManifest=ph,e.parseJpegExif=Jm,e.readJpegExif=Ym,e.serializeCaptureManifest=fh,e.sphericalPitchGrid=sp,e.statusPatternFor=Qc,e.stripRequiredExtensions=Uf,e.summarizeSession=xh,e.triggerDownload=Mh,e.validateCaptureManifest=mh,e.validateCaptureSession=hh,e.validateCapturedImage=bh,e.validateReconstructionReport=kf,e.validateTileset=wf});
|
|
1361
|
+
//# sourceMappingURL=index.umd.cjs.map
|