@nnepoch/dtc-sdk 3.0.13 → 3.0.15

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/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import{EventEmitter as e,LogLevel as t,Logger as n}from"@epicgames-ps/lib-pixelstreamingcommon-ue5.6";import{z as r}from"zod";import i from"axios";import{Config as a,Flags as o,NumericParameters as s,OptionParameters as c,PixelStreaming as l}from"@epicgames-ps/lib-pixelstreamingfrontend-ue5.6";import{inflate as u}from"pako";var d=class extends Error{constructor(e,t,n){super(`Invalid payload for ${e}.${t}: ${n.map(e=>`${e.field}: ${e.reason}`).join(`; `)}`),this.moduleName=e,this.methodName=t,this.issues=n,this.name=`SDKValidationError`,this.code=`VALIDATION_ERROR`}toJSON(){return{name:this.name,code:this.code,message:this.message,module:this.moduleName,method:this.methodName,issues:this.issues}}};function f(e,t,n,r){let i=e.safeParse(t);if(i.success)return i.data;throw new d(n,r,i.error.issues.map(e=>({field:e.path.length>0?e.path.join(`.`):`<root>`,reason:e.message,code:e.code})))}function p(e){return e instanceof d?JSON.stringify(e.toJSON()):e instanceof Error?`${e.name}: ${e.message}`:String(e)}const m={InitLogging(){},Debug(e){console.log(`[Debug] - ${e}`)},Info(e){console.log(`[Info] - ${e}`)},Warning(e){console.warn(`[Warning] - ${e}`)},Error(e){console.error(`[Error] - ${e}`)}},h={debug(){},info(){},warn(){},error(){}},g=[`silent`,`error`,`warn`,`info`,`debug`],_={silent:0,error:1,warn:2,info:3,debug:4};function ee(e){switch(e){case`silent`:return t.Disabled;case`error`:return t.Error;case`warn`:return t.Warning;case`info`:return t.Info;default:return t.Debug}}function te(e){n.InitLogging(ee(e),!1)}function v(e){return typeof e==`string`&&g.includes(e)}function y(e){if(e===void 0)return`info`;if(v(e))return e;let t=typeof e==`string`?e:JSON.stringify(e);throw Error(`Invalid logger level: ${t}. Expected one of: ${g.join(`, `)}.`)}function ne(e){if(e===void 0)return``;try{let t=JSON.stringify(e);return t?` ${t}`:``}catch{return` ${String(e)}`}}function re(){let e=Error().stack;return e?e.replace(/^Error(?::\s*)?\n?/,``):`No Stack Available for this browser`}var ie=class{constructor(e,t,n,r,i,a){this.driver=e,this.prefix=t,this.level=n,this.moduleName=r,this.includeStack=i,this.reporter=a}formatMessage(e,t,n){let r=`${this.prefix} ${t}${ne(n)}`.trim();return this.shouldIncludeStack(e)?`${r}\nStack: ${re()}`:r}shouldLog(e){return _[this.level]>=_[e]}shouldIncludeStack(e){return _[this.includeStack]>=_[e]}debug(e,t){this.shouldLog(`debug`)&&this.driver.Debug(this.formatMessage(`debug`,e,t))}info(e,t){this.shouldLog(`info`)&&this.driver.Info(this.formatMessage(`info`,e,t))}warn(e,t){this.reportWarnOrError(`warn`,e,t),this.shouldLog(`warn`)&&this.driver.Warning(this.formatMessage(`warn`,e,t))}error(e,t){this.reportWarnOrError(`error`,e,t),this.shouldLog(`error`)&&this.driver.Error(this.formatMessage(`error`,e,t))}reportWarnOrError(e,t,n){this.reporter?.recordLogSignal({level:e,moduleName:this.moduleName,message:t,meta:n})}},ae=class{constructor(e,t=m,n){this.level=y(e),this.driver=t,this.includeStack=n?.includeStack??`warn`,this.driver.InitLogging(ee(this.level),!1),this.reporter=n?.reporter??n?.qosMonitor}setReporter(e){this.reporter=e}child(e){return new ie(this.driver,`[DTCEngine:${e}]`,this.level,e,this.includeStack,this.reporter)}};const b={EngineIniting:`云渲染引擎初始化中...`,ServiceUrlInValid:`调度中心地址不正确,请检查中心地址!`,SerriceError:`调度中心连接失败,尝试重连中...`,SerriceUnAvaible:`没有服务资源,请检查服务是否启动!`,SerriceLoadingForWaiting:`服务资源启动中,请稍候!`,EngineWaiting:`云渲染服务坐席已满,当前排队人数:1人....`,EngineTockenChecking:`云引擎授权文件验证中...`,EngineTokenCheckFail:`云引擎授权许可无效,请联系管理员!`,EngineConnectioning:`云渲染引擎连接中...`,EngineConnectionSuccess:`云渲染引擎连接成功...`,EngineClose:`云渲染引擎连接断开,请检查服务状态!`,SourcePreparing:`资源准备中...`,TokenInValid:`许可未激活!`,TokenExpired:`许可授权已过期,实时渲染服务已停止!`,TokenWillExpired:`您的授权许可将于 YYYY-MM-DD 到期,请尽快续期!`};var oe=class{constructor(e){this.options=e,this.logger=e.logger??h}show(e,t,n=!0){if(console.log(`loading show`,e,t,n),this.options.emit({message:e,key:t,isFinish:!n}),!this.options.enabled)return;let r=this.getRoot();r&&(this.progressDiv||=this.createTipDiv(r,`engineProgressTips`),this.progressDiv.textContent=e,n||(this.clearAutoCloseTimer(),this.autoCloseTimer=setTimeout(()=>{this.removeProgressBar()},2e3)))}showTokenWillExpire(e,t=`TokenWillExpired`,n=!0){let r=this.formatTokenWillExpireMessage(e);if(this.options.emit({message:r,key:t,isFinish:!n}),!this.options.enabled)return;let i=this.getRoot();i&&(this.tokenWillExpireDiv||(this.tokenWillExpireDiv=this.createTipDiv(i,`TokenWillExpireTips`),this.tokenWillExpireDiv.style.top=`60px`),this.tokenWillExpireDiv.textContent=r)}dispose(){this.clearAutoCloseTimer(),this.removeProgressBar(),this.removeTokenWillExpireBar()}getRoot(){if(this.options.hostElement?.ownerDocument?.body)return this.options.hostElement.ownerDocument.body;if(typeof document<`u`&&document.body)return document.body;this.logger.debug(`skip loading progress ui render: document is unavailable`)}createTipDiv(e,t){let n=e.ownerDocument.createElement(`div`);return n.id=t,n.style.position=`fixed`,n.style.left=`50%`,n.style.top=`16px`,n.style.transform=`translateX(-50%)`,n.style.zIndex=`99999`,n.style.padding=`8px 14px`,n.style.borderRadius=`6px`,n.style.background=`rgba(0, 0, 0, 0.72)`,n.style.color=`#fff`,n.style.fontSize=`14px`,n.style.lineHeight=`1.4`,n.style.pointerEvents=`none`,n.style.maxWidth=`80vw`,n.style.textAlign=`center`,e.appendChild(n),n}removeProgressBar(){this.progressDiv&&=(this.progressDiv.remove(),void 0)}removeTokenWillExpireBar(){this.tokenWillExpireDiv&&=(this.tokenWillExpireDiv.remove(),void 0)}clearAutoCloseTimer(){this.autoCloseTimer&&=(clearTimeout(this.autoCloseTimer),void 0)}formatTokenWillExpireMessage(e){let t=e.trim();return t?t.includes(`到期`)?t:`您的授权许可将于 ${t}到期,请尽快续期!`:b.TokenWillExpired}};const se=`sdk3-agent-bridge/v1`;function ce(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in current runtime.`);return new WebSocket(e)}function le(e){return{ok:!0,data:e,ts:Date.now()}}function ue(e,t){return{ok:!1,error:{code:`PROTOCOL_ERROR`,message:e,details:t},ts:Date.now()}}function de(e){if(typeof e==`string`)try{let t=JSON.parse(e);if(typeof t!=`object`||!t)return;let n=t;return n.protocolVersion!==`sdk3-agent-bridge/v1`||typeof n.type!=`string`||typeof n.callId!=`string`?void 0:n}catch{return}}var fe=class{constructor(e,t,n={}){this.runtime=e,this.options=t,this.reconnectAttempt=0,this.running=!1,this.startedAt=0,this.beforeUnloadHandler=()=>{this.stop(`pagehide`)},this.socketFactory=n.socketFactory??ce}start(){this.socket||(this.running=!0,this.openSocket(),typeof window<`u`&&(window.addEventListener(`beforeunload`,this.beforeUnloadHandler),window.addEventListener(`pagehide`,this.beforeUnloadHandler)))}stop(e=`stop`){this.running=!1,this.clearReconnect(),typeof window<`u`&&(window.removeEventListener(`beforeunload`,this.beforeUnloadHandler),window.removeEventListener(`pagehide`,this.beforeUnloadHandler)),this.clearHeartbeat(),this.runtime.dispose?.();let t=this.socket;t&&(t.readyState===1&&this.sendUnregister(e),this.clearSocketHandlers(t),t.close(1e3,e),this.socket=void 0)}openSocket(){this.startedAt=Date.now();let e=this.socketFactory(this.options.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`);this.socket=e,e.onopen=()=>{this.reconnectAttempt=0,this.sendRegister(),this.startHeartbeat()},e.onmessage=e=>{this.handleMessage(e.data)},e.onclose=()=>{this.clearSocketHandlers(e),this.clearHeartbeat(),this.runtime.closeAllStreams?.(`Agent bridge WebSocket disconnected`),this.runtime.cancelAllPrograms?.(`Agent bridge WebSocket disconnected`),this.socket===e&&(this.socket=void 0),this.scheduleReconnect()},e.onerror=()=>{this.clearHeartbeat()}}scheduleReconnect(){if(!this.running||this.reconnectTimer!==void 0||this.options.reconnect===!1)return;let e=this.getReconnectDelay();this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,!(!this.running||this.socket)&&this.openSocket()},e),this.reconnectAttempt+=1}getReconnectDelay(){let e=typeof this.options.reconnect==`object`?this.options.reconnect:void 0,t=Math.max(0,e?.initialDelayMs??1e3),n=Math.max(t,e?.maxDelayMs??15e3),r=Math.max(0,e?.jitterMs??500);return Math.min(n,t*2**this.reconnectAttempt)+Math.floor(Math.random()*(r+1))}clearReconnect(){this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0)}sendRegister(){let e={...this.runtime.getSnapshot(),heartbeatIntervalMs:this.getHeartbeatInterval(),capabilities:{catalog:!0,schema:!0,validateActions:!0,invoke:!0,stream:!0,businessPrograms:!0,businessProgramProtocolVersion:1}};this.send({type:`register`,protocolVersion:se,bridgeId:e.bridgeId,ts:Date.now(),payload:e})}sendUnregister(e){let t={...this.runtime.getSnapshot(),reason:e};this.send({type:`unregister`,protocolVersion:se,bridgeId:t.bridgeId,ts:Date.now(),payload:t})}sendHeartbeat(){let e={...this.runtime.getSnapshot(),heartbeatIntervalMs:this.getHeartbeatInterval(),uptimeMs:Math.max(0,Date.now()-this.startedAt)};this.send({type:`heartbeat`,protocolVersion:se,bridgeId:e.bridgeId,ts:Date.now(),payload:e})}getHeartbeatInterval(){return Math.max(1e3,this.options.heartbeatIntervalMs??5e3)}startHeartbeat(){this.clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.sendHeartbeat()},this.getHeartbeatInterval())}clearHeartbeat(){this.heartbeatTimer!==void 0&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async handleMessage(e){let t=de(e);if(t){if(t.type===`catalog`){let e=t.payload,n=e.kind===`modules`?le(this.runtime.listModules()):this.runtime.listMethods(e.moduleName??``);this.sendResult(t,`catalog`,n);return}if(t.type===`schema`){let e=t.payload;this.sendResult(t,`schema`,this.runtime.getMethodSchema(e.moduleName,e.methodName));return}if(t.type===`validate-actions`){this.sendResult(t,`validate-actions`,this.runtime.validateActions(t.payload));return}if(t.type===`invoke`){this.sendResult(t,`invoke`,await this.runtime.invoke(t.payload));return}if(t.type===`stream-start`){let e=t.payload,n=await this.runtime.startStream(e,e=>{this.sendStreamEvent(e)});this.sendResult(t,`stream-start`,n);return}if(t.type===`stream-close`){this.sendResult(t,`stream-close`,await this.runtime.closeStream(t.payload));return}if(t.type===`load-program`){this.sendResult(t,`load-program`,await this.runtime.loadProgram(t.payload));return}if(t.type===`start-program`){this.sendResult(t,`start-program`,await this.runtime.startProgram(t.payload,e=>{this.sendProgramEvent(e)}));return}if(t.type===`cancel-program`){this.sendResult(t,`cancel-program`,await this.runtime.cancelProgram(t.payload));return}this.sendResult(t,`catalog`,ue(`Unsupported message type "${t.type}".`))}}sendStreamEvent(e){this.send({type:`stream-event`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,ts:Date.now(),payload:e})}sendProgramEvent(e){this.send({type:`program-event`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,traceId:e.traceId,ts:Date.now(),payload:e})}sendResult(e,t,n){let r={requestType:t,result:n,traceId:e.traceId};this.send({type:`result`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,callId:e.callId,traceId:e.traceId,ts:Date.now(),payload:r})}send(e){!this.socket||this.socket.readyState!==1||this.socket.send(JSON.stringify(e))}clearSocketHandlers(e){e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null}};function pe(e,t){return t&&e.then(e=>{t(e)}).catch(e=>{t(e)}),e}var x=class{constructor(e,t,n){this.bridge=e,this.moduleName=t,this.logger=n?.logger??h}request(e,t,n,r){return pe(Promise.resolve().then(()=>{let n=r?f(r,t,this.moduleName,e):t;return r||this.logger.debug(`validation schema not configured`,{method:e}),this.logger.debug(`sending request`,{method:e}),this.bridge.sendRequest(this.moduleName,e,n)}).then(t=>(this.logger.info(`request success`,{method:e,code:t.code}),t)).catch(t=>{throw this.logger.warn(`request failed`,{method:e,error:p(t)}),t}),n)}requestStream(e,t,n,r){try{if(!this.bridge.sendStreamRequest)throw Error(`Current bridge does not support stream request`);let i=r?f(r,t,this.moduleName,e):t;return r||this.logger.debug(`validation schema not configured`,{method:e}),this.logger.debug(`sending stream request`,{method:e}),this.bridge.sendStreamRequest(this.moduleName,e,i,n)}catch(t){let r=t instanceof Error?t:Error(String(t));if(this.logger.warn(`stream request failed before send`,{method:e,error:p(r)}),n)try{n({type:`error`,requestId:``,error:r})}catch(t){this.logger.warn(`stream error callback failed`,{method:e,error:p(t)})}let i=Promise.reject(r);return Object.defineProperty(i,"requestId",{value:``,enumerable:!0}),i.cancel=()=>{},i}}};const me=r.string().trim().min(1),he=r.lazy(()=>r.union([r.null(),r.string(),r.number().finite(),r.boolean(),r.array(he),r.record(he)])),ge=r.object({x:r.number().finite(),y:r.number().finite(),z:r.number().finite()}),_e=ge.extend({x:r.number().finite().min(-180).max(180),y:r.number().finite().min(-90).max(90)}),ve=r.object({x:r.number().finite().min(0).max(1),y:r.number().finite().min(0).max(1)}).strict(),ye=r.object({type:r.literal(`MODEL`).optional(),name:r.string().optional(),path:me,poiAsset:r.string().optional()}).strict(),be={code:r.string().optional(),name:r.string().optional(),position:_e.optional().describe(`已知经纬高;与 screenPosition 二选一;addPoint 不传时等待点击`),screenPosition:ve.optional().describe(`drop 当时的视频图像归一化坐标 [0,1];用 getScreenPosition 获取`),rotation:ge.optional().describe(`旋转角度,与既有 payload 一致:x=Roll、y=Pitch、z=Yaw`),scale:ge.optional(),show:r.boolean().optional().describe(`模型显隐,创建默认 true,更新不传则保留`),poiEnabled:r.boolean().optional().describe(`模型附属 POI 显隐,不是独立 POI 点位`),poiOffsetY:r.number().finite().optional().describe(`附属 POI 向上偏移(米),允许 0`),poiScaleFactor:r.number().finite().nonnegative().optional().describe(`附属 POI 等比缩放,创建默认 1,允许 0`),poiShowName:r.boolean().optional().describe(`附属 POI 是否显示模型名称`),extraProps:r.record(he).optional().describe(`JSON 对象;更新时整体替换该字段`),lookAt:r.string().optional(),resource:ye.describe(`UE Actor 蓝图资源:path 必填,poiAsset 可选,不能使用 Unity 资源路径`),category:r.object({code:r.string().optional(),name:r.string().optional(),type:r.string().optional()}).strict().optional()},xe={parentId:me.describe(`场景分组 ID,沿用既有加载结果,不要求新增 SDK 来源标签`),id:me.describe(`点位 globalId,不是数据库主键`),type:r.literal(`MODEL`).describe(`固定为 MODEL,本期不支持独立 POI`)},Se=r.object({...xe,...be}).strict(),Ce={addPoint:Se.refine(e=>!(e.position&&e.screenPosition),`position 与 screenPosition 不能同时传入`),addPointByDrag:Se.refine(e=>!!e.position!=!!e.screenPosition,`请传入 position 或 drop 时记录的 screenPosition(二选一)`),getScreenPosition:r.object({clientX:r.number().finite(),clientY:r.number().finite()}).strict(),cancelPlacement:r.undefined().optional(),updatePoint:Se.omit({screenPosition:!0}).partial().extend({...xe,resource:ye.partial().optional()}),deletePoints:r.object({parentId:me,ids:r.array(me).min(1).refine(e=>new Set(e).size===e.length,`ids 不能重复`)}).strict()},we=Se.omit({screenPosition:!0}).extend({position:_e,rotation:ge,scale:ge,show:r.boolean(),poiEnabled:r.boolean(),poiOffsetY:r.number().finite(),poiScaleFactor:r.number().finite().nonnegative(),poiShowName:r.boolean(),extraProps:r.record(he)}).strip(),Te=r.object({deletedIds:r.array(me),failedIds:r.array(me)}),Ee={startSimpleGizmoMode:r.object({parentId:r.string().trim().min(1),id:r.string().trim().min(1)}).strict(),endSimpleGizmoMode:r.undefined().optional()};var De=class extends x{constructor(e,t){super(e,`GizmosService`,t),this.options=t,this.sequence=Promise.resolve(),this.sessionVersion=0,this.finishFromEngine=()=>{this.restoreInput?.(),this.restoreInput=void 0},this.resetRuntime=()=>{++this.sessionVersion,this.sequence=Promise.resolve(),this.finishFromEngine()},this.enqueue=(e,t)=>{let n=this.sessionVersion,r=this.sequence.catch(()=>void 0).then(async()=>{if(n!==this.sessionVersion)throw Error(`编辑会话已结束`);let r=await e();if(n!==this.sessionVersion)throw Error(`编辑会话已结束`);return t?this.restoreInput??=this.options?.beginMouseInput?.():this.finishFromEngine(),r});return this.sequence=r,r}}startSimpleGizmoMode(e,t){return pe(this.enqueue(async()=>{let t=await this.request(`EnterSimpleGizmoMode`,e,void 0,Ee.startSimpleGizmoMode);if(t.success===!1||t.errorMsg)throw Error(t.errorMsg||`开启模型编辑失败`);return t},!0),t)}endSimpleGizmoMode(e){return pe(this.enqueue(async()=>{let e=await this.request(`ExitSimpleGizmoMode`,void 0,void 0,Ee.endSimpleGizmoMode);if(e.success===!1||e.errorMsg)throw Error(e.errorMsg||`退出模型编辑失败`);return e},!1),e)}},Oe=class e{constructor(e=0,t=0){this.x=e,this.y=t}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}clone(){return new e(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this):this.addVectors(e,t)}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,t){return t==null?(this.x-=e.x,this.y-=e.y,this):this.subVectors(e,t)}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)}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=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this}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=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(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)}angle(){let e=Math.atan2(this.y,this.x);return e<0&&(e+=2*Math.PI),e}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}equals(e){return e.x==this.x&&e.y==this.y}toString(){return JSON.stringify(this)}};function ke(e,t){let n=e*20037508.34/180,r=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return r=r*20037508.34/180,{x:n,y:r}}function Ae(e,t){let n=e/20037508.34*180,r=t/20037508.34*180;return r=180/Math.PI*(2*Math.atan(Math.exp(r*Math.PI/180))-Math.PI/2),{x:n,y:r}}const S={EPSGType:{EPSG84:`4326`,EPSGWeb:`3857`,EPSGWorld:`0000`}};var C=class e{constructor(e=0,t=0,n=0,r=S.EPSGType.EPSG84){typeof e!=`number`&&(e=this.parseFloatDeal(e)),typeof t!=`number`&&(t=this.parseFloatDeal(t)),typeof n!=`number`&&(n=this.parseFloatDeal(n)),e!=e&&(e=0),t!=t&&(t=0),n!=n&&(n=0),this.x=e,this.y=t,this.z=n,this.ePSGType=r}parseFloatDeal(e){try{return parseFloat(e)}catch(e){return console.log(e),0}}set(e,t,n){return typeof e!=`number`&&(e=0),typeof t!=`number`&&(t=0),typeof n!=`number`&&(n=0),e!=e&&(e=0),t!=t&&(t=0),n!=n&&(n=0),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}clone(){return new e(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this.z+=e.z,this):this.addVectors(e,t)}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,t){return t==null?(this.x-=e.x,this.y-=e.y,this.z-=e.z,this):this.subVectors(e,t)}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,t){return t==null?(this.x*=e.x,this.y*=e.y,this.z*=e.z,this):this.multiplyVectors(e,t)}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}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=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this}clampScalar(t,n){let r=new e,i=new e;return r.set(t,t,t),i.set(n,n,n),this.clamp(r,i)}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(Math.max(e,Math.min(t,n)))}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=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(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.subVectors(t,e).multiplyScalar(n).add(e)}cross(e,t){return t==null?this.crossVectors(this,e):this.crossVectors(e,t)}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}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}equals(e){return e.x==this.x&&e.y==this.y&&e.z==this.z}toString(){return JSON.stringify(this)}changeEPSGType(e){if(this.ePSGType!=e){if(e==S.EPSGType.EPSG84){let e=Ae(this.x,this.y);this.x=e.x,this.y=e.y}else if(e==S.EPSGType.EPSGWeb){let e=ke(this.x,this.y);this.x=e.x,this.y=e.y}else console.log(`暂不支持[${this.ePSGType}]转换为${e}`);return this.ePSGType=e,this}}};const w={Off:0,Auto:1,DLAA:2,UltraQuality:3,Quality:4,Balanced:5,Performance:6,UltraPerformance:7},T={Auto:`auto`,Low:`low`,High:`high`,Super:`super`,Blue:`blue`},je=[{label:`自动`,type:T.Auto,value:12e6},{label:`标清`,type:T.Low,value:4e6},{label:`高清`,type:T.High,value:8e6},{label:`超清`,type:T.Super,value:12e6},{label:`蓝光`,type:T.Blue,value:24e6}],Me={[T.Auto]:12e6,[T.Low]:4e6,[T.High]:8e6,[T.Super]:12e6,[T.Blue]:24e6};let Ne=function(e){return e.VP8=`VP8`,e.VP9=`VP9`,e.AV1=`AV1`,e.H264=`H264`,e}({}),Pe=function(e){return e.Model=`MODEL`,e.POI=`POI`,e}({});const Fe={Spring:0,Summer:1,Autumn:2,Winter:3};let Ie=function(e){return e[e.Linear=0]=`Linear`,e[e.EaseInQuad=1]=`EaseInQuad`,e[e.EaseOutQuad=2]=`EaseOutQuad`,e[e.EaseInOutQuad=3]=`EaseInOutQuad`,e[e.EaseOutInQuad=4]=`EaseOutInQuad`,e[e.EaseInCubic=5]=`EaseInCubic`,e[e.EaseOutCubic=6]=`EaseOutCubic`,e[e.EaseInOutCubic=7]=`EaseInOutCubic`,e[e.EaseOutInCubic=8]=`EaseOutInCubic`,e[e.EaseInQuart=9]=`EaseInQuart`,e[e.EaseOutQuart=10]=`EaseOutQuart`,e[e.EaseInOutQuart=11]=`EaseInOutQuart`,e[e.EaseOutInQuart=12]=`EaseOutInQuart`,e[e.EaseInQuint=13]=`EaseInQuint`,e[e.EaseOutQuint=14]=`EaseOutQuint`,e[e.EaseInOutQuint=15]=`EaseInOutQuint`,e[e.EaseOutInQuint=16]=`EaseOutInQuint`,e[e.EaseInSine=17]=`EaseInSine`,e[e.EaseOutSine=18]=`EaseOutSine`,e[e.EaseInOutSine=19]=`EaseInOutSine`,e[e.EaseOutInSine=20]=`EaseOutInSine`,e[e.EaseInExpo=21]=`EaseInExpo`,e[e.EaseOutExpo=22]=`EaseOutExpo`,e[e.EaseInOutExpo=23]=`EaseInOutExpo`,e[e.EaseOutInExpo=24]=`EaseOutInExpo`,e[e.EaseInCirc=25]=`EaseInCirc`,e[e.EaseOutCirc=26]=`EaseOutCirc`,e[e.EaseInOutCirc=27]=`EaseInOutCirc`,e[e.EaseOutInCirc=28]=`EaseOutInCirc`,e[e.EaseInElastic=29]=`EaseInElastic`,e[e.EaseOutElastic=30]=`EaseOutElastic`,e[e.EaseInOutElastic=31]=`EaseInOutElastic`,e[e.EaseOutInElastic=32]=`EaseOutInElastic`,e[e.EaseInBack=33]=`EaseInBack`,e[e.EaseOutBack=34]=`EaseOutBack`,e[e.EaseInOutBack=35]=`EaseInOutBack`,e[e.EaseOutInBack=36]=`EaseOutInBack`,e[e.EaseInBounce=37]=`EaseInBounce`,e[e.EaseOutBounce=38]=`EaseOutBounce`,e[e.EaseInOutBounce=39]=`EaseInOutBounce`,e[e.EaseOutInBounce=40]=`EaseOutInBounce`,e}({}),Le=function(e){return e[e.Loose=0]=`Loose`,e[e.Strict=1]=`Strict`,e}({}),Re=function(e){return e.StopAtTheEnd=`StopAtTheEnd`,e.Loop=`Loop`,e.BackAndForward=`BackAndForward`,e}({}),ze=function(e){return e[e.Move=1]=`Move`,e[e.Rotate=2]=`Rotate`,e[e.Scale=3]=`Scale`,e[e.Universal=4]=`Universal`,e}({});const E=r.string().min(1),D=E.optional(),O=r.number().finite(),k=O.optional(),A=r.instanceof(C),Be=r.object({x:O,y:O,z:O,ePSGType:E}),Ve=r.union([r.instanceof(Oe),r.object({x:O,y:O})]),j=r.union([A,Be]),He=A.optional(),Ue=j.optional(),We=r.union([r.literal(Fe.Spring).describe(`春季`),r.literal(Fe.Summer).describe(`夏季`),r.literal(Fe.Autumn).describe(`秋季`),r.literal(Fe.Winter).describe(`冬季`)]).describe(`场景季节`),Ge=r.union([r.literal(w.Off).describe(`关闭 DLSS`),r.literal(w.Auto).describe(`自动质量档位`),r.literal(w.DLAA).describe(`DLAA 2倍效果`),r.literal(w.UltraQuality).describe(`超高质量`),r.literal(w.Quality).describe(`高质量`),r.literal(w.Balanced).describe(`平衡`),r.literal(w.Performance).describe(`性能`),r.literal(w.UltraPerformance).describe(`超高性能`)]).describe(`DLSS 质量档位`),Ke=r.union([r.literal(T.Auto).describe(`自动`),r.literal(T.Low).describe(`标清`),r.literal(T.High).describe(`高清`),r.literal(T.Super).describe(`超清`),r.literal(T.Blue).describe(`蓝光`)]).describe(`渲染码率档位`),qe=r.union([r.literal(`VP8`).describe(`VP8`),r.literal(`VP9`).describe(`VP9`),r.literal(`AV1`).describe(`AV1`),r.literal(`H264`).describe(`H264`)]).describe(`视频解码器类别`),Je=r.union([r.literal(`MODEL`).describe(`模型图层`),r.literal(`POI`).describe(`POI 图层`)]).describe(`图层类别`),Ye=r.union([E,r.array(E).min(1)]),M=r.undefined().optional(),Xe=r.object({ids:r.array(E).min(1)}),Ze=r.object({codes:r.array(E).min(1)}),N={show:Xe,hide:Xe,showByCode:Ze,hideByCode:Ze,showByGroup:Xe,hideByGroup:Xe,showAll:M,hideAll:M},Qe=r.object({parentId:r.string().optional(),id:D}),$e=e=>e.refine(e=>!!(e.id||e.timelineId),{message:`id or timelineId is required`}),et={connect:M,disconnect:M,reconnect:M,KickOtherConnect:M,KeepConnect:M,GetEngineServiceStatus:M},P={lookAt:r.object({parentId:r.string().optional(),id:Ye,offSet:Ue,positionOffSetDistance:k,offSetX:k,distance:k,time:k,isRotate:r.boolean().optional(),isHighlight:r.boolean().optional(),showBack:r.boolean().optional()}),lookAtArray:r.object({parentId:D,ids:r.array(E).min(1),offSet:Ue,offSetX:k,distance:k,time:k,isRotate:r.boolean().optional(),isHighlight:r.boolean().optional()}),flyToTarget:r.object({point:Ue,target:Ue,fov:r.number().finite().min(10).max(150).optional(),time:k}),flyByPath:r.object({points:r.union([r.array(A),r.string()]).optional(),lookAts:r.union([r.array(A),r.string()]).optional(),nodes:r.string().optional(),time:k,smoothMode:r.union([r.literal(0),r.literal(1)]).optional()}),setFlySpeed:r.object({speed:O}),endFly:M,pauseFly:M,resumeFly:M,getCameraInfo:M,setCameraPositionAndRotation:r.object({point:A,rotation:A}),setCameraFov:r.object({fov:O}),startCameraObjFollow:r.object({parentId:r.string().optional(),id:E,offSet:j,smooth:O.optional().default(.85).refine(e=>e>=0&&e<=1,{message:`smooth must be in [0, 1]`,path:[`smooth`]})}),endCameraObjFollow:M,resetCameraFov:M,reset:M},tt={getAllSceneName:M,switchSceneByName:r.object({sceneName:E}),getCurrentSceneName:M,listenMapCompass:r.object({enable:r.boolean()}),setFeatureToggle:r.object({key:E,enabled:r.boolean()}),getSceneMeta:M},nt={setVisible:r.object({parentId:r.string().optional().default(``),id:Ye,visible:r.boolean().optional()}),setVisibleResolved:r.object({parentId:r.string().optional(),ids:r.array(E).min(1),visible:r.boolean()}),setVisibleByTags:r.object({tags:Ye,visible:r.boolean()}),setVisibleByAttribute:r.object({attributes:r.record(r.string(),r.any()),filterMode:r.nativeEnum(Le).optional().default(0),visible:r.boolean().optional().default(!0),otherVisible:r.boolean().optional().default(!1)}),add:r.object({parentId:r.string().optional().default(``),id:E,assetsPath:D,position:He,angle:He,scale:He,description:r.string().optional()}),remove:r.object({parentId:r.string().optional().default(``),ids:r.array(E).min(1)}),getElementTree:r.object({parentId:r.string().optional().default(``),id:E}),getModelInfo:r.object({parentId:r.string().optional().default(``),id:E}),getModelBoundsInfo:r.object({parentId:r.string().optional().default(``),id:Ye}),getModelBoundsInfoResolved:r.object({parentId:r.string().optional(),ids:r.array(E).min(1)})},F=r.object({parentId:r.string().optional(),id:E}),rt=r.object({parentId:r.string().optional(),ids:r.array(E).min(1)}),it=F.extend({rotate:A}),I={startMoveByNodes:F.extend({nodes:r.array(j).min(1),speed:O.optional().default(1),linear:O.optional().default(1),isLookAtTarget:r.boolean().optional().default(!1),needDirection:r.boolean().optional().default(!0)}),pauseMove:F,resumeMove:F,endMove:F,restoreMove:rt,rotate:it,endRotate:F,continuedRotate:it,rotateByTarget:F.extend({parentTargetId:D,targetID:E,point:A,axisX:O.optional().default(0),axisY:O.optional().default(0),axisZ:O.optional().default(0),angle:O.optional().default(0),isPersistence:r.boolean().optional().default(!1)}),restoreRotate:rt,setScale:F.extend({scale:A,duration:O.optional().default(.5)}),endScale:F,restoreScale:rt},at={enable:r.object({enable:r.boolean()}),setHighLightModel:r.object({parentId:r.string().optional().default(``),ids:r.array(E).min(1),showBack:r.boolean()}),removeHighLightModel:r.object({parentId:r.string().optional(),ids:r.array(E).min(1)}),clear:r.object({})},ot=r.object({parentId:D,id:D}),st=e=>e.refine(e=>!!(e.id||e.parentId),{message:`id or parentId is required`}),L={addLayer:st(ot.extend({layerName:r.string().optional(),show:r.boolean().optional(),poiEnabled:r.boolean().optional(),type:Je.optional(),description:r.string().optional()})),addLayerResolved:r.object({parentId:r.string().optional(),id:E,layerName:r.string().optional(),show:r.boolean().optional().default(!0),poiEnabled:r.boolean().optional().default(!0),description:r.string().optional().default(``),isSystem:r.boolean().optional().default(!1),poiOffsetY:r.number().optional().default(0)}),layerSelector:st(ot),removeLayer:st(ot),isLayerOrGroupExit:st(ot),layerSelectorResolved:r.object({parentId:r.string().optional().default(``),id:E}),switchModelLayer:r.object({parentId:E,ids:r.array(E).min(1),toParentId:E}),showUIPop:r.object({parentId:r.string().optional(),id:E,visible:r.boolean().optional().default(!0),assetsPath:r.string().optional().default(``),offSet:j,scale:j}),addModel:r.object({parentId:E,id:E,assetsPath:D,position:j,name:r.string().optional().default(``),rotation:j,scale:j,description:r.string().optional(),isSystem:r.boolean().optional(),tags:r.array(r.string()).optional(),extraProps:r.any().optional()}),addPOI:r.object({parentId:r.string().optional(),id:E,assetsPath:E,position:Ue,targetParentId:r.string().optional(),targetId:r.string().optional(),rotation:j,scale:j,offSet:j,description:r.string().optional(),isSystem:r.boolean().optional(),name:r.string(),fontSize:r.number().optional(),tags:r.array(r.string()).optional(),extraProps:r.any().optional()}),removeModel:r.object({parentId:E,ids:r.array(E).min(1)}),getLayerChildElement:r.object({parentId:r.string().optional().default(``),id:E}),updatePOIName:r.object({parentId:r.string().optional(),id:E,name:r.string(),updateType:r.enum([`update`,`append`,`remove`]).optional().describe(`文本更新方式:update 更新、append 追加、remove 移除,默认 update`)}),resetPOIName:r.object({parentId:r.string().optional(),ids:r.array(E).min(1).describe(`POI 对象编号集合,至少一个`)})},R={closeCameraFog:M,getWeatherTypes:M,resetWeather:M,resetWeatherAndTime:M,openCameraFog:r.object({fogIntensity:k,fogStartColor:r.string().optional(),fogEndColor:r.string().optional(),fogStartDistance:k,fogEndDistance:k,directionalIntensity:k,directionalFallOff:k,directionalColor:r.string().optional()}).refine(e=>e.fogIntensity===void 0||e.fogIntensity>=0&&e.fogIntensity<=1,{message:`fogIntensity must be between 0 and 1`,path:[`fogIntensity`]}),setSceneTime:r.object({hour:O,timeDuration:k}).refine(e=>e.hour>=0&&e.hour<24,{message:`hour must be in [0, 24)`,path:[`hour`]}),changeWeatherType:r.object({weatherType:E,timeDuration:k}),setAnimateTimeOfDay:r.object({isAnimate:r.boolean(),dayLength:k,nightLength:k}),changeSeason:r.object({season:We,duration:k.describe(`切换过渡时长,单位秒`)}),resetSeason:r.object({}),setTimeSync:r.object({syncSystemTime:r.boolean()}),resetSceneTime:r.object({}),setDayAndNight:r.object({dayType:E}),setWeatherVolume:r.object({volumeOn:r.boolean().optional().default(!0).describe(`天气声音是否开启,true 开启,false 关闭,默认 true`)})},z={add:r.object({groupName:E,poiInfos:r.array(r.record(r.unknown())).min(1)}),deleteById:r.object({groupName:E,id:E}),deleteByGroup:r.object({groupName:E}),update:r.object({groupName:E,poiInfos:r.array(r.record(r.unknown())).min(1)}),updatePopStates:r.object({groupName:E,popStates:r.array(r.record(r.unknown())).min(1)}),enableOverlap:r.object({enable:r.boolean()}),showDistance:r.object({distance:O})},ct={add:r.object({id:E,groupName:E,assetPath:E,targetParentId:D,targetId:D,visible:r.boolean().optional()}),deleteById:r.object({groupName:E,ids:r.array(E).min(1)}),deleteByGroup:r.object({groupName:E}),getPOIInfo:r.object({groupName:E,id:E}),update:r.object({id:E,groupName:E,assetPath:D,targetParentId:D,targetId:D,visible:r.boolean().optional()}),setVisibleByGroup:r.object({groupName:E,visible:r.boolean()})},lt=r.array(r.object({groupName:E,id:E,parentId:r.string().optional().default(``),position:Ue})),ut={addPop:lt,removePop:lt,removeAll:lt,show:lt,showAll:lt,setPopDelayFrame:r.object({time:O}),setPopShowDistance:r.object({distance:O})},dt={startLoopAnimation:r.object({parentId:D,id:E,stateName:E,loopStartTime:k,loopEndTime:k,speed:k}).refine(e=>e.loopStartTime===void 0||e.loopStartTime>=0&&(e.loopEndTime===void 0||e.loopEndTime>e.loopStartTime),{message:`loopStartTime must be >= 0 and loopEndTime must be greater than loopStartTime`,path:[`loopStartTime`]}),stopLoopAnimation:r.object({parentId:D,id:E}),playAnimator:r.object({parentId:D,id:E,stateName:E,speed:k,startTime:k,endTime:k,isStop:r.boolean().optional()}),setAnimatorSpeed:r.object({parentId:D,id:E,speed:O}),getAnimationLength:r.object({parentId:D,id:E,stateName:E}),stopAnimator:r.object({parentId:D,id:E})},ft={play:$e(Qe.extend({initialTime:k,speed:k,keepLastFrame:r.boolean().optional()}).refine(e=>e.speed===void 0||e.speed<0||e.speed>=.1,{message:`speed must be negative or >= 0.1`,path:[`speed`]})),pause:$e(Qe),resume:$e(Qe),stop:$e(Qe.extend({resetTime:k,isCameraToStart:r.boolean().optional()})),stopAll:r.object({}).optional(),setSpeed:$e(Qe.extend({speed:O}).refine(e=>e.speed<0||e.speed>=.1,{message:`speed must be negative or >= 0.1`,path:[`speed`]}))},pt={setSceneRenderBitrate:r.object({bitrate:Ke.optional()}),setSceneRenderBitrateResolved:r.object({bitrate:O}).refine(e=>e.bitrate>=1e6,{message:`bitrate must be >= 1000000`,path:[`bitrate`]}),setSceneFPS:r.object({fps:O}).refine(e=>e.fps>=1&&e.fps<=300,{message:`fps must be in [1, 300]`,path:[`fps`]}),setVideoDecode:r.object({decode:qe}),setScreenResolution:r.object({width:O,height:O}).refine(e=>e.width>0&&e.height>0,{message:`width and height must be > 0`,path:[`width`]})},mt={setDlssEnable:r.object({enable:r.boolean(),quality:Ge}),setDlss:r.object({enable:r.boolean(),quality:Ge}),setDlssQuality:r.object({quality:Ge})},ht=r.object({node:j,time:r.string()}),gt=r.object({parentId:r.string().optional().default(``),id:E}),_t={add:r.object({parentId:r.string().optional().default(``),id:E,assetPath:r.string().optional().default(``),scale:j,showPath:r.boolean().optional().default(!0),passedColor:r.string().optional().default(`#ffffff`),lineColor:r.string().optional().default(`#00ff00`),lineWidth:O,duration:k,nodes:r.array(j).optional(),timeNodes:r.array(ht).optional(),lineLayer:D,afterRender:r.boolean().optional().default(!1),isAutoClear:r.boolean().optional().default(!0)}),update:r.object({parentId:r.string().optional().default(``),id:E,lineColor:r.string().optional(),lineWidth:k,passedColor:r.string().optional(),speed:k}).refine(e=>e.speed===void 0||e.speed>=0,{message:`speed must be >= 0`,path:[`speed`]}),setTimeNode:r.object({parentId:r.string().optional().default(``),id:E,timeStart:r.string().optional(),startNodeIndex:r.string().optional()}).refine(e=>e.timeStart!==void 0||e.startNodeIndex!==void 0,{message:`timeStart or startNodeIndex is required`,path:[`timeStart`]}).refine(e=>e.startNodeIndex===void 0||parseInt(e.startNodeIndex)>=0,{message:`startNodeIndex must be >= 0`,path:[`startNodeIndex`]}),node:gt,pause:gt,resume:gt,stop:gt,clear:r.object({}).optional()},vt=r.object({position:j,value:O.min(0).max(999).optional().default(1)}),yt={create:r.object({parentId:r.string().optional().default(``),id:r.string().optional(),textureSize:Ve.optional().default({x:256,y:256}),mapSize:Ve.optional().default({x:1e3,y:1e3}),influenceSize:r.number().int().positive().optional().default(13),points:r.union([r.array(vt).min(1),r.array(j).min(1)]),opacity:r.number().min(0).max(1).optional().default(.7),heightScale:r.number().positive().optional().default(3.5),lerpScale:r.number().positive().optional().default(2.5),isAddAsset:r.boolean().optional().default(!1)}),remove:r.object({parentId:r.string().optional().default(``),id:r.string().optional()}),clear:M,setConfig:r.object({parentId:r.string().optional().default(``),id:r.string().optional(),opacity:r.number().min(0).max(1).optional().default(.7),heightScale:r.number().positive().optional().default(3.5),lerpScale:r.number().positive().optional().default(2.5),influenceSize:r.number().int().positive().optional().default(13)})},bt={updateWebView:r.object({parentId:r.string().optional().default(``),id:E,url:E})},xt=r.object({parentId:r.string().optional().default(``),id:r.string()}),St=e=>e.refine(e=>{let t=e;return t.nodes!==void 0||t.targetIds!==void 0||t.targetCodes!==void 0},{message:`nodes or targetIds or targetCodes is required`,path:[`nodes`,`targetIds`,`targetCodes`]}),Ct=r.object({parentId:r.string().optional().default(``),id:r.string(),nodes:r.array(j).optional(),targetIds:r.array(E).optional(),targetCodes:r.array(E).optional(),speed:r.number().positive().optional().default(2),isCache:r.boolean().optional().default(!0),planColor:r.string().optional(),passColor:r.string().optional(),lineWidth:r.number().positive().optional().default(3),isAutoPlay:r.boolean().optional().default(!0),assetPath:r.string().optional(),isAutoClear:r.boolean().optional().default(!0),offSetZ:r.number().optional().default(.5),scale:A.default(new C(1,1,1))}),B={startNav:St(Ct),getMeshNavDistance:St(Ct.extend({isCache:r.boolean().optional().default(!1),isAutoPlay:r.boolean().optional().default(!1)})),pauseNav:xt,resumeNav:xt,stopNav:xt,updateNav:r.object({parentId:r.string().optional().default(``),id:r.string(),speed:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()}),updateSpeed:r.object({parentId:r.string().optional().default(``),id:r.string(),speed:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()}),startNavByPath:r.object({parentId:r.string().optional().default(``),id:r.array(E).min(1),nodes:r.array(j).min(1),isCache:r.boolean().optional().default(!0),duration:r.number().positive().optional().default(10),planColor:r.string().optional(),passColor:r.string().optional()}),pauseNavPath:xt,resumeNavPath:xt,stopNavPath:xt,updateNavPath:r.object({parentId:r.string().optional().default(``),id:r.array(E).min(1),duration:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()})},wt=r.array(E).min(1).describe(`查询的图层组编号集合`),Tt={layerQueryByModel:r.object({parentId:r.string().optional(),id:r.string().optional(),queryRadius:r.number().positive().optional().default(50),queryMinHeight:r.number().optional().default(0),queryMaxHeight:r.number().optional().default(20),queryParentIds:wt}),layerQueryByPosition:r.object({queryPosition:j.optional(),queryRadius:r.number().positive().optional().default(50),queryMinHeight:r.number().optional().default(0),queryMaxHeight:r.number().optional().default(20),queryParentIds:wt}),layerQueryByModelBox:r.object({parentId:r.string().optional(),id:r.string().optional(),queryParentIds:wt})},Et={startTrain:r.object({parentId:r.string().optional(),id:E,trainCode:r.string().optional(),startStationName:r.string().optional(),endStationName:r.string().optional(),direction:r.string().optional(),action:r.string().optional(),stopTime:k,moveType:r.nativeEnum(Re).optional()}),setTrainBehavior:r.object({parentId:r.string().optional(),id:E,moveType:r.nativeEnum(Re).optional()}),setCameraFollowTrain:r.object({parentId:r.string().optional(),id:E,offSet:Ue}),setTrainVolume:r.object({parentId:r.string().optional(),id:E,volumeOn:r.boolean().optional().default(!0)}),cancelCameraFollowTrain:M},Dt={},Ot={Connect:et,Camera:P,Scene:tt,Layer:L,Model:nt,ModelTransform:I,HighlighterEffect:at,UIPOI:z,ModelPOI:ct,Popup:ut,Animation:dt,TimeLine:ft,Screen:pt,Dlss:mt,WeatherSystem:R,PathPatrol:_t,pointIcon:N,PointEditor:Ce,GizmosTool:Ee,HeatMap:yt,WebView:bt,Navigation:B,SpatialQuery:Tt,TrainSimulate:Et};var kt=class extends x{constructor(e,t){super(e,`Animation`,t)}startLoopAnimation(e,t){let n={...e,speed:e.speed??1};return this.request(`startLoopAnimation`,n,t,dt.startLoopAnimation)}stopLoopAnimation(e,t){return this.request(`stopLoopAnimation`,e,t,dt.stopLoopAnimation)}playAnimator(e,t){let n={...e,speed:e.speed??1,startTime:e.startTime??0,endTime:e.endTime??1,isStop:e.isStop??!1};return this.request(`playAnimator`,n,t,dt.playAnimator)}setAnimatorSpeed(e,t){return this.request(`setAnimatorSpeed`,e,t,dt.setAnimatorSpeed)}getAnimationLength(e,t){return this.request(`getAnimationLength`,e,t,dt.getAnimationLength)}stopAnimator(e,t){return this.request(`stopAnimator`,e,t,dt.stopAnimator)}},At=class extends x{constructor(e,t){super(e,`CameraService`,t)}lookAt(e,t){let n={...e,time:e.time??1.5,distance:e.distance??20,isRotate:e.isRotate??!0,isHighlight:e.isHighlight??!0,offSet:e.offSet??new C(50,150,100)};if(n.offSet&&(n.offSet.ePSGType=`0000`),Array.isArray(n.id)){let e={parentId:n.parentId,ids:n.id,offSet:n.offSet,offSetX:n.offSetX,distance:n.distance,time:n.time,isRotate:n.isRotate,isHighlight:n.isHighlight};return this.request(`LookAtArray`,e,t,P.lookAtArray)}return this.request(`LookAt`,n,t,P.lookAt)}flyToTarget(e,t){let n={...e,time:e.time??2};return this.request(`FlyToTarget`,n,t,P.flyToTarget)}flyByPath(e,t){let n=Array.isArray(e.points)?JSON.stringify(e.points):e.points,r=Array.isArray(e.lookAts)?JSON.stringify(e.lookAts):e.lookAts,i={...e,points:n,lookAts:r,nodes:JSON.stringify(e.points),time:e.time??4,smoothMode:e.smoothMode??0};return this.request(`flyByPath`,i,t,P.flyByPath)}setFlySpeed(e,t){return this.request(`setFlySpeed`,e,t,P.setFlySpeed)}endFly(e){return this.request(`endFly`,void 0,e,M)}pauseFly(e){return this.request(`pauseFly`,void 0,e,M)}resumeFly(e){return this.request(`resumeFly`,void 0,e,M)}getCameraInfo(e){return this.request(`GetCameraInfo`,void 0,e,M)}setCameraPositionAndRotation(e,t){return e.rotation&&(e.rotation.ePSGType=`0000`),this.request(`setCameraPositionAndRotation`,e,t,P.setCameraPositionAndRotation)}setCameraFov(e,t){return this.request(`setCameraFov`,e,t,P.setCameraFov)}resetCameraFov(e){return this.request(`resetCameraFov`,void 0,e,M)}reset(e){return this.request(`reset`,void 0,e,M)}startCameraObjFollow(e,t){e.offSet&&(e.offSet.ePSGType=`0000`);let n={...e,offSet:e.offSet??new C(-30,0,10,`0000`)};return this.request(`StartCameraObjFollow`,n,t,P.startCameraObjFollow)}endCameraObjFollow(e){return this.request(`EndCameraObjFollow`,void 0,e,M)}},jt=class extends x{constructor(e,t,n){super(e,`Connect`,n),this.connectionLifecycle=t}connect(e){return pe(Promise.resolve().then(()=>(this.logger.warn(`connect called as compatibility API; SDK auto-connects after DTCEngine init`),this.connectionLifecycle.connect().then(()=>({requestId:``,success:!0,code:`CONNECT_OK`,message:`Connect requested (compatibility path)`,ts:Date.now()})))),e)}disconnect(e){return pe(Promise.resolve().then(()=>(this.logger.info(`disconnect requested`),Promise.resolve(this.connectionLifecycle.disconnect()).then(()=>({requestId:``,success:!0,code:`DISCONNECT_OK`,message:`Disconnected`,ts:Date.now()})))),e)}reconnect(e){return pe(Promise.resolve().then(()=>(this.logger.info(`reconnect requested`),this.connectionLifecycle.reconnect().then(()=>({requestId:``,success:!0,code:`RECONNECT_OK`,message:`Reconnect requested`,ts:Date.now()})))),e)}KickOtherConnect(e){return this.request(`KickOtherConnect`,void 0,e,M)}KeepConnect(e){return this.request(`KeepConnect`,void 0,e,M)}GetEngineServiceStatus(e){return this.request(`GetEngineServiceStatus`,void 0,e,M)}},Mt=class extends x{constructor(e,t){super(e,`DLSSService`,t)}setDlss(e={},t){let n={enable:e.enable??!1,quality:e.quality??w.Balanced};return this.request(`SetDlss`,n,t,mt.setDlss)}},Nt=class extends x{constructor(e,t){super(e,`HeatMapService`,t)}create(e,t){let n={...e,opacity:e.opacity??.7,heightScale:e.heightScale??3.5,lerpScale:e.lerpScale??2.5,influenceSize:e.influenceSize??13,points:e.points.map(e=>`position`in e?e:{position:e,value:1})};return n.heightScale*=100,this.request(`CreateHeatMap`,n,t,yt.create)}remove(e,t){return this.request(`RemoveHeatMap`,e,t,yt.remove)}clear(e){return this.request(`ClearHeatMap`,void 0,e,yt.clear)}setConfig(e,t){let n={...e,opacity:e.opacity??.7,heightScale:e.heightScale??3.5,lerpScale:e.lerpScale??2.5,influenceSize:e.influenceSize??13};return n.heightScale*=100,this.request(`SetHeatMapConfig`,n,t,yt.setConfig)}},Pt=class extends x{constructor(e,t){super(e,`HighLighterService`,t)}enable(e,t){return this.request(`HighlightEnable`,e,t,at.enable)}setHighLightModel(e,t){return this.request(`AddHighLighterModel`,e,t,at.setHighLightModel)}removeHighLightModel(e,t){return this.request(`RemoveHighLightModel`,e,t,at.removeHighLightModel)}clear(e){return this.request(`Clear`,{},e,at.clear)}},Ft=class e{constructor(e=0,t=0,n=0,r=0,i=S.EPSGType.EPSG84){this.x=e,this.y=t,this.z=n,this.v=r,this.EPSGType=i}set(e,t,n,r){return this.x=e,this.y=t,this.z=n,this.v=r,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}clone(){return new e(this.x,this.y,this.z,this.v)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.v=e.v,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this.z+=e.z,this.v+=e.v,this):this.addVectors(e,t)}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.v+=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.v=e.v+t.v,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this.v+=e.v*t,this}sub(e,t){return t==null?(this.x-=e.x,this.y-=e.y,this.z-=e.z,this.v-=e.v,this):this.subVectors(e,t)}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.v-=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.v=e.v-t.v,this}multiply(e,t){return t==null?(this.x*=e.x,this.y*=e.y,this.z*=e.z,this.v*=e.v,this):this.multiplyVectors(e,t)}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.v*=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.v=e.v*t.v,this}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.v/=e.v,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.v=Math.min(this.v,e.v),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.v=Math.max(this.v,e.v),this}clamp(e,t){return this.x=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this.v=Math.max(e.v,Math.min(t.v,this.v)),this}clampScalar(t,n){let r=new e,i=new e;return r.set(t,t,t,t),i.set(n,n,n,n),this.clamp(r,i)}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(Math.max(e,Math.min(t,n)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.v=Math.floor(this.v),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.v=Math.ceil(this.v),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.v=Math.round(this.v),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this.v=this.v<0?Math.ceil(this.v):Math.floor(this.v),this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.v*e.v}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.v*this.v}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.v*this.v)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.v)}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.v+=(e.v-this.v)*t,this}lerpVectors(e,t,n){return this.subVectors(t,e).multiplyScalar(n).add(e)}cross(e,t){return t==null?this.crossVectors(this,e):this.crossVectors(e,t)}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}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,i=this.v-e.v;return t*t+n*n+r*r+i*i}equals(e){return e.x==this.x&&e.y==this.y&&e.z==this.z&&e.v==this.v}toString(){return JSON.stringify(this)}changeEPSGType(e){if(this.EPSGType!=e){if(e==S.EPSGType.EPSG84){let e=Ae(this.x,this.y);this.x=e.x,this.y=e.y}else if(e==S.EPSGType.EPSGWeb){let e=ke(this.x,this.y);this.x=e.x,this.y=e.y}else console.log(`暂不支持[${this.EPSGType}]转换为${e}`);return this.EPSGType=e,this}}},It=class{constructor(){this.Vector2=Oe,this.Vector3=C,this.Vector4=Ft}},Lt=class extends x{constructor(e,t){super(e,`LayerService`,t)}addLayer(e,t){let n={...e,show:e.show??!0,poiEnabled:e.poiEnabled??!0,isSystem:e.isSystem??!1,poiOffsetY:e.poiOffsetY??0};return this.request(`AddLayer`,n,t,L.addLayerResolved)}removeLayer(e,t){let n={...e};return this.request(`RemoveLayer`,n,t,L.layerSelectorResolved)}isLayerOrGroupExit(e,t){let n={...e};return this.request(`IsLayerOrGroupExit`,n,t,L.layerSelectorResolved)}switchModelLayer(e,t){return this.request(`SwitchLayer`,e,t,L.switchModelLayer)}showUIPop(e,t){let n={...e,id:e.id.trim(),visible:e.visible??!0,assetsPath:e.assetsPath??`/Game/Resources/POIS/BluePrints/BP_Camera.uasset`,scale:e.scale??new C(1,1,1),offSet:e.offSet??new C(0,0,0)};return n.scale&&(n.scale.ePSGType=`0000`),n.offSet&&(n.offSet.ePSGType=`0000`),console.log(n),this.request(`ShowLayerUIPop`,n,t,L.showUIPop)}addModel(e,t){let n={...e,id:e.id.trim(),name:e.name?.trim()||``,scale:e.scale??new C(1,1,1),rotation:e.rotation??new C(0,0,0)};return n.extraProps&&=JSON.stringify(n.extraProps),n.scale&&(n.scale.ePSGType=`0000`),n.rotation&&(n.rotation.ePSGType=`0000`),this.request(`AddModel`,n,t,L.addModel)}addPOI(e,t){let n={...e,id:e.id.trim(),scale:e.scale??new C(1,1,1),rotation:e.rotation??new C(0,0,0),fontSize:e.fontSize??16,isSystem:e.isSystem??!1,name:e.name??``,targetParentId:e.targetParentId??``,targetId:e.targetId??``,offSet:e.offSet??new C(0,0,0)};return n.extraProps=n.extraProps?JSON.stringify(n.extraProps):`{}`,n.scale&&(n.scale.ePSGType=`0000`),n.rotation&&(n.rotation.ePSGType=`0000`),n.offSet&&(n.offSet.ePSGType=`0000`),this.request(`AddPOI`,n,t,L.addPOI)}updatePOIName(e,t){let n={...e,id:e.id.trim(),updateType:e.updateType??`update`};return this.request(`UpdatePOIName`,n,t,L.updatePOIName)}resetPOIName(e,t){return this.request(`ResetPOIName`,e,t,L.resetPOIName)}removeModel(e,t){return this.request(`RemoveModelByIds`,e,t,L.removeModel)}getLayerChildElement(e,t){return this.request(`GetLayerChildElements`,e,t,L.getLayerChildElement)}},Rt=class extends x{constructor(e,t){super(e,`ModelService`,t)}toIdArray(e){return Array.isArray(e)?e:[e]}setVisible(e,t){let n={parentId:e.parentId,ids:this.toIdArray(e.id),visible:e.visible??!0};return this.request(`SetVisible`,n,t,nt.setVisibleResolved)}setVisibleByTags(e,t){let n={tags:this.toIdArray(e.tags),visible:e.visible??!0};return this.request(`SetVisibleByTags`,n,t,nt.setVisibleByTags)}setVisibleByAttribute(e,t){let n={attributes:e.attributes,filterMode:e.filterMode??0,visible:e.visible??!0,otherVisible:e.otherVisible??!1};return this.request(`SetVisibleByAttribute`,n,t,nt.setVisibleByAttribute)}getElementTree(e,t){return this.request(`GetElementTree`,e,t,nt.getElementTree)}getModelInfo(e,t){return this.request(`GetModelInfo`,e,t,nt.getModelInfo)}},zt=class extends x{constructor(e,t){super(e,`ModelPOI`,t)}add(e,t){let n={...e,visible:e.visible??!0};return this.request(`add`,n,t,ct.add)}deleteById(e,t){return this.request(`deleteById`,e,t,ct.deleteById)}deleteByGroup(e,t){return this.request(`deleteByGroup`,e,t,ct.deleteByGroup)}getPOIInfo(e,t){return this.request(`getPOIInfo`,e,t,ct.getPOIInfo)}update(e,t){let n={...e,visible:e.visible??!0};return this.request(`update`,n,t,ct.update)}setVisibleByGroup(e,t){return this.request(`setVisibleByGroup`,e,t,ct.setVisibleByGroup)}},Bt=class extends x{constructor(e,t){super(e,`ModelTransformService`,t)}startMoveByNodes(e,t){return this.request(`StartMoveByNodes`,e,t,I.startMoveByNodes)}pauseMove(e,t){return this.request(`PauseMove`,e,t,I.pauseMove)}resumeMove(e,t){return this.request(`ResumeMove`,e,t,I.resumeMove)}endMove(e,t){return this.request(`EndMove`,e,t,I.endMove)}restoreMove(e,t){return this.request(`RestoreMove`,e,t,I.restoreMove)}rotate(e,t){return e.rotate.ePSGType=S.EPSGType.EPSGWorld,this.request(`StartRotate`,e,t,I.rotate)}endRotate(e,t){return this.request(`EndRotate`,e,t,I.endRotate)}continuedRotate(e,t){return e.rotate.ePSGType=S.EPSGType.EPSGWorld,this.request(`ContinuedRotate`,e,t,I.continuedRotate)}rotateByTarget(e,t){return this.request(`RotateByTarget`,e,t,I.rotateByTarget)}restoreRotate(e,t){return this.request(`RestoreRotate`,e,t,I.restoreRotate)}setScale(e,t){e.scale.ePSGType=S.EPSGType.EPSGWorld;let n={...e,id:e.id.trim()};return n.scale&&(n.scale.ePSGType=`0000`),this.request(`SetScale`,n,t,I.setScale)}endScale(e,t){return this.request(`EndScale`,e,t,I.endScale)}restoreScale(e,t){return this.request(`RestoreScale`,e,t,I.restoreScale)}},Vt=class extends x{constructor(e,t){super(e,`NavigationService`,t)}startNav(e,t){let n={...e,scale:e.scale??new C(1,1,1)};return n.scale&&(n.scale.ePSGType=`0000`),this.request(`PlayMeshNavByNodes`,n,t,B.startNav)}getMeshNavDistance(e,t){return this.request(`PlayMeshNavByNodes`,e,t,B.getMeshNavDistance)}pauseNav(e,t){return this.request(`PauseMeshNav`,e,t,B.pauseNav)}resumeNav(e,t){return this.request(`ResumeMeshNav`,e,t,B.resumeNav)}stopNav(e,t){return this.request(`StopMeshNav`,e,t,B.resumeNav)}updateNav(e,t){return this.request(`UpdateMeshNavProperty`,e,t,B.updateNav)}updateSpeed(e,t){return this.request(`UpdateNavSpeed`,e,t,B.updateSpeed)}startNavByPath(e,t){return this.request(`StartNavByPath`,e,t,B.startNavByPath)}pauseNavPath(e,t){return this.request(`PauseNavPath`,e,t,B.pauseNavPath)}resumeNavPath(e,t){return this.request(`ResumeNavPath`,e,t,B.resumeNavPath)}stopNavPath(e,t){return this.request(`StopNavPath`,e,t,B.stopNavPath)}updateNavPath(e,t){return this.request(`UpdateNavPathProperty`,e,t,B.updateNavPath)}},Ht=class extends x{constructor(e,t){super(e,`PathPatrolService`,t)}add(e,t){return e.scale&&(e.scale.ePSGType=S.EPSGType.EPSGWorld),this.requestStream(`AddPath`,e,t,_t.add)}update(e,t){return this.request(`UpdatePath`,e,t,_t.update)}setTimeNode(e,t){return this.request(`CuriserTimeSet`,e,t,_t.setTimeNode)}clear(e){return this.request(`ClearPath`,void 0,e,_t.clear)}pause(e,t){return this.request(`Pause`,e,t,_t.node)}resume(e,t){return this.request(`Resume`,e,t,_t.node)}stop(e,t){return this.request(`Stop`,e,t,_t.node)}};function Ut(e){return Array.isArray(e)?{ids:e}:e}function Wt(e){return Array.isArray(e)?{codes:e}:e}var Gt=class extends x{constructor(e,t){super(e,`PointIcon`,t)}show(e,t){return this.request(`Show`,Ut(e),t,N.show)}hide(e,t){return this.request(`Hide`,Ut(e),t,N.hide)}showByCode(e,t){return this.request(`ShowByCode`,Wt(e),t,N.showByCode)}hideByCode(e,t){return this.request(`HideByCode`,Wt(e),t,N.hideByCode)}showByGroup(e,t){return this.request(`ShowByGroup`,Ut(e),t,N.showByGroup)}hideByGroup(e,t){return this.request(`HideByGroup`,Ut(e),t,N.hideByGroup)}showAll(e){return this.request(`ShowAll`,void 0,e,N.showAll)}hideAll(e){return this.request(`HideAll`,void 0,e,N.hideAll)}};function Kt(e,t){let n=e.getBoundingClientRect(),r=e.ownerDocument.defaultView.getComputedStyle(e);if(n.width<=0||n.height<=0||e.videoWidth<=0||e.videoHeight<=0)throw Error(`视频尚未就绪,无法计算点位落点`);for(let t=e;t;t=t.parentElement){let n=e.ownerDocument.defaultView.getComputedStyle(t).transform;if(!n||n===`none`)continue;let r=n.startsWith(`matrix(`)?n.slice(7,-1).split(`,`).map(Number):[];if(r.length!==6||r[1]!==0||r[2]!==0||r[0]<=0||r[3]<=0)throw Error(`点位拾取暂不支持旋转、翻转或 3D 变换的视频元素`)}let i=n.width/(e.offsetWidth||n.width),a=n.height/(e.offsetHeight||n.height),o=(parseFloat(r.borderLeftWidth)||0)+(parseFloat(r.paddingLeft)||0),s=(parseFloat(r.borderTopWidth)||0)+(parseFloat(r.paddingTop)||0),c=n.width-i*(o+(parseFloat(r.borderRightWidth)||0)+(parseFloat(r.paddingRight)||0)),l=n.height-a*(s+(parseFloat(r.borderBottomWidth)||0)+(parseFloat(r.paddingBottom)||0)),u=t.clientX-n.left-o*i,d=t.clientY-n.top-s*a;if(c<=0||l<=0||u<0||u>c||d<0||d>l)throw Error(`落点不在视频区域内`);let f=r.objectFit||`fill`,p=c,m=l;if(f!==`fill`){let t=f===`cover`?Math.max(c/i/e.videoWidth,l/a/e.videoHeight):f===`none`?1:Math.min(c/i/e.videoWidth,l/a/e.videoHeight),n=f===`scale-down`?Math.min(1,t):t;p=e.videoWidth*n*i,m=e.videoHeight*n*a}let h=(r.objectPosition||`50% 50%`).split(/\s+/);if(h.length!==2)throw Error(`暂不支持当前视频的 object-position 写法`);function g(e,t,n){if(e===`center`)return t/2;if(e===`left`||e===`top`)return 0;if(e===`right`||e===`bottom`)return t;if(/^-?[\d.]+%$/.test(e))return parseFloat(e)*t/100;if(/^-?[\d.]+px$/.test(e))return parseFloat(e)*n;throw Error(`暂不支持当前视频的 object-position 写法`)}let _={x:(u-g(h[0],c-p,i))/p,y:(d-g(h[1],l-m,a))/m};if(_.x<0||_.x>1||_.y<0||_.y>1)throw Error(`落点位于视频黑边,不在实际图像内`);return _}var qt=class{constructor(e){this.getVideo=e}cancel(){this.cancelPending?.()}pick(){if(this.cancelPending)return Promise.reject(Error(`已有点位放置操作,请先取消或完成`));let e=this.getVideo();return e?new Promise((t,n)=>{let r=e.style.cursor,i,a=()=>{l.forEach(t=>e.removeEventListener(t,c,!0)),e.ownerDocument.removeEventListener(`keydown`,s,!0),e.ownerDocument.defaultView?.removeEventListener?.(`blur`,o),e.style.cursor=r,this.cancelPending=void 0},o=()=>{a(),n(Error(`点位放置已取消`))},s=e=>{e.key===`Escape`&&(e.preventDefault(),e.stopImmediatePropagation(),o())},c=r=>{let s=r;if(s.button===0||s.button===2){if(s.preventDefault(),s.stopImmediatePropagation(),s.type===`contextmenu`){o();return}if((s.type===`pointerdown`||s.type===`mousedown`)&&s.button===0&&(i={x:s.clientX,y:s.clientY}),!(s.type!==`click`||s.button!==0||!i)){if(Math.hypot(s.clientX-i.x,s.clientY-i.y)>4){i=void 0;return}try{let n=Kt(e,{clientX:s.clientX,clientY:s.clientY});a(),t(n)}catch(e){a(),n(e)}}}},l=[`pointerdown`,`pointerup`,`mousedown`,`mouseup`,`click`,`contextmenu`];this.cancelPending=o,e.style.cursor=`crosshair`,l.forEach(t=>e.addEventListener(t,c,{capture:!0,passive:!1})),e.ownerDocument.addEventListener(`keydown`,s,!0),e.ownerDocument.defaultView?.addEventListener?.(`blur`,o)}):Promise.reject(Error(`未找到 Pixel Streaming 视频元素`))}},Jt=class extends x{constructor(e,t){let n={version:0};super({async sendRequest(t,r,i){let{__placementVersion:a,...o}=i??{};if(a!==void 0&&a!==n.version)throw Error(`点位放置已取消`);let s=await e.sendRequest(t,r,{...o,editorSource:`sdk3`});if(s.success===!1||s.errorMsg)throw Error(s.errorMsg||s.message||`点位操作失败`);if(r===`DeletePoints`){let e=s.data??s.params,t=typeof e==`string`?JSON.parse(e):e;return{...s,params:f(Te,t,`PointEditor`,`DeletePointsResponse`)}}return s}},`PointEditorService`,t),this.createPoint=(e,t,n)=>{let r=this.placementState.version,i=Promise.resolve().then(async()=>{if(r!==this.placementState.version)throw Error(`点位放置已取消`);let t=f(Ce[n],e,`PointEditor`,n),{screenPosition:i,...a}=t,o=t.position?void 0:i??await this.placement.pick();if(r!==this.placementState.version)throw Error(`点位放置已取消`);return this.request(o?`AddPointAtScreen`:`AddPoint`,{__placementVersion:r,...a,...o?{screenPosition:o}:{},resource:{...t.resource,type:`MODEL`},show:t.show??!0,poiEnabled:t.poiEnabled??!0,poiScaleFactor:t.poiScaleFactor??1,poiOffsetY:t.poiOffsetY??0,poiShowName:t.poiShowName??!0,extraProps:t.extraProps??{},rotation:t.rotation??{x:0,y:0,z:0},scale:t.scale??{x:1,y:1,z:1}})}).then(t=>{let n=t.data??t.params,r=typeof n==`string`?JSON.parse(n):n,i=f(we,r,`PointEditor`,`AddPointResponse`);if(i.id!==e.id.trim()||i.parentId!==e.parentId.trim())throw Error(`UE 返回的点位与本次创建目标不一致`);return i});return t&&i.then(t,e=>t(e instanceof Error?e:Error(String(e)))).catch(e=>this.logger.warn(`point callback failed`,{error:String(e)})),i},this.placementState=n,this.getVideo=t?.getVideoElement??(()=>null),this.placement=new qt(this.getVideo)}addPoint(e,t){return this.createPoint(e,t,`addPoint`)}addPointByDrag(e,t){return this.createPoint(e,t,`addPointByDrag`)}getScreenPosition(e){let t=f(Ce.getScreenPosition,e,`PointEditor`,`getScreenPosition`),n=this.getVideo();if(!n)throw Error(`未找到 Pixel Streaming 视频元素`);return Kt(n,t)}cancelPlacement(){return++this.placementState.version,this.placement.cancel(),Promise.resolve()}updatePoint(e,t){return this.request(`UpdatePoint`,e,t,Ce.updatePoint)}deletePoints(e,t){return this.request(`DeletePoints`,e,t,Ce.deletePoints)}},Yt=class{static getUUID(e=11){let t=16,n=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`.split(``),r=[],i;if(t||=n.length,e)for(i=0;i<e;i++)r[i]=n[0|Math.random()*t];else{let e;for(r[8]=r[13]=r[18]=r[23]=`-`,r[14]=`4`,i=0;i<36;i++)r[i]||(e=0|Math.random()*16,r[i]=n[i==19?e&3|8:e])}return`U`+r.join(``)}static warn(e,t=!1){console.log(`warn`,e,t);let n=document.createElement(`div`);return n.innerHTML=e,document.body.appendChild(n),n.setAttribute(`id`,`engineWarnTips`),n.style.cssText=`
1
+ import{EventEmitter as e,LogLevel as t,Logger as n}from"@epicgames-ps/lib-pixelstreamingcommon-ue5.6";import{z as r}from"zod";import i from"axios";import{Config as a,Flags as o,NumericParameters as s,OptionParameters as c,PixelStreaming as l}from"@epicgames-ps/lib-pixelstreamingfrontend-ue5.6";import{inflate as u}from"pako";var d=class extends Error{constructor(e,t,n){super(`Invalid payload for ${e}.${t}: ${n.map(e=>`${e.field}: ${e.reason}`).join(`; `)}`),this.moduleName=e,this.methodName=t,this.issues=n,this.name=`SDKValidationError`,this.code=`VALIDATION_ERROR`}toJSON(){return{name:this.name,code:this.code,message:this.message,module:this.moduleName,method:this.methodName,issues:this.issues}}};function f(e,t,n,r){let i=e.safeParse(t);if(i.success)return i.data;throw new d(n,r,i.error.issues.map(e=>({field:e.path.length>0?e.path.join(`.`):`<root>`,reason:e.message,code:e.code})))}function p(e){return e instanceof d?JSON.stringify(e.toJSON()):e instanceof Error?`${e.name}: ${e.message}`:String(e)}const m={InitLogging(){},Debug(e){console.log(`[Debug] - ${e}`)},Info(e){console.log(`[Info] - ${e}`)},Warning(e){console.warn(`[Warning] - ${e}`)},Error(e){console.error(`[Error] - ${e}`)}},h={debug(){},info(){},warn(){},error(){}},g=[`silent`,`error`,`warn`,`info`,`debug`],_={silent:0,error:1,warn:2,info:3,debug:4};function ee(e){switch(e){case`silent`:return t.Disabled;case`error`:return t.Error;case`warn`:return t.Warning;case`info`:return t.Info;default:return t.Debug}}function te(e){n.InitLogging(ee(e),!1)}function v(e){return typeof e==`string`&&g.includes(e)}function y(e){if(e===void 0)return`info`;if(v(e))return e;let t=typeof e==`string`?e:JSON.stringify(e);throw Error(`Invalid logger level: ${t}. Expected one of: ${g.join(`, `)}.`)}function ne(e){if(e===void 0)return``;try{let t=JSON.stringify(e);return t?` ${t}`:``}catch{return` ${String(e)}`}}function re(){let e=Error().stack;return e?e.replace(/^Error(?::\s*)?\n?/,``):`No Stack Available for this browser`}var ie=class{constructor(e,t,n,r,i,a){this.driver=e,this.prefix=t,this.level=n,this.moduleName=r,this.includeStack=i,this.reporter=a}formatMessage(e,t,n){let r=`${this.prefix} ${t}${ne(n)}`.trim();return this.shouldIncludeStack(e)?`${r}\nStack: ${re()}`:r}shouldLog(e){return _[this.level]>=_[e]}shouldIncludeStack(e){return _[this.includeStack]>=_[e]}debug(e,t){this.shouldLog(`debug`)&&this.driver.Debug(this.formatMessage(`debug`,e,t))}info(e,t){this.shouldLog(`info`)&&this.driver.Info(this.formatMessage(`info`,e,t))}warn(e,t){this.reportWarnOrError(`warn`,e,t),this.shouldLog(`warn`)&&this.driver.Warning(this.formatMessage(`warn`,e,t))}error(e,t){this.reportWarnOrError(`error`,e,t),this.shouldLog(`error`)&&this.driver.Error(this.formatMessage(`error`,e,t))}reportWarnOrError(e,t,n){this.reporter?.recordLogSignal({level:e,moduleName:this.moduleName,message:t,meta:n})}},ae=class{constructor(e,t=m,n){this.level=y(e),this.driver=t,this.includeStack=n?.includeStack??`warn`,this.driver.InitLogging(ee(this.level),!1),this.reporter=n?.reporter??n?.qosMonitor}setReporter(e){this.reporter=e}child(e){return new ie(this.driver,`[DTCEngine:${e}]`,this.level,e,this.includeStack,this.reporter)}};const b={EngineIniting:`云渲染引擎初始化中...`,ServiceUrlInValid:`调度中心地址不正确,请检查中心地址!`,SerriceError:`调度中心连接失败,尝试重连中...`,SerriceUnAvaible:`没有服务资源,请检查服务是否启动!`,SerriceLoadingForWaiting:`服务资源启动中,请稍候!`,EngineWaiting:`云渲染服务坐席已满,当前排队人数:1人....`,EngineTockenChecking:`云引擎授权文件验证中...`,EngineTokenCheckFail:`云引擎授权许可无效,请联系管理员!`,EngineConnectioning:`云渲染引擎连接中...`,EngineConnectionSuccess:`云渲染引擎连接成功...`,EngineClose:`云渲染引擎连接断开,请检查服务状态!`,SourcePreparing:`资源准备中...`,TokenInValid:`许可未激活!`,TokenExpired:`许可授权已过期,实时渲染服务已停止!`,TokenWillExpired:`您的授权许可将于 YYYY-MM-DD 到期,请尽快续期!`};var oe=class{constructor(e){this.options=e,this.logger=e.logger??h}show(e,t,n=!0){if(console.log(`loading show`,e,t,n),this.options.emit({message:e,key:t,isFinish:!n}),!this.options.enabled)return;let r=this.getRoot();r&&(this.progressDiv||=this.createTipDiv(r,`engineProgressTips`),this.progressDiv.textContent=e,n||(this.clearAutoCloseTimer(),this.autoCloseTimer=setTimeout(()=>{this.removeProgressBar()},2e3)))}showTokenWillExpire(e,t=`TokenWillExpired`,n=!0){let r=this.formatTokenWillExpireMessage(e);if(this.options.emit({message:r,key:t,isFinish:!n}),!this.options.enabled)return;let i=this.getRoot();i&&(this.tokenWillExpireDiv||(this.tokenWillExpireDiv=this.createTipDiv(i,`TokenWillExpireTips`),this.tokenWillExpireDiv.style.top=`60px`),this.tokenWillExpireDiv.textContent=r)}dispose(){this.clearAutoCloseTimer(),this.removeProgressBar(),this.removeTokenWillExpireBar()}getRoot(){if(this.options.hostElement?.ownerDocument?.body)return this.options.hostElement.ownerDocument.body;if(typeof document<`u`&&document.body)return document.body;this.logger.debug(`skip loading progress ui render: document is unavailable`)}createTipDiv(e,t){let n=e.ownerDocument.createElement(`div`);return n.id=t,n.style.position=`fixed`,n.style.left=`50%`,n.style.top=`16px`,n.style.transform=`translateX(-50%)`,n.style.zIndex=`99999`,n.style.padding=`8px 14px`,n.style.borderRadius=`6px`,n.style.background=`rgba(0, 0, 0, 0.72)`,n.style.color=`#fff`,n.style.fontSize=`14px`,n.style.lineHeight=`1.4`,n.style.pointerEvents=`none`,n.style.maxWidth=`80vw`,n.style.textAlign=`center`,e.appendChild(n),n}removeProgressBar(){this.progressDiv&&=(this.progressDiv.remove(),void 0)}removeTokenWillExpireBar(){this.tokenWillExpireDiv&&=(this.tokenWillExpireDiv.remove(),void 0)}clearAutoCloseTimer(){this.autoCloseTimer&&=(clearTimeout(this.autoCloseTimer),void 0)}formatTokenWillExpireMessage(e){let t=e.trim();return t?t.includes(`到期`)?t:`您的授权许可将于 ${t}到期,请尽快续期!`:b.TokenWillExpired}};const se=`sdk3-agent-bridge/v1`;function ce(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in current runtime.`);return new WebSocket(e)}function le(e){return{ok:!0,data:e,ts:Date.now()}}function ue(e,t){return{ok:!1,error:{code:`PROTOCOL_ERROR`,message:e,details:t},ts:Date.now()}}function de(e){if(typeof e==`string`)try{let t=JSON.parse(e);if(typeof t!=`object`||!t)return;let n=t;return n.protocolVersion!==`sdk3-agent-bridge/v1`||typeof n.type!=`string`||typeof n.callId!=`string`?void 0:n}catch{return}}var fe=class{constructor(e,t,n={}){this.runtime=e,this.options=t,this.reconnectAttempt=0,this.running=!1,this.startedAt=0,this.beforeUnloadHandler=()=>{this.stop(`pagehide`)},this.socketFactory=n.socketFactory??ce}start(){this.socket||(this.running=!0,this.openSocket(),typeof window<`u`&&(window.addEventListener(`beforeunload`,this.beforeUnloadHandler),window.addEventListener(`pagehide`,this.beforeUnloadHandler)))}stop(e=`stop`){this.running=!1,this.clearReconnect(),typeof window<`u`&&(window.removeEventListener(`beforeunload`,this.beforeUnloadHandler),window.removeEventListener(`pagehide`,this.beforeUnloadHandler)),this.clearHeartbeat(),this.runtime.dispose?.();let t=this.socket;t&&(t.readyState===1&&this.sendUnregister(e),this.clearSocketHandlers(t),t.close(1e3,e),this.socket=void 0)}openSocket(){this.startedAt=Date.now();let e=this.socketFactory(this.options.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`);this.socket=e,e.onopen=()=>{this.reconnectAttempt=0,this.sendRegister(),this.startHeartbeat()},e.onmessage=e=>{this.handleMessage(e.data)},e.onclose=()=>{this.clearSocketHandlers(e),this.clearHeartbeat(),this.runtime.closeAllStreams?.(`Agent bridge WebSocket disconnected`),this.runtime.cancelAllPrograms?.(`Agent bridge WebSocket disconnected`),this.socket===e&&(this.socket=void 0),this.scheduleReconnect()},e.onerror=()=>{this.clearHeartbeat()}}scheduleReconnect(){if(!this.running||this.reconnectTimer!==void 0||this.options.reconnect===!1)return;let e=this.getReconnectDelay();this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,!(!this.running||this.socket)&&this.openSocket()},e),this.reconnectAttempt+=1}getReconnectDelay(){let e=typeof this.options.reconnect==`object`?this.options.reconnect:void 0,t=Math.max(0,e?.initialDelayMs??1e3),n=Math.max(t,e?.maxDelayMs??15e3),r=Math.max(0,e?.jitterMs??500);return Math.min(n,t*2**this.reconnectAttempt)+Math.floor(Math.random()*(r+1))}clearReconnect(){this.reconnectTimer!==void 0&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0)}sendRegister(){let e={...this.runtime.getSnapshot(),heartbeatIntervalMs:this.getHeartbeatInterval(),capabilities:{catalog:!0,schema:!0,validateActions:!0,invoke:!0,stream:!0,businessPrograms:!0,businessProgramProtocolVersion:1}};this.send({type:`register`,protocolVersion:se,bridgeId:e.bridgeId,ts:Date.now(),payload:e})}sendUnregister(e){let t={...this.runtime.getSnapshot(),reason:e};this.send({type:`unregister`,protocolVersion:se,bridgeId:t.bridgeId,ts:Date.now(),payload:t})}sendHeartbeat(){let e={...this.runtime.getSnapshot(),heartbeatIntervalMs:this.getHeartbeatInterval(),uptimeMs:Math.max(0,Date.now()-this.startedAt)};this.send({type:`heartbeat`,protocolVersion:se,bridgeId:e.bridgeId,ts:Date.now(),payload:e})}getHeartbeatInterval(){return Math.max(1e3,this.options.heartbeatIntervalMs??5e3)}startHeartbeat(){this.clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.sendHeartbeat()},this.getHeartbeatInterval())}clearHeartbeat(){this.heartbeatTimer!==void 0&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=void 0)}async handleMessage(e){let t=de(e);if(t){if(t.type===`catalog`){let e=t.payload,n=e.kind===`modules`?le(this.runtime.listModules()):this.runtime.listMethods(e.moduleName??``);this.sendResult(t,`catalog`,n);return}if(t.type===`schema`){let e=t.payload;this.sendResult(t,`schema`,this.runtime.getMethodSchema(e.moduleName,e.methodName));return}if(t.type===`validate-actions`){this.sendResult(t,`validate-actions`,this.runtime.validateActions(t.payload));return}if(t.type===`invoke`){this.sendResult(t,`invoke`,await this.runtime.invoke(t.payload));return}if(t.type===`stream-start`){let e=t.payload,n=await this.runtime.startStream(e,e=>{this.sendStreamEvent(e)});this.sendResult(t,`stream-start`,n);return}if(t.type===`stream-close`){this.sendResult(t,`stream-close`,await this.runtime.closeStream(t.payload));return}if(t.type===`load-program`){this.sendResult(t,`load-program`,await this.runtime.loadProgram(t.payload));return}if(t.type===`start-program`){this.sendResult(t,`start-program`,await this.runtime.startProgram(t.payload,e=>{this.sendProgramEvent(e)}));return}if(t.type===`cancel-program`){this.sendResult(t,`cancel-program`,await this.runtime.cancelProgram(t.payload));return}this.sendResult(t,`catalog`,ue(`Unsupported message type "${t.type}".`))}}sendStreamEvent(e){this.send({type:`stream-event`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,ts:Date.now(),payload:e})}sendProgramEvent(e){this.send({type:`program-event`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,traceId:e.traceId,ts:Date.now(),payload:e})}sendResult(e,t,n){let r={requestType:t,result:n,traceId:e.traceId};this.send({type:`result`,protocolVersion:se,bridgeId:this.runtime.getSnapshot().bridgeId,callId:e.callId,traceId:e.traceId,ts:Date.now(),payload:r})}send(e){!this.socket||this.socket.readyState!==1||this.socket.send(JSON.stringify(e))}clearSocketHandlers(e){e.onopen=null,e.onmessage=null,e.onclose=null,e.onerror=null}};function pe(e,t){return t&&e.then(e=>{t(e)}).catch(e=>{t(e)}),e}var x=class{constructor(e,t,n){this.bridge=e,this.moduleName=t,this.logger=n?.logger??h}request(e,t,n,r){return pe(Promise.resolve().then(()=>{let n=r?f(r,t,this.moduleName,e):t;return r||this.logger.debug(`validation schema not configured`,{method:e}),this.logger.debug(`sending request`,{method:e}),this.bridge.sendRequest(this.moduleName,e,n)}).then(t=>(this.logger.info(`request success`,{method:e,code:t.code}),t)).catch(t=>{throw this.logger.warn(`request failed`,{method:e,error:p(t)}),t}),n)}requestStream(e,t,n,r){try{if(!this.bridge.sendStreamRequest)throw Error(`Current bridge does not support stream request`);let i=r?f(r,t,this.moduleName,e):t;return r||this.logger.debug(`validation schema not configured`,{method:e}),this.logger.debug(`sending stream request`,{method:e}),this.bridge.sendStreamRequest(this.moduleName,e,i,n)}catch(t){let r=t instanceof Error?t:Error(String(t));if(this.logger.warn(`stream request failed before send`,{method:e,error:p(r)}),n)try{n({type:`error`,requestId:``,error:r})}catch(t){this.logger.warn(`stream error callback failed`,{method:e,error:p(t)})}let i=Promise.reject(r);return Object.defineProperty(i,"requestId",{value:``,enumerable:!0}),i.cancel=()=>{},i}}};const me=r.string().trim().min(1),he=r.lazy(()=>r.union([r.null(),r.string(),r.number().finite(),r.boolean(),r.array(he),r.record(he)])),ge=r.object({x:r.number().finite(),y:r.number().finite(),z:r.number().finite()}),_e=ge.extend({x:r.number().finite().min(-180).max(180),y:r.number().finite().min(-90).max(90)}),ve=r.object({x:r.number().finite().min(0).max(1),y:r.number().finite().min(0).max(1)}).strict(),ye=r.object({type:r.literal(`MODEL`).optional(),name:r.string().optional(),path:me,poiAsset:r.string().optional()}).strict(),be={code:r.string().optional(),name:r.string().optional(),position:_e.optional().describe(`已知经纬高;与 screenPosition 二选一;addPoint 不传时等待点击`),screenPosition:ve.optional().describe(`drop 当时的视频图像归一化坐标 [0,1];用 getScreenPosition 获取`),rotation:ge.optional().describe(`旋转角度,与既有 payload 一致:x=Roll、y=Pitch、z=Yaw`),scale:ge.optional(),show:r.boolean().optional().describe(`模型显隐,创建默认 true,更新不传则保留`),poiEnabled:r.boolean().optional().describe(`模型附属 POI 显隐,不是独立 POI 点位`),poiOffsetY:r.number().finite().optional().describe(`附属 POI 向上偏移(米),允许 0`),poiScaleFactor:r.number().finite().nonnegative().optional().describe(`附属 POI 等比缩放,创建默认 1,允许 0`),poiShowName:r.boolean().optional().describe(`附属 POI 是否显示模型名称`),extraProps:r.record(he).optional().describe(`JSON 对象;更新时整体替换该字段`),lookAt:r.string().optional(),resource:ye.describe(`UE Actor 蓝图资源:path 必填,poiAsset 可选,不能使用 Unity 资源路径`),category:r.object({code:r.string().optional(),name:r.string().optional(),type:r.string().optional()}).strict().optional()},xe={parentId:me.describe(`场景分组 ID,沿用既有加载结果,不要求新增 SDK 来源标签`),id:me.describe(`点位 globalId,不是数据库主键`),type:r.literal(`MODEL`).describe(`固定为 MODEL,本期不支持独立 POI`)},Se=r.object({...xe,...be}).strict(),Ce={addPoint:Se.refine(e=>!(e.position&&e.screenPosition),`position 与 screenPosition 不能同时传入`),addPointByDrag:Se.refine(e=>!!e.position!=!!e.screenPosition,`请传入 position 或 drop 时记录的 screenPosition(二选一)`),getScreenPosition:r.object({clientX:r.number().finite(),clientY:r.number().finite()}).strict(),cancelPlacement:r.undefined().optional(),updatePoint:Se.omit({screenPosition:!0}).partial().extend({...xe,resource:ye.partial().optional()}),deletePoints:r.object({parentId:me,ids:r.array(me).min(1).refine(e=>new Set(e).size===e.length,`ids 不能重复`)}).strict()},we=Se.omit({screenPosition:!0}).extend({position:_e,rotation:ge,scale:ge,show:r.boolean(),poiEnabled:r.boolean(),poiOffsetY:r.number().finite(),poiScaleFactor:r.number().finite().nonnegative(),poiShowName:r.boolean(),extraProps:r.record(he)}).strip(),Te=r.object({deletedIds:r.array(me),failedIds:r.array(me)}),Ee={startSimpleGizmoMode:r.object({parentId:r.string().trim().min(1),id:r.string().trim().min(1)}).strict(),endSimpleGizmoMode:r.undefined().optional(),modelSnapById:r.object({parentId:r.string().trim().min(1),ids:r.array(r.string().trim().min(1)).min(1).refine(e=>new Set(e).size===e.length,`点位 ID 不能重复`).optional()}).strict()},De=r.object({snappedIds:r.array(r.string()),failedIds:r.array(r.string()),errors:r.array(r.object({id:r.string(),message:r.string()}))});var Oe=class extends x{constructor(e,t){super(e,`GizmosService`,t),this.options=t,this.sequence=Promise.resolve(),this.sessionVersion=0,this.finishFromEngine=()=>{this.restoreInput?.(),this.restoreInput=void 0},this.resetRuntime=()=>{++this.sessionVersion,this.sequence=Promise.resolve(),this.finishFromEngine()},this.enqueue=(e,t)=>{let n=this.sessionVersion,r=this.sequence.catch(()=>void 0).then(async()=>{if(n!==this.sessionVersion)throw Error(`编辑会话已结束`);let r=await e();if(n!==this.sessionVersion)throw Error(`编辑会话已结束`);return t?this.restoreInput??=this.options?.beginMouseInput?.():this.finishFromEngine(),r});return this.sequence=r,r}}startSimpleGizmoMode(e,t){return pe(this.enqueue(async()=>{let t=await this.request(`EnterSimpleGizmoMode`,e,void 0,Ee.startSimpleGizmoMode);if(t.success===!1||t.errorMsg)throw Error(t.errorMsg||`开启模型编辑失败`);return t},!0),t)}endSimpleGizmoMode(e){return pe(this.enqueue(async()=>{let e=await this.request(`ExitSimpleGizmoMode`,void 0,void 0,Ee.endSimpleGizmoMode);if(e.success===!1||e.errorMsg)throw Error(e.errorMsg||`退出模型编辑失败`);return e},!1),e)}modelSnapById(e,t){return pe(this.request(`ModelSnapById`,e,void 0,Ee.modelSnapById).then(e=>{if(e.success===!1||e.errorMsg)throw Error(e.errorMsg||`模型吸附失败`);let t=e.data??e.params,n=f(De,typeof t==`string`?JSON.parse(t):t,`GizmosTool`,`ModelSnapByIdResponse`);return{...e,params:n}}),t)}},ke=class e{constructor(e=0,t=0){this.x=e,this.y=t}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}clone(){return new e(this.x,this.y)}copy(e){return this.x=e.x,this.y=e.y,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this):this.addVectors(e,t)}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,t){return t==null?(this.x-=e.x,this.y-=e.y,this):this.subVectors(e,t)}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)}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=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this}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=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(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)}angle(){let e=Math.atan2(this.y,this.x);return e<0&&(e+=2*Math.PI),e}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}equals(e){return e.x==this.x&&e.y==this.y}toString(){return JSON.stringify(this)}};function Ae(e,t){let n=e*20037508.34/180,r=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return r=r*20037508.34/180,{x:n,y:r}}function je(e,t){let n=e/20037508.34*180,r=t/20037508.34*180;return r=180/Math.PI*(2*Math.atan(Math.exp(r*Math.PI/180))-Math.PI/2),{x:n,y:r}}const S={EPSGType:{EPSG84:`4326`,EPSGWeb:`3857`,EPSGWorld:`0000`}};var C=class e{constructor(e=0,t=0,n=0,r=S.EPSGType.EPSG84){typeof e!=`number`&&(e=this.parseFloatDeal(e)),typeof t!=`number`&&(t=this.parseFloatDeal(t)),typeof n!=`number`&&(n=this.parseFloatDeal(n)),e!=e&&(e=0),t!=t&&(t=0),n!=n&&(n=0),this.x=e,this.y=t,this.z=n,this.ePSGType=r}parseFloatDeal(e){try{return parseFloat(e)}catch(e){return console.log(e),0}}set(e,t,n){return typeof e!=`number`&&(e=0),typeof t!=`number`&&(t=0),typeof n!=`number`&&(n=0),e!=e&&(e=0),t!=t&&(t=0),n!=n&&(n=0),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}clone(){return new e(this.x,this.y,this.z)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this.z+=e.z,this):this.addVectors(e,t)}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,t){return t==null?(this.x-=e.x,this.y-=e.y,this.z-=e.z,this):this.subVectors(e,t)}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,t){return t==null?(this.x*=e.x,this.y*=e.y,this.z*=e.z,this):this.multiplyVectors(e,t)}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}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=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this}clampScalar(t,n){let r=new e,i=new e;return r.set(t,t,t),i.set(n,n,n),this.clamp(r,i)}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(Math.max(e,Math.min(t,n)))}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=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(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.subVectors(t,e).multiplyScalar(n).add(e)}cross(e,t){return t==null?this.crossVectors(this,e):this.crossVectors(e,t)}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}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}equals(e){return e.x==this.x&&e.y==this.y&&e.z==this.z}toString(){return JSON.stringify(this)}changeEPSGType(e){if(this.ePSGType!=e){if(e==S.EPSGType.EPSG84){let e=je(this.x,this.y);this.x=e.x,this.y=e.y}else if(e==S.EPSGType.EPSGWeb){let e=Ae(this.x,this.y);this.x=e.x,this.y=e.y}else console.log(`暂不支持[${this.ePSGType}]转换为${e}`);return this.ePSGType=e,this}}};const w={Off:0,Auto:1,DLAA:2,UltraQuality:3,Quality:4,Balanced:5,Performance:6,UltraPerformance:7},T={Auto:`auto`,Low:`low`,High:`high`,Super:`super`,Blue:`blue`},Me=[{label:`自动`,type:T.Auto,value:12e6},{label:`标清`,type:T.Low,value:4e6},{label:`高清`,type:T.High,value:8e6},{label:`超清`,type:T.Super,value:12e6},{label:`蓝光`,type:T.Blue,value:24e6}],Ne={[T.Auto]:12e6,[T.Low]:4e6,[T.High]:8e6,[T.Super]:12e6,[T.Blue]:24e6};let Pe=function(e){return e.VP8=`VP8`,e.VP9=`VP9`,e.AV1=`AV1`,e.H264=`H264`,e}({}),Fe=function(e){return e.Model=`MODEL`,e.POI=`POI`,e}({});const Ie={Spring:0,Summer:1,Autumn:2,Winter:3};let Le=function(e){return e[e.Linear=0]=`Linear`,e[e.EaseInQuad=1]=`EaseInQuad`,e[e.EaseOutQuad=2]=`EaseOutQuad`,e[e.EaseInOutQuad=3]=`EaseInOutQuad`,e[e.EaseOutInQuad=4]=`EaseOutInQuad`,e[e.EaseInCubic=5]=`EaseInCubic`,e[e.EaseOutCubic=6]=`EaseOutCubic`,e[e.EaseInOutCubic=7]=`EaseInOutCubic`,e[e.EaseOutInCubic=8]=`EaseOutInCubic`,e[e.EaseInQuart=9]=`EaseInQuart`,e[e.EaseOutQuart=10]=`EaseOutQuart`,e[e.EaseInOutQuart=11]=`EaseInOutQuart`,e[e.EaseOutInQuart=12]=`EaseOutInQuart`,e[e.EaseInQuint=13]=`EaseInQuint`,e[e.EaseOutQuint=14]=`EaseOutQuint`,e[e.EaseInOutQuint=15]=`EaseInOutQuint`,e[e.EaseOutInQuint=16]=`EaseOutInQuint`,e[e.EaseInSine=17]=`EaseInSine`,e[e.EaseOutSine=18]=`EaseOutSine`,e[e.EaseInOutSine=19]=`EaseInOutSine`,e[e.EaseOutInSine=20]=`EaseOutInSine`,e[e.EaseInExpo=21]=`EaseInExpo`,e[e.EaseOutExpo=22]=`EaseOutExpo`,e[e.EaseInOutExpo=23]=`EaseInOutExpo`,e[e.EaseOutInExpo=24]=`EaseOutInExpo`,e[e.EaseInCirc=25]=`EaseInCirc`,e[e.EaseOutCirc=26]=`EaseOutCirc`,e[e.EaseInOutCirc=27]=`EaseInOutCirc`,e[e.EaseOutInCirc=28]=`EaseOutInCirc`,e[e.EaseInElastic=29]=`EaseInElastic`,e[e.EaseOutElastic=30]=`EaseOutElastic`,e[e.EaseInOutElastic=31]=`EaseInOutElastic`,e[e.EaseOutInElastic=32]=`EaseOutInElastic`,e[e.EaseInBack=33]=`EaseInBack`,e[e.EaseOutBack=34]=`EaseOutBack`,e[e.EaseInOutBack=35]=`EaseInOutBack`,e[e.EaseOutInBack=36]=`EaseOutInBack`,e[e.EaseInBounce=37]=`EaseInBounce`,e[e.EaseOutBounce=38]=`EaseOutBounce`,e[e.EaseInOutBounce=39]=`EaseInOutBounce`,e[e.EaseOutInBounce=40]=`EaseOutInBounce`,e}({}),Re=function(e){return e[e.Loose=0]=`Loose`,e[e.Strict=1]=`Strict`,e}({}),ze=function(e){return e.StopAtTheEnd=`StopAtTheEnd`,e.Loop=`Loop`,e.BackAndForward=`BackAndForward`,e}({}),Be=function(e){return e.Normal=`normal`,e.Alert=`alert`,e.Offline=`offline`,e}({}),Ve=function(e){return e[e.Move=1]=`Move`,e[e.Rotate=2]=`Rotate`,e[e.Scale=3]=`Scale`,e[e.Universal=4]=`Universal`,e}({});const E=r.string().min(1),D=E.optional(),O=r.number().finite(),k=O.optional(),A=r.instanceof(C),He=r.object({x:O,y:O,z:O,ePSGType:E}),Ue=r.union([r.instanceof(ke),r.object({x:O,y:O})]),j=r.union([A,He]),We=A.optional(),Ge=j.optional(),Ke=r.union([r.literal(Ie.Spring).describe(`春季`),r.literal(Ie.Summer).describe(`夏季`),r.literal(Ie.Autumn).describe(`秋季`),r.literal(Ie.Winter).describe(`冬季`)]).describe(`场景季节`),qe=r.union([r.literal(w.Off).describe(`关闭 DLSS`),r.literal(w.Auto).describe(`自动质量档位`),r.literal(w.DLAA).describe(`DLAA 2倍效果`),r.literal(w.UltraQuality).describe(`超高质量`),r.literal(w.Quality).describe(`高质量`),r.literal(w.Balanced).describe(`平衡`),r.literal(w.Performance).describe(`性能`),r.literal(w.UltraPerformance).describe(`超高性能`)]).describe(`DLSS 质量档位`),Je=r.union([r.literal(T.Auto).describe(`自动`),r.literal(T.Low).describe(`标清`),r.literal(T.High).describe(`高清`),r.literal(T.Super).describe(`超清`),r.literal(T.Blue).describe(`蓝光`)]).describe(`渲染码率档位`),Ye=r.union([r.literal(`VP8`).describe(`VP8`),r.literal(`VP9`).describe(`VP9`),r.literal(`AV1`).describe(`AV1`),r.literal(`H264`).describe(`H264`)]).describe(`视频解码器类别`),Xe=r.union([r.literal(`MODEL`).describe(`模型图层`),r.literal(`POI`).describe(`POI 图层`)]).describe(`图层类别`),Ze=r.union([E,r.array(E).min(1)]),M=r.undefined().optional(),Qe=r.object({ids:r.array(E).min(1)}),$e=r.object({codes:r.array(E).min(1)}),N={show:Qe,hide:Qe,showByCode:$e,hideByCode:$e,showByGroup:Qe,hideByGroup:Qe,showAll:M,hideAll:M},et=r.object({parentId:r.string().optional(),id:D}),tt=e=>e.refine(e=>!!(e.id||e.timelineId),{message:`id or timelineId is required`}),nt={connect:M,disconnect:M,reconnect:M,KickOtherConnect:M,KeepConnect:M,GetEngineServiceStatus:M},P={lookAt:r.object({parentId:r.string().optional(),id:Ze,offSet:Ge,positionOffSetDistance:k,offSetX:k,distance:k,time:k,isRotate:r.boolean().optional(),isHighlight:r.boolean().optional(),showBack:r.boolean().optional()}),lookAtArray:r.object({parentId:D,ids:r.array(E).min(1),offSet:Ge,offSetX:k,distance:k,time:k,isRotate:r.boolean().optional(),isHighlight:r.boolean().optional()}),flyToTarget:r.object({point:Ge,target:Ge,fov:r.number().finite().min(10).max(150).optional(),time:k}),flyByPath:r.object({points:r.union([r.array(A),r.string()]).optional(),lookAts:r.union([r.array(A),r.string()]).optional(),nodes:r.string().optional(),time:k,smoothMode:r.union([r.literal(0),r.literal(1)]).optional()}),setFlySpeed:r.object({speed:O}),endFly:M,pauseFly:M,resumeFly:M,getCameraInfo:M,setCameraPositionAndRotation:r.object({point:A,rotation:A}),setCameraFov:r.object({fov:O}),startCameraObjFollow:r.object({parentId:r.string().optional(),id:E,offSet:j,smooth:O.optional().default(.85).refine(e=>e>=0&&e<=1,{message:`smooth must be in [0, 1]`,path:[`smooth`]})}),endCameraObjFollow:M,resetCameraFov:M,reset:M},rt={getAllSceneName:M,switchSceneByName:r.object({sceneName:E}),getCurrentSceneName:M,listenMapCompass:r.object({enable:r.boolean()}),setFeatureToggle:r.object({key:E,enabled:r.boolean()}),getSceneMeta:M},it={setVisible:r.object({parentId:r.string().optional().default(``),id:Ze,visible:r.boolean().optional()}),setVisibleResolved:r.object({parentId:r.string().optional(),ids:r.array(E).min(1),visible:r.boolean()}),setVisibleByTags:r.object({tags:Ze,visible:r.boolean()}),setVisibleByAttribute:r.object({attributes:r.record(r.string(),r.any()),filterMode:r.nativeEnum(Re).optional().default(0),visible:r.boolean().optional().default(!0),otherVisible:r.boolean().optional().default(!1)}),add:r.object({parentId:r.string().optional().default(``),id:E,assetsPath:D,position:We,angle:We,scale:We,description:r.string().optional()}),remove:r.object({parentId:r.string().optional().default(``),ids:r.array(E).min(1)}),getElementTree:r.object({parentId:r.string().optional().default(``),id:E}),getModelInfo:r.object({parentId:r.string().optional().default(``),id:E}),getModelBoundsInfo:r.object({parentId:r.string().optional().default(``),id:Ze}),getModelBoundsInfoResolved:r.object({parentId:r.string().optional(),ids:r.array(E).min(1)})},F=r.object({parentId:r.string().optional(),id:E}),at=r.object({parentId:r.string().optional(),ids:r.array(E).min(1)}),ot=F.extend({rotate:A}),I={startMoveByNodes:F.extend({nodes:r.array(j).min(1),speed:O.optional().default(1),linear:O.optional().default(1),isLookAtTarget:r.boolean().optional().default(!1),needDirection:r.boolean().optional().default(!0)}),pauseMove:F,resumeMove:F,endMove:F,restoreMove:at,rotate:ot,endRotate:F,continuedRotate:ot,rotateByTarget:F.extend({parentTargetId:D,targetID:E,point:A,axisX:O.optional().default(0),axisY:O.optional().default(0),axisZ:O.optional().default(0),angle:O.optional().default(0),isPersistence:r.boolean().optional().default(!1)}),restoreRotate:at,setScale:F.extend({scale:A,duration:O.optional().default(.5)}),endScale:F,restoreScale:at},st={enable:r.object({enable:r.boolean()}),setHighLightModel:r.object({parentId:r.string().optional().default(``),ids:r.array(E).min(1),showBack:r.boolean()}),removeHighLightModel:r.object({parentId:r.string().optional(),ids:r.array(E).min(1)}),clear:r.object({})},ct=r.object({parentId:D,id:D}),lt=e=>e.refine(e=>!!(e.id||e.parentId),{message:`id or parentId is required`}),L={addLayer:lt(ct.extend({layerName:r.string().optional(),show:r.boolean().optional(),poiEnabled:r.boolean().optional(),type:Xe.optional(),description:r.string().optional()})),addLayerResolved:r.object({parentId:r.string().optional(),id:E,layerName:r.string().optional(),show:r.boolean().optional().default(!0),poiEnabled:r.boolean().optional().default(!0),description:r.string().optional().default(``),isSystem:r.boolean().optional().default(!1),poiOffsetY:r.number().optional().default(0)}),layerSelector:lt(ct),removeLayer:lt(ct),isLayerOrGroupExit:lt(ct),layerSelectorResolved:r.object({parentId:r.string().optional().default(``),id:E}),switchModelLayer:r.object({parentId:E,ids:r.array(E).min(1),toParentId:E}),showUIPop:r.object({parentId:r.string().optional(),id:E,visible:r.boolean().optional().default(!0),assetsPath:r.string().optional().default(``),offSet:j,scale:j}),addModel:r.object({parentId:E,id:E,assetsPath:D,position:j,name:r.string().optional().default(``),rotation:j,scale:j,description:r.string().optional(),isSystem:r.boolean().optional(),tags:r.array(r.string()).optional(),extraProps:r.any().optional()}),addPOI:r.object({parentId:r.string().optional(),id:E,assetsPath:E,position:Ge,targetParentId:r.string().optional(),targetId:r.string().optional(),rotation:j,scale:j,offSet:j,description:r.string().optional(),isSystem:r.boolean().optional(),name:r.string(),fontSize:r.number().optional(),tags:r.array(r.string()).optional(),extraProps:r.any().optional()}),removeModel:r.object({parentId:E,ids:r.array(E).min(1)}),getLayerChildElement:r.object({parentId:r.string().optional().default(``),id:E}),updatePOIName:r.object({parentId:r.string().optional(),id:E,name:r.string(),updateType:r.enum([`update`,`append`,`remove`]).optional().describe(`文本更新方式:update 更新、append 追加、remove 移除,默认 update`)}),resetPOIName:r.object({parentId:r.string().optional(),ids:r.array(E).min(1).describe(`POI 对象编号集合,至少一个`)}),updatePoiStates:r.object({parentId:r.string().optional().default(``),poiStates:r.array(r.object({id:E.describe(`气泡唯一编号`),state:r.union([r.literal(`normal`).describe(`正常`),r.literal(`alert`).describe(`警告`),r.literal(`offline`).describe(`离线`)]).describe(`气泡状态`)})).min(1).describe(`需更新的气泡状态列表,至少一个`)})},R={closeCameraFog:M,getWeatherTypes:M,resetWeather:M,resetWeatherAndTime:M,openCameraFog:r.object({fogIntensity:k,fogStartColor:r.string().optional(),fogEndColor:r.string().optional(),fogStartDistance:k,fogEndDistance:k,directionalIntensity:k,directionalFallOff:k,directionalColor:r.string().optional()}).refine(e=>e.fogIntensity===void 0||e.fogIntensity>=0&&e.fogIntensity<=1,{message:`fogIntensity must be between 0 and 1`,path:[`fogIntensity`]}),setSceneTime:r.object({hour:O,timeDuration:k}).refine(e=>e.hour>=0&&e.hour<24,{message:`hour must be in [0, 24)`,path:[`hour`]}),changeWeatherType:r.object({weatherType:E,timeDuration:k}),setAnimateTimeOfDay:r.object({isAnimate:r.boolean(),dayLength:k,nightLength:k}),changeSeason:r.object({season:Ke,duration:k.describe(`切换过渡时长,单位秒`)}),resetSeason:r.object({}),setTimeSync:r.object({syncSystemTime:r.boolean()}),resetSceneTime:r.object({}),setDayAndNight:r.object({dayType:E}),setWeatherVolume:r.object({volumeOn:r.boolean().optional().default(!0).describe(`天气声音是否开启,true 开启,false 关闭,默认 true`)})},z={add:r.object({groupName:E,poiInfos:r.array(r.record(r.unknown())).min(1)}),deleteById:r.object({groupName:E,id:E}),deleteByGroup:r.object({groupName:E}),update:r.object({groupName:E,poiInfos:r.array(r.record(r.unknown())).min(1)}),updatePoiStates:r.object({parentId:E,poiStates:r.array(r.record(r.unknown())).min(1)}),enableOverlap:r.object({enable:r.boolean()}),showDistance:r.object({distance:O})},ut={add:r.object({id:E,groupName:E,assetPath:E,targetParentId:D,targetId:D,visible:r.boolean().optional()}),deleteById:r.object({groupName:E,ids:r.array(E).min(1)}),deleteByGroup:r.object({groupName:E}),getPOIInfo:r.object({groupName:E,id:E}),update:r.object({id:E,groupName:E,assetPath:D,targetParentId:D,targetId:D,visible:r.boolean().optional()}),setVisibleByGroup:r.object({groupName:E,visible:r.boolean()})},dt=r.array(r.object({groupName:E,id:E,parentId:r.string().optional().default(``),position:Ge})),ft={addPop:dt,removePop:dt,removeAll:dt,show:dt,showAll:dt,setPopDelayFrame:r.object({time:O}),setPopShowDistance:r.object({distance:O})},pt={startLoopAnimation:r.object({parentId:D,id:E,stateName:E,loopStartTime:k,loopEndTime:k,speed:k}).refine(e=>e.loopStartTime===void 0||e.loopStartTime>=0&&(e.loopEndTime===void 0||e.loopEndTime>e.loopStartTime),{message:`loopStartTime must be >= 0 and loopEndTime must be greater than loopStartTime`,path:[`loopStartTime`]}),stopLoopAnimation:r.object({parentId:D,id:E}),playAnimator:r.object({parentId:D,id:E,stateName:E,speed:k,startTime:k,endTime:k,isStop:r.boolean().optional()}),setAnimatorSpeed:r.object({parentId:D,id:E,speed:O}),getAnimationLength:r.object({parentId:D,id:E,stateName:E}),stopAnimator:r.object({parentId:D,id:E})},mt={play:tt(et.extend({initialTime:k,speed:k,keepLastFrame:r.boolean().optional()}).refine(e=>e.speed===void 0||e.speed<0||e.speed>=.1,{message:`speed must be negative or >= 0.1`,path:[`speed`]})),pause:tt(et),resume:tt(et),stop:tt(et.extend({resetTime:k,isCameraToStart:r.boolean().optional()})),stopAll:r.object({}).optional(),setSpeed:tt(et.extend({speed:O}).refine(e=>e.speed<0||e.speed>=.1,{message:`speed must be negative or >= 0.1`,path:[`speed`]}))},ht={setSceneRenderBitrate:r.object({bitrate:Je.optional()}),setSceneRenderBitrateResolved:r.object({bitrate:O}).refine(e=>e.bitrate>=1e6,{message:`bitrate must be >= 1000000`,path:[`bitrate`]}),setSceneFPS:r.object({fps:O}).refine(e=>e.fps>=1&&e.fps<=300,{message:`fps must be in [1, 300]`,path:[`fps`]}),setVideoDecode:r.object({decode:Ye}),setScreenResolution:r.object({width:O,height:O}).refine(e=>e.width>0&&e.height>0,{message:`width and height must be > 0`,path:[`width`]})},gt={setDlssEnable:r.object({enable:r.boolean(),quality:qe}),setDlss:r.object({enable:r.boolean(),quality:qe}),setDlssQuality:r.object({quality:qe})},_t=r.object({node:j,time:r.string()}),vt=r.object({parentId:r.string().optional().default(``),id:E}),yt={add:r.object({parentId:r.string().optional().default(``),id:E,assetPath:r.string().optional().default(``),scale:j,showPath:r.boolean().optional().default(!0),passedColor:r.string().optional().default(`#ffffff`),lineColor:r.string().optional().default(`#00ff00`),lineWidth:O,duration:k,nodes:r.array(j).optional(),timeNodes:r.array(_t).optional(),lineLayer:D,afterRender:r.boolean().optional().default(!1),isAutoClear:r.boolean().optional().default(!0)}),update:r.object({parentId:r.string().optional().default(``),id:E,lineColor:r.string().optional(),lineWidth:k,passedColor:r.string().optional(),speed:k}).refine(e=>e.speed===void 0||e.speed>=0,{message:`speed must be >= 0`,path:[`speed`]}),setTimeNode:r.object({parentId:r.string().optional().default(``),id:E,timeStart:r.string().optional(),startNodeIndex:r.string().optional()}).refine(e=>e.timeStart!==void 0||e.startNodeIndex!==void 0,{message:`timeStart or startNodeIndex is required`,path:[`timeStart`]}).refine(e=>e.startNodeIndex===void 0||parseInt(e.startNodeIndex)>=0,{message:`startNodeIndex must be >= 0`,path:[`startNodeIndex`]}),node:vt,pause:vt,resume:vt,stop:vt,clear:r.object({}).optional()},bt=r.object({position:j,value:O.min(0).max(999).optional().default(1)}),xt={create:r.object({parentId:r.string().optional().default(``),id:r.string().optional(),textureSize:Ue.optional().default({x:256,y:256}),mapSize:Ue.optional().default({x:1e3,y:1e3}),influenceSize:r.number().int().positive().optional().default(13),points:r.union([r.array(bt).min(1),r.array(j).min(1)]),opacity:r.number().min(0).max(1).optional().default(.7),heightScale:r.number().positive().optional().default(3.5),lerpScale:r.number().positive().optional().default(2.5),isAddAsset:r.boolean().optional().default(!1)}),remove:r.object({parentId:r.string().optional().default(``),id:r.string().optional()}),clear:M,setConfig:r.object({parentId:r.string().optional().default(``),id:r.string().optional(),opacity:r.number().min(0).max(1).optional().default(.7),heightScale:r.number().positive().optional().default(3.5),lerpScale:r.number().positive().optional().default(2.5),influenceSize:r.number().int().positive().optional().default(13)})},St={updateWebView:r.object({parentId:r.string().optional().default(``),id:E,url:E})},Ct=r.object({parentId:r.string().optional().default(``),id:r.string()}),wt=e=>e.refine(e=>{let t=e;return t.nodes!==void 0||t.targetIds!==void 0||t.targetCodes!==void 0},{message:`nodes or targetIds or targetCodes is required`,path:[`nodes`,`targetIds`,`targetCodes`]}),Tt=r.object({parentId:r.string().optional().default(``),id:r.string(),nodes:r.array(j).optional(),targetIds:r.array(E).optional(),targetCodes:r.array(E).optional(),speed:r.number().positive().optional().default(2),isCache:r.boolean().optional().default(!0),planColor:r.string().optional(),passColor:r.string().optional(),lineWidth:r.number().positive().optional().default(3),isAutoPlay:r.boolean().optional().default(!0),assetPath:r.string().optional(),isAutoClear:r.boolean().optional().default(!0),offSetZ:r.number().optional().default(.5),scale:A.default(new C(1,1,1))}),B={startNav:wt(Tt),getMeshNavDistance:wt(Tt.extend({isCache:r.boolean().optional().default(!1),isAutoPlay:r.boolean().optional().default(!1)})),pauseNav:Ct,resumeNav:Ct,stopNav:Ct,updateNav:r.object({parentId:r.string().optional().default(``),id:r.string(),speed:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()}),updateSpeed:r.object({parentId:r.string().optional().default(``),id:r.string(),speed:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()}),startNavByPath:r.object({parentId:r.string().optional().default(``),id:r.array(E).min(1),nodes:r.array(j).min(1),isCache:r.boolean().optional().default(!0),duration:r.number().positive().optional().default(10),planColor:r.string().optional(),passColor:r.string().optional()}),pauseNavPath:Ct,resumeNavPath:Ct,stopNavPath:Ct,updateNavPath:r.object({parentId:r.string().optional().default(``),id:r.array(E).min(1),duration:r.number().finite().optional().default(-1),planColor:r.string().optional(),passColor:r.string().optional()})},Et=r.array(E).min(1).describe(`查询的图层组编号集合`),Dt={layerQueryByModel:r.object({parentId:r.string().optional(),id:r.string().optional(),queryRadius:r.number().positive().optional().default(50),queryMinHeight:r.number().optional().default(0),queryMaxHeight:r.number().optional().default(20),queryParentIds:Et}),layerQueryByPosition:r.object({queryPosition:j.optional(),queryRadius:r.number().positive().optional().default(50),queryMinHeight:r.number().optional().default(0),queryMaxHeight:r.number().optional().default(20),queryParentIds:Et}),layerQueryByModelBox:r.object({parentId:r.string().optional(),id:r.string().optional(),queryParentIds:Et})},Ot={startTrain:r.object({parentId:r.string().optional(),id:E,trainCode:r.string().optional(),startStationName:r.string().optional(),endStationName:r.string().optional(),direction:r.string().optional(),action:r.string().optional(),stopTime:k,moveType:r.nativeEnum(ze).optional()}),setTrainBehavior:r.object({parentId:r.string().optional(),id:E,moveType:r.nativeEnum(ze).optional()}),setCameraFollowTrain:r.object({parentId:r.string().optional(),id:E,offSet:Ge}),setTrainVolume:r.object({parentId:r.string().optional(),id:E,volumeOn:r.boolean().optional().default(!0)}),cancelCameraFollowTrain:M},kt={},At={Connect:nt,Camera:P,Scene:rt,Layer:L,Model:it,ModelTransform:I,HighlighterEffect:st,UIPOI:z,ModelPOI:ut,Popup:ft,Animation:pt,TimeLine:mt,Screen:ht,Dlss:gt,WeatherSystem:R,PathPatrol:yt,pointIcon:N,PointEditor:Ce,GizmosTool:Ee,HeatMap:xt,WebView:St,Navigation:B,SpatialQuery:Dt,TrainSimulate:Ot};var jt=class extends x{constructor(e,t){super(e,`Animation`,t)}startLoopAnimation(e,t){let n={...e,speed:e.speed??1};return this.request(`startLoopAnimation`,n,t,pt.startLoopAnimation)}stopLoopAnimation(e,t){return this.request(`stopLoopAnimation`,e,t,pt.stopLoopAnimation)}playAnimator(e,t){let n={...e,speed:e.speed??1,startTime:e.startTime??0,endTime:e.endTime??1,isStop:e.isStop??!1};return this.request(`playAnimator`,n,t,pt.playAnimator)}setAnimatorSpeed(e,t){return this.request(`setAnimatorSpeed`,e,t,pt.setAnimatorSpeed)}getAnimationLength(e,t){return this.request(`getAnimationLength`,e,t,pt.getAnimationLength)}stopAnimator(e,t){return this.request(`stopAnimator`,e,t,pt.stopAnimator)}},Mt=class extends x{constructor(e,t){super(e,`CameraService`,t)}lookAt(e,t){let n={...e,time:e.time??1.5,distance:e.distance??20,isRotate:e.isRotate??!0,isHighlight:e.isHighlight??!0,offSet:e.offSet??new C(50,150,100)};if(n.offSet&&(n.offSet.ePSGType=`0000`),Array.isArray(n.id)){let e={parentId:n.parentId,ids:n.id,offSet:n.offSet,offSetX:n.offSetX,distance:n.distance,time:n.time,isRotate:n.isRotate,isHighlight:n.isHighlight};return this.request(`LookAtArray`,e,t,P.lookAtArray)}return this.request(`LookAt`,n,t,P.lookAt)}flyToTarget(e,t){let n={...e,time:e.time??2};return this.request(`FlyToTarget`,n,t,P.flyToTarget)}flyByPath(e,t){let n=Array.isArray(e.points)?JSON.stringify(e.points):e.points,r=Array.isArray(e.lookAts)?JSON.stringify(e.lookAts):e.lookAts,i={...e,points:n,lookAts:r,nodes:JSON.stringify(e.points),time:e.time??4,smoothMode:e.smoothMode??0};return this.request(`flyByPath`,i,t,P.flyByPath)}setFlySpeed(e,t){return this.request(`setFlySpeed`,e,t,P.setFlySpeed)}endFly(e){return this.request(`endFly`,void 0,e,M)}pauseFly(e){return this.request(`pauseFly`,void 0,e,M)}resumeFly(e){return this.request(`resumeFly`,void 0,e,M)}getCameraInfo(e){return this.request(`GetCameraInfo`,void 0,e,M)}setCameraPositionAndRotation(e,t){return e.rotation&&(e.rotation.ePSGType=`0000`),this.request(`setCameraPositionAndRotation`,e,t,P.setCameraPositionAndRotation)}setCameraFov(e,t){return this.request(`setCameraFov`,e,t,P.setCameraFov)}resetCameraFov(e){return this.request(`resetCameraFov`,void 0,e,M)}reset(e){return this.request(`reset`,void 0,e,M)}startCameraObjFollow(e,t){e.offSet&&(e.offSet.ePSGType=`0000`);let n={...e,offSet:e.offSet??new C(-30,0,10,`0000`)};return this.request(`StartCameraObjFollow`,n,t,P.startCameraObjFollow)}endCameraObjFollow(e){return this.request(`EndCameraObjFollow`,void 0,e,M)}},Nt=class extends x{constructor(e,t,n){super(e,`Connect`,n),this.connectionLifecycle=t}connect(e){return pe(Promise.resolve().then(()=>(this.logger.warn(`connect called as compatibility API; SDK auto-connects after DTCEngine init`),this.connectionLifecycle.connect().then(()=>({requestId:``,success:!0,code:`CONNECT_OK`,message:`Connect requested (compatibility path)`,ts:Date.now()})))),e)}disconnect(e){return pe(Promise.resolve().then(()=>(this.logger.info(`disconnect requested`),Promise.resolve(this.connectionLifecycle.disconnect()).then(()=>({requestId:``,success:!0,code:`DISCONNECT_OK`,message:`Disconnected`,ts:Date.now()})))),e)}reconnect(e){return pe(Promise.resolve().then(()=>(this.logger.info(`reconnect requested`),this.connectionLifecycle.reconnect().then(()=>({requestId:``,success:!0,code:`RECONNECT_OK`,message:`Reconnect requested`,ts:Date.now()})))),e)}KickOtherConnect(e){return this.request(`KickOtherConnect`,void 0,e,M)}KeepConnect(e){return this.request(`KeepConnect`,void 0,e,M)}GetEngineServiceStatus(e){return this.request(`GetEngineServiceStatus`,void 0,e,M)}},Pt=class extends x{constructor(e,t){super(e,`DLSSService`,t)}setDlss(e={},t){let n={enable:e.enable??!1,quality:e.quality??w.Balanced};return this.request(`SetDlss`,n,t,gt.setDlss)}},Ft=class extends x{constructor(e,t){super(e,`HeatMapService`,t)}create(e,t){let n={...e,opacity:e.opacity??.7,heightScale:e.heightScale??3.5,lerpScale:e.lerpScale??2.5,influenceSize:e.influenceSize??13,points:e.points.map(e=>`position`in e?e:{position:e,value:1})};return n.heightScale*=100,this.request(`CreateHeatMap`,n,t,xt.create)}remove(e,t){return this.request(`RemoveHeatMap`,e,t,xt.remove)}clear(e){return this.request(`ClearHeatMap`,void 0,e,xt.clear)}setConfig(e,t){let n={...e,opacity:e.opacity??.7,heightScale:e.heightScale??3.5,lerpScale:e.lerpScale??2.5,influenceSize:e.influenceSize??13};return n.heightScale*=100,this.request(`SetHeatMapConfig`,n,t,xt.setConfig)}},It=class extends x{constructor(e,t){super(e,`HighLighterService`,t)}enable(e,t){return this.request(`HighlightEnable`,e,t,st.enable)}setHighLightModel(e,t){return this.request(`AddHighLighterModel`,e,t,st.setHighLightModel)}removeHighLightModel(e,t){return this.request(`RemoveHighLightModel`,e,t,st.removeHighLightModel)}clear(e){return this.request(`Clear`,{},e,st.clear)}},Lt=class e{constructor(e=0,t=0,n=0,r=0,i=S.EPSGType.EPSG84){this.x=e,this.y=t,this.z=n,this.v=r,this.EPSGType=i}set(e,t,n,r){return this.x=e,this.y=t,this.z=n,this.v=r,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}clone(){return new e(this.x,this.y,this.z,this.v)}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this.v=e.v,this}add(e,t){return t==null?(this.x+=e.x,this.y+=e.y,this.z+=e.z,this.v+=e.v,this):this.addVectors(e,t)}addScalar(e){return this.x+=e,this.y+=e,this.z+=e,this.v+=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.v=e.v+t.v,this}addScaledVector(e,t){return this.x+=e.x*t,this.y+=e.y*t,this.z+=e.z*t,this.v+=e.v*t,this}sub(e,t){return t==null?(this.x-=e.x,this.y-=e.y,this.z-=e.z,this.v-=e.v,this):this.subVectors(e,t)}subScalar(e){return this.x-=e,this.y-=e,this.z-=e,this.v-=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.v=e.v-t.v,this}multiply(e,t){return t==null?(this.x*=e.x,this.y*=e.y,this.z*=e.z,this.v*=e.v,this):this.multiplyVectors(e,t)}multiplyScalar(e){return this.x*=e,this.y*=e,this.z*=e,this.v*=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.v=e.v*t.v,this}divide(e){return this.x/=e.x,this.y/=e.y,this.z/=e.z,this.v/=e.v,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.v=Math.min(this.v,e.v),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.v=Math.max(this.v,e.v),this}clamp(e,t){return this.x=Math.max(e.x,Math.min(t.x,this.x)),this.y=Math.max(e.y,Math.min(t.y,this.y)),this.z=Math.max(e.z,Math.min(t.z,this.z)),this.v=Math.max(e.v,Math.min(t.v,this.v)),this}clampScalar(t,n){let r=new e,i=new e;return r.set(t,t,t,t),i.set(n,n,n,n),this.clamp(r,i)}clampLength(e,t){let n=this.length();return this.divideScalar(n||1).multiplyScalar(Math.max(e,Math.min(t,n)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this.v=Math.floor(this.v),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this.v=Math.ceil(this.v),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this.v=Math.round(this.v),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this.v=this.v<0?Math.ceil(this.v):Math.floor(this.v),this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.v*e.v}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z+this.v*this.v}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.v*this.v)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.v)}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.v+=(e.v-this.v)*t,this}lerpVectors(e,t,n){return this.subVectors(t,e).multiplyScalar(n).add(e)}cross(e,t){return t==null?this.crossVectors(this,e):this.crossVectors(e,t)}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}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,i=this.v-e.v;return t*t+n*n+r*r+i*i}equals(e){return e.x==this.x&&e.y==this.y&&e.z==this.z&&e.v==this.v}toString(){return JSON.stringify(this)}changeEPSGType(e){if(this.EPSGType!=e){if(e==S.EPSGType.EPSG84){let e=je(this.x,this.y);this.x=e.x,this.y=e.y}else if(e==S.EPSGType.EPSGWeb){let e=Ae(this.x,this.y);this.x=e.x,this.y=e.y}else console.log(`暂不支持[${this.EPSGType}]转换为${e}`);return this.EPSGType=e,this}}},Rt=class{constructor(){this.Vector2=ke,this.Vector3=C,this.Vector4=Lt}},zt=class extends x{constructor(e,t){super(e,`LayerService`,t)}addLayer(e,t){let n={...e,show:e.show??!0,poiEnabled:e.poiEnabled??!0,isSystem:e.isSystem??!1,poiOffsetY:e.poiOffsetY??0};return this.request(`AddLayer`,n,t,L.addLayerResolved)}removeLayer(e,t){let n={...e};return this.request(`RemoveLayer`,n,t,L.layerSelectorResolved)}isLayerOrGroupExit(e,t){let n={...e};return this.request(`IsLayerOrGroupExit`,n,t,L.layerSelectorResolved)}switchModelLayer(e,t){return this.request(`SwitchLayer`,e,t,L.switchModelLayer)}showUIPop(e,t){let n={...e,id:e.id.trim(),visible:e.visible??!0,assetsPath:e.assetsPath??`/Game/Resources/POIS/BluePrints/BP_Camera.uasset`,scale:e.scale??new C(1,1,1),offSet:e.offSet??new C(0,0,0)};return n.scale&&(n.scale.ePSGType=`0000`),n.offSet&&(n.offSet.ePSGType=`0000`),console.log(n),this.request(`ShowLayerUIPop`,n,t,L.showUIPop)}addModel(e,t){let n={...e,id:e.id.trim(),name:e.name?.trim()||``,scale:e.scale??new C(1,1,1),rotation:e.rotation??new C(0,0,0)};return n.extraProps&&=JSON.stringify(n.extraProps),n.scale&&(n.scale.ePSGType=`0000`),n.rotation&&(n.rotation.ePSGType=`0000`),this.request(`AddModel`,n,t,L.addModel)}addPOI(e,t){let n={...e,id:e.id.trim(),scale:e.scale??new C(1,1,1),rotation:e.rotation??new C(0,0,0),fontSize:e.fontSize??16,isSystem:e.isSystem??!1,name:e.name??``,targetParentId:e.targetParentId??``,targetId:e.targetId??``,offSet:e.offSet??new C(0,0,0)};return n.extraProps=n.extraProps?JSON.stringify(n.extraProps):`{}`,n.scale&&(n.scale.ePSGType=`0000`),n.rotation&&(n.rotation.ePSGType=`0000`),n.offSet&&(n.offSet.ePSGType=`0000`),this.request(`AddPOI`,n,t,L.addPOI)}updatePOIName(e,t){let n={...e,id:e.id.trim(),updateType:e.updateType??`update`};return this.request(`UpdatePOIName`,n,t,L.updatePOIName)}resetPOIName(e,t){return this.request(`ResetPOIName`,e,t,L.resetPOIName)}updatePoiStates(e,t){return this.request(`UpdatePOIState`,e,t,L.updatePoiStates)}removeModel(e,t){return this.request(`RemoveModelByIds`,e,t,L.removeModel)}getLayerChildElement(e,t){return this.request(`GetLayerChildElements`,e,t,L.getLayerChildElement)}},Bt=class extends x{constructor(e,t){super(e,`ModelService`,t)}toIdArray(e){return Array.isArray(e)?e:[e]}setVisible(e,t){let n={parentId:e.parentId,ids:this.toIdArray(e.id),visible:e.visible??!0};return this.request(`SetVisible`,n,t,it.setVisibleResolved)}setVisibleByTags(e,t){let n={tags:this.toIdArray(e.tags),visible:e.visible??!0};return this.request(`SetVisibleByTags`,n,t,it.setVisibleByTags)}setVisibleByAttribute(e,t){let n={attributes:e.attributes,filterMode:e.filterMode??0,visible:e.visible??!0,otherVisible:e.otherVisible??!1};return this.request(`SetVisibleByAttribute`,n,t,it.setVisibleByAttribute)}getElementTree(e,t){return this.request(`GetElementTree`,e,t,it.getElementTree)}getModelInfo(e,t){return this.request(`GetModelInfo`,e,t,it.getModelInfo)}},Vt=class extends x{constructor(e,t){super(e,`ModelPOI`,t)}add(e,t){let n={...e,visible:e.visible??!0};return this.request(`add`,n,t,ut.add)}deleteById(e,t){return this.request(`deleteById`,e,t,ut.deleteById)}deleteByGroup(e,t){return this.request(`deleteByGroup`,e,t,ut.deleteByGroup)}getPOIInfo(e,t){return this.request(`getPOIInfo`,e,t,ut.getPOIInfo)}update(e,t){let n={...e,visible:e.visible??!0};return this.request(`update`,n,t,ut.update)}setVisibleByGroup(e,t){return this.request(`setVisibleByGroup`,e,t,ut.setVisibleByGroup)}},Ht=class extends x{constructor(e,t){super(e,`ModelTransformService`,t)}startMoveByNodes(e,t){return this.request(`StartMoveByNodes`,e,t,I.startMoveByNodes)}pauseMove(e,t){return this.request(`PauseMove`,e,t,I.pauseMove)}resumeMove(e,t){return this.request(`ResumeMove`,e,t,I.resumeMove)}endMove(e,t){return this.request(`EndMove`,e,t,I.endMove)}restoreMove(e,t){return this.request(`RestoreMove`,e,t,I.restoreMove)}rotate(e,t){return e.rotate.ePSGType=S.EPSGType.EPSGWorld,this.request(`StartRotate`,e,t,I.rotate)}endRotate(e,t){return this.request(`EndRotate`,e,t,I.endRotate)}continuedRotate(e,t){return e.rotate.ePSGType=S.EPSGType.EPSGWorld,this.request(`ContinuedRotate`,e,t,I.continuedRotate)}rotateByTarget(e,t){return this.request(`RotateByTarget`,e,t,I.rotateByTarget)}restoreRotate(e,t){return this.request(`RestoreRotate`,e,t,I.restoreRotate)}setScale(e,t){e.scale.ePSGType=S.EPSGType.EPSGWorld;let n={...e,id:e.id.trim()};return n.scale&&(n.scale.ePSGType=`0000`),this.request(`SetScale`,n,t,I.setScale)}endScale(e,t){return this.request(`EndScale`,e,t,I.endScale)}restoreScale(e,t){return this.request(`RestoreScale`,e,t,I.restoreScale)}},Ut=class extends x{constructor(e,t){super(e,`NavigationService`,t)}startNav(e,t){let n={...e,scale:e.scale??new C(1,1,1)};return n.scale&&(n.scale.ePSGType=`0000`),this.request(`PlayMeshNavByNodes`,n,t,B.startNav)}getMeshNavDistance(e,t){return this.request(`PlayMeshNavByNodes`,e,t,B.getMeshNavDistance)}pauseNav(e,t){return this.request(`PauseMeshNav`,e,t,B.pauseNav)}resumeNav(e,t){return this.request(`ResumeMeshNav`,e,t,B.resumeNav)}stopNav(e,t){return this.request(`StopMeshNav`,e,t,B.resumeNav)}updateNav(e,t){return this.request(`UpdateMeshNavProperty`,e,t,B.updateNav)}updateSpeed(e,t){return this.request(`UpdateNavSpeed`,e,t,B.updateSpeed)}startNavByPath(e,t){return this.request(`StartNavByPath`,e,t,B.startNavByPath)}pauseNavPath(e,t){return this.request(`PauseNavPath`,e,t,B.pauseNavPath)}resumeNavPath(e,t){return this.request(`ResumeNavPath`,e,t,B.resumeNavPath)}stopNavPath(e,t){return this.request(`StopNavPath`,e,t,B.stopNavPath)}updateNavPath(e,t){return this.request(`UpdateNavPathProperty`,e,t,B.updateNavPath)}},Wt=class extends x{constructor(e,t){super(e,`PathPatrolService`,t)}add(e,t){return e.scale&&(e.scale.ePSGType=S.EPSGType.EPSGWorld),this.requestStream(`AddPath`,e,t,yt.add)}update(e,t){return this.request(`UpdatePath`,e,t,yt.update)}setTimeNode(e,t){return this.request(`CuriserTimeSet`,e,t,yt.setTimeNode)}clear(e){return this.request(`ClearPath`,void 0,e,yt.clear)}pause(e,t){return this.request(`Pause`,e,t,yt.node)}resume(e,t){return this.request(`Resume`,e,t,yt.node)}stop(e,t){return this.request(`Stop`,e,t,yt.node)}};function Gt(e){return Array.isArray(e)?{ids:e}:e}function Kt(e){return Array.isArray(e)?{codes:e}:e}var qt=class extends x{constructor(e,t){super(e,`PointIcon`,t)}show(e,t){return this.request(`Show`,Gt(e),t,N.show)}hide(e,t){return this.request(`Hide`,Gt(e),t,N.hide)}showByCode(e,t){return this.request(`ShowByCode`,Kt(e),t,N.showByCode)}hideByCode(e,t){return this.request(`HideByCode`,Kt(e),t,N.hideByCode)}showByGroup(e,t){return this.request(`ShowByGroup`,Gt(e),t,N.showByGroup)}hideByGroup(e,t){return this.request(`HideByGroup`,Gt(e),t,N.hideByGroup)}showAll(e){return this.request(`ShowAll`,void 0,e,N.showAll)}hideAll(e){return this.request(`HideAll`,void 0,e,N.hideAll)}};function Jt(e,t){let n=e.getBoundingClientRect(),r=e.ownerDocument.defaultView.getComputedStyle(e);if(n.width<=0||n.height<=0||e.videoWidth<=0||e.videoHeight<=0)throw Error(`视频尚未就绪,无法计算点位落点`);for(let t=e;t;t=t.parentElement){let n=e.ownerDocument.defaultView.getComputedStyle(t).transform;if(!n||n===`none`)continue;let r=n.startsWith(`matrix(`)?n.slice(7,-1).split(`,`).map(Number):[];if(r.length!==6||r[1]!==0||r[2]!==0||r[0]<=0||r[3]<=0)throw Error(`点位拾取暂不支持旋转、翻转或 3D 变换的视频元素`)}let i=n.width/(e.offsetWidth||n.width),a=n.height/(e.offsetHeight||n.height),o=(parseFloat(r.borderLeftWidth)||0)+(parseFloat(r.paddingLeft)||0),s=(parseFloat(r.borderTopWidth)||0)+(parseFloat(r.paddingTop)||0),c=n.width-i*(o+(parseFloat(r.borderRightWidth)||0)+(parseFloat(r.paddingRight)||0)),l=n.height-a*(s+(parseFloat(r.borderBottomWidth)||0)+(parseFloat(r.paddingBottom)||0)),u=t.clientX-n.left-o*i,d=t.clientY-n.top-s*a;if(c<=0||l<=0||u<0||u>c||d<0||d>l)throw Error(`落点不在视频区域内`);let f=r.objectFit||`fill`,p=c,m=l;if(f!==`fill`){let t=f===`cover`?Math.max(c/i/e.videoWidth,l/a/e.videoHeight):f===`none`?1:Math.min(c/i/e.videoWidth,l/a/e.videoHeight),n=f===`scale-down`?Math.min(1,t):t;p=e.videoWidth*n*i,m=e.videoHeight*n*a}let h=(r.objectPosition||`50% 50%`).split(/\s+/);if(h.length!==2)throw Error(`暂不支持当前视频的 object-position 写法`);function g(e,t,n){if(e===`center`)return t/2;if(e===`left`||e===`top`)return 0;if(e===`right`||e===`bottom`)return t;if(/^-?[\d.]+%$/.test(e))return parseFloat(e)*t/100;if(/^-?[\d.]+px$/.test(e))return parseFloat(e)*n;throw Error(`暂不支持当前视频的 object-position 写法`)}let _={x:(u-g(h[0],c-p,i))/p,y:(d-g(h[1],l-m,a))/m};if(_.x<0||_.x>1||_.y<0||_.y>1)throw Error(`落点位于视频黑边,不在实际图像内`);return _}var Yt=class{constructor(e){this.getVideo=e}cancel(){this.cancelPending?.()}pick(){if(this.cancelPending)return Promise.reject(Error(`已有点位放置操作,请先取消或完成`));let e=this.getVideo();return e?new Promise((t,n)=>{let r=e.style.cursor,i,a=()=>{l.forEach(t=>e.removeEventListener(t,c,!0)),e.ownerDocument.removeEventListener(`keydown`,s,!0),e.ownerDocument.defaultView?.removeEventListener?.(`blur`,o),e.style.cursor=r,this.cancelPending=void 0},o=()=>{a(),n(Error(`点位放置已取消`))},s=e=>{e.key===`Escape`&&(e.preventDefault(),e.stopImmediatePropagation(),o())},c=r=>{let s=r;if(s.button===0||s.button===2){if(s.preventDefault(),s.stopImmediatePropagation(),s.type===`contextmenu`){o();return}if((s.type===`pointerdown`||s.type===`mousedown`)&&s.button===0&&(i={x:s.clientX,y:s.clientY}),!(s.type!==`click`||s.button!==0||!i)){if(Math.hypot(s.clientX-i.x,s.clientY-i.y)>4){i=void 0;return}try{let n=Jt(e,{clientX:s.clientX,clientY:s.clientY});a(),t(n)}catch(e){a(),n(e)}}}},l=[`pointerdown`,`pointerup`,`mousedown`,`mouseup`,`click`,`contextmenu`];this.cancelPending=o,e.style.cursor=`crosshair`,l.forEach(t=>e.addEventListener(t,c,{capture:!0,passive:!1})),e.ownerDocument.addEventListener(`keydown`,s,!0),e.ownerDocument.defaultView?.addEventListener?.(`blur`,o)}):Promise.reject(Error(`未找到 Pixel Streaming 视频元素`))}},Xt=class extends x{constructor(e,t){let n={version:0};super({async sendRequest(t,r,i){let{__placementVersion:a,...o}=i??{};if(a!==void 0&&a!==n.version)throw Error(`点位放置已取消`);let s=await e.sendRequest(t,r,{...o,editorSource:`sdk3`});if(s.success===!1||s.errorMsg)throw Error(s.errorMsg||s.message||`点位操作失败`);if(r===`DeletePoints`){let e=s.data??s.params,t=typeof e==`string`?JSON.parse(e):e;return{...s,params:f(Te,t,`PointEditor`,`DeletePointsResponse`)}}return s}},`PointEditorService`,t),this.createPoint=(e,t,n)=>{let r=this.placementState.version,i=Promise.resolve().then(async()=>{if(r!==this.placementState.version)throw Error(`点位放置已取消`);let t=f(Ce[n],e,`PointEditor`,n),{screenPosition:i,...a}=t,o=t.position?void 0:i??await this.placement.pick();if(r!==this.placementState.version)throw Error(`点位放置已取消`);return this.request(o?`AddPointAtScreen`:`AddPoint`,{__placementVersion:r,...a,...o?{screenPosition:o}:{},resource:{...t.resource,type:`MODEL`},show:t.show??!0,poiEnabled:t.poiEnabled??!0,poiScaleFactor:t.poiScaleFactor??1,poiOffsetY:t.poiOffsetY??0,poiShowName:t.poiShowName??!0,extraProps:t.extraProps??{},rotation:t.rotation??{x:0,y:0,z:0},scale:t.scale??{x:1,y:1,z:1}})}).then(t=>{let n=t.data??t.params,r=typeof n==`string`?JSON.parse(n):n,i=f(we,r,`PointEditor`,`AddPointResponse`);if(i.id!==e.id.trim()||i.parentId!==e.parentId.trim())throw Error(`UE 返回的点位与本次创建目标不一致`);return i});return t&&i.then(t,e=>t(e instanceof Error?e:Error(String(e)))).catch(e=>this.logger.warn(`point callback failed`,{error:String(e)})),i},this.placementState=n,this.getVideo=t?.getVideoElement??(()=>null),this.placement=new Yt(this.getVideo)}addPoint(e,t){return this.createPoint(e,t,`addPoint`)}addPointByDrag(e,t){return this.createPoint(e,t,`addPointByDrag`)}getScreenPosition(e){let t=f(Ce.getScreenPosition,e,`PointEditor`,`getScreenPosition`),n=this.getVideo();if(!n)throw Error(`未找到 Pixel Streaming 视频元素`);return Jt(n,t)}cancelPlacement(){return++this.placementState.version,this.placement.cancel(),Promise.resolve()}updatePoint(e,t){return this.request(`UpdatePoint`,e,t,Ce.updatePoint)}deletePoints(e,t){return this.request(`DeletePoints`,e,t,Ce.deletePoints)}},Zt=class{static getUUID(e=11){let t=16,n=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`.split(``),r=[],i;if(t||=n.length,e)for(i=0;i<e;i++)r[i]=n[0|Math.random()*t];else{let e;for(r[8]=r[13]=r[18]=r[23]=`-`,r[14]=`4`,i=0;i<36;i++)r[i]||(e=0|Math.random()*16,r[i]=n[i==19?e&3|8:e])}return`U`+r.join(``)}static warn(e,t=!1){console.log(`warn`,e,t);let n=document.createElement(`div`);return n.innerHTML=e,document.body.appendChild(n),n.setAttribute(`id`,`engineWarnTips`),n.style.cssText=`
2
2
  pointer-events: none;
3
3
  padding: 10px 40px;
4
4
  letter-spacing: 1px;
@@ -34,7 +34,7 @@ import{EventEmitter as e,LogLevel as t,Logger as n}from"@epicgames-ps/lib-pixels
34
34
  color: rgb(255, 255, 255);
35
35
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
36
36
  z-index:999;
37
- `,n.style.left=`calc(50vw - ${n.offsetWidth/2}px)`,n.style.left=`calc( - ${n.offsetWidth/2}px+50vw)`,n.style.transition=`top 250ms ease-out`,n.style.top=`440px`,t||window.setTimeout(()=>{document.body.removeChild(n)},15e3),n}static removeLoadingTokenWillExpireDiv(){let e=document.getElementById(`TokenWillExpireTips`);e&&document.body.removeChild(e)}static stopEvents(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()}static degToRad(e){return e*Math.PI/180}static WGS84ToMercator(e,t){let n=e*20037508.34/180,r=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return r=r*20037508.34/180,{x:n,y:r}}static MercatorToWGS84(e,t){let n=e/20037508.34*180,r=t/20037508.34*180;return r=180/Math.PI*(2*Math.atan(Math.exp(r*Math.PI/180))-Math.PI/2),{x:n,y:r}}static isPC(){let e=navigator.userAgent,t=[`Android`,`iPhone`,`SymbianOS`,`Windows Phone`,`iPad`,`iPod`],n=!0;for(let r=0;r<t.length;r++)if(e.indexOf(t[r])>0){n=!1;break}return n}static getTotalPage(e,t=50){let n=0,r=e/t;return n=e/t>parseInt(r+``)?parseInt(r+``)+1:parseInt(r+``),n}static{this.isEmpty=e=>e===null||e===``||e===void 0||e.length===0}static getValueOrDefault(e,t,n){return e[t]==null?e[t]=n:e[t]}static dynamicAddCrossAccess(){let e=document.head||document.getElementsByTagName(`head`)[0];function t(){let e=document.getElementsByTagName(`meta`);for(let t=0;t<e.length;t++)if(e[t].getAttribute(`http-equiv`)===`Access-Control-Allow-Origin`&&e[t].getAttribute(`content`)===`*`)return!0;return!1}if(!t()){let t=document.createElement(`meta`);t.setAttribute(`http-equiv`,`Access-Control-Allow-Origin`),t.setAttribute(`content`,`*`),e.appendChild(t)}}static GetAxios(e,t,n){i.defaults.headers.common[`content-Type`]=`application/json;charset=UTF-8`,i.get(e,n).then(function(e){t&&t(e)}).catch(function(e){e.response||(e.request?console.log(e.request):console.error(`Error`,e.message))})}static IsValidHexColor(e){return e=e.replace(/^#/,``),e.length!==3&&e.length!==6?!1:/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(e)}static calculatePercentage(e,t){return(e/t*100).toFixed(2)}static getCurrentTimeFormatted(){let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}`}static CalTimeDifferToHHMMSS(e){Math.floor(e/864e5);let t=e%864e5,n=Math.floor(t/36e5).toString().padStart(2,`0`),r=t%36e5,i=Math.floor(r/6e4).toString().padStart(2,`0`),a=r%6e4;return`${n}:${i}:${Math.round(a/1e3).toString().padStart(2,`0`)}`}static isNumeric(e){return!isNaN(parseFloat(e))&&!isNaN(e)}},Xt=class{constructor(e){this.pops={},this.def=`VEC_POP`,this.maxShowDistance=2e4,this.syncPopsHandler=e=>{this.SyncPops(e)},this.started=!1,this.dtcEngine=e,this.hostElement=e.getEngineConfig().dom,this.start()}start(){this.started||=(this.dtcEngine.on(`SyncPops`,this.syncPopsHandler),!0)}dispose(){this.started&&=(this.dtcEngine.off(`SyncPops`,this.syncPopsHandler),!1)}SyncPops(e){let t=JSON.parse(e.param??`[]`);Object.keys(this.pops).length!=0&&t.forEach(e=>{if(this.pops[e.groupName]&&this.pops[e.groupName][e.id]){let t=this.pops[e.groupName][e.id];t!=null&&(t.visible&&e.visible&&e.distance<this.maxShowDistance?t.showOnly(e.x,e.y,e.distance):t.disableOnly())}})}Set(e,t){e??=this.def,this.pops[e]||(this.pops[e]={}),t?.forEach(t=>{this.pops[e][t.id]||(this.pops[e][t.id]=t)})}RemovePop(e,t){e??=this.def,this.pops[e]&&(t==null?(Object.keys(this.pops[e]).map(t=>{if(this.pops[e]&&this.pops[e][t]){let n=this.pops[e][t];n&&n.dispose()}}),delete this.pops[e]):t.forEach(t=>{if(this.pops[e]&&this.pops[e][t]){let n=this.pops[e][t];n&&(n.dispose(),delete this.pops[e][t])}}))}RemoveAll(){Object.keys(this.pops).map(e=>{Object.keys(this.pops[e]).map(t=>{let n=this.pops[e][t];n&&n.dispose()}),delete this.pops[e]})}Switch(e,t,n){t??=this.def,this.pops[t]&&(n?n.forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable(),r.visible=e)}):Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable(),r.visible=e)}))}SwitchAll(e){Object.keys(this.pops).forEach(t=>{Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable())})})}SendNeedSyncPopsInfo(){let e=[];return Object.keys(this.pops).forEach(t=>{Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r.visible&&e.push({groupName:t,id:r.id,parentId:r.parentId,position:r.position})})}),e}},Zt=class{constructor(e,t,n,r,i,a,o=0,s=0){this.id=t,this.parentId=a,this.div=n,[`mousedown`,`mouseup`,`mousemove`,`click`,`dblclick`,`contextmenu`,`wheel`,`touchstart`,`touchmove`,`touchend`,`touchcancel`].forEach(e=>{this.div?.addEventListener(e,t=>{t.stopPropagation(),(e===`contextmenu`||e===`wheel`)&&t.preventDefault()})}),this.position=i,this.offSetX=o,this.offSetY=s,this.outDistance=!1,this.visible=r??!0,this.videoDom=e,this.div&&(this.div.style.userSelect=`none`,this.div.style.touchAction=`none`,this.div.style.left=`-9999px`,this.div.style.top=`-9999px`,this.videoDom.appendChild(this.div))}showOnly(e,t,n){let r=this.videoDom.getBoundingClientRect(),i=r.left,a=r.top,o=this.offSetY;this.div.style.left=e+this.offSetX+i+`px`,this.div.style.top=t+o+a+`px`,this.div.style.display=`block`,this.div.style.position=`absolute`}disableOnly(){this.div.style.left=`-9999px`,this.div.style.top=`-9999px`,this.div.style.display=`none`}show(e,t){this.visible=!0,this.showOnly(e,t)}disable(){this.visible=!1,this.disableOnly()}dispose(){this.videoDom.contains(this.div)&&this.videoDom.removeChild(this.div)}},Qt=class extends x{constructor(e,t,n){super(e,`WebPopService`,n),this.popupManager=t}addPop(e,t){let n=(e.popInfo??[]).map(e=>{let t=Yt.getValueOrDefault(e,`offSetX`,0),n=Yt.getValueOrDefault(e,`offSetY`,0);return new Zt(this.popupManager.hostElement,e.id,e.div,e.visible,e.position,e.parentId,t,n)});return this.popupManager.Set(e.groupName,n),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ut.addPop)}removePop(e={},t){return this.popupManager.RemovePop(e.groupName,e.ids),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ut.removePop)}removeAll(e){return this.popupManager.RemoveAll(),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),e,ut.removeAll)}show(e,t){let n=Yt.getValueOrDefault(e,`show`,!0);return this.popupManager.Switch(n,e.groupName,e.ids),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ut.show)}showAll(e=!0,t){return this.popupManager.SwitchAll(e),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ut.showAll)}setPopDelayFrame(e,t){return this.request(`SetPopDelayFrame`,e,t,ut.setPopDelayFrame)}setPopShowDistance(e){if(e==null||typeof e!=`number`){console.log(`请检查传入参数,参见接口说明`);return}this.popupManager.maxShowDistance=e}},$t=class extends x{constructor(e,t){super(e,`WebScreenService`,t)}setSceneRenderBitrate(e={},t){let n=typeof e.bitrate==`number`?{bitrate:e.bitrate}:{bitrate:Me[f(pt.setSceneRenderBitrate,e,this.moduleName,`SetSceneRenderBitrate`).bitrate??T.High]};return this.request(`SetSceneRenderBitrate`,n,t,pt.setSceneRenderBitrateResolved)}setSceneFPS(e={},t){let n={fps:e.fps??150};return this.request(`SetSceneRenderFPS`,n,t,pt.setSceneFPS)}setScreenResolution(e={},t){let n={width:e.width??1920,height:e.height??1080};return this.request(`SetScreenResolution`,n,t,pt.setScreenResolution)}},en=class extends x{constructor(e,t){super(e,`Scene`,t)}getAllSceneName(e){return this.request(`getAllSceneName`,void 0,e,tt.getAllSceneName)}switchSceneByName(e,t){return this.request(`switchSceneByName`,e,t,tt.switchSceneByName)}getCurrentSceneName(e){return this.request(`getCurrentSceneName`,void 0,e,tt.getCurrentSceneName)}listenMapCompass(e,t){return this.request(`listenMapCompass`,e,t,tt.listenMapCompass)}setFeatureToggle(e,t){return this.request(`setFeatureToggle`,e,t,tt.setFeatureToggle)}getSceneMeta(e){return this.request(`getSceneMeta`,void 0,e,M)}},tn=class extends x{constructor(e,t){super(e,`SpatialQueryService`,t)}layerQueryByModel(e,t){let n={...e,queryRadius:e.queryRadius||50,queryMinHeight:e.queryMinHeight||0,queryMaxHeight:e.queryMaxHeight||20,queryParentIds:e.queryParentIds||[]};return n.id===void 0?(Yt.warn(`操作失败:id不能为空`),Promise.reject(`id is empty`)):this.request(`LayerQueryByModel`,n,t,Tt.layerQueryByModel)}layerQueryByPosition(e,t){let n={...e,queryRadius:e.queryRadius||20,queryMinHeight:e.queryMinHeight||0,queryMaxHeight:e.queryMaxHeight||20,queryParentIds:e.queryParentIds||[]};return n.queryPosition===void 0?(Yt.warn(`操作失败:queryPosition不能为空`),Promise.reject(`queryPosition is empty`)):this.request(`LayerQueryByPosition`,n,t,Tt.layerQueryByPosition)}layerQueryByModelBox(e,t){let n={...e,queryParentIds:e.queryParentIds||[]};return n.id===void 0?(Yt.warn(`操作失败:id不能为空`),Promise.reject(`id is empty`)):n.queryParentIds.length?this.request(`LayerQueryByModelCollider`,n,t,Tt.layerQueryByModelBox):(Yt.warn(`操作失败:queryParentIds不能为空`),Promise.reject(`queryParentIds is empty`))}},nn=class extends x{constructor(e,t){super(e,`TimeLineService`,t)}play(e,t){let n={...e,speed:e.speed??1,initialTime:e.initialTime??0,keepLastFrame:e.keepLastFrame??!1};return this.requestStream(`Play`,n,t,ft.play)}pause(e,t){return this.request(`Pause`,e,t,ft.pause)}resume(e,t){return this.request(`Resume`,e,t,ft.resume)}stop(e,t){let n={...e,resetTime:e.resetTime??-1,isCameraToStart:e.isCameraToStart??!1};return this.request(`Stop`,n,t,ft.stop)}stopAll(e){return this.request(`StopAll`,void 0,e,ft.stopAll??M)}setSpeed(e,t){return this.request(`SetSpeed`,e,t,ft.setSpeed)}},rn=class extends x{constructor(e,t){super(e,`TrainService`,t),this.camera=new At(e,t)}startTrain(e,t){let n={...e,direction:e.direction??`0`,action:e.action??`1`,stopTime:e.stopTime??180,moveType:e.moveType??`StopAtTheEnd`};return this.request(`SetTrainStart`,n,t,Et.startTrain)}setTrainBehavior(e,t){let n={...e,moveType:e.moveType??`StopAtTheEnd`};return this.request(`SetTrainFollowBehavior`,n,t,Et.setTrainBehavior)}setCameraFollowTrain(e,t){let n=e.offSet??new C(-100,0,30),r=new C(n.x,n.y,n.z,`0000`);return this.camera.startCameraObjFollow({parentId:e.parentId,id:e.id,offSet:r},t)}setTrainVolume(e,t){let n={...e,volumeOn:e.volumeOn??!0};return this.request(`SetTrainVolume`,n,t,Et.setTrainVolume)}cancelCameraFollowTrain(e){return this.camera.endCameraObjFollow(e)}},an=class extends x{constructor(e,t){super(e,`UIPOI`,t)}add(e,t){return this.request(`add`,e,t,z.add)}deleteById(e,t){return this.request(`deleteById`,e,t,z.deleteById)}deleteByGroup(e,t){return this.request(`deleteByGroup`,e,t,z.deleteByGroup)}update(e,t){return this.request(`update`,e,t,z.update)}updatePopStates(e,t){return this.request(`updatePopStates`,e,t,z.updatePopStates)}enableOverlap(e,t){let n={...e,enable:e.enable??!0};return this.request(`enableOverlap`,n,t,z.enableOverlap)}showDistance(e,t){return this.request(`showDistance`,e,t,z.showDistance)}},on=class extends x{constructor(e,t){super(e,`WebViewService`,t)}updateWebView(e,t){let n={...e};return this.request(`UpdateWebView`,n,t,bt.updateWebView)}},sn=class extends x{constructor(e,t){super(e,`WeathersService`,t)}changeWeatherType(e,t){let n={weatherType:e.weatherType,timeDuration:e.timeDuration||6};return this.request(`ChangeWeatherType`,n,t,R.changeWeatherType)}getWeatherTypes(e){return this.request(`GetWeatherPresets`,void 0,e,M)}resetWeather(e){return this.request(`ResetWeather`,void 0,e,M)}setSceneTime(e,t){let n={...e,timeDuration:e.timeDuration??5};return this.request(`SetCurrentSceneTime`,n,t,R.setSceneTime)}setTimeSync(e,t){let n={...e,syncSystemTime:e.syncSystemTime??!1};return this.request(`SetTimeSync`,n,t,R.setTimeSync)}resetSceneTime(e){return this.request(`ResetSceneTime`,{},e,R.resetSceneTime)}setAnimateTimeOfDay(e,t){let n={...e,isAnimate:e.isAnimate??!0,dayLength:e.dayLength??.5,nightLength:e.nightLength??.5};return this.request(`SetAnimateTimeOfDay`,n,t,R.setAnimateTimeOfDay)}resetWeatherAndTime(e){return this.request(`ResetWeatherAndTime`,void 0,e,M)}changeSeason(e,t){return this.request(`ChangeSeason`,e,t,R.changeSeason)}resetSeason(e){return this.request(`ResetSeason`,{},e,R.resetSeason)}setDayAndNight(e,t){return this.request(`setDayAndNight`,e,t,R.setDayAndNight)}setWeatherVolume(e,t){let n={...e,volumeOn:e.volumeOn??!0};return this.request(`SetWeatherVolume`,n,t,R.setWeatherVolume)}openCameraFog(e,t){let n={...e,fogIntensity:e.fogIntensity??-1,fogStartDistance:e.fogStartDistance??-1,fogEndDistance:e.fogEndDistance??-1,directionalIntensity:e.directionalIntensity??-1,directionalFallOff:e.directionalFallOff??-1};return this.request(`openCameraFog`,n,t,R.openCameraFog)}closeCameraFog(e){return this.request(`closeCameraFog`,void 0,e,R.closeCameraFog??M)}};const cn={Connect:e=>new jt(e.bridge,e.connectionLifecycle,{logger:e.createLogger(`Connect`)}),Type:()=>new It,Screen:e=>new $t(e.bridge,{logger:e.createLogger(`Screen`)}),Dlss:e=>new Mt(e.bridge,{logger:e.createLogger(`Dlss`)}),Camera:e=>new At(e.bridge,{logger:e.createLogger(`Camera`)}),Scene:e=>new en(e.bridge,{logger:e.createLogger(`Scene`)}),Layer:e=>new Lt(e.bridge,{logger:e.createLogger(`Layer`)}),Model:e=>new Rt(e.bridge,{logger:e.createLogger(`Model`)}),UIPOI:e=>new an(e.bridge,{logger:e.createLogger(`UIPOI`)}),ModelPOI:e=>new zt(e.bridge,{logger:e.createLogger(`ModelPOI`)}),ModelTransform:e=>new Bt(e.bridge,{logger:e.createLogger(`ModelTransform`)}),Navigation:e=>new Vt(e.bridge,{logger:e.createLogger(`Navigation`)}),PathPatrol:e=>new Ht(e.bridge,{logger:e.createLogger(`PathPatrol`)}),pointIcon:e=>new Gt(e.bridge,{logger:e.createLogger(`pointIcon`)}),PointEditor:e=>new Jt(e.bridge,{logger:e.createLogger(`PointEditor`),getVideoElement:()=>e.videoElementParent?.querySelector(`video`)??null}),GizmosTool:e=>new De(e.bridge,{logger:e.createLogger(`GizmosTool`),beginMouseInput:e.beginPointEditorMouseInput}),HeatMap:e=>new Nt(e.bridge,{logger:e.createLogger(`HeatMap`)}),HighlighterEffect:e=>new Pt(e.bridge,{logger:e.createLogger(`HighlighterEffect`)}),Popup:e=>new Qt(e.bridge,e.popupManager,{logger:e.createLogger(`Popup`)}),Animation:e=>new kt(e.bridge,{logger:e.createLogger(`Animation`)}),TimeLine:e=>new nn(e.bridge,{logger:e.createLogger(`TimeLine`)}),WeatherSystem:e=>new sn(e.bridge,{logger:e.createLogger(`WeatherSystem`)}),WebView:e=>new on(e.bridge,{logger:e.createLogger(`WebView`)}),SpatialQuery:e=>new tn(e.bridge,{logger:e.createLogger(`SpatialQuery`)}),TrainSimulate:e=>new rn(e.bridge,{logger:e.createLogger(`TrainSimulate`)})},ln=Object.freeze(Object.keys(cn)),V=[`DTCEngine 已完成鉴权并建立 WebRTC 连接`],H=`Promise<ApiResponseEnvelope<unknown>>`,un={Connect:{title:`连接控制`,description:`连接控制 API。`,capabilities:[`连接建立`,`连接断开`,`连接重连`,`会话接管`,`会话保活`,`服务状态查询`],methods:{connect:{description:"发起连接(兼容接口,SDK 实际已在 `new DTCEngine` 后自动连接)。",payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},disconnect:{description:`断开连接。`,payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},reconnect:{description:`重新连接。`,payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},KickOtherConnect:{description:`踢掉已存在会话并接管连接。`,payloadType:``,returnType:H,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},KeepConnect:{description:`保持当前连接会话。`,payloadType:``,returnType:H,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},GetEngineServiceStatus:{description:`获取引擎服务状态。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Type:{title:`数学类型`,description:`SDK 数学类型构造器。`,capabilities:[`二维向量类型`,`三维向量类型`,`四维向量类型`,`坐标参数构造`],methods:{}},Screen:{title:`画面质量控制`,description:`屏幕与渲染质量控制 API。`,capabilities:[`渲染码率调整`,`场景帧率调整`,`屏幕分辨率调整`],methods:{setSceneRenderBitrate:{description:`设置场景渲染码率档位。`,payloadType:`ScreenSetSceneRenderBitrateRequest | { bitrate: number }`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{bitrate:`high`}],riskLevel:`low`,responseMode:`single`},setSceneFPS:{description:`设置场景帧率。`,payloadType:`ScreenSetSceneFPSRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fps:30}],riskLevel:`low`,responseMode:`single`},setScreenResolution:{description:`设置渲染分辨率。`,payloadType:`ScreenSetScreenResolutionRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{width:1280,height:720}],riskLevel:`low`,responseMode:`single`}}},Dlss:{title:`DLSS 画质控制`,description:`DLSS 画质控制 API。`,capabilities:[`DLSS 开关控制`,`DLSS 质量档位控制`],methods:{setDlss:{description:`同时设置 DLSS 开关和质量档位。`,payloadType:`DlssSetEnableRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{enable:!0,quality:`Balanced`}],riskLevel:`low`,responseMode:`single`}}},Camera:{title:`相机控制`,description:`相机相关操作 API。`,capabilities:[`模型视角定位`,`批量目标定位`,`自由飞行`,`路径飞行`,`飞行控制`,`相机信息查询`,`相机姿态设置`,`视场角控制`,`相机重置`,`相机跟随控制`],methods:{lookAt:{description:`定位到指定模型对象或对象集合。`,payloadType:`CameraLookAtRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Sphere`,time:2}],riskLevel:`low`,responseMode:`single`},flyToTarget:{description:`相机飞向指定坐标点,并在飞行过程中看向目标点。`,payloadType:`CameraFlyToTargetRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{point:{x:120.1704,y:30.2472,z:148.1303,ePSGType:`0000`},target:{x:120.1691,y:30.2471,z:65.7,ePSGType:`0000`},time:2}],riskLevel:`low`,responseMode:`single`},flyByPath:{description:`按多点路径执行相机飞行。`,payloadType:`CameraFlyByPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{points:[{x:0,y:0,z:100},{x:100,y:0,z:100}],lookAts:[{x:0,y:0,z:0},{x:100,y:0,z:0}],time:6,smoothMode:0}],riskLevel:`low`,responseMode:`single`},setFlySpeed:{description:`设置相机飞行速度。`,payloadType:`CameraSetFlySpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{speed:2}],riskLevel:`low`,responseMode:`single`},endFly:{description:`终止当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},pauseFly:{description:`暂停当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},resumeFly:{description:`恢复当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},getCameraInfo:{description:`获取当前相机信息。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setCameraPositionAndRotation:{description:`设置相机位置与旋转。`,payloadType:`CameraSetPositionAndRotationRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{point:{x:0,y:0,z:100,ePSGType:`0000`},rotation:{x:0,y:0,z:0,ePSGType:`0000`}}],riskLevel:`low`,responseMode:`single`},setCameraFov:{description:`设置相机 FOV。`,payloadType:`CameraSetFovRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fov:75}],riskLevel:`low`,responseMode:`single`},resetCameraFov:{description:`重置相机 FOV。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},reset:{description:`重置相机到默认状态。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},startCameraObjFollow:{description:`相机跟随场景中运动的对象。`,payloadType:`CameraObjFollowRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`myCar`,offSet:{x:0,y:3,z:5,ePSGType:`0000`},smooth:.85}],riskLevel:`low`,responseMode:`single`},endCameraObjFollow:{description:`停止相机跟随。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Scene:{title:`场景管理`,description:`场景管理 API。`,capabilities:[`场景列表查询`,`场景切换`,`当前场景查询`,`地图罗盘监听`,`场景特性开关`,`场景元数据查询`],methods:{getAllSceneName:{description:`获取当前引擎服务支持的场景名称列表。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},switchSceneByName:{description:`按场景名称切换场景。`,payloadType:`SceneSwitchRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{sceneName:`TestScene`}],riskLevel:`low`,responseMode:`single`},getCurrentSceneName:{description:`获取当前正在运行的场景名称。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},listenMapCompass:{description:`监听地图指北针角度变化。`,payloadType:`SceneListenCompassRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{enable:!0}],riskLevel:`low`,responseMode:`single`},setFeatureToggle:{description:`设置场景特性开关。`,payloadType:`FeatureToggleRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{key:`minimap`,enabled:!0}],riskLevel:`low`,responseMode:`single`},getSceneMeta:{description:`获取当前场景扩展元信息。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Layer:{title:`图层管理`,description:`场景图层对象管理 API。`,capabilities:[`图层添加`,`图层删除`,`图层存在性查询`,`模型图层切换`,`图层气泡显隐`,`图层模型添加`,`图层模型删除`,`图层子对象查询`,`POI名称更新`,`POI名称重置`],methods:{addLayer:{description:`添加对象图层组。`,payloadType:`LayerAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraGroup`,id:`CameraLayerModel`,layerName:`摄像机图层`,show:!0,poiEnabled:!0,type:`MODEL`}],riskLevel:`low`,responseMode:`single`},removeLayer:{description:`删除对象图层组,并清空其下所有对象。`,payloadType:`LayerSelectorRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraGroup`,id:`CameraLayerModel`}],riskLevel:`low`,responseMode:`single`},isLayerOrGroupExit:{description:`判断图层或组对象是否存在。`,payloadType:`LayerSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{id:`cameraGroup`}],riskLevel:`low`,responseMode:`single`},switchModelLayer:{description:`切换模型的图层组。`,payloadType:`LayerSwitchModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,ids:[`camera01`,`camera02`],toParentId:`destLayer`}],riskLevel:`low`,responseMode:`single`},showUIPop:{description:`显示或隐藏指定图层下的 UI Pop。`,payloadType:`LayerShowUIPopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`CameraLayer`,visible:!0}],riskLevel:`low`,responseMode:`single`},addModel:{description:`在指定图层下添加模型资源。`,payloadType:`LayerModelAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,id:`camera01`,assetsPath:`Sphere`}],riskLevel:`low`,responseMode:`single`},addPOI:{description:`在指定图层下添加模型资源。`,payloadType:`LayerPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,id:`camera01`,assetsPath:`Sphere`}],riskLevel:`low`,responseMode:`single`},updatePOIName:{description:`更新 POI 气泡的显示文本。`,payloadType:`LayerUpdatePOINameRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraLayerModel`,id:`camera01`,name:`一体化球击摄像机`,updateType:`update`}],riskLevel:`low`,responseMode:`single`},resetPOIName:{description:`*`,payloadType:`LayerResetPOINameRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraLayerModel`,ids:[`camera01`,`camera02`]}],riskLevel:`low`,responseMode:`single`},removeModel:{description:`删除图层下指定模型资源。`,payloadType:`LayerModelRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,ids:[`camera01`,`camera02`]}],riskLevel:`low`,responseMode:`single`},getLayerChildElement:{description:`获取图层下所有一级子对象。`,payloadType:`LayerChildElementRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{id:`test`}],riskLevel:`low`,responseMode:`single`}}},Model:{title:`模型管理`,description:`模型对象管理 API。`,capabilities:[`模型显隐控制`,`模型添加`,`模型删除`,`模型树查询`,`模型信息查询`,`模型包围盒查询`],methods:{setVisible:{description:`设置模型对象显隐状态。`,payloadType:`ModelSetVisibleRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraGroup`,id:[`camera01`,`camera02`],visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByTags:{description:`按标签批量设置模型对象显隐状态。`,payloadType:`ModelSetVisibleByTagsRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{tags:[`camera`,`sensor`],visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByAttribute:{description:`按对象属性过滤设置模型对象显隐状态。`,payloadType:`ModelSetVisibleByAttributeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{attributes:{floor:`B2`},filterMode:0,visible:!1}],riskLevel:`low`,responseMode:`single`},getElementTree:{description:`获取指定节点的一层子对象树。`,payloadType:`ModelSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`test`,id:`Root`}],riskLevel:`low`,responseMode:`single`},getModelInfo:{description:`获取指定模型对象信息。`,payloadType:`ModelSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`test`,id:`Sphere`}],riskLevel:`low`,responseMode:`single`}}},UIPOI:{title:`后端 UI 气泡`,description:`后端 UI 气泡(UIPOI)管理 API。`,capabilities:[`UI 气泡添加`,`UI 气泡删除`,`UI 气泡更新`,`弹窗状态更新`,`重叠控制`,`距离显示控制`],methods:{add:{description:`批量添加 UIPOI。`,payloadType:`UIPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,poiInfos:[{id:`camera01`,state:`normal`}]}],riskLevel:`low`,responseMode:`single`},deleteById:{description:`删除指定组下的单个 UIPOI。`,payloadType:`UIPOIDeleteByIdRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,id:`camera01`}],riskLevel:`low`,responseMode:`single`},deleteByGroup:{description:`删除指定组下的全部 UIPOI。`,payloadType:`UIPOIDeleteByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`}],riskLevel:`low`,responseMode:`single`},update:{description:`更新指定组 UIPOI 配置。`,payloadType:`UIPOIUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,poiInfos:[{id:`camera01`,state:`alert`}]}],riskLevel:`low`,responseMode:`single`},updatePopStates:{description:`批量更新 UIPOI 状态。`,payloadType:`UIPOIUpdateStateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`LCD80CunXianShiPingPop`,popStates:[{id:`1`,state:`normal`}]}],riskLevel:`low`,responseMode:`single`},enableOverlap:{description:`开启或关闭 UIPOI 碰撞避让。`,payloadType:`UIPOIEnableOverlapRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{enable:!1}],riskLevel:`low`,responseMode:`single`},showDistance:{description:`设置 UIPOI 可视距离。`,payloadType:`UIPOIShowDistanceRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{distance:800}],riskLevel:`low`,responseMode:`single`}}},ModelPOI:{title:`模型气泡`,description:`模型气泡(ModelPOI)管理 API。`,capabilities:[`模型气泡添加`,`模型气泡删除`,`模型气泡查询`,`模型气泡更新`,`分组显隐控制`],methods:{add:{description:`添加模型气泡。`,payloadType:`ModelPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`123`,groupName:`cameraGroup`,assetPath:`dotPop`,targetId:`Camera01`}],riskLevel:`low`,responseMode:`single`},deleteById:{description:`按编号批量删除模型气泡。`,payloadType:`ModelPOIDeleteByIdRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`cameraGroup`,ids:[`Camera01`]}],riskLevel:`low`,responseMode:`single`},deleteByGroup:{description:`删除指定组下全部模型气泡。`,payloadType:`ModelPOIDeleteByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`}],riskLevel:`low`,responseMode:`single`},getPOIInfo:{description:`获取单个模型气泡信息。`,payloadType:`ModelPOIGetInfoRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{groupName:`cameraGroup`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},update:{description:`更新模型气泡信息。`,payloadType:`ModelPOIUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`123`,groupName:`cameraGroup`,assetPath:`dotPop`,visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByGroup:{description:`设置指定组模型气泡显隐。`,payloadType:`ModelPOIVisibleByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`,visible:!0}],riskLevel:`low`,responseMode:`single`}}},ModelTransform:{title:`模型变换`,description:`模型对象变换 API,涵盖旋转、缩放、移动操作。`,capabilities:[`模型轨迹移动`,`暂停/继续/结束移动`,`恢复位置`,`模型旋转`,`绕目标旋转`,`恢复旋转`,`模型缩放`,`停止缩放`,`恢复缩放`],methods:{startMoveByNodes:{description:`设置模型对象的移动轨迹。`,payloadType:`ModelTransformStartMoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myRobot`,nodes:[{x:120.0001,y:30.0001,z:100.1},{x:122.0001,y:28.0001,z:110.1}],speed:3,linear:1,isLookAtTarget:!0}],riskLevel:`low`,responseMode:`single`},pauseMove:{description:`暂停模型对象的移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myRobot`}],riskLevel:`low`,responseMode:`single`},resumeMove:{description:`继续模型对象的移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},endMove:{description:`结束轨迹移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},restoreMove:{description:`重置对象到原来的位置。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`},rotate:{description:`指定轴旋转模型角度到。`,payloadType:`ModelTransformRotateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myBus`,rotate:{x:30,y:180,z:120}}],riskLevel:`low`,responseMode:`single`},endRotate:{description:`结束旋转。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myBus`}],riskLevel:`low`,responseMode:`single`},continuedRotate:{description:`持续不断的绕自身旋转。`,payloadType:`ModelTransformRotateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,rotate:{x:30,y:180,z:120}}],riskLevel:`low`,responseMode:`single`},rotateByTarget:{description:`围绕某个对象做旋转。`,payloadType:`ModelTransformRotateByTargetRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,targetID:`target`,point:{x:1,y:2,z:3},axisX:1,axisY:0,axisZ:0,angle:10,isPersistence:!0}],riskLevel:`low`,responseMode:`single`},restoreRotate:{description:`重置恢复场景多个对象的旋转。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`},setScale:{description:`设置模型对象的缩放。`,payloadType:`ModelTransformScaleRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,scale:{x:.5,y:.5,z:.5},duration:3}],riskLevel:`low`,responseMode:`single`},endScale:{description:`停止模型对象的缩放。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},restoreScale:{description:`重置模型的缩放,恢复到开始状态。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`}}},Navigation:{title:`对象导航`,description:`场景对象导航 API,支持两种导航模式:`,capabilities:[`网格导航寻路`,`导航距离查询`,`网格导航暂停`,`网格导航继续`,`网格导航停止`,`网格导航属性修改`,`路径导航开始`,`路径导航暂停`,`路径导航继续`,`路径导航停止`,`路径导航属性修改`],methods:{startNav:{description:`网格导航寻路:模型对象根据路过的节点进行导航。`,payloadType:`NavigationMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,planColor:`#00ff00`,passColor:`#e1e1e1`}],riskLevel:`low`,responseMode:`single`},getMeshNavDistance:{description:`网格导航距离查询:模型对象根据路过的节点进行导航,并返回导航距离信息。`,payloadType:`NavigationMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,planColor:`#00ff00`,passColor:`#e1e1e1`}],riskLevel:`low`,responseMode:`single`},pauseNav:{description:`暂停模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},resumeNav:{description:`继续模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},stopNav:{description:`停止模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},updateNav:{description:`设置网格导航路径属性。`,payloadType:`NavigationUpdateMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,planColor:`#00ff00`,passColor:`#e1e1e1`,speed:4}],riskLevel:`low`,responseMode:`single`},updateSpeed:{description:`设置网格导航路径属性。`,payloadType:`NavigationUpdateSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,speed:4}],riskLevel:`low`,responseMode:`single`},startNavByPath:{description:`路径导航开始:根据指定的轨迹节点进行直线导航行走。`,payloadType:`NavigationNavByPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,duration:10}],riskLevel:`low`,responseMode:`single`},pauseNavPath:{description:`暂停模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},resumeNavPath:{description:`继续模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},stopNavPath:{description:`停止模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},updateNavPath:{description:`设置路径导航属性。`,payloadType:`NavigationUpdateNavPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],planColor:`#00ff00`,passColor:`#e1e1e1`,duration:5}],riskLevel:`low`,responseMode:`single`}}},PathPatrol:{title:`路径巡逻`,description:`路径巡逻 API,支持巡逻路线添加、样式修改、时间节点设置与巡逻控制。`,capabilities:[`添加巡逻路线`,`修改巡逻样式`,`设置巡逻时间节点`,`清除巡逻路径`,`暂停巡逻`,`继续巡逻`,`停止巡逻`],methods:{add:{description:`添加巡逻路线。`,payloadType:`PathPatrolAddRequest`,returnType:`StreamRequestPromise<unknown>`,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,assetPath:`PatrolMan`,scale:{x:2,y:2,z:2},showPath:!0,passedColor:`#ff0013`,lineColor:`#0040ef`,lineWidth:2,nodes:[{x:114.79234244388735,y:34.8353249473732,z:67.76611328125},{x:114.78552975378634,y:34.84532722646887,z:67.76627349853516}],duration:10}],riskLevel:`low`,responseMode:`stream`},update:{description:`修改巡逻路径的样式。`,payloadType:`PathPatrolUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,lineColor:`#ff00ff`,lineWidth:3.5}],riskLevel:`low`,responseMode:`single`},setTimeNode:{description:`设置巡逻开始的时间节点或是节点索引。`,payloadType:`PathPatrolSetTimeNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,timeStart:`2025-09-10 00:05:00`}],riskLevel:`low`,responseMode:`single`},clear:{description:`清除巡逻路径。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},pause:{description:`暂停巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`},resume:{description:`继续巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`},stop:{description:`停止巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`}}},pointIcon:{title:`设备点位图标`,description:`设备点位图标显隐控制 API。`,capabilities:[`指定点位显隐`,`按编码点位显隐`,`分组点位显隐`,`全部点位显隐`],methods:{show:{description:`显示指定设备点位的图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`point-001`,`point-002`]}],riskLevel:`low`,responseMode:`single`},hide:{description:`隐藏指定设备点位的图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`point-001`,`point-002`]}],riskLevel:`low`,responseMode:`single`},showByCode:{description:`显示指定编码(code)的全部设备点位图标,编码精确匹配且不要求唯一。`,payloadType:`PointIconCodesInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{codes:[`CAM-001`,`CAM-002`]}],riskLevel:`low`,responseMode:`single`},hideByCode:{description:`隐藏指定编码(code)的全部设备点位图标,编码精确匹配且不要求唯一。`,payloadType:`PointIconCodesInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{codes:[`CAM-001`,`CAM-002`]}],riskLevel:`low`,responseMode:`single`},showByGroup:{description:`显示指定分组及其子分组内的设备点位图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`group-f1`]}],riskLevel:`low`,responseMode:`single`},hideByGroup:{description:`隐藏指定分组及其子分组内的设备点位图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`group-f1`]}],riskLevel:`low`,responseMode:`single`},showAll:{description:`显示全部设备点位图标。`,payloadType:``,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`},hideAll:{description:`隐藏全部设备点位图标。`,payloadType:``,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`}}},PointEditor:{title:`模型点位编辑`,description:`MODEL 打点 API,复用既有场景对象;不读写平台 JSON、PointTool 文件或修改 MQTT 流程。`,capabilities:[`按坐标创建点位`,`点击创建点位`,`拖放创建点位`,`落点坐标换算`,`取消点位放置`,`局部更新点位`,`批量删除点位`],methods:{addPoint:{description:`创建模型点位;未传 position/screenPosition 时等待视频区域的一次有效点击,可按 Escape/右键取消。`,payloadType:`PointEditorAddRequest`,returnType:`Promise<PointEditorPoint>`,sideEffects:[`write`],preconditions:[`已建立 WebRTC 连接,UE CoreModules 支持 sdk3 点位编辑`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`,type:`MODEL`,position:{x:120,y:30,z:5},resource:{path:`/Game/Devices/BP_Camera.BP_Camera_C`}}],riskLevel:`medium`,responseMode:`single`},addPointByDrag:{description:`拖放创建;使用 drop 当时保存的 screenPosition 或显式经纬高,不读取当前或上一次鼠标位置。`,payloadType:`PointEditorAddRequest`,returnType:`Promise<PointEditorPoint>`,sideEffects:[`write`],preconditions:[`已建立 WebRTC 连接;必须提供 position 或 drop 时记录的 screenPosition`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-2`,type:`MODEL`,position:{x:120,y:30,z:5},resource:{path:`/Game/Devices/BP_Camera.BP_Camera_C`}}],riskLevel:`medium`,responseMode:`single`},getScreenPosition:{description:`在实际 drop 事件中同步换算位置,随后可等待后端保存;不在等待结束后重新读取鼠标。`,payloadType:`PointEditorClientPosition`,returnType:`PointEditorScreenPosition`,sideEffects:[`read`],preconditions:[`视频已就绪,必须使用真实 drop 事件坐标`],examples:[{clientX:400,clientY:300}],riskLevel:`low`,responseMode:`single`},cancelPlacement:{description:`取消正在等待网页点击的放置操作并恢复输入;不撤销已经发送到 UE 的创建请求。`,payloadType:``,returnType:`Promise<void>`,sideEffects:[`write`],riskLevel:`low`,responseMode:`single`},updatePoint:{description:`局部更新 MODEL 及附属 POI;不传的字段保持原值,false、0 和空名称有效。`,payloadType:`PointEditorUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:[`目标是既有场景加载或 API 创建的 MODEL;PointTool 本地工作台对象除外`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`,type:`MODEL`,show:!1}],riskLevel:`medium`,responseMode:`single`},deletePoints:{description:`批量删除网页模型点位及附属 POI;混入其他来源或纯 POI 目标时整批拒绝。`,payloadType:`PointEditorDeleteRequest`,returnType:`Promise<ApiResponseEnvelope<PointEditorDeleteResult>>`,sideEffects:[`write`],preconditions:[`目标属于场景 MODEL 点位管理范围,按 parentId/id 准确定位`],examples:[{parentId:`sdk3-point-editor-test`,ids:[`G-test-1`]}],riskLevel:`high`,responseMode:`single`}}},GizmosTool:{title:`模型交互编辑`,description:`网页 MODEL 运行时编辑,不开启本地工作台,不保存 PointTool 文件。`,capabilities:[`开启模型编辑`,`切换编辑目标`,`退出模型编辑`],methods:{startSimpleGizmoMode:{description:`开启或切换模型编辑目标,同时显示平移、旋转和缩放手柄,无需指定编辑模式。`,payloadType:`GizmosStartSimpleRequest`,returnType:H,sideEffects:[`write`],preconditions:[`WebRTC 已连接;PointTool 本地工作台未占用输入`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`}],riskLevel:`medium`,responseMode:`single`},endSimpleGizmoMode:{description:`退出简易编辑并恢复进入前的鼠标转发配置,不保存本地点位文件。`,payloadType:``,returnType:H,sideEffects:[`write`],riskLevel:`low`,responseMode:`single`}}},HeatMap:{title:`热力图`,description:`热力图 API,支持热力图创建(地理热力点数据)、移除、清空与参数设置。`,capabilities:[`创建热力图`,`移除热力图`,`清除热力图`,`修改热力图参数`],methods:{create:{description:`创建热力图。`,payloadType:`HeatMapCreateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`,influenceSize:50,points:[{position:{x:120.15,y:30.28,z:10,ePSGType:`4326`},value:.8}]}],riskLevel:`low`,responseMode:`single`},remove:{description:`移除热力图。`,payloadType:`HeatMapRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`}],riskLevel:`low`,responseMode:`single`},clear:{description:`清空全部热力图,无需传参。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setConfig:{description:`设置热力图参数(透明度/高度缩放/颜色过渡)。`,payloadType:`HeatMapConfigRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`,opacity:.5,heightScale:3e3,lerpScale:3}],riskLevel:`low`,responseMode:`single`}}},HighlighterEffect:{title:`高亮效果`,description:`高亮效果 API,控制场景中模型对象的高亮。`,capabilities:[`打开高亮`,`关闭高亮`,`模型高亮`,`移除模型高亮`,`清除全部高亮`],methods:{enable:{description:`打开高亮效果。`,payloadType:`HighLighterEnableRequest`,returnType:H,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`},setHighLightModel:{description:`设置场景当中,指定模型对象 高亮效果`,payloadType:`HighLighterSetHighLightModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,ids:[`Sphere`,`Sphere1`],showBack:!0}],riskLevel:`low`,responseMode:`single`},removeHighLightModel:{description:`清除 指定模型对象的高亮效果`,payloadType:`HighLighterRemoveHighLightModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,ids:[`Sphere`,`Sphere1`]}],riskLevel:`low`,responseMode:`single`},clear:{description:`清除场景中模型的所有的高亮效果`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`}}},Popup:{title:`前端 Popup`,description:`前端 Popup 管理 API。`,capabilities:[`Popup 添加`,`Popup 删除`,`Popup 清除`,`Popup 显隐控制`,`Popup 全部显隐控制`,`Popup 延迟帧控制`,`Popup 显示距离控制`],methods:{addPop:{description:`创建前端弹出气泡。`,payloadType:`PopupAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`CameraPopGroup`,popInfo:[{id:`Camera1`,visible:!0}]}],riskLevel:`low`,responseMode:`single`},removePop:{description:`删除前端气泡。`,payloadType:`PopupRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`cameraLayer`,ids:[`camera01`]}],riskLevel:`low`,responseMode:`single`},removeAll:{description:`清除所有前端气泡。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[void 0],riskLevel:`low`,responseMode:`single`},show:{description:`显示或隐藏气泡。`,payloadType:`PopupShowRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`CameraPopGroup`,ids:[`Camera2`],show:!1}],riskLevel:`low`,responseMode:`single`},showAll:{description:`显示或隐藏所有组下的所有气泡。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[!0],riskLevel:`low`,responseMode:`single`},setPopDelayFrame:{description:`设置前端气泡同步的延迟时间。`,payloadType:`PopupDelayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{time:.3}],riskLevel:`low`,responseMode:`single`},setPopShowDistance:{description:`设置前端页面气泡最远的显示距离(仅本地生效,不发送请求)。`,payloadType:``,returnType:`void`,sideEffects:[`write`],preconditions:V,examples:[2e3],riskLevel:`low`,responseMode:`single`}}},Animation:{title:`模型动画`,description:`控制模型 Animator 和循环动画。`,capabilities:[`循环动画播放`,`循环动画停止`,`Animator 播放`,`Animator 停止`,`动画速度控制`,`动画长度查询`],methods:{startLoopAnimation:{description:`播放循环动画片段。`,payloadType:`AnimationStartLoopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`,loopStartTime:0,loopEndTime:3,speed:1}],riskLevel:`low`,responseMode:`single`},stopLoopAnimation:{description:`停止循环动画片段。`,payloadType:`AnimationStopLoopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`}],riskLevel:`low`,responseMode:`single`},playAnimator:{description:`播放 Animator 动画片段。`,payloadType:`AnimationPlayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`,speed:1,startTime:0,endTime:1,isStop:!1}],riskLevel:`low`,responseMode:`single`},setAnimatorSpeed:{description:`设置 Animator 动画播放速度。`,payloadType:`AnimationSetSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,speed:1.5}],riskLevel:`low`,responseMode:`single`},getAnimationLength:{description:`获取动画片段长度。`,payloadType:`AnimationGetLengthRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`}],riskLevel:`low`,responseMode:`single`},stopAnimator:{description:`停止指定对象的 Animator 播放。`,payloadType:`AnimationStopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`}],riskLevel:`low`,responseMode:`single`}}},TimeLine:{title:`时间线动画`,description:`TimeLine 动画控制 API。`,capabilities:[`时间线播放`,`时间线暂停`,`时间线恢复`,`时间线停止`,`全部时间线停止`,`播放速度控制`],methods:{play:{description:`播放指定 TimeLine 动画。`,payloadType:`TimelinePlayRequest`,returnType:`StreamRequestPromise<unknown>`,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,speed:2}],riskLevel:`low`,responseMode:`stream`},pause:{description:`暂停指定 TimeLine 动画。`,payloadType:`TimelineNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`}],riskLevel:`low`,responseMode:`single`},resume:{description:`继续播放指定 TimeLine 动画。`,payloadType:`TimelineNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`}],riskLevel:`low`,responseMode:`single`},stop:{description:`停止指定 TimeLine 动画。`,payloadType:`TimelineStopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,resetTime:-1,isCameraToStart:!1}],riskLevel:`low`,responseMode:`single`},stopAll:{description:`停止全部 TimeLine 动画。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setSpeed:{description:`设置指定 TimeLine 的播放速度。`,payloadType:`TimelineSetSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,speed:1.2}],riskLevel:`low`,responseMode:`single`}}},WeatherSystem:{title:`天气时间环境`,description:`天气与时间环境控制 API。`,capabilities:[`天气类型查询`,`天气切换`,`天气重置`,`天气时间重置`,`场景时间设置`,`时间同步控制`,`昼夜动画控制`,`昼夜模式设置`,`季节切换`,`季节重置`,`雾效开启`,`雾效关闭`,`天气音量控制`],methods:{changeWeatherType:{description:`切换天气类型。`,payloadType:`WeatherTypeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{weatherType:`Clear_Skies`,timeDuration:6}],riskLevel:`low`,responseMode:`single`},getWeatherTypes:{description:`得到所有天气类型。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},resetWeather:{description:`重置天气`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setSceneTime:{description:`设置场景时间(小时)。`,payloadType:`WeatherSetSceneTimeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{hour:10.5,timeDuration:5}],riskLevel:`low`,responseMode:`single`},setTimeSync:{description:`设置是否同步系统时间。`,payloadType:`WeatherSetTimeSyncRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{syncSystemTime:!0}],riskLevel:`low`,responseMode:`single`},resetSceneTime:{description:`重置场景时间。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setAnimateTimeOfDay:{description:`设置是否模拟白天,黑夜轮换动画。`,payloadType:`WeatherSetAnimateTimeOfDayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{isAnimate:!0,dayLength:.5,nightLength:.5}],riskLevel:`low`,responseMode:`single`},resetWeatherAndTime:{description:`场景天气和时间重置`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},changeSeason:{description:`切换场景季节状态。`,payloadType:`WeatherChangeSeasonRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{season:1,duration:5}],riskLevel:`low`,responseMode:`single`},resetSeason:{description:`重置场景季节状态。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setDayAndNight:{description:`在白天与夜晚模式之间切换。`,payloadType:`WeatherSetDayAndNightRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{dayType:`night`}],riskLevel:`low`,responseMode:`single`},setWeatherVolume:{description:`设置天气声音的开关。`,payloadType:`WeatherSetVolumeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{volumeOn:!1}],riskLevel:`low`,responseMode:`single`},openCameraFog:{description:`开启并调整相机镜头雾效。`,payloadType:`WeatherOpenCameraFogRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fogStartDistance:20,fogEndDistance:1500,fogIntensity:.5}],riskLevel:`low`,responseMode:`single`},closeCameraFog:{description:`关闭相机镜头雾效。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},WebView:{title:`网页视图`,description:`网页视图(WebView)管理 API。`,capabilities:[`网页视图更新`],methods:{updateWebView:{description:`更新网页视图参数。`,payloadType:`WebViewUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`WebViews`,id:`tv1`,url:`http://www.163.com`}],riskLevel:`low`,responseMode:`single`}}},SpatialQuery:{title:`空间查询`,description:`场景缓冲空间查询 API,支持三种查询方式:`,capabilities:[`模型空间查询`,`坐标空间查询`,`模型包围盒空间查询`],methods:{layerQueryByModel:{description:`模型空间查询:根据场景模型当前的位置进行空间查询。`,payloadType:`SpatialQueryLayerByModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:``,id:`LayerSearchCore`,queryRadius:10,queryMinHeight:0,queryMaxHeight:50,queryParentIds:[`SM_B8_XueShenSuShe`,`daoZha`]}],riskLevel:`low`,responseMode:`single`},layerQueryByPosition:{description:`坐标空间查询:根据场景坐标位置进行空间查询。`,payloadType:`SpatialQueryLayerByPositionRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{queryPosition:{x:120.40284254780221,y:30.830451474524036,z:10,ePSGType:`4326`},queryRadius:20,queryMinHeight:0,queryMaxHeight:50,queryParentIds:[`SM_B8_XueShenSuShe`,`daoZha`]}],riskLevel:`low`,responseMode:`single`},layerQueryByModelBox:{description:`模型包围盒空间查询:根据场景模型的边界框进行空间查询。`,payloadType:`SpatialQueryLayerByModelBoxRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:``,id:`LayerSearchCore`,queryParentIds:[`JianKong_QiangJiTest`,`daoZha`]}],riskLevel:`low`,responseMode:`single`}}},TrainSimulate:{title:`列车模拟`,description:`列车模拟 API,支持启动列车、设置列车运动方式与音量、相机跟随/取消跟随列车。`,capabilities:[`列车启动`,`列车运动方式设置`,`列车音量设置`,`相机跟随列车`,`取消相机跟随列车`],methods:{startTrain:{description:`设置火车的动态并启动列车。`,payloadType:`TrainSimulateStartTrainRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,trainCode:`G501`,startStationName:`北京`,endStationName:`上海`,direction:`0`,action:`1`,stopTime:180,moveType:`StopAtTheEnd`}],riskLevel:`low`,responseMode:`single`},setTrainBehavior:{description:`设置火车的运动方式。`,payloadType:`TrainSimulateSetTrainBehaviorRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,moveType:`Loop`}],riskLevel:`low`,responseMode:`single`},setCameraFollowTrain:{description:`设置相机跟随火车。`,payloadType:`TrainSimulateSetCameraFollowTrainRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,offSet:{x:26,y:18,z:15,ePSGType:`0000`}}],riskLevel:`low`,responseMode:`single`},setTrainVolume:{description:`设置火车的声音的开关。`,payloadType:`TrainSimulateSetTrainVolumeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,volumeOn:!1}],riskLevel:`low`,responseMode:`single`},cancelCameraFollowTrain:{description:`取消相机跟随火车,无需传参。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}}},dn=e=>e instanceof r.ZodEffects?dn(e._def.schema):e,fn=e=>{let t=dn(e);return t instanceof r.ZodOptional||t instanceof r.ZodDefault?{schema:dn(t._def.innerType),required:!1,description:t.description??``}:{schema:t,required:!0,description:t.description??``}},pn=e=>fn(e).schema instanceof r.ZodUndefined,mn=e=>{if(!(e instanceof r.ZodUnion))return;let t=e._def.options;if(!t.every(e=>e instanceof r.ZodLiteral))return;let n=t.map(e=>({value:e._def.value,...e.description?{description:e.description}:{}}));return{enumValues:n.map(e=>e.value),enumOptions:n}},hn=e=>{let t=mn(e);if(t)return{type:`enum`,...t};let n=`unknown`;return e instanceof r.ZodString?n=`string`:e instanceof r.ZodNumber?n=`number`:e instanceof r.ZodBoolean?n=`boolean`:e instanceof r.ZodObject?n=`object`:e instanceof r.ZodArray&&(n=`array`),{type:n}},gn=e=>{if(pn(e))return[];let t=fn(e).schema;return t instanceof r.ZodObject?Object.entries(t.shape).map(([e,t])=>{let{schema:n,required:r,description:i}=fn(t);return{name:e,required:r,description:i,...hn(n)}}):[]},_n=[`write`],vn=[`DTCEngine 已完成鉴权并建立 WebRTC 连接`],yn=(e,t,n)=>{let r=e[t],i=`${n.charAt(0).toLowerCase()}${n.slice(1)}`;return r?.[n]??r?.[i]},bn=e=>e.apiModuleKeys.reduce((t,n)=>{let r=e.jsDocMetadata[n];return t[n]={moduleName:n,title:r.title,description:r.description,capabilities:r.capabilities,methods:Object.entries(r.methods).map(([t,r])=>{let i=[...r.sideEffects??_n],a=[...r.preconditions??vn],o=r.responseMode??`single`,s=yn(e.schemaMap,n,t);if(!s)throw Error(`Missing validation schema for ${n}.${t}`);let c=pn(s)?`none`:`object`,l=c===`none`?[]:[...r.examples??[]],u=gn(s);return{moduleName:n,methodName:t,description:r.description,sideEffects:i,preconditions:a,responseMode:o,riskLevel:r.riskLevel,schema:{payloadKind:c,fields:u,examples:l,responseMode:o}}})},t},{});function xn(e){return{moduleName:e.moduleName,methodName:e.methodName,description:e.description,sideEffects:e.sideEffects,preconditions:e.preconditions,responseMode:e.responseMode}}const Sn=bn({apiModuleKeys:ln,schemaMap:Ot,jsDocMetadata:un});function Cn(e){return e}function wn(e){return ln.indexOf(e)>=0}function Tn(e){return e??`all`}function En(e,t){let n=Tn(t);return n===`all`||n[e]!==void 0}function Dn(e,t,n){let r=Tn(n);if(r===`all`)return!0;let i=r[e];return i===!0||Array.isArray(i)&&i.indexOf(t)>=0}function On(e){return ln.filter(t=>En(t,e)).map(t=>{let n=Sn[t],r=kn(t,e).length;return{moduleName:n.moduleName,title:n.title,description:n.description,capabilities:n.capabilities,methodCount:r}})}function kn(e,t){return En(e,t)?Sn[e].methods.filter(n=>Dn(e,n.methodName,t)).map(e=>xn(e)):[]}function An(e,t,n){if(Dn(e,t,n))return Sn[e].methods.find(e=>e.methodName===t)?.schema}function jn(e,t,n){if(!Dn(e,t,n))return;let r=Ot[e],i=`${t.charAt(0).toLowerCase()}${t.slice(1)}`;return r?.[t]??r?.[i]}function Mn(e){return`'use strict';
37
+ `,n.style.left=`calc(50vw - ${n.offsetWidth/2}px)`,n.style.left=`calc( - ${n.offsetWidth/2}px+50vw)`,n.style.transition=`top 250ms ease-out`,n.style.top=`440px`,t||window.setTimeout(()=>{document.body.removeChild(n)},15e3),n}static removeLoadingTokenWillExpireDiv(){let e=document.getElementById(`TokenWillExpireTips`);e&&document.body.removeChild(e)}static stopEvents(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()}static degToRad(e){return e*Math.PI/180}static WGS84ToMercator(e,t){let n=e*20037508.34/180,r=Math.log(Math.tan((90+t)*Math.PI/360))/(Math.PI/180);return r=r*20037508.34/180,{x:n,y:r}}static MercatorToWGS84(e,t){let n=e/20037508.34*180,r=t/20037508.34*180;return r=180/Math.PI*(2*Math.atan(Math.exp(r*Math.PI/180))-Math.PI/2),{x:n,y:r}}static isPC(){let e=navigator.userAgent,t=[`Android`,`iPhone`,`SymbianOS`,`Windows Phone`,`iPad`,`iPod`],n=!0;for(let r=0;r<t.length;r++)if(e.indexOf(t[r])>0){n=!1;break}return n}static getTotalPage(e,t=50){let n=0,r=e/t;return n=e/t>parseInt(r+``)?parseInt(r+``)+1:parseInt(r+``),n}static{this.isEmpty=e=>e===null||e===``||e===void 0||e.length===0}static getValueOrDefault(e,t,n){return e[t]==null?e[t]=n:e[t]}static dynamicAddCrossAccess(){let e=document.head||document.getElementsByTagName(`head`)[0];function t(){let e=document.getElementsByTagName(`meta`);for(let t=0;t<e.length;t++)if(e[t].getAttribute(`http-equiv`)===`Access-Control-Allow-Origin`&&e[t].getAttribute(`content`)===`*`)return!0;return!1}if(!t()){let t=document.createElement(`meta`);t.setAttribute(`http-equiv`,`Access-Control-Allow-Origin`),t.setAttribute(`content`,`*`),e.appendChild(t)}}static GetAxios(e,t,n){i.defaults.headers.common[`content-Type`]=`application/json;charset=UTF-8`,i.get(e,n).then(function(e){t&&t(e)}).catch(function(e){e.response||(e.request?console.log(e.request):console.error(`Error`,e.message))})}static IsValidHexColor(e){return e=e.replace(/^#/,``),e.length!==3&&e.length!==6?!1:/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(e)}static calculatePercentage(e,t){return(e/t*100).toFixed(2)}static getCurrentTimeFormatted(){let e=new Date;return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)} ${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}:${String(e.getSeconds()).padStart(2,`0`)}`}static CalTimeDifferToHHMMSS(e){Math.floor(e/864e5);let t=e%864e5,n=Math.floor(t/36e5).toString().padStart(2,`0`),r=t%36e5,i=Math.floor(r/6e4).toString().padStart(2,`0`),a=r%6e4;return`${n}:${i}:${Math.round(a/1e3).toString().padStart(2,`0`)}`}static isNumeric(e){return!isNaN(parseFloat(e))&&!isNaN(e)}},Qt=class{constructor(e){this.pops={},this.def=`VEC_POP`,this.maxShowDistance=2e4,this.syncPopsHandler=e=>{this.SyncPops(e)},this.started=!1,this.dtcEngine=e,this.hostElement=e.getEngineConfig().dom,this.start()}start(){this.started||=(this.dtcEngine.on(`SyncPops`,this.syncPopsHandler),!0)}dispose(){this.started&&=(this.dtcEngine.off(`SyncPops`,this.syncPopsHandler),!1)}SyncPops(e){let t=JSON.parse(e.param??`[]`);Object.keys(this.pops).length!=0&&t.forEach(e=>{if(this.pops[e.groupName]&&this.pops[e.groupName][e.id]){let t=this.pops[e.groupName][e.id];t!=null&&(t.visible&&e.visible&&e.distance<this.maxShowDistance?t.showOnly(e.x,e.y,e.distance):t.disableOnly())}})}Set(e,t){e??=this.def,this.pops[e]||(this.pops[e]={}),t?.forEach(t=>{this.pops[e][t.id]||(this.pops[e][t.id]=t)})}RemovePop(e,t){e??=this.def,this.pops[e]&&(t==null?(Object.keys(this.pops[e]).map(t=>{if(this.pops[e]&&this.pops[e][t]){let n=this.pops[e][t];n&&n.dispose()}}),delete this.pops[e]):t.forEach(t=>{if(this.pops[e]&&this.pops[e][t]){let n=this.pops[e][t];n&&(n.dispose(),delete this.pops[e][t])}}))}RemoveAll(){Object.keys(this.pops).map(e=>{Object.keys(this.pops[e]).map(t=>{let n=this.pops[e][t];n&&n.dispose()}),delete this.pops[e]})}Switch(e,t,n){t??=this.def,this.pops[t]&&(n?n.forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable(),r.visible=e)}):Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable(),r.visible=e)}))}SwitchAll(e){Object.keys(this.pops).forEach(t=>{Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r!=null&&(e?r.show():r.disable())})})}SendNeedSyncPopsInfo(){let e=[];return Object.keys(this.pops).forEach(t=>{Object.keys(this.pops[t]).forEach(n=>{let r=this.pops[t][n];r.visible&&e.push({groupName:t,id:r.id,parentId:r.parentId,position:r.position})})}),e}},$t=class{constructor(e,t,n,r,i,a,o=0,s=0){this.id=t,this.parentId=a,this.div=n,[`mousedown`,`mouseup`,`mousemove`,`click`,`dblclick`,`contextmenu`,`wheel`,`touchstart`,`touchmove`,`touchend`,`touchcancel`].forEach(e=>{this.div?.addEventListener(e,t=>{t.stopPropagation(),(e===`contextmenu`||e===`wheel`)&&t.preventDefault()})}),this.position=i,this.offSetX=o,this.offSetY=s,this.outDistance=!1,this.visible=r??!0,this.videoDom=e,this.div&&(this.div.style.userSelect=`none`,this.div.style.touchAction=`none`,this.div.style.left=`-9999px`,this.div.style.top=`-9999px`,this.videoDom.appendChild(this.div))}showOnly(e,t,n){let r=this.videoDom.getBoundingClientRect(),i=r.left,a=r.top,o=this.offSetY;this.div.style.left=e+this.offSetX+i+`px`,this.div.style.top=t+o+a+`px`,this.div.style.display=`block`,this.div.style.position=`absolute`}disableOnly(){this.div.style.left=`-9999px`,this.div.style.top=`-9999px`,this.div.style.display=`none`}show(e,t){this.visible=!0,this.showOnly(e,t)}disable(){this.visible=!1,this.disableOnly()}dispose(){this.videoDom.contains(this.div)&&this.videoDom.removeChild(this.div)}},en=class extends x{constructor(e,t,n){super(e,`WebPopService`,n),this.popupManager=t}addPop(e,t){let n=(e.popInfo??[]).map(e=>{let t=Zt.getValueOrDefault(e,`offSetX`,0),n=Zt.getValueOrDefault(e,`offSetY`,0);return new $t(this.popupManager.hostElement,e.id,e.div,e.visible,e.position,e.parentId,t,n)});return this.popupManager.Set(e.groupName,n),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ft.addPop)}removePop(e={},t){return this.popupManager.RemovePop(e.groupName,e.ids),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ft.removePop)}removeAll(e){return this.popupManager.RemoveAll(),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),e,ft.removeAll)}show(e,t){let n=Zt.getValueOrDefault(e,`show`,!0);return this.popupManager.Switch(n,e.groupName,e.ids),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ft.show)}showAll(e=!0,t){return this.popupManager.SwitchAll(e),this.request(`SynPopsInfo`,this.popupManager.SendNeedSyncPopsInfo(),t,ft.showAll)}setPopDelayFrame(e,t){return this.request(`SetPopDelayFrame`,e,t,ft.setPopDelayFrame)}setPopShowDistance(e){if(e==null||typeof e!=`number`){console.log(`请检查传入参数,参见接口说明`);return}this.popupManager.maxShowDistance=e}},tn=class extends x{constructor(e,t){super(e,`WebScreenService`,t)}setSceneRenderBitrate(e={},t){let n=typeof e.bitrate==`number`?{bitrate:e.bitrate}:{bitrate:Ne[f(ht.setSceneRenderBitrate,e,this.moduleName,`SetSceneRenderBitrate`).bitrate??T.High]};return this.request(`SetSceneRenderBitrate`,n,t,ht.setSceneRenderBitrateResolved)}setSceneFPS(e={},t){let n={fps:e.fps??150};return this.request(`SetSceneRenderFPS`,n,t,ht.setSceneFPS)}setScreenResolution(e={},t){let n={width:e.width??1920,height:e.height??1080};return this.request(`SetScreenResolution`,n,t,ht.setScreenResolution)}},nn=class extends x{constructor(e,t){super(e,`SceneService`,t)}getAllSceneName(e){return this.request(`getAllSceneName`,void 0,e,rt.getAllSceneName)}switchSceneByName(e,t){return this.request(`switchSceneByName`,e,t,rt.switchSceneByName)}getCurrentSceneName(e){return this.request(`getCurrentSceneName`,void 0,e,rt.getCurrentSceneName)}},rn=class extends x{constructor(e,t){super(e,`SpatialQueryService`,t)}layerQueryByModel(e,t){let n={...e,queryRadius:e.queryRadius||50,queryMinHeight:e.queryMinHeight||0,queryMaxHeight:e.queryMaxHeight||20,queryParentIds:e.queryParentIds||[]};return n.id===void 0?(Zt.warn(`操作失败:id不能为空`),Promise.reject(`id is empty`)):this.request(`LayerQueryByModel`,n,t,Dt.layerQueryByModel)}layerQueryByPosition(e,t){let n={...e,queryRadius:e.queryRadius||20,queryMinHeight:e.queryMinHeight||0,queryMaxHeight:e.queryMaxHeight||20,queryParentIds:e.queryParentIds||[]};return n.queryPosition===void 0?(Zt.warn(`操作失败:queryPosition不能为空`),Promise.reject(`queryPosition is empty`)):this.request(`LayerQueryByPosition`,n,t,Dt.layerQueryByPosition)}layerQueryByModelBox(e,t){let n={...e,queryParentIds:e.queryParentIds||[]};return n.id===void 0?(Zt.warn(`操作失败:id不能为空`),Promise.reject(`id is empty`)):n.queryParentIds.length?this.request(`LayerQueryByModelCollider`,n,t,Dt.layerQueryByModelBox):(Zt.warn(`操作失败:queryParentIds不能为空`),Promise.reject(`queryParentIds is empty`))}},an=class extends x{constructor(e,t){super(e,`TimeLineService`,t)}play(e,t){let n={...e,speed:e.speed??1,initialTime:e.initialTime??0,keepLastFrame:e.keepLastFrame??!1};return this.requestStream(`Play`,n,t,mt.play)}pause(e,t){return this.request(`Pause`,e,t,mt.pause)}resume(e,t){return this.request(`Resume`,e,t,mt.resume)}stop(e,t){let n={...e,resetTime:e.resetTime??-1,isCameraToStart:e.isCameraToStart??!1};return this.request(`Stop`,n,t,mt.stop)}stopAll(e){return this.request(`StopAll`,void 0,e,mt.stopAll??M)}setSpeed(e,t){return this.request(`SetSpeed`,e,t,mt.setSpeed)}},on=class extends x{constructor(e,t){super(e,`TrainService`,t),this.camera=new Mt(e,t)}startTrain(e,t){let n={...e,direction:e.direction??`0`,action:e.action??`1`,stopTime:e.stopTime??180,moveType:e.moveType??`StopAtTheEnd`};return this.request(`SetTrainStart`,n,t,Ot.startTrain)}setTrainBehavior(e,t){let n={...e,moveType:e.moveType??`StopAtTheEnd`};return this.request(`SetTrainFollowBehavior`,n,t,Ot.setTrainBehavior)}setCameraFollowTrain(e,t){let n=e.offSet??new C(-100,0,30),r=new C(n.x,n.y,n.z,`0000`);return this.camera.startCameraObjFollow({parentId:e.parentId,id:e.id,offSet:r},t)}setTrainVolume(e,t){let n={...e,volumeOn:e.volumeOn??!0};return this.request(`SetTrainVolume`,n,t,Ot.setTrainVolume)}cancelCameraFollowTrain(e){return this.camera.endCameraObjFollow(e)}},sn=class extends x{constructor(e,t){super(e,`UIPOI`,t)}add(e,t){return this.request(`add`,e,t,z.add)}deleteById(e,t){return this.request(`deleteById`,e,t,z.deleteById)}deleteByGroup(e,t){return this.request(`deleteByGroup`,e,t,z.deleteByGroup)}update(e,t){return this.request(`update`,e,t,z.update)}updatePoiStates(e,t){return this.request(`updatePoiStates`,e,t,z.updatePoiStates)}enableOverlap(e,t){let n={...e,enable:e.enable??!0};return this.request(`enableOverlap`,n,t,z.enableOverlap)}showDistance(e,t){return this.request(`showDistance`,e,t,z.showDistance)}},cn=class extends x{constructor(e,t){super(e,`WebViewService`,t)}updateWebView(e,t){let n={...e};return this.request(`UpdateWebView`,n,t,St.updateWebView)}},ln=class extends x{constructor(e,t){super(e,`WeathersService`,t)}changeWeatherType(e,t){let n={weatherType:e.weatherType,timeDuration:e.timeDuration||6};return this.request(`ChangeWeatherType`,n,t,R.changeWeatherType)}getWeatherTypes(e){return this.request(`GetWeatherPresets`,void 0,e,M)}resetWeather(e){return this.request(`ResetWeather`,void 0,e,M)}setSceneTime(e,t){let n={...e,timeDuration:e.timeDuration??5};return this.request(`SetCurrentSceneTime`,n,t,R.setSceneTime)}setTimeSync(e,t){let n={...e,syncSystemTime:e.syncSystemTime??!1};return this.request(`SetTimeSync`,n,t,R.setTimeSync)}resetSceneTime(e){return this.request(`ResetSceneTime`,{},e,R.resetSceneTime)}setAnimateTimeOfDay(e,t){let n={...e,isAnimate:e.isAnimate??!0,dayLength:e.dayLength??.5,nightLength:e.nightLength??.5};return this.request(`SetAnimateTimeOfDay`,n,t,R.setAnimateTimeOfDay)}resetWeatherAndTime(e){return this.request(`ResetWeatherAndTime`,void 0,e,M)}changeSeason(e,t){return this.request(`ChangeSeason`,e,t,R.changeSeason)}resetSeason(e){return this.request(`ResetSeason`,{},e,R.resetSeason)}setDayAndNight(e,t){return this.request(`setDayAndNight`,e,t,R.setDayAndNight)}setWeatherVolume(e,t){let n={...e,volumeOn:e.volumeOn??!0};return this.request(`SetWeatherVolume`,n,t,R.setWeatherVolume)}openCameraFog(e,t){let n={...e,fogIntensity:e.fogIntensity??-1,fogStartDistance:e.fogStartDistance??-1,fogEndDistance:e.fogEndDistance??-1,directionalIntensity:e.directionalIntensity??-1,directionalFallOff:e.directionalFallOff??-1};return this.request(`openCameraFog`,n,t,R.openCameraFog)}closeCameraFog(e){return this.request(`closeCameraFog`,void 0,e,R.closeCameraFog??M)}};const un={Connect:e=>new Nt(e.bridge,e.connectionLifecycle,{logger:e.createLogger(`Connect`)}),Type:()=>new Rt,Screen:e=>new tn(e.bridge,{logger:e.createLogger(`Screen`)}),Dlss:e=>new Pt(e.bridge,{logger:e.createLogger(`Dlss`)}),Camera:e=>new Mt(e.bridge,{logger:e.createLogger(`Camera`)}),Scene:e=>new nn(e.bridge,{logger:e.createLogger(`Scene`)}),Layer:e=>new zt(e.bridge,{logger:e.createLogger(`Layer`)}),Model:e=>new Bt(e.bridge,{logger:e.createLogger(`Model`)}),UIPOI:e=>new sn(e.bridge,{logger:e.createLogger(`UIPOI`)}),ModelPOI:e=>new Vt(e.bridge,{logger:e.createLogger(`ModelPOI`)}),ModelTransform:e=>new Ht(e.bridge,{logger:e.createLogger(`ModelTransform`)}),Navigation:e=>new Ut(e.bridge,{logger:e.createLogger(`Navigation`)}),PathPatrol:e=>new Wt(e.bridge,{logger:e.createLogger(`PathPatrol`)}),pointIcon:e=>new qt(e.bridge,{logger:e.createLogger(`pointIcon`)}),PointEditor:e=>new Xt(e.bridge,{logger:e.createLogger(`PointEditor`),getVideoElement:()=>e.videoElementParent?.querySelector(`video`)??null}),GizmosTool:e=>new Oe(e.bridge,{logger:e.createLogger(`GizmosTool`),beginMouseInput:e.beginPointEditorMouseInput}),HeatMap:e=>new Ft(e.bridge,{logger:e.createLogger(`HeatMap`)}),HighlighterEffect:e=>new It(e.bridge,{logger:e.createLogger(`HighlighterEffect`)}),Popup:e=>new en(e.bridge,e.popupManager,{logger:e.createLogger(`Popup`)}),Animation:e=>new jt(e.bridge,{logger:e.createLogger(`Animation`)}),TimeLine:e=>new an(e.bridge,{logger:e.createLogger(`TimeLine`)}),WeatherSystem:e=>new ln(e.bridge,{logger:e.createLogger(`WeatherSystem`)}),WebView:e=>new cn(e.bridge,{logger:e.createLogger(`WebView`)}),SpatialQuery:e=>new rn(e.bridge,{logger:e.createLogger(`SpatialQuery`)}),TrainSimulate:e=>new on(e.bridge,{logger:e.createLogger(`TrainSimulate`)})},dn=Object.freeze(Object.keys(un)),V=[`DTCEngine 已完成鉴权并建立 WebRTC 连接`],H=`Promise<ApiResponseEnvelope<unknown>>`,fn={Connect:{title:`连接控制`,description:`连接控制 API。`,capabilities:[`连接建立`,`连接断开`,`连接重连`,`会话接管`,`会话保活`,`服务状态查询`],methods:{connect:{description:"发起连接(兼容接口,SDK 实际已在 `new DTCEngine` 后自动连接)。",payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},disconnect:{description:`断开连接。`,payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},reconnect:{description:`重新连接。`,payloadType:``,returnType:`Promise<ApiResponseEnvelope<void>>`,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},KickOtherConnect:{description:`踢掉已存在会话并接管连接。`,payloadType:``,returnType:H,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},KeepConnect:{description:`保持当前连接会话。`,payloadType:``,returnType:H,sideEffects:[`connection`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},GetEngineServiceStatus:{description:`获取引擎服务状态。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Type:{title:`数学类型`,description:`SDK 数学类型构造器。`,capabilities:[`二维向量类型`,`三维向量类型`,`四维向量类型`,`坐标参数构造`],methods:{}},Screen:{title:`画面质量控制`,description:`屏幕与渲染质量控制 API。`,capabilities:[`渲染码率调整`,`场景帧率调整`,`屏幕分辨率调整`],methods:{setSceneRenderBitrate:{description:`设置场景渲染码率档位。`,payloadType:`ScreenSetSceneRenderBitrateRequest | { bitrate: number }`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{bitrate:`high`}],riskLevel:`low`,responseMode:`single`},setSceneFPS:{description:`设置场景帧率。`,payloadType:`ScreenSetSceneFPSRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fps:30}],riskLevel:`low`,responseMode:`single`},setScreenResolution:{description:`设置渲染分辨率。`,payloadType:`ScreenSetScreenResolutionRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{width:1280,height:720}],riskLevel:`low`,responseMode:`single`}}},Dlss:{title:`DLSS 画质控制`,description:`DLSS 画质控制 API。`,capabilities:[`DLSS 开关控制`,`DLSS 质量档位控制`],methods:{setDlss:{description:`同时设置 DLSS 开关和质量档位。`,payloadType:`DlssSetEnableRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{enable:!0,quality:`Balanced`}],riskLevel:`low`,responseMode:`single`}}},Camera:{title:`相机控制`,description:`相机相关操作 API。`,capabilities:[`模型视角定位`,`批量目标定位`,`自由飞行`,`路径飞行`,`飞行控制`,`相机信息查询`,`相机姿态设置`,`视场角控制`,`相机重置`,`相机跟随控制`],methods:{lookAt:{description:`定位到指定模型对象或对象集合。`,payloadType:`CameraLookAtRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Sphere`,time:2}],riskLevel:`low`,responseMode:`single`},flyToTarget:{description:`相机飞向指定坐标点,并在飞行过程中看向目标点。`,payloadType:`CameraFlyToTargetRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{point:{x:120.1704,y:30.2472,z:148.1303,ePSGType:`0000`},target:{x:120.1691,y:30.2471,z:65.7,ePSGType:`0000`},time:2}],riskLevel:`low`,responseMode:`single`},flyByPath:{description:`按多点路径执行相机飞行。`,payloadType:`CameraFlyByPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{points:[{x:0,y:0,z:100},{x:100,y:0,z:100}],lookAts:[{x:0,y:0,z:0},{x:100,y:0,z:0}],time:6,smoothMode:0}],riskLevel:`low`,responseMode:`single`},setFlySpeed:{description:`设置相机飞行速度。`,payloadType:`CameraSetFlySpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{speed:2}],riskLevel:`low`,responseMode:`single`},endFly:{description:`终止当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},pauseFly:{description:`暂停当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},resumeFly:{description:`恢复当前飞行。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},getCameraInfo:{description:`获取当前相机信息。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setCameraPositionAndRotation:{description:`设置相机位置与旋转。`,payloadType:`CameraSetPositionAndRotationRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{point:{x:0,y:0,z:100,ePSGType:`0000`},rotation:{x:0,y:0,z:0,ePSGType:`0000`}}],riskLevel:`low`,responseMode:`single`},setCameraFov:{description:`设置相机 FOV。`,payloadType:`CameraSetFovRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fov:75}],riskLevel:`low`,responseMode:`single`},resetCameraFov:{description:`重置相机 FOV。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},reset:{description:`重置相机到默认状态。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},startCameraObjFollow:{description:`相机跟随场景中运动的对象。`,payloadType:`CameraObjFollowRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`myCar`,offSet:{x:0,y:3,z:5,ePSGType:`0000`},smooth:.85}],riskLevel:`low`,responseMode:`single`},endCameraObjFollow:{description:`停止相机跟随。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Scene:{title:`场景管理`,description:`场景管理 API。`,capabilities:[`场景列表查询`,`场景切换`,`当前场景查询`,`地图罗盘监听`,`场景特性开关`,`场景元数据查询`],methods:{getAllSceneName:{description:`获取当前引擎服务支持的场景名称列表。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},switchSceneByName:{description:`按场景名称切换场景。`,payloadType:`SceneSwitchRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{sceneName:`TestScene`}],riskLevel:`low`,responseMode:`single`},getCurrentSceneName:{description:`获取当前正在运行的场景名称。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},Layer:{title:`图层管理`,description:`场景图层对象管理 API。`,capabilities:[`图层添加`,`图层删除`,`图层存在性查询`,`模型图层切换`,`图层气泡显隐`,`图层模型添加`,`图层模型删除`,`图层子对象查询`,`POI名称更新`,`POI名称重置`,`气泡状态更新`],methods:{addLayer:{description:`添加对象图层组。`,payloadType:`LayerAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraGroup`,id:`CameraLayerModel`,layerName:`摄像机图层`,show:!0,poiEnabled:!0,type:`MODEL`}],riskLevel:`low`,responseMode:`single`},removeLayer:{description:`删除对象图层组,并清空其下所有对象。`,payloadType:`LayerSelectorRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraGroup`,id:`CameraLayerModel`}],riskLevel:`low`,responseMode:`single`},isLayerOrGroupExit:{description:`判断图层或组对象是否存在。`,payloadType:`LayerSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{id:`cameraGroup`}],riskLevel:`low`,responseMode:`single`},switchModelLayer:{description:`切换模型的图层组。`,payloadType:`LayerSwitchModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,ids:[`camera01`,`camera02`],toParentId:`destLayer`}],riskLevel:`low`,responseMode:`single`},showUIPop:{description:`显示或隐藏指定图层下的 UI Pop。`,payloadType:`LayerShowUIPopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`CameraLayer`,visible:!0}],riskLevel:`low`,responseMode:`single`},addModel:{description:`在指定图层下添加模型资源。`,payloadType:`LayerModelAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,id:`camera01`,assetsPath:`Sphere`}],riskLevel:`low`,responseMode:`single`},addPOI:{description:`在指定图层下添加模型资源。`,payloadType:`LayerPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,id:`camera01`,assetsPath:`Sphere`}],riskLevel:`low`,responseMode:`single`},updatePOIName:{description:`更新 POI 气泡的显示文本。`,payloadType:`LayerUpdatePOINameRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraLayerModel`,id:`camera01`,name:`一体化球击摄像机`,updateType:`update`}],riskLevel:`low`,responseMode:`single`},resetPOIName:{description:`*`,payloadType:`LayerResetPOINameRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`CameraLayerModel`,ids:[`camera01`,`camera02`]}],riskLevel:`low`,responseMode:`single`},updatePoiStates:{description:`更新分组下气泡的状态。`,payloadType:`LayerUpdatePoiStatesRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`LCD80CunXianShiPingPop`,poiStates:[{id:`1`,state:`normal`},{id:`2`,state:`alert`}]}],riskLevel:`low`,responseMode:`single`},removeModel:{description:`删除图层下指定模型资源。`,payloadType:`LayerModelRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraLayer`,ids:[`camera01`,`camera02`]}],riskLevel:`low`,responseMode:`single`},getLayerChildElement:{description:`获取图层下所有一级子对象。`,payloadType:`LayerChildElementRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{id:`test`}],riskLevel:`low`,responseMode:`single`}}},Model:{title:`模型管理`,description:`模型对象管理 API。`,capabilities:[`模型显隐控制`,`模型添加`,`模型删除`,`模型树查询`,`模型信息查询`,`模型包围盒查询`],methods:{setVisible:{description:`设置模型对象显隐状态。`,payloadType:`ModelSetVisibleRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`cameraGroup`,id:[`camera01`,`camera02`],visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByTags:{description:`按标签批量设置模型对象显隐状态。`,payloadType:`ModelSetVisibleByTagsRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{tags:[`camera`,`sensor`],visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByAttribute:{description:`按对象属性过滤设置模型对象显隐状态。`,payloadType:`ModelSetVisibleByAttributeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{attributes:{floor:`B2`},filterMode:0,visible:!1}],riskLevel:`low`,responseMode:`single`},getElementTree:{description:`获取指定节点的一层子对象树。`,payloadType:`ModelSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`test`,id:`Root`}],riskLevel:`low`,responseMode:`single`},getModelInfo:{description:`获取指定模型对象信息。`,payloadType:`ModelSelectorRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`test`,id:`Sphere`}],riskLevel:`low`,responseMode:`single`}}},UIPOI:{title:`后端 UI 气泡`,description:`后端 UI 气泡(UIPOI)管理 API。`,capabilities:[`UI 气泡添加`,`UI 气泡删除`,`UI 气泡更新`,`弹窗状态更新`,`重叠控制`,`距离显示控制`],methods:{add:{description:`批量添加 UIPOI。`,payloadType:`UIPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,poiInfos:[{id:`camera01`,state:`normal`}]}],riskLevel:`low`,responseMode:`single`},deleteById:{description:`删除指定组下的单个 UIPOI。`,payloadType:`UIPOIDeleteByIdRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,id:`camera01`}],riskLevel:`low`,responseMode:`single`},deleteByGroup:{description:`删除指定组下的全部 UIPOI。`,payloadType:`UIPOIDeleteByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`}],riskLevel:`low`,responseMode:`single`},update:{description:`更新指定组 UIPOI 配置。`,payloadType:`UIPOIUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`testGroup`,poiInfos:[{id:`camera01`,state:`alert`}]}],riskLevel:`low`,responseMode:`single`},updatePoiStates:{description:`批量更新 UIPOI 状态。`,payloadType:`UIPOIUpdateStateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`LCD80CunXianShiPingPop`,popStates:[{id:`1`,state:`normal`}]}],riskLevel:`low`,responseMode:`single`},enableOverlap:{description:`开启或关闭 UIPOI 碰撞避让。`,payloadType:`UIPOIEnableOverlapRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{enable:!1}],riskLevel:`low`,responseMode:`single`},showDistance:{description:`设置 UIPOI 可视距离。`,payloadType:`UIPOIShowDistanceRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{distance:800}],riskLevel:`low`,responseMode:`single`}}},ModelPOI:{title:`模型气泡`,description:`模型气泡(ModelPOI)管理 API。`,capabilities:[`模型气泡添加`,`模型气泡删除`,`模型气泡查询`,`模型气泡更新`,`分组显隐控制`],methods:{add:{description:`添加模型气泡。`,payloadType:`ModelPOIAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`123`,groupName:`cameraGroup`,assetPath:`dotPop`,targetId:`Camera01`}],riskLevel:`low`,responseMode:`single`},deleteById:{description:`按编号批量删除模型气泡。`,payloadType:`ModelPOIDeleteByIdRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`cameraGroup`,ids:[`Camera01`]}],riskLevel:`low`,responseMode:`single`},deleteByGroup:{description:`删除指定组下全部模型气泡。`,payloadType:`ModelPOIDeleteByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`}],riskLevel:`low`,responseMode:`single`},getPOIInfo:{description:`获取单个模型气泡信息。`,payloadType:`ModelPOIGetInfoRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{groupName:`cameraGroup`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},update:{description:`更新模型气泡信息。`,payloadType:`ModelPOIUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`123`,groupName:`cameraGroup`,assetPath:`dotPop`,visible:!1}],riskLevel:`low`,responseMode:`single`},setVisibleByGroup:{description:`设置指定组模型气泡显隐。`,payloadType:`ModelPOIVisibleByGroupRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`myGroup`,visible:!0}],riskLevel:`low`,responseMode:`single`}}},ModelTransform:{title:`模型变换`,description:`模型对象变换 API,涵盖旋转、缩放、移动操作。`,capabilities:[`模型轨迹移动`,`暂停/继续/结束移动`,`恢复位置`,`模型旋转`,`绕目标旋转`,`恢复旋转`,`模型缩放`,`停止缩放`,`恢复缩放`],methods:{startMoveByNodes:{description:`设置模型对象的移动轨迹。`,payloadType:`ModelTransformStartMoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myRobot`,nodes:[{x:120.0001,y:30.0001,z:100.1},{x:122.0001,y:28.0001,z:110.1}],speed:3,linear:1,isLookAtTarget:!0}],riskLevel:`low`,responseMode:`single`},pauseMove:{description:`暂停模型对象的移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myRobot`}],riskLevel:`low`,responseMode:`single`},resumeMove:{description:`继续模型对象的移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},endMove:{description:`结束轨迹移动。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},restoreMove:{description:`重置对象到原来的位置。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`},rotate:{description:`指定轴旋转模型角度到。`,payloadType:`ModelTransformRotateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myBus`,rotate:{x:30,y:180,z:120}}],riskLevel:`low`,responseMode:`single`},endRotate:{description:`结束旋转。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`myBus`}],riskLevel:`low`,responseMode:`single`},continuedRotate:{description:`持续不断的绕自身旋转。`,payloadType:`ModelTransformRotateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,rotate:{x:30,y:180,z:120}}],riskLevel:`low`,responseMode:`single`},rotateByTarget:{description:`围绕某个对象做旋转。`,payloadType:`ModelTransformRotateByTargetRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,targetID:`target`,point:{x:1,y:2,z:3},axisX:1,axisY:0,axisZ:0,angle:10,isPersistence:!0}],riskLevel:`low`,responseMode:`single`},restoreRotate:{description:`重置恢复场景多个对象的旋转。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`},setScale:{description:`设置模型对象的缩放。`,payloadType:`ModelTransformScaleRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`,scale:{x:.5,y:.5,z:.5},duration:3}],riskLevel:`low`,responseMode:`single`},endScale:{description:`停止模型对象的缩放。`,payloadType:`ModelTransformNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,id:`Camera01`}],riskLevel:`low`,responseMode:`single`},restoreScale:{description:`重置模型的缩放,恢复到开始状态。`,payloadType:`ModelTransformRestoreRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{ids:[`Camera01`,`Camera02`]}],riskLevel:`low`,responseMode:`single`}}},Navigation:{title:`对象导航`,description:`场景对象导航 API,支持两种导航模式:`,capabilities:[`网格导航寻路`,`导航距离查询`,`网格导航暂停`,`网格导航继续`,`网格导航停止`,`网格导航属性修改`,`路径导航开始`,`路径导航暂停`,`路径导航继续`,`路径导航停止`,`路径导航属性修改`],methods:{startNav:{description:`网格导航寻路:模型对象根据路过的节点进行导航。`,payloadType:`NavigationMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,planColor:`#00ff00`,passColor:`#e1e1e1`}],riskLevel:`low`,responseMode:`single`},getMeshNavDistance:{description:`网格导航距离查询:模型对象根据路过的节点进行导航,并返回导航距离信息。`,payloadType:`NavigationMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,planColor:`#00ff00`,passColor:`#e1e1e1`}],riskLevel:`low`,responseMode:`single`},pauseNav:{description:`暂停模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},resumeNav:{description:`继续模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},stopNav:{description:`停止模型对象网格导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},updateNav:{description:`设置网格导航路径属性。`,payloadType:`NavigationUpdateMeshNavRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,planColor:`#00ff00`,passColor:`#e1e1e1`,speed:4}],riskLevel:`low`,responseMode:`single`},updateSpeed:{description:`设置网格导航路径属性。`,payloadType:`NavigationUpdateSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:`Player1`,speed:4}],riskLevel:`low`,responseMode:`single`},startNavByPath:{description:`路径导航开始:根据指定的轨迹节点进行直线导航行走。`,payloadType:`NavigationNavByPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],nodes:[{x:114.7985155712282,y:34.842421780635625,z:2},{x:114.79789723105696,y:34.84218433379876,z:1.5}],isCache:!1,duration:10}],riskLevel:`low`,responseMode:`single`},pauseNavPath:{description:`暂停模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},resumeNavPath:{description:`继续模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},stopNavPath:{description:`停止模型对象路径导航。`,payloadType:`NavigationNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`]}],riskLevel:`low`,responseMode:`single`},updateNavPath:{description:`设置路径导航属性。`,payloadType:`NavigationUpdateNavPathRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`Players`,id:[`Player1`,`MyRobut`],planColor:`#00ff00`,passColor:`#e1e1e1`,duration:5}],riskLevel:`low`,responseMode:`single`}}},PathPatrol:{title:`路径巡逻`,description:`路径巡逻 API,支持巡逻路线添加、样式修改、时间节点设置与巡逻控制。`,capabilities:[`添加巡逻路线`,`修改巡逻样式`,`设置巡逻时间节点`,`清除巡逻路径`,`暂停巡逻`,`继续巡逻`,`停止巡逻`],methods:{add:{description:`添加巡逻路线。`,payloadType:`PathPatrolAddRequest`,returnType:`StreamRequestPromise<unknown>`,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,assetPath:`PatrolMan`,scale:{x:2,y:2,z:2},showPath:!0,passedColor:`#ff0013`,lineColor:`#0040ef`,lineWidth:2,nodes:[{x:114.79234244388735,y:34.8353249473732,z:67.76611328125},{x:114.78552975378634,y:34.84532722646887,z:67.76627349853516}],duration:10}],riskLevel:`low`,responseMode:`stream`},update:{description:`修改巡逻路径的样式。`,payloadType:`PathPatrolUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,lineColor:`#ff00ff`,lineWidth:3.5}],riskLevel:`low`,responseMode:`single`},setTimeNode:{description:`设置巡逻开始的时间节点或是节点索引。`,payloadType:`PathPatrolSetTimeNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`patrolLayer`,id:`patrolMan`,timeStart:`2025-09-10 00:05:00`}],riskLevel:`low`,responseMode:`single`},clear:{description:`清除巡逻路径。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},pause:{description:`暂停巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`},resume:{description:`继续巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`},stop:{description:`停止巡逻。`,payloadType:`PathPatrolNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`patrolMan`}],riskLevel:`low`,responseMode:`single`}}},pointIcon:{title:`设备点位图标`,description:`设备点位图标显隐控制 API。`,capabilities:[`指定点位显隐`,`按编码点位显隐`,`分组点位显隐`,`全部点位显隐`],methods:{show:{description:`显示指定设备点位的图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`point-001`,`point-002`]}],riskLevel:`low`,responseMode:`single`},hide:{description:`隐藏指定设备点位的图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`point-001`,`point-002`]}],riskLevel:`low`,responseMode:`single`},showByCode:{description:`显示指定编码(code)的全部设备点位图标,编码精确匹配且不要求唯一。`,payloadType:`PointIconCodesInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{codes:[`CAM-001`,`CAM-002`]}],riskLevel:`low`,responseMode:`single`},hideByCode:{description:`隐藏指定编码(code)的全部设备点位图标,编码精确匹配且不要求唯一。`,payloadType:`PointIconCodesInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{codes:[`CAM-001`,`CAM-002`]}],riskLevel:`low`,responseMode:`single`},showByGroup:{description:`显示指定分组及其子分组内的设备点位图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`group-f1`]}],riskLevel:`low`,responseMode:`single`},hideByGroup:{description:`隐藏指定分组及其子分组内的设备点位图标。`,payloadType:`PointIconIdsInput`,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,examples:[{ids:[`group-f1`]}],riskLevel:`low`,responseMode:`single`},showAll:{description:`显示全部设备点位图标。`,payloadType:``,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`},hideAll:{description:`隐藏全部设备点位图标。`,payloadType:``,returnType:`Promise<PointIconResponse>`,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`}}},PointEditor:{title:`模型点位编辑`,description:`MODEL 打点 API,复用既有场景对象;不读写平台 JSON、PointTool 文件或修改 MQTT 流程。`,capabilities:[`按坐标创建点位`,`点击创建点位`,`拖放创建点位`,`落点坐标换算`,`取消点位放置`,`局部更新点位`,`批量删除点位`],methods:{addPoint:{description:`创建模型点位;未传 position/screenPosition 时等待视频区域的一次有效点击,可按 Escape/右键取消。`,payloadType:`PointEditorAddRequest`,returnType:`Promise<PointEditorPoint>`,sideEffects:[`write`],preconditions:[`已建立 WebRTC 连接,UE CoreModules 支持 sdk3 点位编辑`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`,type:`MODEL`,position:{x:120,y:30,z:5},resource:{path:`/Game/Devices/BP_Camera.BP_Camera_C`}}],riskLevel:`medium`,responseMode:`single`},addPointByDrag:{description:`拖放创建;使用 drop 当时保存的 screenPosition 或显式经纬高,不读取当前或上一次鼠标位置。`,payloadType:`PointEditorAddRequest`,returnType:`Promise<PointEditorPoint>`,sideEffects:[`write`],preconditions:[`已建立 WebRTC 连接;必须提供 position 或 drop 时记录的 screenPosition`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-2`,type:`MODEL`,position:{x:120,y:30,z:5},resource:{path:`/Game/Devices/BP_Camera.BP_Camera_C`}}],riskLevel:`medium`,responseMode:`single`},getScreenPosition:{description:`在实际 drop 事件中同步换算位置,随后可等待后端保存;不在等待结束后重新读取鼠标。`,payloadType:`PointEditorClientPosition`,returnType:`PointEditorScreenPosition`,sideEffects:[`read`],preconditions:[`视频已就绪,必须使用真实 drop 事件坐标`],examples:[{clientX:400,clientY:300}],riskLevel:`low`,responseMode:`single`},cancelPlacement:{description:`取消正在等待网页点击的放置操作并恢复输入;不撤销已经发送到 UE 的创建请求。`,payloadType:``,returnType:`Promise<void>`,sideEffects:[`write`],riskLevel:`low`,responseMode:`single`},updatePoint:{description:`局部更新 MODEL 及附属 POI;不传的字段保持原值,false、0 和空名称有效。`,payloadType:`PointEditorUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:[`目标是既有场景加载或 API 创建的 MODEL;PointTool 本地工作台对象除外`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`,type:`MODEL`,show:!1}],riskLevel:`medium`,responseMode:`single`},deletePoints:{description:`批量删除网页模型点位及附属 POI;混入其他来源或纯 POI 目标时整批拒绝。`,payloadType:`PointEditorDeleteRequest`,returnType:`Promise<ApiResponseEnvelope<PointEditorDeleteResult>>`,sideEffects:[`write`],preconditions:[`目标属于场景 MODEL 点位管理范围,按 parentId/id 准确定位`],examples:[{parentId:`sdk3-point-editor-test`,ids:[`G-test-1`]}],riskLevel:`high`,responseMode:`single`}}},GizmosTool:{title:`模型交互编辑`,description:`网页 MODEL 运行时编辑,不开启本地工作台,不保存 PointTool 文件。`,capabilities:[`开启模型编辑`,`切换编辑目标`,`退出模型编辑`,`模型表面吸附`],methods:{startSimpleGizmoMode:{description:`开启或切换模型编辑目标,同时显示平移、旋转和缩放手柄,无需指定编辑模式。`,payloadType:`GizmosStartSimpleRequest`,returnType:H,sideEffects:[`write`],preconditions:[`WebRTC 已连接;PointTool 本地工作台未占用输入`],examples:[{parentId:`sdk3-point-editor-test`,id:`G-test-1`}],riskLevel:`medium`,responseMode:`single`},endSimpleGizmoMode:{description:`退出简易编辑并恢复进入前的鼠标转发配置,不保存本地点位文件。`,payloadType:``,returnType:H,sideEffects:[`write`],riskLevel:`low`,responseMode:`single`},modelSnapById:{description:`将指定模型或整个分组吸附到允许的最近表面,安装类型沿用 UE 资源绑定及点位安装属性。`,payloadType:`GizmosModelSnapRequest`,returnType:`Promise<ApiResponseEnvelope<GizmosModelSnapResult>>`,sideEffects:[`write`],preconditions:[`WebRTC 已连接;UE 已编译表面吸附服务;本地工作台未占用输入`],examples:[{parentId:`sdk3-point-editor-test`,ids:[`G-test-1`]}],riskLevel:`medium`,responseMode:`single`}}},HeatMap:{title:`热力图`,description:`热力图 API,支持热力图创建(地理热力点数据)、移除、清空与参数设置。`,capabilities:[`创建热力图`,`移除热力图`,`清除热力图`,`修改热力图参数`],methods:{create:{description:`创建热力图。`,payloadType:`HeatMapCreateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`,influenceSize:50,points:[{position:{x:120.15,y:30.28,z:10,ePSGType:`4326`},value:.8}]}],riskLevel:`low`,responseMode:`single`},remove:{description:`移除热力图。`,payloadType:`HeatMapRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`}],riskLevel:`low`,responseMode:`single`},clear:{description:`清空全部热力图,无需传参。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setConfig:{description:`设置热力图参数(透明度/高度缩放/颜色过渡)。`,payloadType:`HeatMapConfigRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`heatMap1`,opacity:.5,heightScale:3e3,lerpScale:3}],riskLevel:`low`,responseMode:`single`}}},HighlighterEffect:{title:`高亮效果`,description:`高亮效果 API,控制场景中模型对象的高亮。`,capabilities:[`打开高亮`,`关闭高亮`,`模型高亮`,`移除模型高亮`,`清除全部高亮`],methods:{enable:{description:`打开高亮效果。`,payloadType:`HighLighterEnableRequest`,returnType:H,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`},setHighLightModel:{description:`设置场景当中,指定模型对象 高亮效果`,payloadType:`HighLighterSetHighLightModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,ids:[`Sphere`,`Sphere1`],showBack:!0}],riskLevel:`low`,responseMode:`single`},removeHighLightModel:{description:`清除 指定模型对象的高亮效果`,payloadType:`HighLighterRemoveHighLightModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`test`,ids:[`Sphere`,`Sphere1`]}],riskLevel:`low`,responseMode:`single`},clear:{description:`清除场景中模型的所有的高亮效果`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,riskLevel:`low`,responseMode:`single`}}},Popup:{title:`前端 Popup`,description:`前端 Popup 管理 API。`,capabilities:[`Popup 添加`,`Popup 删除`,`Popup 清除`,`Popup 显隐控制`,`Popup 全部显隐控制`,`Popup 延迟帧控制`,`Popup 显示距离控制`],methods:{addPop:{description:`创建前端弹出气泡。`,payloadType:`PopupAddRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`CameraPopGroup`,popInfo:[{id:`Camera1`,visible:!0}]}],riskLevel:`low`,responseMode:`single`},removePop:{description:`删除前端气泡。`,payloadType:`PopupRemoveRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`cameraLayer`,ids:[`camera01`]}],riskLevel:`low`,responseMode:`single`},removeAll:{description:`清除所有前端气泡。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[void 0],riskLevel:`low`,responseMode:`single`},show:{description:`显示或隐藏气泡。`,payloadType:`PopupShowRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{groupName:`CameraPopGroup`,ids:[`Camera2`],show:!1}],riskLevel:`low`,responseMode:`single`},showAll:{description:`显示或隐藏所有组下的所有气泡。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[!0],riskLevel:`low`,responseMode:`single`},setPopDelayFrame:{description:`设置前端气泡同步的延迟时间。`,payloadType:`PopupDelayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{time:.3}],riskLevel:`low`,responseMode:`single`},setPopShowDistance:{description:`设置前端页面气泡最远的显示距离(仅本地生效,不发送请求)。`,payloadType:``,returnType:`void`,sideEffects:[`write`],preconditions:V,examples:[2e3],riskLevel:`low`,responseMode:`single`}}},Animation:{title:`模型动画`,description:`控制模型 Animator 和循环动画。`,capabilities:[`循环动画播放`,`循环动画停止`,`Animator 播放`,`Animator 停止`,`动画速度控制`,`动画长度查询`],methods:{startLoopAnimation:{description:`播放循环动画片段。`,payloadType:`AnimationStartLoopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`,loopStartTime:0,loopEndTime:3,speed:1}],riskLevel:`low`,responseMode:`single`},stopLoopAnimation:{description:`停止循环动画片段。`,payloadType:`AnimationStopLoopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`}],riskLevel:`low`,responseMode:`single`},playAnimator:{description:`播放 Animator 动画片段。`,payloadType:`AnimationPlayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`,speed:1,startTime:0,endTime:1,isStop:!1}],riskLevel:`low`,responseMode:`single`},setAnimatorSpeed:{description:`设置 Animator 动画播放速度。`,payloadType:`AnimationSetSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,speed:1.5}],riskLevel:`low`,responseMode:`single`},getAnimationLength:{description:`获取动画片段长度。`,payloadType:`AnimationGetLengthRequest`,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`,stateName:`door_open`}],riskLevel:`low`,responseMode:`single`},stopAnimator:{description:`停止指定对象的 Animator 播放。`,payloadType:`AnimationStopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`AnimatorTest`,id:`rotateObj`}],riskLevel:`low`,responseMode:`single`}}},TimeLine:{title:`时间线动画`,description:`TimeLine 动画控制 API。`,capabilities:[`时间线播放`,`时间线暂停`,`时间线恢复`,`时间线停止`,`全部时间线停止`,`播放速度控制`],methods:{play:{description:`播放指定 TimeLine 动画。`,payloadType:`TimelinePlayRequest`,returnType:`StreamRequestPromise<unknown>`,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,speed:2}],riskLevel:`low`,responseMode:`stream`},pause:{description:`暂停指定 TimeLine 动画。`,payloadType:`TimelineNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`}],riskLevel:`low`,responseMode:`single`},resume:{description:`继续播放指定 TimeLine 动画。`,payloadType:`TimelineNodeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`}],riskLevel:`low`,responseMode:`single`},stop:{description:`停止指定 TimeLine 动画。`,payloadType:`TimelineStopRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,resetTime:-1,isCameraToStart:!1}],riskLevel:`low`,responseMode:`single`},stopAll:{description:`停止全部 TimeLine 动画。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setSpeed:{description:`设置指定 TimeLine 的播放速度。`,payloadType:`TimelineSetSpeedRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{id:`Path1`,speed:1.2}],riskLevel:`low`,responseMode:`single`}}},WeatherSystem:{title:`天气时间环境`,description:`天气与时间环境控制 API。`,capabilities:[`天气类型查询`,`天气切换`,`天气重置`,`天气时间重置`,`场景时间设置`,`时间同步控制`,`昼夜动画控制`,`昼夜模式设置`,`季节切换`,`季节重置`,`雾效开启`,`雾效关闭`,`天气音量控制`],methods:{changeWeatherType:{description:`切换天气类型。`,payloadType:`WeatherTypeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{weatherType:`Clear_Skies`,timeDuration:6}],riskLevel:`low`,responseMode:`single`},getWeatherTypes:{description:`得到所有天气类型。`,payloadType:``,returnType:H,sideEffects:[`read`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},resetWeather:{description:`重置天气`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setSceneTime:{description:`设置场景时间(小时)。`,payloadType:`WeatherSetSceneTimeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{hour:10.5,timeDuration:5}],riskLevel:`low`,responseMode:`single`},setTimeSync:{description:`设置是否同步系统时间。`,payloadType:`WeatherSetTimeSyncRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{syncSystemTime:!0}],riskLevel:`low`,responseMode:`single`},resetSceneTime:{description:`重置场景时间。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setAnimateTimeOfDay:{description:`设置是否模拟白天,黑夜轮换动画。`,payloadType:`WeatherSetAnimateTimeOfDayRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{isAnimate:!0,dayLength:.5,nightLength:.5}],riskLevel:`low`,responseMode:`single`},resetWeatherAndTime:{description:`场景天气和时间重置`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},changeSeason:{description:`切换场景季节状态。`,payloadType:`WeatherChangeSeasonRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{season:1,duration:5}],riskLevel:`low`,responseMode:`single`},resetSeason:{description:`重置场景季节状态。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`},setDayAndNight:{description:`在白天与夜晚模式之间切换。`,payloadType:`WeatherSetDayAndNightRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{dayType:`night`}],riskLevel:`low`,responseMode:`single`},setWeatherVolume:{description:`设置天气声音的开关。`,payloadType:`WeatherSetVolumeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{volumeOn:!1}],riskLevel:`low`,responseMode:`single`},openCameraFog:{description:`开启并调整相机镜头雾效。`,payloadType:`WeatherOpenCameraFogRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{fogStartDistance:20,fogEndDistance:1500,fogIntensity:.5}],riskLevel:`low`,responseMode:`single`},closeCameraFog:{description:`关闭相机镜头雾效。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}},WebView:{title:`网页视图`,description:`网页视图(WebView)管理 API。`,capabilities:[`网页视图更新`],methods:{updateWebView:{description:`更新网页视图参数。`,payloadType:`WebViewUpdateRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`WebViews`,id:`tv1`,url:`http://www.163.com`}],riskLevel:`low`,responseMode:`single`}}},SpatialQuery:{title:`空间查询`,description:`场景缓冲空间查询 API,支持三种查询方式:`,capabilities:[`模型空间查询`,`坐标空间查询`,`模型包围盒空间查询`],methods:{layerQueryByModel:{description:`模型空间查询:根据场景模型当前的位置进行空间查询。`,payloadType:`SpatialQueryLayerByModelRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:``,id:`LayerSearchCore`,queryRadius:10,queryMinHeight:0,queryMaxHeight:50,queryParentIds:[`SM_B8_XueShenSuShe`,`daoZha`]}],riskLevel:`low`,responseMode:`single`},layerQueryByPosition:{description:`坐标空间查询:根据场景坐标位置进行空间查询。`,payloadType:`SpatialQueryLayerByPositionRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{queryPosition:{x:120.40284254780221,y:30.830451474524036,z:10,ePSGType:`4326`},queryRadius:20,queryMinHeight:0,queryMaxHeight:50,queryParentIds:[`SM_B8_XueShenSuShe`,`daoZha`]}],riskLevel:`low`,responseMode:`single`},layerQueryByModelBox:{description:`模型包围盒空间查询:根据场景模型的边界框进行空间查询。`,payloadType:`SpatialQueryLayerByModelBoxRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:``,id:`LayerSearchCore`,queryParentIds:[`JianKong_QiangJiTest`,`daoZha`]}],riskLevel:`low`,responseMode:`single`}}},TrainSimulate:{title:`列车模拟`,description:`列车模拟 API,支持启动列车、设置列车运动方式与音量、相机跟随/取消跟随列车。`,capabilities:[`列车启动`,`列车运动方式设置`,`列车音量设置`,`相机跟随列车`,`取消相机跟随列车`],methods:{startTrain:{description:`设置火车的动态并启动列车。`,payloadType:`TrainSimulateStartTrainRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,trainCode:`G501`,startStationName:`北京`,endStationName:`上海`,direction:`0`,action:`1`,stopTime:180,moveType:`StopAtTheEnd`}],riskLevel:`low`,responseMode:`single`},setTrainBehavior:{description:`设置火车的运动方式。`,payloadType:`TrainSimulateSetTrainBehaviorRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,moveType:`Loop`}],riskLevel:`low`,responseMode:`single`},setCameraFollowTrain:{description:`设置相机跟随火车。`,payloadType:`TrainSimulateSetCameraFollowTrainRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,offSet:{x:26,y:18,z:15,ePSGType:`0000`}}],riskLevel:`low`,responseMode:`single`},setTrainVolume:{description:`设置火车的声音的开关。`,payloadType:`TrainSimulateSetTrainVolumeRequest`,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{parentId:`RailTrains`,id:`DTrain1`,volumeOn:!1}],riskLevel:`low`,responseMode:`single`},cancelCameraFollowTrain:{description:`取消相机跟随火车,无需传参。`,payloadType:``,returnType:H,sideEffects:[`write`],preconditions:V,examples:[{}],riskLevel:`low`,responseMode:`single`}}}},pn=e=>e instanceof r.ZodEffects?pn(e._def.schema):e,mn=e=>{let t=pn(e);return t instanceof r.ZodOptional||t instanceof r.ZodDefault?{schema:pn(t._def.innerType),required:!1,description:t.description??``}:{schema:t,required:!0,description:t.description??``}},hn=e=>mn(e).schema instanceof r.ZodUndefined,gn=e=>{if(!(e instanceof r.ZodUnion))return;let t=e._def.options;if(!t.every(e=>e instanceof r.ZodLiteral))return;let n=t.map(e=>({value:e._def.value,...e.description?{description:e.description}:{}}));return{enumValues:n.map(e=>e.value),enumOptions:n}},_n=e=>{let t=gn(e);if(t)return{type:`enum`,...t};let n=`unknown`;return e instanceof r.ZodString?n=`string`:e instanceof r.ZodNumber?n=`number`:e instanceof r.ZodBoolean?n=`boolean`:e instanceof r.ZodObject?n=`object`:e instanceof r.ZodArray&&(n=`array`),{type:n}},vn=e=>{if(hn(e))return[];let t=mn(e).schema;return t instanceof r.ZodObject?Object.entries(t.shape).map(([e,t])=>{let{schema:n,required:r,description:i}=mn(t);return{name:e,required:r,description:i,..._n(n)}}):[]},yn=[`write`],bn=[`DTCEngine 已完成鉴权并建立 WebRTC 连接`],xn=(e,t,n)=>{let r=e[t],i=`${n.charAt(0).toLowerCase()}${n.slice(1)}`;return r?.[n]??r?.[i]},Sn=e=>e.apiModuleKeys.reduce((t,n)=>{let r=e.jsDocMetadata[n];return t[n]={moduleName:n,title:r.title,description:r.description,capabilities:r.capabilities,methods:Object.entries(r.methods).map(([t,r])=>{let i=[...r.sideEffects??yn],a=[...r.preconditions??bn],o=r.responseMode??`single`,s=xn(e.schemaMap,n,t);if(!s)throw Error(`Missing validation schema for ${n}.${t}`);let c=hn(s)?`none`:`object`,l=c===`none`?[]:[...r.examples??[]],u=vn(s);return{moduleName:n,methodName:t,description:r.description,sideEffects:i,preconditions:a,responseMode:o,riskLevel:r.riskLevel,schema:{payloadKind:c,fields:u,examples:l,responseMode:o}}})},t},{});function Cn(e){return{moduleName:e.moduleName,methodName:e.methodName,description:e.description,sideEffects:e.sideEffects,preconditions:e.preconditions,responseMode:e.responseMode}}const wn=Sn({apiModuleKeys:dn,schemaMap:At,jsDocMetadata:fn});function Tn(e){return e}function En(e){return dn.indexOf(e)>=0}function Dn(e){return e??`all`}function On(e,t){let n=Dn(t);return n===`all`||n[e]!==void 0}function kn(e,t,n){let r=Dn(n);if(r===`all`)return!0;let i=r[e];return i===!0||Array.isArray(i)&&i.indexOf(t)>=0}function An(e){return dn.filter(t=>On(t,e)).map(t=>{let n=wn[t],r=jn(t,e).length;return{moduleName:n.moduleName,title:n.title,description:n.description,capabilities:n.capabilities,methodCount:r}})}function jn(e,t){return On(e,t)?wn[e].methods.filter(n=>kn(e,n.methodName,t)).map(e=>Cn(e)):[]}function Mn(e,t,n){if(kn(e,t,n))return wn[e].methods.find(e=>e.methodName===t)?.schema}function Nn(e,t,n){if(!kn(e,t,n))return;let r=At[e],i=`${t.charAt(0).toLowerCase()}${t.slice(1)}`;return r?.[t]??r?.[i]}function Pn(e){return`'use strict';
38
38
  let registeredProgram;
39
39
  let cancelled = false;
40
40
  let nextRequestId = 1;
@@ -105,5 +105,5 @@ onmessage = async (event) => {
105
105
  }
106
106
  }
107
107
  };
108
- postMessage({ type: 'ready' });\n`}var U=class extends Error{constructor(e,t,n){super(t),this.code=e,this.details=n,this.name=`BusinessProgramRuntimeError`}},Nn=class{constructor(e,t=Pn){this.host=e,this.workerFactory=t,this.loaded=new Map,this.active=new Map,this.activeProgramLocks=new Map}async load(e){if(this.loaded.has(e.capsuleHash))return{loaded:!1};if(!/^[a-f0-9]{64}$/.test(e.capsuleHash))throw new U(`PROGRAM_HASH_INVALID`,`capsuleHash must be a SHA-256 hex string.`);if(await Fn(e),await Ln(In(e))!==e.capsuleHash)throw new U(`PROGRAM_HASH_INVALID`,`Business Program capsuleHash mismatch.`);return this.validatePermissions(e.manifest),this.loaded.set(e.capsuleHash,{manifest:structuredClone(e.manifest),bundle:e.bundle,data:structuredClone(e.data)}),{loaded:!0}}async start(e,t){if(this.active.has(e.executionId))throw new U(`PROGRAM_EXECUTION_EXISTS`,`Execution "${e.executionId}" already exists.`);let n=this.loaded.get(e.capsuleHash);if(!n)throw new U(`PROGRAM_NOT_LOADED`,`Business Program capsule is not loaded.`);let r=this.activeProgramLocks.get(n.manifest.programId);if(r)throw new U(`PROGRAM_LOCK_CONFLICT`,`Business Program "${n.manifest.programId}" is already running.`,{executionId:r});let i;try{i=this.workerFactory(Mn(n.bundle))}catch(e){throw new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker could not be created. Check the page CSP worker-src policy.`,Un(e))}let a={};Object.assign(a,{request:e,program:n,worker:i,onEvent:t,timeout:setTimeout(()=>{this.finishExecution(a,`failed`,`Business Program execution timed out.`)},n.manifest.limits.timeoutMs),sdkCallCount:0,totalDelayMs:0,emittedEventCount:0,pendingDelays:new Set,streams:new Map,nextStreamId:1,terminal:!1}),this.active.set(e.executionId,a),this.activeProgramLocks.set(n.manifest.programId,e.executionId);try{return await this.waitForWorkerReady(a),i.postMessage({type:`start`,inputs:structuredClone(e.inputs),data:structuredClone(n.data)}),this.emit(a,{type:`started`},!1,`running`),{executionId:e.executionId,state:`running`}}catch(e){throw this.finishExecution(a,`failed`,e instanceof Error?e.message:String(e)),e}}cancel(e){let t=this.active.get(e.executionId);return t&&this.finishExecution(t,`cancelled`,e.reason??`Business Program cancelled.`),{executionId:e.executionId,state:`cancelled`}}cancelAll(e=`Business Program runtime disposed.`){for(let t of[...this.active.values()])this.finishExecution(t,`cancelled`,e)}validatePermissions(e){let t=new Set;for(let n of e.permissions.methods){let e=`${n.module}\u0000${n.method}\u0000${n.mode}`;if(t.has(e))throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program permissions must be unique.`);t.add(e);let r=this.host.getMethodMetadata(n.module,n.method);if(!r)throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program method "${n.module}.${n.method}" is not exposed.`);if(n.mode===`query`&&(r.responseMode!==`single`||r.sideEffects.some(e=>e!==`read`)))throw new U(`PROGRAM_PERMISSION_INVALID`,`Query permission requires a read-only single method: ${n.module}.${n.method}.`);if(n.mode===`stage`&&r.responseMode!==`single`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stage permission requires responseMode=single: ${n.module}.${n.method}.`);if(n.mode===`stream`&&r.responseMode!==`stream`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stream permission requires responseMode=stream: ${n.module}.${n.method}.`)}}waitForWorkerReady(e){return new Promise((t,n)=>{let r=setTimeout(()=>n(new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker did not become ready in 5 seconds.`)),5e3);e.worker.onmessage=n=>{G(n.data)?.type===`ready`&&(clearTimeout(r),e.worker.onmessage=t=>{this.handleWorkerMessage(e,t.data)},e.worker.onerror=t=>{this.finishExecution(e,`failed`,t.message||`Business Program Worker failed.`)},t())},e.worker.onerror=e=>{clearTimeout(r),n(new U(`PROGRAM_WORKER_ERROR`,e.message||`Business Program Worker failed.`))}})}async handleWorkerMessage(e,t){if(e.terminal)return;let n=G(t);if(!(!n||typeof n.type!=`string`)){if(n.type===`host-request`&&typeof n.id==`string`&&typeof n.operation==`string`){try{let t=await this.handleHostRequest(e,n.operation,n.payload);if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!0,result:t})}catch(t){if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!1,error:Un(t)})}return}if(n.type===`emit`){let t=G(n.event);this.emit(e,{type:t?.type===`action`?`action`:`progress`,phase:typeof t?.phase==`string`?t.phase:void 0,message:typeof t?.message==`string`?t.message:void 0,data:t?.data},!1,`running`);return}if(n.type===`complete`){this.finishExecution(e,`completed`,void 0,n.result);return}if(n.type===`fail`){let t=G(n.error);this.finishExecution(e,`failed`,typeof t?.message==`string`?t.message:`Business Program failed.`,t?.details)}}}async handleHostRequest(e,t,n){if(t===`query`){let t=Bn(n);this.requirePermission(e.program.manifest,t,`query`),this.incrementSdkCalls(e,1);let r=await this.host.invoke(t);if(!r.ok)throw new U(r.error.code,r.error.message,r.error.details);return r.data}if(t===`execute-stage`)return this.executeStage(e,n);if(t===`open-stream`)return this.openStream(e,n);if(t===`stream-next`)return this.nextStreamEvent(e,n);if(t===`close-stream`)return this.closeStream(e,n);if(t===`delay`){let t=G(n)?.delayMs;if(!Number.isInteger(t)||t<0)throw new U(`PROGRAM_REQUEST_INVALID`,`delayMs must be a non-negative integer.`);return await this.controlledDelay(e,t),null}throw new U(`PROGRAM_REQUEST_INVALID`,`Unsupported host operation "${t}".`)}async executeStage(e,t){let n=G(t)?.actions;if(!Array.isArray(n)||n.length===0||n.length>e.program.manifest.limits.maxStageActions)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action count is invalid.`);let r=Hn(n),i=r.filter(e=>e.type===`invoke`);for(let t of i)this.requirePermission(e.program.manifest,Vn(t),`stage`);this.incrementSdkCalls(e,i.length);let a=this.host.validateActions({actions:i.map(e=>({id:e.id,...Vn(e),responseMode:`single`}))});if(!a.ok)throw new U(a.error.code,a.error.message,a.error.details);let o=a.data.items.find(e=>!e.valid);if(!a.data.valid||o)throw new U(o?.error?.code??`INVALID_PAYLOAD`,o?.error?.message??`Business Program stage preflight failed.`,o?.error?.details);let s=[],c={};for(let[t,n]of r.entries()){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(n.type===`delay`)await this.controlledDelay(e,n.delayMs);else{let e=await this.host.invoke(Vn(n));if(!e.ok)return{state:`failed`,completedActionIds:s,skippedActionIds:r.slice(t+1).map(e=>e.id),results:c,failedAction:{id:n.id,...e.error}};n.saveAs&&(c[n.saveAs]=e.data)}s.push(n.id)}return{state:`completed`,completedActionIds:s,skippedActionIds:[],results:c}}async openStream(e,t){let n=Bn(t);this.requirePermission(e.program.manifest,n,`stream`),this.incrementSdkCalls(e,1);let r=`${e.request.executionId}:stream:${e.nextStreamId++}`,i={streamId:r,requestId:``,events:[],waiters:[],terminal:!1};e.streams.set(r,i);let a=await this.host.startStream({...n,streamId:r},t=>{this.pushStreamEvent(e,i,t)});if(!a.ok)throw e.streams.delete(r),new U(a.error.code,a.error.message,a.error.details);return i.requestId=a.data.requestId,a.data}nextStreamEvent(e,t){let n=this.requireProgramStream(e,t),r=n.events.shift();return r?(r.terminal&&e.streams.delete(n.streamId),Promise.resolve(r)):n.terminal?(e.streams.delete(n.streamId),Promise.reject(new U(`PROGRAM_STREAM_CLOSED`,`Stream "${n.streamId}" is closed.`))):new Promise((e,t)=>{n.waiters.push({resolve:e,reject:t})})}async closeStream(e,t){let n=this.requireProgramStream(e,t),r=G(t)?.reason,i=await this.host.closeStream({streamId:n.streamId,reason:typeof r==`string`?r:`Business Program closed stream.`});if(!i.ok)throw new U(i.error.code,i.error.message,i.error.details);return this.disposeProgramStream(e,n,`Business Program closed stream.`,!1),{streamId:n.streamId,closed:!0}}requireProgramStream(e,t){let n=G(t)?.streamId,r=typeof n==`string`?e.streams.get(n):void 0;if(!r)throw new U(`PROGRAM_STREAM_NOT_FOUND`,`Business Program stream does not exist.`);return r}pushStreamEvent(e,t,n){if(e.terminal||!e.streams.has(t.streamId))return;t.terminal=n.terminal;let r=t.waiters.shift();r?(r.resolve(n),n.terminal&&e.streams.delete(t.streamId)):t.events.push(n)}disposeProgramStream(e,t,n,r=!0){e.streams.delete(t.streamId),t.terminal=!0;for(let e of t.waiters.splice(0))e.reject(new U(`PROGRAM_CANCELLED`,n));r&&this.host.closeStream({streamId:t.streamId,reason:n})}async controlledDelay(e,t){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(e.totalDelayMs+=t,e.totalDelayMs>e.program.manifest.limits.maxTotalDelayMs)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program total delay limit exceeded.`);await new Promise((n,r)=>{let i={};i.reject=r,i.timer=setTimeout(()=>{e.pendingDelays.delete(i),n()},t),e.pendingDelays.add(i)})}requirePermission(e,t,n){if(!e.permissions.methods.some(e=>e.module===t.moduleName&&e.method===t.methodName&&e.mode===n))throw new U(`PROGRAM_PERMISSION_DENIED`,`Business Program cannot use ${t.moduleName}.${t.methodName} as ${n}.`)}incrementSdkCalls(e,t){if(e.sdkCallCount+=t,e.sdkCallCount>e.program.manifest.limits.maxSdkCalls)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program SDK call limit exceeded.`)}emit(e,t,n,r){if(e.emittedEventCount+=1,e.emittedEventCount>e.program.manifest.limits.maxEventCount){this.finishExecution(e,`failed`,`Business Program event limit exceeded.`);return}e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:t,terminal:n,state:r})}finishExecution(e,t,n,r){if(!e.terminal){e.terminal=!0,clearTimeout(e.timeout);for(let t of e.pendingDelays)clearTimeout(t.timer),t.reject(new U(`PROGRAM_CANCELLED`,n??`Business Program stopped.`));e.pendingDelays.clear();for(let r of[...e.streams.values()])this.disposeProgramStream(e,r,n??`Business Program ${t}.`);e.worker.terminate(),this.active.delete(e.request.executionId),this.activeProgramLocks.get(e.program.manifest.programId)===e.request.executionId&&this.activeProgramLocks.delete(e.program.manifest.programId),e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:{type:t,message:n,data:r},terminal:!0,state:t})}}};function Pn(e){let t=URL.createObjectURL(new Blob([e],{type:`text/javascript`}));try{return new Worker(t)}finally{URL.revokeObjectURL(t)}}async function Fn(e){if(await Ln(e.bundle)!==e.manifest.entry.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program entry sha256 mismatch.`);for(let t of e.manifest.data){let n=e.data[t.name];if(typeof n!=`string`||await Ln(n)!==t.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program data "${t.name}" sha256 mismatch.`)}}function In(e){return JSON.stringify(e.manifest)+e.bundle+e.manifest.data.map(t=>e.data[t.name]??``).join(``)}async function Ln(e){let t=new TextEncoder().encode(e);if(typeof crypto<`u`&&crypto.subtle){let e=await crypto.subtle.digest(`SHA-256`,t);return zn(new Uint8Array(e))}return zn(Rn(t))}function Rn(e){let t=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),n=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),r=Math.ceil((e.length+9)/64)*64,i=new Uint8Array(r);i.set(e),i[e.length]=128;let a=e.length*8,o=new DataView(i.buffer);o.setUint32(r-8,Math.floor(a/4294967296)),o.setUint32(r-4,a>>>0);let s=new Uint32Array(64);for(let e=0;e<r;e+=64){for(let t=0;t<16;t+=1)s[t]=o.getUint32(e+t*4);for(let e=16;e<64;e+=1){let t=W(s[e-15],7)^W(s[e-15],18)^s[e-15]>>>3,n=W(s[e-2],17)^W(s[e-2],19)^s[e-2]>>>10;s[e]=s[e-16]+t+s[e-7]+n>>>0}let[r,i,a,c,l,u,d,f]=n;for(let e=0;e<64;e+=1){let n=W(l,6)^W(l,11)^W(l,25),o=l&u^~l&d,p=f+n+o+t[e]+s[e]>>>0,m=(W(r,2)^W(r,13)^W(r,22))+(r&i^r&a^i&a)>>>0;f=d,d=u,u=l,l=c+p>>>0,c=a,a=i,i=r,r=p+m>>>0}n[0]=n[0]+r>>>0,n[1]=n[1]+i>>>0,n[2]=n[2]+a>>>0,n[3]=n[3]+c>>>0,n[4]=n[4]+l>>>0,n[5]=n[5]+u>>>0,n[6]=n[6]+d>>>0,n[7]=n[7]+f>>>0}let c=new Uint8Array(32),l=new DataView(c.buffer);return n.forEach((e,t)=>l.setUint32(t*4,e)),c}function W(e,t){return e>>>t|e<<32-t}function zn(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function Bn(e){let t=G(e);if(!t||typeof t.module!=`string`||typeof t.method!=`string`)throw new U(`PROGRAM_REQUEST_INVALID`,`SDK request requires module and method.`);return{moduleName:t.module,methodName:t.method,payload:t.payload}}function Vn(e){return{moduleName:e.module,methodName:e.method,payload:e.payload}}function Hn(e){let t=new Map,n=new Set;for(let r of e){if(!r||typeof r.id!=`string`||!r.id||t.has(r.id))throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action IDs must be unique.`);if(r.type!==`invoke`&&r.type!==`delay`)throw new U(`PROGRAM_STAGE_INVALID`,`Unsupported Program stage action type.`);if(r.type===`invoke`){if(!r.module||!r.method||r.responseMode!==`single`)throw new U(`PROGRAM_STAGE_INVALID`,`Invoke action "${r.id}" is invalid.`);if(r.saveAs&&(n.has(r.saveAs)||!/^[A-Za-z][A-Za-z0-9-]*$/.test(r.saveAs)))throw new U(`PROGRAM_STAGE_INVALID`,`saveAs "${r.saveAs}" is invalid or duplicated.`);r.saveAs&&n.add(r.saveAs)}else if(!Number.isInteger(r.delayMs)||r.delayMs<0)throw new U(`PROGRAM_STAGE_INVALID`,`Delay action "${r.id}" is invalid.`);t.set(r.id,r)}for(let n of e)for(let e of n.dependsOn??[])if(!t.has(e)||e===n.id)throw new U(`PROGRAM_STAGE_INVALID`,`Action "${n.id}" has an invalid dependency.`);let r=[],i=new Set;for(;r.length<e.length;){let t=e.find(e=>!i.has(e.id)&&(e.dependsOn??[]).every(e=>i.has(e)));if(!t)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage dependency graph contains a cycle.`);r.push(t),i.add(t.id)}return r}function G(e){return typeof e==`object`&&e?e:void 0}function Un(e){return e instanceof U?{name:e.name,message:e.message,code:e.code,details:e.details}:e instanceof Error?{name:e.name,message:e.message}:{name:`Error`,message:String(e)}}function Wn(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?`sdk3_${crypto.randomUUID()}`:`sdk3_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function K(e){return{ok:!0,data:e,ts:Date.now()}}function q(e,t,n){return{ok:!1,error:{code:e,message:t,moduleName:n?.moduleName,methodName:n?.methodName,details:n?.details},ts:Date.now()}}function Gn(){return typeof document>`u`?void 0:document.title}function Kn(){return typeof window>`u`?void 0:window.location.href}function qn(e){return e.runtimeName??e.engineConfig?.sceneName??Gn()??e.engineConfig?.engineUuid}function Jn(e){if(e)return{sceneName:e.sceneName,engineUuid:e.engineUuid,mapType:e.mapType,operationType:e.operationType,viewMode:e.viewMode,centerIP:e.centerIP,signalingServer:e.signalingServer,codec:e.codec}}function Yn(e){return typeof e==`object`&&!!e}function Xn(e){return Yn(e)&&Object.keys(e).length===0}function Zn(e){return Yn(e)&&e.ok===!1&&typeof e.ts==`number`}function Qn(e){return new Promise(t=>{setTimeout(t,e)})}function $n(e,t){let n=t?.fields.filter(e=>e.required)??[];if(n.length!==0)return Yn(e)?n.find(t=>e[t.name]===void 0):n[0]}function er(e){return e instanceof d?e.toJSON():e instanceof Error?{name:e.name,message:e.message}:e}function tr(e){if(typeof e!=`object`&&typeof e!=`function`||e===null)return!1;let t=e;return typeof t.then==`function`&&typeof t.cancel==`function`&&typeof t.requestId==`string`}function nr(e){if(!(!Yn(e)||typeof e.id!=`string`))return{parentId:typeof e.parentId==`string`?e.parentId:``,id:e.id}}function rr(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return}}function ir(e){let t=e.response,n=rr(t?.param??t?.params??e.param??e.params);return Yn(n)&&n.status===`finished`}function ar(e,t={},n={}){let r=t.bridgeId??Wn(),i=Tn(t.expose),a=new Map,o=!1,s=()=>{o=!0},c=()=>{o=!1};e.on(e.Events.WebRtcConnected,s),e.on(e.Events.WebRtcDisconnected,c),e.on(e.Events.WebRtcFailed,c);function l(){return{bridgeId:r,connected:o,runtimeName:qn(t),title:Gn(),pageUrl:Kn(),sdkVersion:t.sdkVersion,metadata:t.metadata,engine:Jn(t.engineConfig)}}function u(e){return wn(e)?En(e,i)?e:q(`API_NOT_EXPOSED`,`API module "${e}" is not exposed by agentBridge.expose.`,{moduleName:e}):q(`API_NOT_FOUND`,`API module "${e}" does not exist.`,{moduleName:e})}function p(t,n){if(!Dn(t,n,i))return q(`API_NOT_EXPOSED`,`API method "${t}.${n}" is not exposed.`,{moduleName:t,methodName:n});let r=e[t];return!Yn(r)||typeof r[n]!=`function`?q(`API_NOT_FOUND`,`API method "${t}.${n}" does not exist.`,{moduleName:t,methodName:n}):r}function m(e,t=!0){let n=u(e.moduleName);if(typeof n!=`string`)return n;let r=p(n,e.methodName);if(Zn(r))return r;let a=An(n,e.methodName,i);if(!a)return q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${e.methodName}" is not available.`,{moduleName:n,methodName:e.methodName});let o=l();if(!o.connected)return q(`SDK_NOT_READY`,`DTCEngine is not connected yet.`,{moduleName:n,methodName:e.methodName,details:o});if(t&&a.payloadKind===`none`&&e.payload!==void 0&&!Xn(e.payload))return q(`INVALID_PAYLOAD`,`API method "${n}.${e.methodName}" does not accept payload.`,{moduleName:n,methodName:e.methodName,details:e.payload});let s=t?$n(e.payload,a):void 0;if(s)return q(`INVALID_PAYLOAD`,`Missing required payload field "${s.name}".`,{moduleName:n,methodName:e.methodName,details:{field:s.name}});let c=r[e.methodName];return typeof c==`function`?{resolvedModule:n,resolvedMethod:r,methodRef:c,schema:a}:q(`API_NOT_FOUND`,`API method "${n}.${e.methodName}" does not exist.`,{moduleName:n,methodName:e.methodName})}function h(e){return{type:e.type,requestId:e.requestId,response:e.response,...e.error?{error:{name:e.error.name,message:e.error.message}}:{}}}function g(e,t,n){let r=e.request.streamId;a.get(r)===e&&(a.delete(r),e.onEvent({streamId:r,requestId:e.promise.requestId,moduleName:e.request.moduleName,methodName:e.request.methodName,event:{type:`cancel`,requestId:e.promise.requestId,error:{name:`StreamClosedError`,message:n}},terminal:!0,terminalReason:t}),e.promise.cancel(n))}function _(e,t){let n=a.get(e);if(!n)return;let r=n.request.moduleName===`PathPatrol`&&n.request.methodName===`add`&&ir(t),i=r||t.type===`done`||t.type===`error`||t.type===`cancel`,o=r?`finished`:t.type===`done`?`completed`:t.type===`error`?`error`:t.type===`cancel`?`cancelled`:void 0;n.onEvent({streamId:e,requestId:t.requestId||n.promise.requestId,moduleName:n.request.moduleName,methodName:n.request.methodName,event:h(t),terminal:i,terminalReason:o}),i&&(a.delete(e),r&&t.type!==`done`&&n.promise.cancel(`PathPatrol.add reported status=finished`))}function ee(e){let t=nr(e);if(t)for(let e of[...a.values()]){let n=nr(e.request.payload);e.request.moduleName===`PathPatrol`&&e.request.methodName===`add`&&n?.id===t.id&&n.parentId===t.parentId&&g(e,`stopped`,`Matching PathPatrol.stop succeeded`)}}function te(e=`Agent bridge disconnected`){for(let t of[...a.values()])g(t,`bridge-disconnected`,e)}let v,y=new Nn({getMethodMetadata(e,t){if(!wn(e)||!En(e,i))return;let n=kn(e,i).find(e=>e.methodName===t);return n?{responseMode:n.responseMode,sideEffects:n.sideEffects}:void 0},validateActions(e){return v.validateActions(e)},invoke(e){return v.invoke(e)},startStream(e,t){return v.startStream(e,t)},closeStream(e){return v.closeStream(e)}},n.businessProgramWorkerFactory);return v={getSnapshot:l,dispose(){te(`Agent bridge runtime disposed`),y.cancelAll(`Agent bridge runtime disposed`),e.off(e.Events.WebRtcConnected,s),e.off(e.Events.WebRtcDisconnected,c),e.off(e.Events.WebRtcFailed,c)},closeAllStreams:te,cancelAllPrograms(e){y.cancelAll(e)},listModules(){return On(i)},listMethods(e){let t=u(e);return typeof t==`string`?K(kn(t,i)):t},getMethodSchema(e,t){let n=u(e);if(typeof n!=`string`)return n;if(!Dn(n,t,i))return q(`API_NOT_EXPOSED`,`API method "${n}.${t}" is not exposed.`,{moduleName:n,methodName:t});let r=An(n,t,i);return r?K(r):q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${t}" is not available.`,{moduleName:n,methodName:t})},validateActions(e){let t=e.actions.map(e=>{let t=m(e,!1);if(Zn(t))return{id:e.id,valid:!1,error:t.error};if(t.schema.responseMode!==e.responseMode)return{id:e.id,valid:!1,error:{code:`STREAM_INVOKE_REQUIRED`,message:`API method "${t.resolvedModule}.${e.methodName}" is ${t.schema.responseMode}, not ${e.responseMode}.`,moduleName:t.resolvedModule,methodName:e.methodName,details:{expected:e.responseMode,actual:t.schema.responseMode}}};let n=jn(t.resolvedModule,e.methodName,i);if(!n)return{id:e.id,valid:!1,error:{code:`METHOD_SCHEMA_NOT_FOUND`,message:`Validation schema for "${t.resolvedModule}.${e.methodName}" is not available.`,moduleName:t.resolvedModule,methodName:e.methodName}};try{return f(n,t.schema.payloadKind===`none`?void 0:e.payload,t.resolvedModule,e.methodName),{id:e.id,valid:!0}}catch(n){return{id:e.id,valid:!1,error:{code:`INVALID_PAYLOAD`,message:n instanceof Error?n.message:String(n),moduleName:t.resolvedModule,methodName:e.methodName,details:er(n)}}}});return K({valid:t.every(e=>e.valid),items:t})},async invoke(e){let n=m(e);if(Zn(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:a,schema:o}=n;if(o.responseMode===`stream`)return q(`STREAM_INVOKE_REQUIRED`,`API method "${r}.${e.methodName}" requires a streaming invoke.`,{moduleName:r,methodName:e.methodName,details:{responseMode:o.responseMode,tool:`sdk3_invoke_stream`}});if(t.mockInvoke===!0)return await Qn(100),K({success:!0,code:`MOCK_OK`,message:`mock invoke success`,data:null});try{let t=o.payloadKind===`none`||e.payload===void 0?await a.call(i):await a.call(i,e.payload);return r===`PathPatrol`&&e.methodName===`stop`&&(!Yn(t)||t.success!==!1)&&ee(e.payload),K(t)}catch(t){return t instanceof d?q(`INVALID_PAYLOAD`,t.message,{moduleName:r,methodName:e.methodName,details:t.toJSON()}):q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed.`,{moduleName:r,methodName:e.methodName,details:er(t)})}},async startStream(e,t){if(a.has(e.streamId))return q(`INVALID_PAYLOAD`,`Stream "${e.streamId}" already exists.`,{moduleName:e.moduleName,methodName:e.methodName});let n=m(e);if(Zn(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:o,schema:s}=n;if(s.responseMode!==`stream`)return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" is not streaming.`,{moduleName:r,methodName:e.methodName});try{let n,c=[],l=!1,u=t=>{if(!l){c.push(t);return}_(e.streamId,t)};if(n=s.payloadKind===`none`||e.payload===void 0?o.call(i,u):o.call(i,e.payload,u),!tr(n))return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" did not return a stream handle.`,{moduleName:r,methodName:e.methodName});let d={request:e,promise:n,onEvent:t};a.set(e.streamId,d),l=!0,n.catch(()=>void 0),c.forEach(t=>_(e.streamId,t));let f=c.find(e=>e.type===`error`);return f?q(`INVALID_PAYLOAD`,f.error?.message??`API method "${r}.${e.methodName}" failed before stream start.`,{moduleName:r,methodName:e.methodName,details:er(f.error)}):K({streamId:e.streamId,requestId:n.requestId})}catch(t){return q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed to start a stream.`,{moduleName:r,methodName:e.methodName,details:er(t)})}},async closeStream(e){let t=a.get(e.streamId);return t?(g(t,`cancelled`,e.reason?.trim()||`Stream closed by MCP client`),K({streamId:e.streamId,closed:!0})):K({streamId:e.streamId,closed:!1})},async loadProgram(e){try{return K(await y.load(e))}catch(e){return q(`PROGRAM_INVALID`,e instanceof Error?e.message:String(e),{details:or(e)})}},async startProgram(e,t){if(!o)return q(`SDK_NOT_READY`,`SDK runtime is not connected.`);try{return K(await y.start(e,t))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:or(e)})}},async cancelProgram(e){try{return K(y.cancel(e))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:or(e)})}}},v}function or(e){return e instanceof U?{code:e.code,message:e.message,details:e.details}:er(e)}function sr(){return typeof globalThis<`u`&&typeof globalThis.location?.href==`string`?globalThis.location?.href??``:``}function cr(){return typeof globalThis<`u`&&typeof globalThis.navigator?.userAgent==`string`?globalThis.navigator?.userAgent??``:``}const lr=r.string().min(1),ur=[`bs`,`cs`],dr=r.custom(e=>typeof e==`object`&&!!e,`dom must be a valid HTMLDivElement`),fr={centerHeartbeatIntervalMs:5e3,centerHeartbeatTimeoutMs:5e4},J={runMode:`RunMode/`,centerIP:`CenterIP/`,privateKey:`PrivateKey/`,showProgressBar:`showProgressBar/`},pr=r.object({centerIP:lr.optional(),signalingServer:lr.optional(),sceneName:lr.optional(),token:lr.optional(),dom:dr.optional(),showProgressBar:r.boolean().optional().default(!0),codec:r.string().optional().default(`H264`),viewMode:r.enum(ur).optional().default(`bs`),turnServer:r.string().optional(),turnUser:r.string().optional(),turnPwd:r.string().optional(),privateKey:r.string().optional(),engineUuid:r.string().optional(),mapType:r.string().optional().default(`web`),operationType:r.string().optional().default(`viewer`),freeCheckInterval:r.number().int().min(0).optional().default(0),initialSettings:r.record(r.unknown()).optional().default({}),logger:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`info`),includeStack:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),pixelStreamingLogger:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),centerHeartbeatIntervalMs:r.never().optional(),centerHeartbeatTimeoutMs:r.never().optional()}).strict().superRefine((e,t)=>{!e.centerIP&&!e.signalingServer&&t.addIssue({code:r.ZodIssueCode.custom,path:[`centerIP`],message:`one of centerIP, signalingServer is required`}),e.sceneName||t.addIssue({code:r.ZodIssueCode.custom,path:[`sceneName`],message:`sceneName is required`}),e.token||t.addIssue({code:r.ZodIssueCode.custom,path:[`token`],message:`token is required`}),e.dom||t.addIssue({code:r.ZodIssueCode.custom,path:[`dom`],message:`dom is required`})});function mr(e){let t={};return e.split(` `).forEach(e=>{if(e.startsWith(J.runMode)){t.viewMode=e.slice(J.runMode.length);return}if(e.startsWith(J.centerIP)){t.centerIP=e.slice(J.centerIP.length);return}if(e.startsWith(J.privateKey)){t.privateKey=e.slice(J.privateKey.length);return}if(e.startsWith(J.showProgressBar)){let n=e.slice(J.showProgressBar.length);n===`true`?t.showProgressBar=!0:n===`false`&&(t.showProgressBar=!1)}}),t}function hr(e){let t=cr()||void 0;if(!t)return e;let n=mr(t);return Object.keys(n).length===0?e:{...e,...n}}function gr(e){let t=hr(e),n=pr.safeParse(t);if(!n.success)throw new d(`Core`,`DTCEngine.constructor`,n.error.issues.map(e=>({field:e.path.length>0?e.path.join(`.`):`<root>`,reason:e.message,code:e.code})));let r=n.data;return{centerIP:r.centerIP??``,signalingServer:r.signalingServer,sceneName:r.sceneName??``,token:r.token??``,dom:r.dom,showProgressBar:r.showProgressBar,codec:r.codec,viewMode:r.viewMode,turnServer:r.turnServer,turnUser:r.turnUser,turnPwd:r.turnPwd,privateKey:r.privateKey??``,engineUuid:r.engineUuid,mapType:r.mapType,operationType:r.operationType,freeCheckInterval:r.freeCheckInterval,initialSettings:r.initialSettings,logger:r.logger,includeStack:r.includeStack,pixelStreamingLogger:r.pixelStreamingLogger,centerHeartbeatIntervalMs:fr.centerHeartbeatIntervalMs,centerHeartbeatTimeoutMs:fr.centerHeartbeatTimeoutMs}}const _r=[`token`,`privatekey`,`authorization`,`cookie`,`set-cookie`],vr={enabled:!1,endpoint:``,apiKey:``,app:{name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`},batching:{enabled:!0,itemLimit:20,sendTimeoutMs:3e4},retry:{maxAttempts:2},failure:{disableAfterConsecutiveFailures:5,warningIntervalMs:3e4},redactKeys:_r},yr=r.object({enabled:r.boolean().default(!1),endpoint:r.string().optional(),apiKey:r.string().optional(),app:r.object({name:r.string().min(1).default(`@nnepoch/dtc-sdk`),version:r.string().min(1).default(`0.1.0`),environment:r.string().min(1).default(`production`)}).default({name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`}),batching:r.object({enabled:r.boolean().default(!0),itemLimit:r.number().int().min(1).default(20),sendTimeoutMs:r.number().int().min(200).default(3e3)}).default({enabled:!0,itemLimit:20,sendTimeoutMs:3e3}),retry:r.object({maxAttempts:r.number().int().min(1).max(5).default(2)}).default({maxAttempts:2}),failure:r.object({disableAfterConsecutiveFailures:r.number().int().min(1).default(5),warningIntervalMs:r.number().int().min(1e3).default(3e4)}).default({disableAfterConsecutiveFailures:5,warningIntervalMs:3e4}),redactKeys:r.array(r.string().min(1)).default(_r)}).superRefine((e,t)=>{let n=typeof e.endpoint==`string`?e.endpoint.trim():``,i=n.length>0;if(e.enabled&&!i){t.addIssue({code:r.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting enabled requires endpoint`});return}e.enabled&&i&&!r.string().url().safeParse(n).success&&t.addIssue({code:r.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting endpoint must be a valid url`})});function br(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function xr(e,t){let n={...e};return Object.entries(t).forEach(([e,t])=>{if(t!==void 0){if(br(t)&&br(n[e])){n[e]=xr(n[e],t);return}n[e]=t}}),n}function Sr(){let e=br(globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__)?{...globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__}:{};typeof e.endpoint==`string`&&e.endpoint.trim().length===0&&delete e.endpoint,typeof e.apiKey==`string`&&e.apiKey.trim().length===0&&delete e.apiKey;let t=xr(vr,e);return yr.parse(t)}function Cr(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}function wr(e){if(typeof e==`string`)return e;if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function Tr(e,t){let n=new WeakSet,r=(e,i)=>{if(i&&Cr(i,t.redactKeys))return`[REDACTED]`;if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(typeof e==`bigint`)return e.toString();if(e===void 0)return`undefined`;if(typeof e==`function`||typeof e==`symbol`)return String(e);if(e instanceof Date)return e.toISOString();if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack};if(Array.isArray(e))return e.map(e=>r(e));if(typeof e==`object`&&e){if(n.has(e))return`[CIRCULAR]`;n.add(e);let t=Object.entries(e),i={};return t.forEach(([e,t])=>{i[e]=r(t,e)}),i}return wr(e)};return r(e)}function Er(e){let t=e.toLowerCase();return t.includes(`auth`)?`auth`:t.includes(`center`)?`center`:t.includes(`sessionadapter`)||t.includes(`webrtc`)||t.includes(`pixelstreaming`)?`webrtc`:t.includes(`enginestatus`)||t.includes(`stream`)?`media`:t.includes(`requestbridge`)||t.includes(`camera`)||t.includes(`scene`)||t.includes(`model`)||t.includes(`poi`)||t.includes(`weather`)||t.includes(`timeline`)||t.includes(`popup`)||t.includes(`animation`)?`ue_api`:`session`}function Dr(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function Or(e){return e.trim().replace(/\s+/g,`_`).slice(0,64)}function kr(e){if(!br(e))return;let t=Dr(e.code)??Dr(e.errorCode)??Dr(e.status);if(t)return Or(t);let n=e.error;if(br(n)){let e=Dr(n.code)??Dr(n.errorCode)??Dr(n.status);if(e)return Or(e)}}var Ar=class{constructor(e,t){this.config=e,this.deps=t}async send(e){let t=typeof AbortController<`u`?new AbortController:void 0,n=t?setTimeout(()=>{t.abort()},this.config.batching.sendTimeoutMs):void 0;try{let n=await this.deps.fetchImpl(this.config.endpoint??``,{method:`POST`,headers:{"Content-Type":`application/json`,...this.config.apiKey?{"x-api-key":this.config.apiKey}:{}},body:JSON.stringify(e),signal:t?.signal});if(!n.ok)throw Error(`qos reporting request failed: ${n.status}`)}finally{n&&clearTimeout(n)}}};function jr(){return typeof fetch==`function`}var Mr=class{constructor(e,t,n,r,i={}){if(this.config=e,this.session=t,this.runtime=n,this.onWarning=r,this.queue=[],this.flushing=!1,this.consecutiveFailures=0,this.lastWarningAt=0,this.disabledByFailure=!1,this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts=new Map,this.now=i.now??Date.now,this.setTimeoutImpl=i.setTimeoutImpl??setTimeout,this.clearTimeoutImpl=i.clearTimeoutImpl??clearTimeout,!e.enabled){this.enabled=!1,this.transport=void 0;return}if(this.enabled=!0,i.createTransport){this.transport=i.createTransport(e);return}if(!jr()){this.transport=void 0,this.warnLimited(`qos reporting skipped: fetch unavailable`);return}this.transport=new Ar(e,{fetchImpl:fetch})}startSession(e){this.resetWarnErrorSummary(),this.recordEvent({eventName:`session_start`,stage:`session`,status:`start`,attrs:e})}endSession(e){this.recordEvent({eventName:`session_end`,stage:`session`,status:`end`,attrs:e,metrics:{summary:this.getWarnErrorSummary()}}),this.flush()}recordEvent(e){if(!this.enabled||!this.transport||this.disabledByFailure)return;let t=e.attrs?Tr(e.attrs,this.config):void 0,n=e.metrics?Tr(e.metrics,this.config):void 0;if(this.queue.push({eventName:e.eventName,stage:e.stage,status:e.status,ts:e.ts??this.now(),level:e.level??(e.status===`failed`?`error`:`info`),durationMs:e.durationMs,errorCode:e.errorCode,errorMessage:e.errorMessage,attrs:t,metrics:n}),!this.config.batching.enabled||this.queue.length>=this.config.batching.itemLimit){this.flush();return}this.flushTimer||=this.setTimeoutImpl(()=>{this.flushTimer=void 0,this.flush()},this.config.batching.sendTimeoutMs)}recordLogSignal(e){if(e.level===`warn`){this.warnCount+=1;return}this.errorCount+=1;let t=Er(e.moduleName);this.errorByStage[t]=(this.errorByStage[t]??0)+1;let n=kr(e.meta)??`UNKNOWN`;this.errorCodeCounts.set(n,(this.errorCodeCounts.get(n)??0)+1)}getWarnErrorSummary(){let e=Array.from(this.errorCodeCounts.entries()).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({code:e,count:t}));return{logWarnCount:this.warnCount,logErrorCount:this.errorCount,logErrorByStage:{...this.errorByStage},logErrorTopCodes:e}}async flush(){if(this.flushing||this.queue.length===0||!this.transport||this.disabledByFailure)return;this.flushing=!0,this.flushTimer&&=(this.clearTimeoutImpl(this.flushTimer),void 0);let e=this.config.batching.enabled?this.config.batching.itemLimit:this.queue.length,t=this.queue.splice(0,e),n={schemaVersion:`1.0.0`,source:`enginesdk3`,sdkVersion:this.config.app.version,sentAt:this.now(),session:this.session,context:this.runtime,events:t};try{await this.sendWithRetry(n),this.consecutiveFailures=0}catch(e){this.onFailure(e,`send qos payload failed`)}finally{this.flushing=!1,this.queue.length>0&&!this.disabledByFailure&&this.flush()}}async sendWithRetry(e){let t=Math.max(1,this.config.retry.maxAttempts),n;for(let r=1;r<=t;r+=1)try{await this.transport?.send(e);return}catch(e){n=e}throw n instanceof Error?n:Error(String(n))}onFailure(e,t){this.consecutiveFailures+=1,this.warnLimited(t,{consecutiveFailures:this.consecutiveFailures,error:e instanceof Error?`${e.name}: ${e.message}`:String(e)}),this.consecutiveFailures>=this.config.failure.disableAfterConsecutiveFailures&&(this.disabledByFailure=!0,this.warnLimited(`qos reporting disabled after repeated failures`))}warnLimited(e,t){let n=this.now();n-this.lastWarningAt<this.config.failure.warningIntervalMs||(this.lastWarningAt=n,this.onWarning(e,t))}resetWarnErrorSummary(){this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts.clear()}},Nr=class{constructor(){this.listeners=new Map,this.debugMode=!1}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),this.debugMode&&console.log(`[EventBus] Subscribed to "${String(e)}"`)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e)),this.debugMode&&console.log(`[EventBus] Unsubscribed from "${String(e)}"`)}emit(e,t){let n=this.listeners.get(e);this.debugMode&&console.log(`[EventBus] Emitting "${String(e)}"`,t),!(!n||n.size===0)&&n.forEach(n=>{try{n(t)}catch(t){console.error(`[EventBus] Error in handler for "${String(e)}":`,t)}})}once(e,t){let n=r=>{this.off(e,n),t(r)};this.on(e,n)}removeAllListeners(e){e===void 0?(this.listeners.clear(),this.debugMode&&console.log(`[EventBus] Removed all listeners`)):(this.listeners.delete(e),this.debugMode&&console.log(`[EventBus] Removed all listeners for "${String(e)}"`))}listenerCount(e){return this.listeners.get(e)?.size??0}eventNames(){return Array.from(this.listeners.keys())}setDebugMode(e){this.debugMode=e}};const Pr=[`webRtcConnected`,`webRtcDisconnected`,`webRtcConnecting`,`webRtcFailed`,`statsReceived`,`subscribeFailed`,`streamerAssigned`];var Fr=class{constructor(){this.mode=`bs`,this.forwardEvents=[...Pr,`streamLoading`]}applyInitialSettings(e){return{[o.KeyboardInput]:!0,[o.MouseInput]:!0,[o.TouchInput]:!0,[o.GamepadInput]:!0,[o.XRControllerInput]:!0,[o.HoveringMouseMode]:!0,[o.AutoPlayVideo]:!0,[o.MatchViewportResolution]:!0,[o.StartVideoMuted]:!0,[s.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for bs mode`)}onAfterConnect(e){e.info(`session connect triggered for bs mode`)}},Ir=class{constructor(){this.mode=`cs`,this.forwardEvents=Pr}applyInitialSettings(e){return{[o.KeyboardInput]:!0,[o.MouseInput]:!1,[o.TouchInput]:!1,[o.GamepadInput]:!1,[o.XRControllerInput]:!1,[o.HoveringMouseMode]:!0,[o.AutoPlayVideo]:!0,[o.MatchViewportResolution]:!0,[o.StartVideoMuted]:!0,[s.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for cs mode`)}onAfterConnect(e){e.info(`session connect triggered for cs mode`)}};function Lr(e){return e===`cs`?new Ir:new Fr}var Rr=class{constructor(e,t,n=h){this.logger=n,this.streamerAssignedListeners=new Set,this.handlePoiCursorResponse=e=>{try{let t=JSON.parse(e);if(t.uuid!==`POICursor`)return;this.setVideoCursor(t.param===`pointer`?`pointer`:`default`)}catch{}},this.videoElementParent=t,this.modeStrategy=Lr(e.viewMode);let r=this.modeStrategy.applyInitialSettings(e.initialSettings??{});this.psConfig=new a({initialSettings:{...r}}),t?.classList?.add(`fixed-size`),t&&getComputedStyle(t).position===`static`&&(t.style.position=`relative`),this.stream=new l(this.psConfig,t?{videoElementParent:t}:void 0),this.stream.addResponseEventListener(`enginesdk_poi_cursor_listener`,this.handlePoiCursorResponse),this.setupStreamerAssignedListener(),this.logger.info(`session initialized`,{hasVideoParent:!!t,viewMode:this.modeStrategy.mode})}connect(){this.modeStrategy.onBeforeConnect(this.logger),this.logger.info(`connect`),this.stream.connect(),this.modeStrategy.onAfterConnect(this.logger)}reconnect(){this.logger.info(`reconnect`),this.stream.reconnect()}disconnect(){this.logger.info(`disconnect`),this.setVideoCursor(`default`),this.stream.disconnect()}beginPointEditorMouseInput(){let e=[o.MouseInput,o.HoveringMouseMode],t=e.map(e=>this.psConfig.isFlagEnabled(e));e.forEach(e=>this.psConfig.setFlagEnabled(e,!0));let n=!1;return()=>{n||(n=!0,e.forEach((e,n)=>this.psConfig.setFlagEnabled(e,t[n])))}}setSignallingUrlBuilder(e){this.logger.info(`setSignallingUrlBuilder configured`),this.stream.setSignallingUrlBuilder(e)}emitUIInteraction(e){let t=this.stream.emitUIInteraction(e);return t?this.logger.debug(`emitUIInteraction sent`):this.logger.warn(`emitUIInteraction failed`),t}emitCommand(e){let t=this.stream.emitCommand(e);return t?this.logger.debug(`emitCommand sent`):this.logger.warn(`emitCommand failed`),t}addResponseEventListener(e,t){this.logger.debug(`addResponseEventListener`,{name:e}),this.stream.addResponseEventListener(e,t)}removeResponseEventListener(e){this.logger.debug(`removeResponseEventListener`,{name:e}),this.stream.removeResponseEventListener(e)}addEventListener(e,t){if(this.logger.debug(`addEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.add(t);return}this.stream.addEventListener(e,t)}removeEventListener(e,t){if(this.logger.debug(`removeEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.delete(t);return}this.stream.removeEventListener(e,t)}getForwardEvents(){return this.modeStrategy.forwardEvents}getViewMode(){return this.modeStrategy.mode}isReconnecting(){return this.stream.isReconnecting()}setVideoCursor(e){this.videoElementParent&&(this.videoElementParent.style.cursor=e,this.videoElementParent.querySelectorAll(`video`).forEach(t=>{t.style.cursor=e}))}setupStreamerAssignedListener(){try{let e=this.stream.webRtcController?.protocol;if(!e||typeof e.addListener!=`function`){this.logger.warn(`webRtcController.protocol not available, streamerAssigned listener not registered`);return}e.addListener(`streamerAssigned`,e=>{if(this.logger.info(`streamerAssigned received`,{streamerId:e.streamerId}),e.streamerId)try{this.psConfig.setOptionSettingValue(c.StreamerId,e.streamerId),this.logger.info(`StreamerId configured`,{streamerId:e.streamerId})}catch(t){this.logger.error(`Failed to set StreamerId`,{streamerId:e.streamerId,error:t instanceof Error?t.message:String(t)})}else this.logger.warn(`streamerAssigned received without streamerId`,{msg:e});this.streamerAssignedListeners.forEach(t=>{try{t(e)}catch(e){this.logger.error(`streamerAssigned listener error`,{error:e instanceof Error?e.message:String(e)})}})}),this.logger.debug(`streamerAssigned listener registered`)}catch(e){this.logger.error(`Failed to setup streamerAssigned listener`,{error:e instanceof Error?e.message:String(e)})}}};const Y={SignallingBootstrapFailed:`SIGNALLING_BOOTSTRAP_FAILED`,CenterUnavailable:`CENTER_UNAVAILABLE`,CenterProtocolInvalid:`CENTER_PROTOCOL_INVALID`,ConnectResultFailed:`CONNECT_RESULT_FAILED`,ServiceAllocationFailed:`SERVICE_ALLOCATION_FAILED`,ResourceWaiting:`RESOURCE_WAITING`,AuthorizeFailed:`AUTHORIZE_FAILED`,TokenInvalid:`TOKEN_INVALID`,TokenExpired:`TOKEN_EXPIRED`,SignallingUrlMissing:`SIGNALLING_URL_MISSING`,HeartbeatTimeout:`HEARTBEAT_TIMEOUT`,CenterDisconnected:`CENTER_DISCONNECTED`};var X=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.retryable=n,this.details=r,this.name=`SDKAuthError`}toErrorInfo(){return{code:this.code,message:this.message,retryable:this.retryable}}};function zr(e){return e instanceof X?e:e instanceof Error?new X(Y.CenterUnavailable,e.message,!0,{cause:e.message}):new X(Y.CenterUnavailable,String(e),!0)}var Br=class{constructor(t,n=h,r){this.config=t,this.logger=n,this.authEvents=r,this.textEncoder=new TextEncoder,this.connectId=``,this.events=new e,this.manualClose=!1}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}isConnected(){return this.socket?.readyState===WebSocket.OPEN}getConnectId(){return this.connectId}async connect(){if(this.isConnected())return;this.disposeSocket(),this.connectId=this.generateConnectId();let e=this.buildCenterWsUrl(this.connectId),t=this.defaultWebSocketFactory;return this.logger.info(`center connecting`,{wsUrl:e}),this.manualClose=!1,this.closeReasonError=void 0,new Promise((n,r)=>{try{let i=t(e);this.socket=i,i.onopen=()=>{this.startHeartbeatLoops(),this.sendHeartbeat(),this.logger.info(`center connected`),i.binaryType=`arraybuffer`,n()},i.onmessage=e=>{this.handleIncomingData(e.data)},i.onerror=()=>{},i.onclose=()=>{this.stopHeartbeatLoops(),this.socket=void 0;let e=this.closeReasonError??new X(Y.CenterDisconnected,`Center websocket disconnected`,!0);this.manualClose||(this.events.emit(`disconnected`,e),r(e)),this.closeReasonError=void 0}}catch(e){this.authEvents.emit(`progress`,{kind:`loading`,message:b.ServiceUrlInValid,key:`ServiceUrlInValid`,isClose:!0}),r(new X(Y.CenterUnavailable,`Failed to create center websocket: ${e instanceof Error?e.message:String(e)}`,!0,{cause:e instanceof Error?e.message:String(e)}))}})}disconnect(){this.manualClose=!0,this.closeReasonError=void 0,this.disposeSocket()}sendApiData(e,t,n){if(!this.socket||this.socket.readyState!==WebSocket.OPEN)throw new X(Y.CenterDisconnected,`Center websocket is not connected`,!0);let r={projectKey:this.config.sceneName,cls:`WebAPI`,method:e,param:t,fn:n},i=JSON.stringify(r),a=this.textEncoder.encode(i),o=new Uint8Array(a.length+1);o.set(a),this.socket.send(o.buffer),e!==`Heart`&&this.logger.debug(`center send`,{method:e,callbackName:n})}defaultWebSocketFactory(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in current runtime.`);return new WebSocket(e)}startHeartbeatLoops(){this.stopHeartbeatLoops(),this.heartbeatTimer=setInterval(()=>{try{this.isConnected()&&this.sendHeartbeat()}catch(e){this.logger.warn(`send heartbeat failed`,{error:e instanceof Error?e.message:String(e)})}},this.config.centerHeartbeatIntervalMs)}sendHeartbeat(){this.sendApiData(`Heart`),this.armHeartbeatTimeout()}stopHeartbeatLoops(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),void 0),this.clearHeartbeatTimeout()}armHeartbeatTimeout(){this.heartbeatTimeoutTimer||=setTimeout(()=>{this.heartbeatTimeoutTimer=void 0;let e=new X(Y.HeartbeatTimeout,`Center heartbeat timed out after ${this.config.centerHeartbeatTimeoutMs}ms`,!0);this.closeReasonError=e,this.events.emit(`heartbeatTimeout`,e),this.socket?.close()},this.config.centerHeartbeatTimeoutMs)}clearHeartbeatTimeout(){this.heartbeatTimeoutTimer&&=(clearTimeout(this.heartbeatTimeoutTimer),void 0)}disposeSocket(){this.stopHeartbeatLoops(),this.socket&&=(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,this.socket.close(),void 0)}async handleIncomingData(e){this.clearHeartbeatTimeout();let t=await this.decodeToBytes(e);if(!t)return;let n;try{n=u(t,{to:`string`})}catch{this.logger.warn(`center message inflate failed`);return}if(!n)return;let r;try{r=JSON.parse(n)}catch{this.logger.warn(`center message parse failed`);return}if(!r.fn){this.logger.warn(`center message missing fn`);return}r.fn!==`Heart`&&this.events.emit(`message`,r)}async decodeToBytes(e){if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);if(typeof Blob<`u`&&e instanceof Blob){let t=await e.arrayBuffer();return new Uint8Array(t)}return typeof e==`string`?this.textEncoder.encode(e):(this.logger.warn(`unsupported center message format`),null)}buildCenterWsUrl(e){return`${this.config.centerIP.replace(/^https:/i,`wss:`).replace(/^http:/i,`ws:`).replace(/\/+$/,``)}/${[this.config.mapType,e,this.config.sceneName,this.config.token,this.config.operationType].map(e=>encodeURIComponent(e)).join(`/`)}`}generateConnectId(){return`w_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}};function Vr(e,t,n){let r=e.endsWith(`/`)?e:`${e}/`,i=new URL(`api/v1/allocate`,r);return i.searchParams.set(`token`,t),i.searchParams.set(`proj`,n),i.toString()}function Hr(e){if(typeof e.signalingAddress==`string`&&e.signalingAddress.trim().length>0)return e.signalingAddress.trim();if(typeof e.signallingAddress==`string`&&e.signallingAddress.trim().length>0)return e.signallingAddress.trim()}function Ur(e,t){return new X(Y.SignallingBootstrapFailed,`Signalling allocate request timed out after ${t}ms`,!0,{endpoint:e,timeoutMs:t})}async function Wr(e,t=h){if(typeof fetch!=`function`)throw new X(Y.SignallingBootstrapFailed,`Fetch API is not available for signalling allocation`,!1);let n=Vr(e.signalingServer,e.token,e.proj),r=e.timeoutMs??15e3,i=typeof AbortController==`function`?new AbortController:void 0,a=!1,o,s=i?void 0:new Promise((e,t)=>{o=t}),c;c=setTimeout(()=>{if(a=!0,i){i.abort();return}o?.(Ur(n,r))},r);try{let e=fetch(n,{method:`GET`,...i?{signal:i.signal}:{}}),r=i?await e:await Promise.race([e,s]);if(!r.ok)throw new X(Y.SignallingBootstrapFailed,`Signalling allocate request failed with status ${r.status}`,!0,{endpoint:n,status:r.status});let a;try{a=await r.json()}catch(e){throw new X(Y.SignallingBootstrapFailed,`Signalling allocate response is not valid JSON`,!1,{endpoint:n,cause:e instanceof Error?e.message:String(e)})}let o=Hr(a);if(!o)throw new X(Y.SignallingUrlMissing,`Signalling allocate response missing signalingAddress`,!1,a);return t.info(`signalling allocate resolved url`,{endpoint:n}),o}catch(e){throw a?Ur(n,r):e instanceof X?e:new X(Y.SignallingBootstrapFailed,e instanceof Error?e.message:`Signalling allocate request failed`,!0,{endpoint:n,cause:e})}finally{c!==void 0&&clearTimeout(c)}}var Gr=class{constructor(t,n,r=h){this.config=t,this.session=n,this.logger=r,this.events=new e,this.handleWebRtcDisconnected=()=>{this.recoverFromWebRtcDisconnection()},this.nextOperationId=0,this.phase=`idle`,this.stopRequested=!1,this.reconnecting=!1,this.snapshot={state:`idle`,reconnecting:!1,updatedAt:Date.now()},this.centerClient=new Br(t,r,this.events),this.centerClient.on(`heartbeatTimeout`,e=>{this.logger.warn(`center heartbeat timeout`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`disconnected`,e=>{this.logger.warn(`center disconnected`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`message`,e=>{this.handleCenterMessage(e)}),this.session.addEventListener(`webRtcDisconnected`,this.handleWebRtcDisconnected)}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}getSnapshot(){return{...this.snapshot,reconnecting:this.reconnecting||this.session.isReconnecting()}}start(){return this.runningFlow?this.runningFlow.promise:this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!1,disconnectSession:!1,resolveOnStop:!0})}reconnect(){return this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!0})}reconnectSignalling(){let e=this.signallingAllocationSource;return e?this.startFlow({route:`signalling`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!1,signallingSource:e}):this.reconnect()}startFlow(e){if(this.runningFlow)return e.reconnecting&&(this.reconnecting=!0),e.disconnectSession&&this.session.disconnect(),this.runningFlow.promise;e.disconnectSession&&this.session.disconnect(),this.stopRequested=!1,this.reconnecting=e.reconnecting;let t=this.advanceOperation(),n=this.createRunningFlow(t,e.resolveOnStop);return this.runningFlow=n,this.phase=e.route===`signalling`?`settling`:`starting`,n.promise=this.decorateRunningFlow(n),(e.route===`center`||e.route===`direct`)&&this.prepareAuthBootstrap(t),this.runFlowRoute(e,t),n.promise}runFlowRoute(e,t){switch(e.route){case`center`:this.runCenterFlow(t);return;case`direct`:this.runDirectFlow(t);return;case`signalling`:this.runSignallingFlow(e.signallingSource,t);return}}prepareAuthBootstrap(e){this.centerClient.disconnect(),this.clearRunningContext(),this.pendingCenterInterruption=void 0,this.updateSnapshot(`centerConnecting`,{lastError:void 0,signallingUrl:void 0,engineToken:void 0,webToken:void 0}),this.isCurrentOperation(e)}runCenterFlow(e){this.runAuthFlowOnce(e)}runDirectFlow(e){this.startDirectSignallingBootstrap(e).catch(t=>{this.rejectActiveFlow(t,e)})}runSignallingFlow(e,t){if(!e){this.rejectActiveFlow(new X(Y.SignallingBootstrapFailed,`Signalling bootstrap source is missing`,!1),t);return}this.signallingAllocationSource=e,this.resolveAndConnectSignalling(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}disconnect(){let e=this.runningFlow;this.advanceOperation(),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!0,this.pendingCenterInterruption=void 0,this.phase=`idle`;let t=new X(Y.CenterDisconnected,`Auth workflow disconnected by user`,!0);e&&(e.stopRequested=!0,e.reject?.(t),e.resolve=void 0,e.reject=void 0),this.centerClient.disconnect(),this.session.disconnect(),this.updateSnapshot(`idle`,{webToken:void 0,engineToken:void 0,signallingUrl:void 0,lastError:void 0}),e&&(e.stopSnapshot=this.getSnapshot())}disconnectAndWait(){let e=this.runningFlow?.promise;return this.disconnect(),e?e.then(()=>void 0,()=>void 0):Promise.resolve()}runAuthFlowOnce(e){this.isCurrentOperation(e)&&this.centerClient.connect().then(()=>{this.isCurrentOperation(e)&&(this.updateSnapshot(`centerConnected`),this.expectMessage(`ConnectResult`))}).catch(t=>{this.rejectActiveFlow(t,e)})}shouldUseDirectSignallingBootstrap(){return!!this.config.signalingServer}async startDirectSignallingBootstrap(e){if(!this.isCurrentOperation(e))return;this.setPhase(`settling`,e);let t=this.resolveDirectSignallingAllocationSource();this.signallingAllocationSource=t,await this.resolveAndConnectSignalling(t,e)}resolveDirectSignallingAllocationSource(){if(this.config.signalingServer)return{signalingServer:this.config.signalingServer,token:this.config.token,proj:this.config.sceneName};throw new X(Y.SignallingBootstrapFailed,`No signalling bootstrap source configured`,!1)}handleCenterMessage(e){switch(e.fn){case`ConnectResult`:this.emitCenterEvent(`ConnectResult`,e),this.handleConnectResult(e);return;case`EngineServiceInit`:this.emitCenterEvent(`EngineServiceInit`,e),this.handleEngineServiceInit(e);return;case`TokenAuthorize`:this.emitCenterEvent(`TokenAuthorize`,e),this.handleTokenAuthorize(e);return;case`CenterCloseMessage`:this.emitCenterEvent(`CenterCloseMessage`,e),this.handleCenterCloseMessage(e);return;case`EngineSocketClose`:this.emitCenterEvent(`EngineSocketClose`,e),this.handleEngineSocketClose(e);return;case`TokenWillExpired`:this.emitCenterEvent(`TokenWillExpired`,e),this.handleTokenWillExpired(e);return;case`Offer`:case`Answer`:case`IceCandidate`:this.logger.debug(`center message ignored by current change scope`,{fn:e.fn});return;default:this.logger.debug(`unhandled center message`,{fn:e.fn})}}handleConnectResult(e){if(this.isExpecting(`ConnectResult`))try{if(e.success===!1){this.logger.warn(`connect result failed`,{status:e.status??``,message:e.message??``});return}let t=this.parseValues(e),n=t.webToken;if(!n)throw new X(Y.ConnectResultFailed,`ConnectResult missing webToken`,!0,e);this.connectResult=t,this.emitCenterEvent(`Connect`,e),this.emitLoadingProgress(b.EngineIniting,`EngineIniting`),this.updateSnapshot(`serviceAllocating`,{webToken:n}),this.centerClient.sendApiData(`GetServiceInfo`,this.config.privateKey||void 0),this.expectMessage(`EngineServiceInit`)}catch(e){this.rejectActiveFlow(e)}}handleEngineServiceInit(e){if(this.isExpecting(`EngineServiceInit`))try{if(e.success===!1){let t=e.message??``;this.emitWaitingProgress(t),this.config.viewMode!==`cs`&&this.emitCenterEvent(`EngineServiceInitWait`,e),this.updateSnapshot(`waiting`);return}let t=this.parseValues(e),n=t.token;if(!n)throw new X(Y.ServiceAllocationFailed,`EngineServiceInit missing engine token`,!0,e);this.serviceInfo=t,this.emitLoadingProgress(b.EngineTockenChecking,`EngineTockenChecking`),this.updateSnapshot(`authorizing`,{engineToken:n});let r=JSON.stringify({engineToken:n,webUuid:this.centerClient.getConnectId(),webToken:this.snapshot.webToken});this.centerClient.sendApiData(`AuthorizeToken`,r,`TokenAuthorize`),this.expectMessage(`TokenAuthorize`)}catch(e){this.rejectActiveFlow(e)}}handleTokenAuthorize(e){if(!this.isExpecting(`TokenAuthorize`))return;if(e.success===!1){this.logger.warn(`token authorize failed, wait center close message`,{status:e.status??``,message:e.message??``});return}let t=this.runningFlow?.operationId;t!==void 0&&this.handleTokenAuthorizeSuccess(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}async handleTokenAuthorizeSuccess(e,t){if(!this.isCurrentOperation(t))return;this.setPhase(`settling`,t);let n=(this.tryParseValues(e)??{}).signalingServer?.trim();if(!n)throw new X(Y.SignallingUrlMissing,`TokenAuthorize missing signalingServer`,!1,e);let r=this.snapshot.engineToken;if(!r)throw new X(Y.ServiceAllocationFailed,`Engine token is missing before signaling allocation`,!1,e);let i={signalingServer:n,token:r,proj:this.config.sceneName};this.signallingAllocationSource=i,await this.resolveAndConnectSignalling(i,t)}async resolveAndConnectSignalling(e,t){let n=await Wr(e,this.logger);if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling allocation result`,{operationId:t});return}this.connectWithSignallingUrl(n,t)}connectWithSignallingUrl(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling connect result`,{operationId:t});return}if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url is missing before connect`,!1);this.session.setSignallingUrlBuilder(()=>{let e=this.snapshot.signallingUrl;if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url not ready before connect`,!1);return e}),this.emitLoadingProgress(b.EngineConnectioning,`EngineConnectioning`),this.updateSnapshot(`webrtcConnecting`,{signallingUrl:e}),this.session.connect(),this.setPhase(`connected`,t),this.updateSnapshot(`connected`),this.completeRunningFlow(this.getSnapshot(),t)}handleCenterCloseMessage(e){let t=e.message??`CenterCloseMessage received`;if(e.status===`TokenInValid`){this.emitLoadingProgress(b.TokenInValid,`TokenInValid`);let n=new X(Y.TokenInvalid,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}if(e.status===`TokenExpired`){this.emitLoadingProgress(b.TokenExpired,`TokenExpired`);let n=new X(Y.TokenExpired,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}this.emitLoadingProgress(b.EngineTokenCheckFail,`EngineTokenCheckFail`);let n=new X(Y.AuthorizeFailed,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n)}handleEngineSocketClose(e){let t=this.snapshot.engineToken,n=this.extractEngineSocketCloseToken(e.values);if(!t||!n||t!==n){this.logger.debug(`ignore EngineSocketClose for non-current session`,{currentToken:t,closedToken:n});return}let r=new X(Y.CenterDisconnected,e.message??`Engine socket closed`,!0,e);this.emitLoadingProgress(b.EngineClose,`EngineClose`),this.handleCenterInterruption(r)}handleTokenWillExpired(e){this.logger.warn(`token will expire soon`,{message:e.message??``}),this.emitTokenWillExpireProgress(e.message??``)}expectMessage(e){this.expectedCenterFn=e}isExpecting(e){return this.expectedCenterFn===e&&this.hasActiveRunningFlow()}advanceOperation(){return this.nextOperationId+=1,this.nextOperationId}isCurrentOperation(e){return this.runningFlow?.operationId===e}setPhase(e,t){return this.isCurrentOperation(t)?(this.phase=e,!0):!1}createRunningFlow(e,t=!1){let n=()=>void 0,r=()=>void 0;return{operationId:e,promise:new Promise((e,t)=>{n=e,r=t}),resolve:n,reject:r,stopRequested:!1,resolveOnStop:t}}decorateRunningFlow(e){return e.promise.then(t=>e.stopRequested?e.stopSnapshot??this.getSnapshot():(this.reconnecting=!1,this.events.emit(`connected`,t),t)).catch(t=>{if(e.stopRequested){if(e.resolveOnStop)return e.stopSnapshot??this.getSnapshot();throw zr(t)}let n=zr(t);throw this.isCurrentOperation(e.operationId)&&(this.updateSnapshot(`failed`,{lastError:n.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())),n}).finally(()=>{if(!this.isCurrentOperation(e.operationId))return;let t=e.stopRequested||this.stopRequested;this.setPhase(this.snapshot.state===`connected`?`connected`:`idle`,e.operationId),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!1,this.flushPendingCenterInterruption(t,e.operationId)})}completeRunningFlow(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale auth flow completion`,{operationId:t});return}let n=this.runningFlow;this.clearRunningContext(t),n?.resolve?.(e),n&&(n.resolve=void 0,n.reject=void 0)}rejectActiveFlow(e,t){let n=zr(e),r=this.runningFlow;if(!r||t!==void 0&&r.operationId!==t)return this.logger.debug(`ignore stale auth flow failure`,{operationId:t,currentOperationId:r?.operationId,code:n.code,message:n.message}),!1;let i=r.reject;return i?(this.clearRunningContext(r.operationId),r.resolve=void 0,r.reject=void 0,i(n),!0):(this.logger.debug(`ignore auth flow failure without active deferred`,{operationId:r.operationId,code:n.code,message:n.message}),!1)}publishFailure(e){this.updateSnapshot(`failed`,{lastError:e.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())}hasActiveRunningFlow(){return!!this.runningFlow?.reject}clearRunningContext(e){e!==void 0&&!this.isCurrentOperation(e)||(this.expectedCenterFn=void 0,this.connectResult=void 0,this.serviceInfo=void 0)}isWaitingMessage(e){return[`坐席已满`,`服务已满`,`排队`,`没有服务资源`,`资源`].some(t=>e.includes(t))}parseValues(e){if(!e.values)return{};try{return JSON.parse(e.values)}catch(t){throw new X(Y.CenterProtocolInvalid,`Invalid center values json for ${e.fn}`,!1,{envelope:e,cause:t instanceof Error?t.message:String(t)})}}tryParseValues(e){if(e.values)try{return JSON.parse(e.values)}catch(t){this.logger.warn(`center values parse failed, fallback to empty payload`,{fn:e.fn,cause:t instanceof Error?t.message:String(t)});return}}extractEngineSocketCloseToken(e){if(!e)return;let t=e.trim();if(t){try{let e=JSON.parse(t);if(typeof e==`string`)return e;if(e&&typeof e.token==`string`&&e.token.trim().length>0)return e.token}catch{}return t}}handleCenterInterruption(e){let t=this.decideCenterInterruption();switch(t.kind){case`ignore`:return;case`reject`:this.rejectActiveFlow(e,t.operationId);return;case`defer`:this.deferCenterInterruption(e,t.operationId);return;case`recover`:this.recoverFromCenterInterruption(e);return}}decideCenterInterruption(){if(this.isTerminalSnapshot())return{kind:`ignore`};let e=this.runningFlow;return e?this.phase===`settling`?{kind:`defer`,operationId:e.operationId}:this.hasActiveRunningFlow()?{kind:`reject`,operationId:e.operationId}:{kind:`defer`,operationId:e.operationId}:{kind:`recover`}}isTerminalSnapshot(){return this.isTerminalSnapshotState(this.snapshot.state)}deferCenterInterruption(e,t){if(this.isCurrentOperation(t)){if(this.pendingCenterInterruption){this.logger.debug(`center interruption already deferred during flow settlement`,{currentCode:this.pendingCenterInterruption.error.code,incomingCode:e.code});return}this.pendingCenterInterruption={operationId:t,error:e},this.logger.debug(`defer center interruption until current flow settles`,{operationId:t,code:e.code,message:e.message})}}flushPendingCenterInterruption(e,t){let n=this.pendingCenterInterruption;if(!(!n||n.operationId!==t)){if(this.pendingCenterInterruption=void 0,e||this.snapshot.state===`idle`||this.snapshot.state===`failed`||this.runningFlow){this.logger.debug(`drop deferred center interruption`,{skip:e,state:this.snapshot.state,code:n.error.code,operationId:t});return}this.recoverFromCenterInterruption(n.error)}}recoverFromWebRtcDisconnection(){let e=this.snapshot.state;if(this.shouldIgnoreWebRtcDisconnection(e)){this.logger.debug(`ignore WebRTC disconnection for current workflow state`,{stopRequested:this.stopRequested,reconnecting:this.reconnecting,hasRunningPromise:!!this.runningFlow,state:e});return}this.logger.warn(`WebRTC disconnected, reconnect signalling`,{state:e}),this.reconnectSignalling().catch(e=>{let t=zr(e);this.publishFailure(t)})}shouldIgnoreWebRtcDisconnection(e){return this.stopRequested||this.reconnecting||!!this.runningFlow||this.isTerminalSnapshotState(e)}isTerminalSnapshotState(e){return e===`idle`||e===`failed`}recoverFromCenterInterruption(e){this.logger.warn(`center interruption detected, start reconnect`,{state:this.snapshot.state,code:e.code,message:e.message}),this.emitCenterEvent(`UnConnect`,{code:e.code,message:e.message}),this.emitLoadingProgress(b.SerriceError,`SerriceError`),this.reconnect().catch(e=>{let t=zr(e);this.publishFailure(t)})}updateSnapshot(e,t){this.snapshot={...this.snapshot,...t,state:e,reconnecting:this.reconnecting||this.session.isReconnecting(),updatedAt:Date.now()},this.events.emit(`stateChanged`,this.getSnapshot())}emitLoadingProgress(e,t,n=!0){this.events.emit(`progress`,{kind:`loading`,message:e,key:t,isClose:n})}emitTokenWillExpireProgress(e,t=!0){this.events.emit(`progress`,{kind:`tokenWillExpire`,message:e,key:`TokenWillExpired`,isClose:t})}emitCenterEvent(e,t){this.events.emit(`centerEvent`,{eventName:e,payload:t})}emitWaitingProgress(e){if(this.config.viewMode!==`cs`){if(e.includes(`云渲染服务坐席已满`)||e.includes(`坐席已满`)||e.includes(`当前服务已满`)){this.emitLoadingProgress(e,`EngineWaiting`);return}e.includes(`没有服务资源`)&&this.emitLoadingProgress(b.SerriceUnAvaible,`SerriceUnAvaible`)}}};function Kr(e){return typeof e==`object`&&!!e}var qr=class{constructor(e,t=h,n={},r={}){this.session=e,this.logger=t,this.hooks=n,this.pending=new Map,this.sendRetries=new Map,this.listenerName=`enginesdk3_response_listener`,this.disconnectEvents=[`webRtcDisconnected`,`webRtcFailed`],this.onResponse=this.handleResponse.bind(this),this.onSessionDisconnected=()=>{this.cleanupPendingOnDisconnect()},this.retryOptions={enabled:r.enabled??!0,intervalMs:r.intervalMs??250,maxWaitMs:r.maxWaitMs??15e3},this.logger.debug(`register response listener`,{listenerName:this.listenerName}),this.session.addResponseEventListener(this.listenerName,this.onResponse),this.disconnectEvents.forEach(e=>{this.session.addEventListener(e,this.onSessionDisconnected)})}sendRequest(e,t,n){let{requestId:r,envelope:i}=this.createRequestEnvelope(e,t,n),a,o,s=new Promise((e,t)=>{a=e,o=t}),c={mode:`single`,module:e,method:t,sentAt:Date.now(),resolve:a,reject:o};return this.pending.set(r,c),this.handleSendAttempt(r,i,c,!1),s}sendStreamRequest(e,t,n,r){let{requestId:i,envelope:a}=this.createRequestEnvelope(e,t,n),o=r??(()=>void 0),s,c,l=new Promise((e,t)=>{s=e,c=t});Object.defineProperty(l,"requestId",{value:i,enumerable:!0}),l.cancel=e=>{this.cancelStreamRequest(i,e)};let u={mode:`stream`,module:e,method:t,sentAt:Date.now(),callback:o,isDone:e=>this.defaultStreamDonePredicate(e),resolve:s,reject:e=>c(e)};return this.pending.set(i,u),this.handleSendAttempt(i,a,u,!0),l}sendPendingRequest(e,t,n){if(this.logger.debug(`emit ${n.mode} request`,{requestId:e,module:n.module,method:n.method}),!this.session.emitUIInteraction(t)){let t=Error(`Failed to send ${n.mode} request: ${n.module}.${n.method}`);return this.logger.error(`emit request failed`,{requestId:e,module:n.module,method:n.method}),t}this.hooks.onRequestSent?.({requestId:e,module:n.module,method:n.method})}handleSendAttempt(e,t,n,r){let i=this.sendPendingRequest(e,t,n);if(i){if(!this.retryOptions.enabled){this.settlePendingFailure(e,n,i,{notifyStream:r});return}this.logger.warn(`emit request failed, will retry until transport ready`,{requestId:e,module:n.module,method:n.method,error:i.message}),this.scheduleSendRetry(e,t,n,r,i)}}scheduleSendRetry(e,t,n,r,i){let a=this.sendRetries.get(e);if(a){a.lastError=i,a.timer===void 0&&(a.timer=setTimeout(()=>this.runSendRetry(a),this.retryOptions.intervalMs));return}let o={requestId:e,envelope:t,pending:n,notifyStream:r,queuedAt:Date.now(),lastError:i};this.sendRetries.set(e,o),o.timer=setTimeout(()=>this.runSendRetry(o),this.retryOptions.intervalMs)}runSendRetry(e){if(e.timer=void 0,this.sendRetries.get(e.requestId)!==e)return;let t=Date.now()-e.queuedAt;if(t>=this.retryOptions.maxWaitMs){this.sendRetries.delete(e.requestId);let{module:n,method:r,mode:i}=e.pending,a=Error(`Failed to send ${i} request: ${n}.${r} after retrying for ${t}ms (${e.lastError.message})`);this.logger.error(`send retry gave up`,{requestId:e.requestId,module:n,method:r,error:a.message}),this.settlePendingFailure(e.requestId,e.pending,a,{notifyStream:e.notifyStream});return}let n=this.sendPendingRequest(e.requestId,e.envelope,e.pending);if(!n){this.sendRetries.delete(e.requestId),this.logger.info(`request sent after transport ready retry`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method});return}e.lastError=n,this.logger.debug(`send retry attempt failed, will retry again`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method,error:n.message}),e.timer=setTimeout(()=>this.runSendRetry(e),this.retryOptions.intervalMs)}clearSendRetry(e){let t=this.sendRetries.get(e);t&&(t.timer!==void 0&&clearTimeout(t.timer),this.sendRetries.delete(e))}settlePendingFailure(e,t,n,r={}){this.pending.get(e)===t&&(this.pending.delete(e),this.clearSendRetry(e),t.mode===`stream`&&r.notifyStream&&this.emitStreamCallback(t,{type:`error`,requestId:e,response:r.response,error:n}),t.reject(n))}handleResponse(e){let t;try{t=JSON.parse(e)}catch(e){this.logger.warn(`response parse failed`,{error:p(e)});return}let n=t.requestId??t.uuid;if(!n){this.logger.warn(`response missing requestId`);return}t.requestId=n,t.param!==void 0&&t.params===void 0&&(t.params=t.param);let r=this.pending.get(n);if(!r){this.logger.debug(`response ignored, no pending request`,{requestId:n});return}if(r.mode===`single`){this.pending.delete(n),this.resolveSingleResponse(t,r);return}this.resolveStreamResponse(t,r)}createRequestEnvelope(e,t,n){let r=`r_${Date.now()}_${Math.random().toString(16).slice(2,10)}`;return{requestId:r,envelope:{AssemblyName:`EngineApi`,fn:r,ClassName:e,FunctionName:t,Value:JSON.stringify(n),ts:Date.now()}}}defaultStreamDonePredicate(e){if(typeof e.code==`string`){let t=e.code.trim().toUpperCase();if(t===`DONE`||t===`STREAM_DONE`)return!0}return!!this.hasDoneFlag(e)}hasDoneFlag(e){return[e,e.data].some(e=>Kr(e)?e.done===!0||e.isEnd===!0:!1)}resolveSingleResponse(e,t){if(e.success||!e.success&&e.errorMsg!=null){this.emitResponseReceivedHook(e,t),this.logger.info(`response success`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}this.logger.warn(`response failed`,{requestId:e.requestId,code:``,message:e.errorMsg}),t.reject(Error(` ${e.errorMsg}`))}resolveStreamResponse(e,t){if(!e.success){let n=Error(` ${e.errorMsg??e.message}`);this.logger.warn(`stream response failed`,{requestId:e.requestId,code:e.code,message:e.errorMsg??e.message}),this.settlePendingFailure(e.requestId,t,n,{response:e,notifyStream:!0});return}if(this.emitResponseReceivedHook(e,t),t.isDone(e)){this.pending.delete(e.requestId);let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`done`,e));if(n){t.reject(n);return}this.logger.info(`stream request done`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`data`,e));n&&this.settlePendingFailure(e.requestId,t,n)}createStreamResponseEvent(e,t){return{...t,type:e,requestId:t.requestId,response:t,data:t.data,params:t.params,param:t.params??t.param,errorMsg:t.errorMsg}}emitResponseReceivedHook(e,t){this.hooks.onResponseReceived?.({requestId:e.requestId,module:t.module,method:t.method,durationMs:Math.max(0,Date.now()-t.sentAt),code:e.code})}emitStreamCallback(e,t){try{e.callback(t);return}catch(e){let n=e instanceof Error?e:Error(String(e));return this.logger.warn(`stream callback failed`,{requestId:t.requestId,type:t.type,error:n.message}),n}}cancelStreamRequest(e,t){let n=this.pending.get(e);if(!n||n.mode!==`stream`)return;this.pending.delete(e),this.clearSendRetry(e);let r=t?.trim()||`Stream request cancelled by client`,i=Error(r);this.logger.info(`stream request cancelled`,{requestId:e,module:n.module,method:n.method}),this.emitStreamCallback(n,{type:`cancel`,requestId:e,error:i}),n.reject(i)}cleanupPendingOnDisconnect(){if(this.sendRetries.forEach(e=>{e.timer!==void 0&&clearTimeout(e.timer)}),this.sendRetries.clear(),this.pending.size===0)return;let e=Error(`Session disconnected before request completed`);this.pending.forEach((t,n)=>{t.mode===`single`||this.emitStreamCallback(t,{type:`error`,requestId:n,error:e}),t.reject(e),this.logger.warn(`pending request cleared on disconnect`,{requestId:n,mode:t.mode})}),this.pending.clear()}};function Jr(e){return typeof e==`object`&&!!e}function Z(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Yr(e){if(!Jr(e))return;let t=e.data;if(!Jr(t))return;let n=t.aggregatedStats;if(Jr(n))return n}function Xr(e,t,n){if(e===void 0||t===void 0)return{packetLossRate:void 0,next:n};let r={packetsLost:e,packetsReceived:t};if(!n)return{packetLossRate:void 0,next:r};let i=e-n.packetsLost,a=t-n.packetsReceived;if(i<0||a<0)return{packetLossRate:void 0,next:r};let o=i+a;if(o<=0)return{packetLossRate:void 0,next:r};let s=i/o;return{packetLossRate:Math.max(0,Math.min(1,s)),next:r}}function Zr(e){let t=e.getActiveCandidatePair;if(typeof t!=`function`)return;let n=t.call(e);if(!Jr(n))return;let r=Z(n.currentRoundTripTime);return r===void 0?void 0:r*1e3}function Qr(e,t){let n=Yr(e);if(!n)return;let r=Jr(n.inboundVideoStats)?n.inboundVideoStats:{},i=Z(r.bitrate),a=Xr(Z(r.packetsLost),Z(r.packetsReceived),t);return{aggregatedStats:n,inboundVideoStats:r,metrics:{fps:Z(r.framesPerSecond),bitrateKbps:i===void 0?void 0:i/1e3,packetLossRate:a.packetLossRate,jitterMs:(()=>{let e=Z(r.jitter);return e===void 0?void 0:e*1e3})(),rttMs:Zr(n),frameWidth:Z(r.frameWidth),frameHeight:Z(r.frameHeight)},packetCounters:a.next}}function $r(){return{CameraHeight:`-`,FPS:`-`,Width:`-`,Height:`-`,runTime:`-`,bytePerSecond:`-`,lostPacketsRate:`-`,delayTime:`-`,Codec:`-`}}function ei(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`)return String(e)}function ti(e){if(e<=0||!Number.isFinite(e))return`00:00:00`;let t=Math.floor(e/1e3);return[Math.floor(t/3600),Math.floor(t%3600/60),t%60].map(e=>String(e).padStart(2,`0`)).join(`:`)}var ni=class{constructor(e,t,n=h,r){this.session=e,this.onStatus=t,this.logger=n,this.onSample=r,this.connected=!1,this.status=$r(),this.onWebRtcConnected=()=>{this.connected=!0,this.firstStatsTimestampMs=void 0,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector started`)},this.onWebRtcDisconnected=()=>{this.pause(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.pause(`webRtcFailed`)},this.onWebRtcConnecting=()=>{this.pause(`webRtcConnecting`)},this.onStatsReceived=e=>{if(!this.connected)return;let t=Qr(e,this.packetCounters);t&&(this.packetCounters=t.packetCounters,this.status=this.patchByStats(this.status,t),this.onSample?.(this.extractMediaSample(t)),this.emit())},this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`statsReceived`,this.onStatsReceived)}stop(){this.pause(`manualStop`)}dispose(){this.stop(),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`statsReceived`,this.onStatsReceived)}pause(e){this.connected&&(this.connected=!1,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector paused`,{reason:e}))}patchByStats(e,t){let n=t.aggregatedStats,r=t.inboundVideoStats,i={...e},a=t.metrics.frameWidth;a!==void 0&&(i.Width=String(a));let o=t.metrics.frameHeight;o!==void 0&&(i.Height=String(o));let s=t.metrics.fps;s!==void 0&&(i.FPS=String(s));let c=t.metrics.bitrateKbps;c!==void 0&&(i.bytePerSecond=`${Math.round(c)} kb/s`),i.lostPacketsRate=t.metrics.packetLossRate===void 0?`-`:`${(t.metrics.packetLossRate*100).toFixed(2)}%`;let l=Z(r.timestamp);if(l!==void 0){if(this.lastStatsTimestamp!==void 0){let e=l-this.lastStatsTimestamp;i.delayTime=`${Math.max(0,1e3-e).toFixed(2)} ms`}this.lastStatsTimestamp=l}this.firstStatsTimestampMs===void 0&&(this.firstStatsTimestampMs=Date.now()),i.runTime=ei(n.sessionStats?.runTime)??ti(Date.now()-this.firstStatsTimestampMs);let u=ei(r.codecId),d=u?this.getCodecMimeType(n,u):void 0;return d&&(i.Codec=d),i}extractMediaSample(e){return{...e.metrics,bitrateKbps:e.metrics.bitrateKbps===void 0?void 0:Math.round(e.metrics.bitrateKbps)}}getCodecMimeType(e,t){let n=e.codecs;if(!n)return;let r;(n instanceof Map||typeof n.get==`function`)&&(r=n.get(t));let i=r?.mimeType;return typeof i==`string`&&i.length>0?i:void 0}emit(){this.onStatus({...this.status})}};const ri=[`Normal`,`Mild`,`Moderate`,`Severe`];function ii(e){return ri.indexOf(e)}function ai(e,t){return ii(e)>=ii(t)?e:t}function oi(e,t){let n=ii(t);return e.filter(e=>ii(e)>=n).length}function si(e){return e===`Severe`?`Moderate`:e===`Moderate`?`Mild`:`Normal`}function ci(e){return e===void 0?`Normal`:e>=.1?`Severe`:e>=.06?`Moderate`:e>=.03?`Mild`:`Normal`}function li(e){return e===void 0?`Normal`:e>=240?`Severe`:e>=180?`Moderate`:e>=120?`Mild`:`Normal`}function ui(e){return e===void 0?`Normal`:e>=80?`Severe`:e>=50?`Moderate`:e>=25?`Mild`:`Normal`}function di(e){return e===void 0?`Normal`:e<=12?`Severe`:e<=20?`Moderate`:e<=28?`Mild`:`Normal`}function fi(e){let t=ci(e.packetLossRate),n=ai(li(e.rttMs),ui(e.jitterMs)),r=[t,n,di(e.fps)],i=[t,n];return r.some(e=>e===`Severe`)?`Severe`:oi(r,`Moderate`)>=2||oi(i,`Moderate`)>=1&&oi(r,`Mild`)>=2?`Moderate`:oi(r,`Mild`)>=2||oi(i,`Moderate`)>=1?`Mild`:`Normal`}function pi(e,t,n,r,i=e){return{measuredLevel:t,outcome:n,reason:r,degradeStreak:i.degradeStreak,recoverStreak:i.recoverStreak}}const mi=[{evaluate(e,t){if(!(e.connected&&e.metrics.connected))return pi(e,t,`hold`,`session not connected, skip adaptation`)}},{evaluate(e,t){if(e.actionInFlight)return pi(e,t,`hold`,`action in flight`)}},{evaluate(e,t){if(!(e.now>=e.cooldownUntil))return pi(e,t,`skip_cooldown`,`cooldown until ${e.cooldownUntil}`)}},{evaluate(e,t){if(ii(t)<=ii(e.stableLevel))return;let n=e.degradeStreak+1,r=t===`Severe`?1:2;return n<r?pi(e,t,`skip_hysteresis`,`degrade streak ${n}/${r}`,{degradeStreak:n,recoverStreak:0}):{measuredLevel:t,outcome:`downgrade`,targetLevel:t,reason:`measured ${t}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){if(t!==`Normal`||e.stableLevel===`Normal`)return;let n=e.recoverStreak+1;if(n<4)return pi(e,t,`skip_hysteresis`,`recover streak ${n}/4`,{degradeStreak:0,recoverStreak:n});let r=si(e.stableLevel);return{measuredLevel:t,outcome:`recover`,targetLevel:r,reason:`recover to ${r}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){return pi(e,t,`hold`,`no transition`,{degradeStreak:0,recoverStreak:t===`Normal`?e.recoverStreak:0})}}];function hi(e){let t=fi(e.metrics);for(let n of mi){let r=n.evaluate(e,t);if(r)return r}return pi(e,t,`hold`,`no transition`)}const gi={Normal:{bitrate:12e6,fps:60,width:1920,height:1080},Mild:{bitrate:8e6,fps:45,width:1600,height:900},Moderate:{bitrate:4e6,fps:30,width:1280,height:720},Severe:{bitrate:2e6,fps:20,width:960,height:540}};function _i(e){let t=e.filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length!==0)return t.reduce((e,t)=>e+t,0)/t.length}var vi=class{constructor(e){this.metricsWindow=[],this.traces=[],this.connected=!1,this.mode=`auto`,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.diagnosticsVisible=!1,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.lastAppliedProfileKey=``,this.transitionGeneration=0,this.onStatsReceived=e=>{this.handleStatsReceived(e)},this.onWebRtcConnected=()=>{this.connected=!0,this.metricsWindow.length=0,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.lastMetrics=void 0,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.lastAppliedProfileKey=``,this.transitionGeneration+=1,this.logger.info(`network adaptation received webRtcConnected`),this.pushTrace({outcome:`hold`,reason:`webrtc connected, resume adaptation`}),this.emitDiagnosticsSnapshot()},this.onWebRtcConnecting=()=>{this.handleConnectionInterrupted(`webRtcConnecting`)},this.onWebRtcDisconnected=()=>{this.handleConnectionInterrupted(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.handleConnectionInterrupted(`webRtcFailed`)},this.session=e.session,this.screen=e.screen,this.logger=e.logger??h,this.onStateChange=e.onStateChange,this.onAction=e.onAction,this.onDiagnostics=e.onDiagnostics}start(){this.session.addEventListener(`statsReceived`,this.onStatsReceived),this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed)}dispose(){this.session.removeEventListener(`statsReceived`,this.onStatsReceived),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed)}setMode(e){this.mode!==e&&(this.mode=e,this.pushTrace({outcome:`manual`,reason:`mode switched to ${e}`}),this.emitDiagnosticsSnapshot(),e===`auto`&&this.lastMetrics&&this.evaluateAutoStrategy(this.lastMetrics))}setManualLevel(e){this.setMode(`manual`),this.transitionToLevel(e,`manual`,`manual override to ${e}`,!0)}setDiagnosticsVisible(e){this.diagnosticsVisible=e,this.emitDiagnosticsSnapshot()}getDiagnosticsSnapshot(){return{ts:Date.now(),visible:this.diagnosticsVisible,mode:this.mode,currentLevel:this.currentLevel,connected:this.connected,lastMetrics:this.lastMetrics,lastAction:this.lastAction,traces:[...this.traces]}}handleStatsReceived(e){let t=Qr(e,this.packetCounters);if(!t)return;this.packetCounters=t.packetCounters;let n={ts:Date.now(),connected:this.connected,...t.metrics};this.lastMetrics=this.pushMetrics(n),this.emitDiagnosticsSnapshot(),this.mode!==`manual`&&this.evaluateAutoStrategy(this.lastMetrics)}handleConnectionInterrupted(e){this.connected=!1,this.logger.warn(`network adaptation connection interrupted`,{source:e}),this.metricsWindow.length=0,this.recoverStreak=0,this.degradeStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.transitionGeneration+=1,this.pushTrace({outcome:`hold`,reason:`${e}; session disconnected, pause adaptation`}),this.emitDiagnosticsSnapshot()}pushMetrics(e){return this.metricsWindow.push(e),this.metricsWindow.length>5&&this.metricsWindow.shift(),{ts:e.ts,connected:e.connected,fps:_i(this.metricsWindow.map(e=>e.fps)),bitrateKbps:_i(this.metricsWindow.map(e=>e.bitrateKbps)),packetLossRate:_i(this.metricsWindow.map(e=>e.packetLossRate)),jitterMs:_i(this.metricsWindow.map(e=>e.jitterMs)),rttMs:_i(this.metricsWindow.map(e=>e.rttMs)),frameWidth:_i(this.metricsWindow.map(e=>e.frameWidth)),frameHeight:_i(this.metricsWindow.map(e=>e.frameHeight))}}evaluateAutoStrategy(e){let t=hi({connected:this.connected,metrics:e,currentLevel:this.currentLevel,stableLevel:this.stableLevel,mode:this.mode,actionInFlight:this.actionInFlight,cooldownUntil:this.cooldownUntil,now:Date.now(),degradeStreak:this.degradeStreak,recoverStreak:this.recoverStreak});this.applyStrategyDecision(t,e)}applyStrategyDecision(e,t){if(this.degradeStreak=e.degradeStreak,this.recoverStreak=e.recoverStreak,e.outcome===`downgrade`||e.outcome===`recover`){this.transitionToLevel(e.targetLevel??e.measuredLevel,e.outcome,e.reason,!1,t);return}this.pushTrace({measuredLevel:e.measuredLevel,currentLevel:this.currentLevel,mode:this.mode,metrics:t,outcome:e.outcome,reason:e.reason})}transitionToLevel(e,t,n,r,i=this.lastMetrics){if(console.log(`transitionToLevel`,e,t,n,r,i),!r&&e===this.stableLevel){this.pushTrace({measuredLevel:fi(i??{ts:Date.now(),connected:!1}),currentLevel:this.currentLevel,mode:this.mode,metrics:i,outcome:`hold`,reason:`target level equals current level`});return}let a=this.transitionGeneration;this.actionInFlight=!0,this.runTransition(e,t,n,a,i).finally(()=>{a===this.transitionGeneration&&(this.actionInFlight=!1)})}async runTransition(e,t,n,r,i=this.lastMetrics){if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition ignored before start`,{targetLevel:e,reason:n});return}let a=this.currentLevel,o=this.stableLevel,s=fi(i??{ts:Date.now(),connected:!1});t===`recover`&&this.currentLevel!==`Recovering`&&(this.currentLevel=`Recovering`,this.onStateChange?.({from:a,to:`Recovering`,mode:this.mode,reason:`enter recovering before ${e}`,ts:Date.now(),metrics:i}));let c=await this.applyLevelProfile(e,n);if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition discarded after action (stale generation)`,{targetLevel:e,reason:n}),this.pushTrace({measuredLevel:s,currentLevel:this.currentLevel,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; stale transition discarded`}),this.emitDiagnosticsSnapshot();return}if(this.lastAction=c,this.onAction?.(c),!c.success){this.logger.warn(`network adaptation transition not committed due to action failure`,{targetLevel:e,reason:n});let t=this.currentLevel;this.currentLevel=o,t!==this.currentLevel&&this.onStateChange?.({from:t,to:this.currentLevel,mode:this.mode,reason:`${n}; action failed rollback`,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:t,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; action failed, keep ${o}`}),this.emitDiagnosticsSnapshot();return}let l=this.currentLevel;this.stableLevel=e,this.currentLevel=e,this.cooldownUntil=Date.now()+6e3,this.onStateChange?.({from:l,to:e,mode:this.mode,reason:n,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:l,mode:this.mode,targetLevel:e,metrics:i,outcome:t,reason:n}),this.emitDiagnosticsSnapshot()}async applyLevelProfile(e,t){let n=gi[e],r=`${n.bitrate}-${n.fps}-${n.width}x${n.height}`;if(r===this.lastAppliedProfileKey)return{level:e,mode:this.mode,success:!0,skipped:!0,reason:`${t}; profile already applied`,ts:Date.now(),steps:[]};let i=[];i.push(await this.runActionStep(`SetSceneRenderBitrate`,{bitrate:n.bitrate})),i.push(await this.runActionStep(`SetSceneFPS`,{fps:n.fps})),i.push(await this.runActionStep(`SetScreenResolution`,{width:n.width,height:n.height}));let a=i.every(e=>e.success);return a&&(this.lastAppliedProfileKey=r),{level:e,mode:this.mode,success:a,skipped:!1,reason:t,ts:Date.now(),steps:i}}async runActionStep(e,t){try{return this.logger.info(`network adaptation action success`,{type:e,payload:t}),{type:e,payload:t,success:!0}}catch(n){let r=n instanceof Error?n.message:String(n);return this.logger.warn(`network adaptation action failed`,{type:e,payload:t,error:r}),{type:e,payload:t,success:!1,error:r}}}pushTrace(e){let t={ts:Date.now(),mode:e.mode??this.mode,currentLevel:e.currentLevel??this.currentLevel,measuredLevel:e.measuredLevel??fi(this.lastMetrics??{ts:Date.now(),connected:this.connected}),targetLevel:e.targetLevel,outcome:e.outcome,reason:e.reason,metrics:e.metrics};this.traces.unshift(t),this.traces.length>30&&(this.traces.length=30),this.emitDiagnosticsSnapshot()}emitDiagnosticsSnapshot(){this.onDiagnostics?.(this.getDiagnosticsSnapshot())}},yi=class{constructor(e){this.visible=!1,this.onKeyDown=e=>{e.ctrlKey&&e.altKey&&e.code===`KeyD`&&(e.preventDefault(),this.toggle())},this.options=e,this.logger=e.logger??h,typeof window<`u`&&window.addEventListener(`keydown`,this.onKeyDown)}dispose(){typeof window<`u`&&window.removeEventListener(`keydown`,this.onKeyDown),this.root?.remove(),this.root=void 0}update(e){this.snapshot=e,this.visible&&(this.ensureRoot(),this.render())}setVisible(e){this.visible!==e&&(this.visible=e,this.ensureRoot(),this.root&&(this.root.style.display=e?`block`:`none`),e&&this.render(),this.options.onVisibilityChange?.(e))}toggle(){this.setVisible(!this.visible)}ensureRoot(){if(this.root||typeof document>`u`||!document.body)return;let e=document.createElement(`div`);e.id=`enginesdk3-network-diagnostics-panel`,e.style.position=`fixed`,e.style.right=`16px`,e.style.bottom=`16px`,e.style.zIndex=`2147483647`,e.style.width=`360px`,e.style.maxWidth=`calc(100vw - 32px)`,e.style.maxHeight=`70vh`,e.style.overflow=`auto`,e.style.padding=`12px`,e.style.borderRadius=`8px`,e.style.boxShadow=`0 6px 24px rgba(0, 0, 0, 0.35)`,e.style.background=`rgba(12, 17, 24, 0.94)`,e.style.color=`#e8f0ff`,e.style.fontFamily=`Menlo, Consolas, Monaco, monospace`,e.style.fontSize=`12px`,e.style.lineHeight=`1.4`,e.style.display=this.visible?`block`:`none`;let t=document.createElement(`div`);t.style.display=`flex`,t.style.justifyContent=`space-between`,t.style.alignItems=`center`,t.style.marginBottom=`8px`;let n=document.createElement(`strong`);n.textContent=`Network Diagnostics`,t.appendChild(n),this.levelLabel=document.createElement(`span`),this.levelLabel.style.color=`#7ee787`,this.levelLabel.textContent=`Normal`,t.appendChild(this.levelLabel),e.appendChild(t);let r=document.createElement(`div`);r.style.display=`flex`,r.style.alignItems=`center`,r.style.gap=`8px`,r.style.marginBottom=`8px`;let i=document.createElement(`span`);i.textContent=`Mode`,r.appendChild(i),this.modeSelect=document.createElement(`select`),this.modeSelect.style.flex=`1`,this.modeSelect.innerHTML=`<option value="auto">Auto</option><option value="manual">Manual</option>`,this.modeSelect.onchange=()=>{let e=this.modeSelect?.value===`manual`?`manual`:`auto`;this.options.onModeChange(e)},r.appendChild(this.modeSelect),e.appendChild(r);let a=document.createElement(`div`);a.style.display=`flex`,a.style.alignItems=`center`,a.style.gap=`8px`,a.style.marginBottom=`8px`;let o=document.createElement(`span`);o.textContent=`Manual Level`,a.appendChild(o),this.levelSelect=document.createElement(`select`),this.levelSelect.style.flex=`1`,this.levelSelect.innerHTML=[`<option value="Normal">Normal</option>`,`<option value="Mild">Mild</option>`,`<option value="Moderate">Moderate</option>`,`<option value="Severe">Severe</option>`].join(``),this.levelSelect.onchange=()=>{let e=this.levelSelect?.value??`Normal`;this.options.onManualLevelChange(e)},a.appendChild(this.levelSelect),e.appendChild(a),this.metricsPre=document.createElement(`pre`),this.metricsPre.style.margin=`0 0 8px 0`,this.metricsPre.style.padding=`8px`,this.metricsPre.style.background=`rgba(255, 255, 255, 0.06)`,this.metricsPre.style.borderRadius=`6px`,this.metricsPre.style.whiteSpace=`pre-wrap`,this.metricsPre.style.wordBreak=`break-word`,e.appendChild(this.metricsPre);let s=document.createElement(`div`);s.style.marginBottom=`6px`,s.textContent=`Recent Decisions`,e.appendChild(s),this.traceList=document.createElement(`div`),this.traceList.style.display=`flex`,this.traceList.style.flexDirection=`column`,this.traceList.style.gap=`4px`,e.appendChild(this.traceList),document.body.appendChild(e),this.root=e,this.logger.info(`network diagnostics panel ready`)}render(){!this.root||!this.snapshot||(this.levelLabel&&(this.levelLabel.textContent=this.snapshot.currentLevel,this.levelLabel.style.color=this.snapshot.currentLevel===`Severe`?`#ff7b72`:`#7ee787`),this.modeSelect&&(this.modeSelect.value=this.snapshot.mode),this.levelSelect&&(this.levelSelect.disabled=this.snapshot.mode!==`manual`),this.metricsPre&&(this.metricsPre.textContent=this.buildMetricsText(this.snapshot)),this.traceList&&(this.traceList.innerHTML=``,this.snapshot.traces.slice(0,10).forEach(e=>{let t=document.createElement(`div`);t.style.padding=`6px`,t.style.borderRadius=`6px`,t.style.background=`rgba(255, 255, 255, 0.04)`,t.textContent=`${new Date(e.ts).toLocaleTimeString()} | ${e.outcome} | ${e.reason}`,this.traceList?.appendChild(t)})))}buildMetricsText(e){let t=e.lastMetrics;if(!t)return`No metrics yet`;let n=t.packetLossRate===void 0?`-`:`${(t.packetLossRate*100).toFixed(2)}%`;return[`connected: ${e.connected}`,`mode: ${e.mode}`,`level: ${e.currentLevel}`,`fps: ${t.fps?.toFixed(2)??`-`}`,`bitrate(kbps): ${t.bitrateKbps?.toFixed(2)??`-`}`,`packetLoss: ${n}`,`rtt(ms): ${t.rttMs?.toFixed(2)??`-`}`,`jitter(ms): ${t.jitterMs?.toFixed(2)??`-`}`,`resolution: ${t.frameWidth??`-`}x${t.frameHeight??`-`}`,`lastAction: ${e.lastAction?`${e.lastAction.level} (${e.lastAction.success?`ok`:`fail`})`:`-`}`].join(`
109
- `)}},bi=class{constructor(e){this.disconnected=!1,this.hasEverConnected=!1,this.authWorkflow=e.authWorkflow,this.logger=e.logger}async connect(){if(this.disconnected)throw Error(`Cannot connect after disconnect. Use restart() instead.`);this.logger.info(`Starting connection flow`);try{let e=await this.authWorkflow.start();return this.logger.info(`Connection established`,{engineToken:e.engineToken?.substring(0,16)+`...`}),e}catch(e){throw this.logger.error(`Connection failed`,{error:e}),e}}async disconnect(){return this.disconnected?(this.logger.info(`Already disconnected, skipping`),this.disconnectPromise||Promise.resolve()):(this.logger.info(`Disconnecting...`),this.disconnected=!0,this.disconnectPromise=(async()=>{try{await this.authWorkflow.disconnectAndWait(),this.logger.info(`Disconnected successfully`)}catch(e){throw this.logger.error(`Error during disconnect`,{error:e}),e}})(),this.disconnectPromise)}async prepareConnectAfterDisconnect(){this.disconnectPromise&&await this.disconnectPromise,this.disconnected=!1,this.disconnectPromise=void 0,this.hasEverConnected=!1}async restart(){return this.logger.info(`Restarting connection...`),await this.disconnect(),await this.prepareConnectAfterDisconnect(),this.connect()}getStatus(){return{disconnected:this.disconnected,hasEverConnected:this.hasEverConnected}}hasConnectedBefore(){return this.hasEverConnected}markConnected(){this.hasEverConnected=!0}},Q=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.moduleName=n,this.dependencyName=r,this.name=`ApiRegistryError`}};function xi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Si(e,t){return xi(e)&&typeof e[t]==`function`}function Ci(e){if(!xi(e))throw new Q(`CONTEXT_INVALID`,`API registry context must be an object`);let t=[[`bridge`,e.bridge,`sendRequest`],[`authWorkflow`,e.authWorkflow,`getSnapshot`],[`connectionLifecycle`,e.connectionLifecycle,`connect`],[`createLogger`,e.createLogger,void 0]];for(let[e,n,r]of t)if(!(r?Si(n,r):typeof n==`function`||n!=null))throw new Q(`CONTEXT_INVALID`,`API registry context dependency '${e}'${r?` with ${r}()`:``} is required`,void 0,e)}function wi(e){if(!xi(e))throw new Q(`REGISTRY_INVALID`,`API registry must be a non-null object`);let t=Object.keys(e).find(e=>!ln.includes(e));if(t)throw new Q(`REGISTRY_UNKNOWN_MODULE`,`API registry contains unknown module '${t}'`,t);let n=ln.find(t=>!(t in e));if(n)throw new Q(`REGISTRY_INCOMPLETE`,`API registry is missing module '${n}'`,n);for(let t of ln)if(typeof e[t]!=`function`)throw new Q(`FACTORY_INVALID`,`API registry factory for '${t}' must be a function`,t)}function Ti(e,t,n,r){let i;try{i=t[r](n)}catch(e){throw new Q(`FACTORY_FAILED`,`API registry factory for '${r}' failed: ${e instanceof Error?e.message:String(e)}`,r,void 0)}if(i==null)throw new Q(`FACTORY_EMPTY_RESULT`,`API registry factory for '${r}' returned ${i===null?`null`:`undefined`}`,r);e[r]=i}function Ei(e,t=cn){if(Ci(e),wi(t),typeof t.Popup==`function`&&(e.popupManager===null||e.popupManager===void 0))throw new Q(`CONTEXT_INVALID`,`API registry context dependency 'popupManager' is required by the Popup module`,`Popup`,`popupManager`);let n={};return ln.forEach(r=>{Ti(n,t,e,r)}),n}const Di=.78;var $=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.buildingId=n,this.floorId=r,this.name=`BuildingFloorError`}};function Oi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ki(e){return Oi(e)&&typeof e.x==`number`&&Number.isFinite(e.x)&&typeof e.y==`number`&&Number.isFinite(e.y)&&typeof e.z==`number`&&Number.isFinite(e.z)}function Ai(e){return{position:ji(e.position),target:ji(e.target),fov:e.fov,time:e.time}}function ji(e){return new C(e.x,e.y,e.z,e.ePSGType)}var Mi=class{constructor(e,t){this.dependencies=e,this.buildings=new Map,this.logger=t?.logger??h}async register(e){let t=Array.isArray(e)?e:[e],n=this.normalizeRegistrations(t),r=await Promise.all(n.map(async e=>({definition:e,positions:await this.measureFloorPositions(e)})));this.assertBuildingsRemainAvailable(n),r.forEach(({definition:e,positions:t})=>{this.buildings.set(e.buildingId,{definition:e,originalPositions:t,explodedDistances:new Map,visibleFloorIds:e.floors.map(e=>e.id),transitionId:0,status:`overview`,activeMoves:new Set})});let i=n.map(e=>e.buildingId);return this.logger.info(`building floors registered`,{buildingIds:i}),{buildingIds:i}}async switchTo(e){let t=this.requireBuilding(e.buildingId),n=t.definition.floors.findIndex(t=>t.id===e.floorId);if(n<0)throw new $(`FLOOR_NOT_FOUND`,`Floor "${e.floorId}" is not registered for building "${e.buildingId}".`,e.buildingId,e.floorId);let r=t.definition.floors[n];return this.transition(t,{floorId:r.id,visibleFloorIds:t.definition.floors.slice(0,n+1).map(e=>e.id),hiddenFloorIds:t.definition.floors.slice(n+1).map(e=>e.id),viewPoint:r.viewPoint,objectIds:r.objects??[],overview:!1,focus:e.focus===!0})}async showOverview(e){let t=this.requireBuilding(e.buildingId);return this.transition(t,{visibleFloorIds:t.definition.floors.map(e=>e.id),hiddenFloorIds:[],viewPoint:t.definition.overview.viewPoint,objectIds:t.definition.overview.objects??[],overview:!0,focus:e.focus===!0})}async cancel(e){let t=this.requireBuilding(e.buildingId);t.transitionId+=1,await this.stopActiveTransition(t),t.currentFloorId=void 0,t.status=`cancelled`,this.logger.info(`building floor transition cancelled`,{buildingId:e.buildingId})}getState(e){let t=this.requireBuilding(e.buildingId);return{buildingId:t.definition.buildingId,status:t.status,currentFloorId:t.currentFloorId,visibleFloorIds:[...t.visibleFloorIds],transitionId:t.transitionId}}normalizeRegistrations(e){if(e.length===0)throw new $(`INVALID_REGISTRATION`,`At least one building is required.`);let t=new Set;return e.map(e=>{let n=this.requireNonEmptyString(e?.buildingId,`buildingId`),r=this.requireNonEmptyString(e?.parentId,`parentId`,n);if(t.has(n))throw new $(`INVALID_REGISTRATION`,`Building "${n}" is duplicated in the registration batch.`,n);if(this.buildings.has(n))throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${n}" is already registered.`,n);if(t.add(n),!Array.isArray(e.floors)||e.floors.length===0)throw new $(`INVALID_REGISTRATION`,`Building "${n}" must contain at least one floor.`,n);let i=new Set,a=e.floors.map((e,t)=>{let r=this.normalizeFloor(e,n,t);if(i.has(r.id))throw new $(`INVALID_REGISTRATION`,`Floor "${r.id}" is duplicated in building "${n}".`,n,r.id);return i.add(r.id),r}),o=e.overview??{},s=o.objects??[];if(!Array.isArray(s)||s.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Building "${n}" overview objects must contain non-empty IDs.`,n);return o.viewPoint&&this.validateViewPoint(o.viewPoint,n,`overview`),{buildingId:n,parentId:r,floors:a,overview:{objects:[...s],viewPoint:o.viewPoint?Ai(o.viewPoint):void 0}}})}normalizeFloor(e,t,n){let r=typeof e==`string`?{id:e}:e;if(!Oi(r))throw new $(`INVALID_REGISTRATION`,`Floor at index ${n} in building "${t}" must be a string or object.`,t);let i=this.requireNonEmptyString(r.id,`floors[${n}].id`,t),a=r.viewPoint;return a!==void 0&&this.validateViewPoint(a,t,i),{id:i,viewPoint:a?Ai(a):void 0,objects:this.normalizeObjectIds(r.objects,t,i)}}normalizeObjectIds(e,t,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Objects for "${t}@${n}" must contain non-empty IDs.`,t,n);return[...e]}}validateViewPoint(e,t,n){if(!Oi(e)||!ki(e.position)||!ki(e.target))throw new $(`INVALID_REGISTRATION`,`View point for "${t}@${n}" requires valid position and target vectors.`,t,n);if(e.fov!==void 0&&(!Number.isFinite(e.fov)||e.fov<10||e.fov>150))throw new $(`INVALID_REGISTRATION`,`View point fov for "${t}@${n}" must be between 10 and 150.`,t,n);if(e.time!==void 0&&(!Number.isFinite(e.time)||e.time<0))throw new $(`INVALID_REGISTRATION`,`View point time for "${t}@${n}" must be a non-negative number.`,t,n)}requireNonEmptyString(e,t,n){if(typeof e!=`string`||e.trim()===``)throw new $(`INVALID_REGISTRATION`,`${t} must be a non-empty string.`,n);return e}assertBuildingsRemainAvailable(e){let t=e.find(e=>this.buildings.has(e.buildingId));if(t)throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${t.buildingId}" was registered while its model information was loading.`,t.buildingId)}async measureFloorPositions(e){let t=await Promise.all(e.floors.map(async t=>{let n=await this.dependencies.model.getModelInfo({parentId:e.parentId,id:t.id});return[t.id,this.extractPosition(n,e.buildingId,t.id)]}));return new Map(t)}extractPosition(e,t,n){let r=e,i=e.params??e.data??r.param;if(Oi(i)&&(`param`in i||`params`in i)&&(i=i.param??i.params),typeof i==`string`)try{i=JSON.parse(i)}catch{i=void 0}let a=Oi(i)?i.position:void 0;if(!ki(a))throw new $(`MODEL_INFO_INVALID`,`Model information for "${t}@${n}" does not contain a valid position.`,t,n);return{x:a.x,y:a.y,z:a.z,ePSGType:typeof a.ePSGType==`string`&&a.ePSGType!==``?a.ePSGType:`0000`}}requireBuilding(e){let t=this.buildings.get(e);if(!t)throw new $(`BUILDING_NOT_REGISTERED`,`Building "${e}" is not registered.`,e);return t}async transition(e,t){let n=e.transitionId+1;if(e.transitionId=n,await this.stopActiveTransition(e),n!==e.transitionId)return this.createResult(e,t,`cancelled`,`none`);e.status=`switching`;let r=t.visibleFloorIds.filter(t=>e.explodedDistances.has(t)),i=t.hiddenFloorIds.filter(t=>!e.explodedDistances.has(t)),a=t.hiddenFloorIds.filter(t=>e.explodedDistances.has(t));try{let r=this.getAccessoryObjectIds(e.definition);if(r.length>0&&(await this.dependencies.model.setVisible({id:r,visible:!1}),n!==e.transitionId)||t.visibleFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:t.visibleFloorIds,visible:!0}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);a.length>0&&await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:a,visible:!1})}catch(t){throw n===e.transitionId&&(e.status=`cancelled`),t}return n===e.transitionId?new Promise((a,o)=>{let s={id:n,timers:new Set,pendingActions:new Set,settled:!1,resolve:a,reject:o};e.activeTransition=s,r.forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let n=e.originalPositions.get(t),r=this.getHideOffset(e),i=Math.max(r*.035,.5),a=e.explodedDistances.get(t)??r;e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(n,n.z-i),this.positionAtZ(n,n.z)],speed:this.getMotionSpeed(a+i*2),linear:6,isLookAtTarget:!1,needDirection:!1})})}),[...i].reverse().forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let r=e.originalPositions.get(t),i=this.getHideOffset(e),a=Math.max(i*.045,.6),o=i*(1+.24*n);e.explodedDistances.set(t,o),e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(r,r.z-a),this.positionAtZ(r,r.z+o)],speed:this.getMotionSpeed(o+a*2),linear:5,isLookAtTarget:!1,needDirection:!1})})});let c=Math.max(this.getBatchDurationMs(r.length),this.getBatchDurationMs(i.length));this.scheduleCompletion(e,s,c,t)}):this.createResult(e,t,`cancelled`,`none`)}schedule(e,t,n,r){let i=setTimeout(()=>{if(t.timers.delete(i),t.settled||t.id!==e.transitionId)return;let n=Promise.resolve().then(()=>{if(!(t.settled||t.id!==e.transitionId))return r()});t.pendingActions.add(n),n.then(()=>{t.pendingActions.delete(n)}).catch(r=>{t.pendingActions.delete(n),this.failTransition(e,t,r)})},n);t.timers.add(i)}scheduleCompletion(e,t,n,r){let i=setTimeout(()=>{t.timers.delete(i),!(t.settled||t.id!==e.transitionId)&&Promise.all([...t.pendingActions]).then(()=>this.completeTransition(e,t,r)).catch(n=>{this.failTransition(e,t,n)})},n);t.timers.add(i)}async completeTransition(e,t,n){if(!(t.settled||t.id!==e.transitionId))try{if(n.hiddenFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:n.hiddenFloorIds,visible:!1}),t.settled||t.id!==e.transitionId)||(n.visibleFloorIds.forEach(t=>e.explodedDistances.delete(t)),e.activeMoves.clear(),e.visibleFloorIds=[...n.visibleFloorIds],e.currentFloorId=n.floorId,e.status=n.overview?`overview`:`floor`,n.objectIds.length>0&&(await this.dependencies.model.setVisible({id:n.objectIds,visible:!0}),t.settled||t.id!==e.transitionId)))return;let r=await this.focusTarget(e,n);if(t.settled||t.id!==e.transitionId)return;this.settleTransition(e,t,this.createResult(e,n,`completed`,r))}catch(n){this.failTransition(e,t,n)}}async focusTarget(e,t){return t.focus?t.viewPoint?(await this.dependencies.camera.flyToTarget({point:t.viewPoint.position,target:t.viewPoint.target,fov:t.viewPoint.fov,time:t.viewPoint.time??.2}),`viewPoint`):(await this.dependencies.camera.lookAt({parentId:e.definition.parentId,id:t.visibleFloorIds,time:.2,isRotate:!1,isHighlight:!1}),`bounds`):`none`}failTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),e.status===`switching`&&(e.currentFloorId=void 0,e.status=`cancelled`),this.stopActiveMoves(e),this.logger.warn(`building floor transition failed`,{buildingId:e.definition.buildingId,error:n}),t.reject(n))}settleTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),t.resolve(n))}async stopActiveTransition(e){let t=e.activeTransition;t&&this.settleTransition(e,t,{buildingId:e.definition.buildingId,status:`cancelled`,visibleFloorIds:[...e.visibleFloorIds],focusMode:`none`,completion:`estimated`}),await this.stopActiveMoves(e)}async stopActiveMoves(e){let t=[...e.activeMoves];e.activeMoves.clear(),t.forEach(t=>{this.dependencies.modelTransform.endMove({parentId:e.definition.parentId,id:t}).catch(n=>{this.logger.warn(`failed to stop building floor move`,{buildingId:e.definition.buildingId,floorId:t,error:n})})}),await Promise.resolve()}createResult(e,t,n,r){return{buildingId:e.definition.buildingId,floorId:t.floorId,status:n,visibleFloorIds:n===`completed`?[...t.visibleFloorIds]:[...e.visibleFloorIds],focusMode:r,completion:`estimated`}}getHideOffset(e){let t=[...e.originalPositions.values()].map(e=>e.z);return t.length<2?2e3:Math.max(Math.max(...t)-Math.min(...t),1)*2.2}getAccessoryObjectIds(e){let t=new Set(e.overview.objects??[]);return e.floors.forEach(e=>{e.objects?.forEach(e=>t.add(e))}),[...t]}getBatchDurationMs(e){return e===0?0:(e-1)*105+Di*1e3}getMotionSpeed(e){return Math.max(e/Di,1)}positionAtZ(e,t){return{x:e.x,y:e.y,z:t,ePSGType:e.ePSGType}}},Ni=class{bind(e){this.lifecycle=e}connect(){return this.getLifecycle().connect()}disconnect(){return this.getLifecycle().disconnect()}reconnect(){return this.getLifecycle().reconnect()}getLifecycle(){if(!this.lifecycle)throw Error(`Connection lifecycle is not bound`);return this.lifecycle}};function Pi(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}var Fi=class{withConfig(e){return this.userConfig=e,this}withOptions(e){return this.videoElementParent=e?.videoElementParent,this}build(){if(!this.userConfig)throw Error(`Config must be set via withConfig() before calling build()`);let e=gr(this.userConfig),t=Pi(`sess`),n=Pi(`trace`);te(e.pixelStreamingLogger);let r=new ae(e.logger,void 0,{includeStack:e.includeStack}),i=r.child(`QoS`),a=Sr(),o=new Mr(a,{sessionId:t,traceId:n,runMode:e.viewMode,viewMode:e.viewMode},{appId:e.sceneName,env:a.app.environment,pageUrl:sr(),userAgent:cr()},(e,t)=>{i.warn(e,t)});r.setReporter(o);let s=new Nr,c=r.child(`Core`);c.info(`engine init`,{logLevel:r.level,qosReportingEnabled:a.enabled}),o.startSession({engineUuid:e.engineUuid??``});let l=new Rr(e,e.dom||this.videoElementParent,r.child(`SessionAdapter`)),u=new Gr(e,l,r.child(`AuthWorkflow`)),d=new qr(l,r.child(`RequestBridge`),{onRequestSent:({requestId:e,module:t,method:n})=>{o.recordEvent({eventName:`ue_request_sent`,stage:`ue_api`,status:`start`,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n}})},onResponseReceived:({requestId:e,module:t,method:n,durationMs:r,code:i})=>{o.recordEvent({eventName:`ue_response_received`,stage:`ue_api`,status:`success`,durationMs:r,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n},metrics:{ueApiRttMs:r,code:i}})}}),f=new bi({authWorkflow:u,logger:r.child(`ConnectionManager`)}),p=new Ni,m=new oe({enabled:e.showProgressBar,hostElement:e.dom,emit:e=>{s.emit(`LoadingProgress`,e)},logger:r.child(`LoadingProgress`)}),h=new ni(l,e=>{s.emit(`EngineStatus`,e)},r.child(`EngineStatus`),e=>{o.recordEvent({eventName:`media_stats_sample`,stage:`media`,status:`update`,metrics:e})}),g=new Xt({getEngineConfig:()=>e,on:(e,t)=>s.on(e,t),off:(e,t)=>s.off(e,t)}),_=Ei({bridge:d,authWorkflow:u,connectionLifecycle:p,createLogger:e=>r.child(e),popupManager:g,videoElementParent:e.dom||this.videoElementParent,beginPointEditorMouseInput:()=>l.beginPointEditorMouseInput()}),ee=new Mi({model:_.Model,modelTransform:_.ModelTransform,camera:_.Camera},{logger:r.child(`BuildingFloor`)}),v={},y=new vi({session:l,screen:_.Screen,logger:r.child(`NetworkAdaptation`),onStateChange:e=>{c.info(`network level changed`,e),s.emit(`networkLevelChanged`,e)},onAction:e=>{(e.success?c.info.bind(c):c.warn.bind(c))(`network adaptation action executed`,e),s.emit(`networkActionExecuted`,e)},onDiagnostics:e=>{s.emit(`networkDiagnosticsUpdated`,e),v.current?.update(e)}}),ne=new yi({logger:r.child(`NetworkDiagnosticsPanel`),onModeChange:e=>{c.info(`network mode changed`,{mode:e}),s.emit(`networkModeChanged`,{mode:e}),y.setMode(e)},onManualLevelChange:e=>{c.info(`network manual level set`,{level:e}),y.setManualLevel(e)},onVisibilityChange:e=>{c.info(`network diagnostics visibility changed`,{visible:e}),y.setDiagnosticsVisible(e),s.emit(`networkDiagnosticsVisibilityChanged`,{visible:e})}});return v.current=ne,{config:e,qosMonitor:o,loggerManager:r,eventBus:s,session:l,authWorkflow:u,bridge:d,connectionManager:f,connectionLifecycle:p,loadingProgress:m,engineStatus:h,networkAdaptation:y,networkDiagnosticsPanel:ne,popupManager:g,buildingFloor:ee,apiFacade:_,sessionId:t,traceId:n}}};const Ii={centerConnecting:`authConnecting`,waiting:`authWaiting`,authorizing:`authAuthorizing`,connected:`authConnected`,failed:`authFailed`};var Li=class{constructor(e,t){this.Events={WebRtcConnected:`webRtcConnected`,WebOnConnect:`webRtcConnected`,MapLoaded:`OnApiDataChannelStarted`,WebRtcDisconnected:`webRtcDisconnected`,WebOnDisconnect:`webRtcDisconnected`,DataChannelDisconnet:`webRtcDisconnected`,WebRtcConnecting:`webRtcConnecting`,WebRtcFailed:`webRtcFailed`,StatsReceived:`statsReceived`,EngineStatus:`EngineStatus`,StreamLoading:`streamLoading`,LoadingProgress:`LoadingProgress`,CenterConnected:`Connect`,CenterDisconnected:`UnConnect`,ConnectResult:`ConnectResult`,CenterCloseMessage:`CenterCloseMessage`,TokenAuthorize:`TokenAuthorize`,EngineServiceInit:`EngineServiceInit`,EngineServiceInitWait:`EngineServiceInitWait`,EngineSocketClose:`EngineSocketClose`,TokenWillExpired:`TokenWillExpired`,AuthStateChanged:`authStateChanged`,AuthConnecting:`authConnecting`,AuthWaiting:`authWaiting`,AuthAuthorizing:`authAuthorizing`,AuthConnected:`authConnected`,AuthFailed:`authFailed`,SessionModeReady:`sessionModeReady`,SessionModeFailed:`sessionModeFailed`,SceneConfig:`SceneConfig`,ModelClick:`ModelClick`,ModelUpdate:`ModelUpdate`,CameraHeight:`CameraHeight`,LeftClick:`MouseLeftButtonClick`,LeftDoubleClick:`MouseLeftButtonDoubleClick`,LeftLongPressed:`MouseLeftButtonLongPressed`,RightClick:`MouseRightButtonClick`,RightDoubleClick:`MouseRightButtonDoubleClick`,RightLongPressed:`MouseRightButtonLongPressed`,ModelTrigger:`ModelTrigger`,SyncPops:`SyncPops`,NetworkLevelChanged:`networkLevelChanged`,NetworkActionExecuted:`networkActionExecuted`,NetworkModeChanged:`networkModeChanged`,NetworkDiagnosticsVisibilityChanged:`networkDiagnosticsVisibilityChanged`,NetworkDiagnosticsUpdated:`networkDiagnosticsUpdated`,LoadMQTTDataFinished:`LoadMQTTDataFinished`,LoadMQTTDataProgress:`LoadMQTTDataProgress`,TrainsVisible:`TrainsVisible`,TrainsInfo:`TrainsInfo`},this.Enums={DlssQuality:w,FilterMode:Le,GizmoType:ze,LayerEnum:Pe,ModelTransformType:Ie,ScreenRenderBitratePreset:T,Season:Fe,TrainBehavior:Re,VideoCodeType:Ne},this.uePushResponseListenerName=`enginesdk3_ue_push_listener`,this.uePushResponseHandler=this.handleUePushResponse.bind(this);let n=new Fi().withConfig(e).withOptions({videoElementParent:t?.videoElementParent}).build();this.resolvedConfig=n.config,this.agentBridgeOptions=t?.agentBridge,this.eventBus=n.eventBus,this.qosMonitor=n.qosMonitor,this.session=n.session,this.authWorkflow=n.authWorkflow,this.connectionManager=n.connectionManager,this.loadingProgressController=n.loadingProgress,this.engineStatusCollector=n.engineStatus,this.networkAdaptation=n.networkAdaptation,this.networkDiagnosticsPanel=n.networkDiagnosticsPanel,this.popupManager=n.popupManager,n.connectionLifecycle.bind({connect:this.connect.bind(this),disconnect:()=>this.disconnectAndWait(),reconnect:this.restart.bind(this)});let r=n.loggerManager.child(`Core`),i=this.resolvedConfig;this.uePushEventNames=new Set([this.Events.MapLoaded,this.Events.ModelClick,this.Events.ModelUpdate,this.Events.CameraHeight,this.Events.LeftClick,this.Events.LeftDoubleClick,this.Events.LeftLongPressed,this.Events.RightClick,this.Events.RightDoubleClick,this.Events.RightLongPressed,this.Events.SceneConfig,this.Events.ModelTrigger,this.Events.SyncPops,this.Events.LoadMQTTDataFinished,this.Events.LoadMQTTDataProgress,this.Events.NetworkDiagnosticsUpdated,this.Events.TrainsVisible,this.Events.TrainsInfo]),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),i.viewMode===`cs`?this.loadingProgressController.show(b.SourcePreparing,`SourcePreparing`):this.loadingProgressController.show(b.EngineIniting,`EngineIniting`),this.mountApiFacade(n.apiFacade),this.BuildingFloor=n.buildingFloor,this.networkAdaptation.start(),this.networkDiagnosticsPanel.update(this.networkAdaptation.getDiagnosticsSnapshot()),this.initializeOptionalRuntimeExtensions(),this.setupEventListeners(r),this.bootstrapPromise=this.startAuthFlowWithQos().catch(e=>(r.error(`auto auth bootstrap failed`,{error:p(e)}),this.authWorkflow.getSnapshot()))}setupEventListeners(e){this.session.getForwardEvents().forEach(t=>{this.session.addEventListener(t,n=>{(t===`webRtcConnecting`||t===`webRtcDisconnected`||t===`webRtcFailed`)&&(this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime()),t===`webRtcConnected`&&(this.connectionManager.markConnected(),this.loadingProgressController.show(b.EngineConnectionSuccess,`EngineConnectionSuccess`,!1)),(t===`webRtcDisconnected`||t===`subscribeFailed`)&&this.loadingProgressController.show(b.EngineClose,`EngineClose`,!0),t===`streamerAssigned`&&(this.connectionManager.hasConnectedBefore()?(this.loadingProgressController.show(b.EngineConnectionSuccess,`EngineConnectionSuccess`,!1),e.info(`streamerAssigned during reconnect, showing success progress`)):e.info(`streamerAssigned during initial connect, skip progress (will show on webRtcConnected)`)),this.handleSessionForwardEventForQos(t),e.debug(`forward event`,{eventName:t}),this.eventBus.emit(t,n)})}),this.authWorkflow.on(`stateChanged`,t=>{this.handleAuthStateForQos(t.state),e.debug(`auth state changed`,{state:t.state}),this.eventBus.emit(this.Events.AuthStateChanged,t);let n=Ii[t.state];n&&this.eventBus.emit(n,t)}),this.authWorkflow.on(`progress`,e=>{this.handleProgressNotice(e)}),this.authWorkflow.on(`centerEvent`,({eventName:e,payload:t})=>{this.handleCenterEventForQos(e),this.eventBus.emit(e,t)}),this.authWorkflow.on(`failed`,t=>{let n=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_failed`,stage:`auth`,status:`failed`,durationMs:n,errorCode:t.lastError?.code,errorMessage:t.lastError?.message}),e.error(`auth workflow failed`,{error:t.lastError?JSON.stringify(t.lastError):`unknown`}),this.eventBus.emit(this.Events.SessionModeFailed,{mode:this.session.getViewMode(),snapshot:t})}),this.authWorkflow.on(`connected`,e=>{let t=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_success`,stage:`auth`,status:`success`,durationMs:t}),this.eventBus.emit(this.Events.SessionModeReady,{mode:this.session.getViewMode(),snapshot:e})})}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}whenReady(){return this.bootstrapPromise}setNetworkAdaptationMode(e){this.handleNetworkModeChange(e)}setNetworkManualLevel(e){this.handleNetworkModeChange(`manual`),this.networkAdaptation.setManualLevel(e)}getNetworkDiagnosticsSnapshot(){return this.latestNetworkDiagnostics??this.networkAdaptation.getDiagnosticsSnapshot()}async disconnectAndWait(){this.connectionManager.getStatus().disconnected||(this.qosMonitor.endSession({reason:`disconnect`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,removeListener:!0}),await this.connectionManager.disconnect())}disconnect(){this.disconnectAndWait()}async connect(){return this.connectionManager.getStatus().disconnected?(await this.connectionManager.prepareConnectAfterDisconnect(),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`connect`}),this.startAuthFlowWithQos()):this.authWorkflow.getSnapshot()}async restart(){return this.qosMonitor.endSession({reason:`restart`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,stopAgentBridge:!1,removeListener:!0}),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`restart`}),this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.restart()}startAuthFlowWithQos(){return this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.connect()}handleSessionForwardEventForQos(e){if(e===`webRtcConnecting`){this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}));return}if(e===`webRtcConnected`){let e=this.durationFrom(this.webrtcConnectStartedAt);this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_connected`,stage:`webrtc`,status:`success`,durationMs:e}),this.qosMonitor.recordEvent({eventName:`first_frame_rendered`,stage:`media`,status:`success`,durationMs:e});return}(e===`webRtcDisconnected`||e===`webRtcFailed`)&&(this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_disconnected`,stage:`webrtc`,status:`failed`,attrs:{reason:e}}))}handleAuthStateForQos(e){if(e===`centerConnecting`){this.centerConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`center_connect_start`,stage:`center`,status:`start`});return}if(e===`centerConnected`){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e});return}e===`webrtcConnecting`&&this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}))}handleCenterEventForQos(e){if(this.qosMonitor.recordEvent({eventName:`center_message_received`,stage:`center`,status:`update`,attrs:{fn:e}}),e===this.Events.CenterDisconnected){this.qosMonitor.recordEvent({eventName:`center_disconnected`,stage:`center`,status:`failed`,attrs:{reason:e}});return}if(e===this.Events.CenterConnected&&this.centerConnectStartedAt!==void 0){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e})}}durationFrom(e){if(e===void 0)return;let t=Date.now()-e;return Number.isFinite(t)&&t>=0?t:void 0}handleProgressNotice(e){if(e.kind===`tokenWillExpire`){this.loadingProgressController.showTokenWillExpire(e.message,e.key,e.isClose);return}this.loadingProgressController.show(e.message,e.key,e.isClose)}handleNetworkModeChange(e){this.networkAdaptation.setMode(e);let t={mode:e,ts:Date.now(),diagnostics:this.networkAdaptation.getDiagnosticsSnapshot()};this.eventBus.emit(this.Events.NetworkModeChanged,t)}mountApiFacade(e){let t=this;Object.keys(e).forEach(n=>{this.setApiModule(t,e,n)})}setApiModule(e,t,n){e[n]=t[n]}initializeOptionalRuntimeExtensions(){if(this.agentBridge||!this.agentBridgeOptions?.enabled)return;let e={...this.agentBridgeOptions,serverUrl:this.agentBridgeOptions.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`},t=ar(this,{runtimeName:e.runtimeName,expose:e.expose,metadata:e.metadata,engineConfig:this.resolvedConfig,getAuthSnapshot:()=>this.authWorkflow.getSnapshot(),mockInvoke:e.mockInvoke});this.agentBridge=new fe(t,e),this.agentBridge.start()}stopRuntimeForLifecycle(e){this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime(),e?.stopAgentBridge!==!1&&(this.agentBridge?.stop(`disconnect`),this.agentBridge=void 0),e?.removeListener!==!1&&this.session.removeResponseEventListener(this.uePushResponseListenerName),this.engineStatusCollector.stop(),e?.disconnectAuth!==!1&&this.authWorkflow.disconnect(),this.loadingProgressController.dispose(),this.qosMonitor.flush()}handleUePushResponse(e){let t=e,n;try{if(t=JSON.parse(e),typeof t==`object`&&t){let e=t,r=e.uuid??e.fn;typeof r==`string`&&r.length>0&&(n=r)}}catch{}if(n===`PointEditorGizmoEnded`){this.GizmosTool.finishFromEngine();return}!n&&this.uePushEventNames.has(e)&&(n=e),!(!n||!this.uePushEventNames.has(n))&&this.eventBus.emit(n,t)}getEngineConfig(){return this.resolvedConfig}};export{Sn as AGENT_BRIDGE_API_METADATA,ln as API_MODULE_KEYS,fe as AgentRuntimeBridge,kt as Animation,Q as ApiRegistryError,Mi as BuildingFloor,$ as BuildingFloorError,At as Camera,jt as Connect,Li as DTCEngine,Mt as Dlss,w as DlssQuality,Le as FilterMode,ze as GizmoType,De as GizmosTool,Nt as HeatMap,Pt as HighLighterEffect,Lt as Layer,Pe as LayerEnum,Rt as Model,zt as ModelPOI,Bt as ModelTransform,Ie as ModelTransformType,Vt as Navigation,Ht as PathPatrol,Dt as PendingValidationSchemaMap,Jt as PointEditor,Gt as PointIcon,Qt as Popup,d as SDKValidationError,en as Scene,$t as Screen,T as ScreenRenderBitratePreset,je as ScreenRenderBitratePresetOptions,Fe as Season,tn as SpatialQuery,nn as TimeLine,Re as TrainBehavior,rn as TrainSimulate,an as UIPOI,Ne as VideoCodeType,sn as WeatherSystem,on as WebView,cn as apiRegistry,Cn as createAgentBridgeMetadata,Ei as createApiFacade,ar as createBridgeRuntime,An as getAgentBridgeMethodSchema,Dn as isAgentBridgeMethodExposed,En as isAgentBridgeModuleExposed,wn as isAgentBridgeModuleName,kn as listAgentBridgeMethods,On as listAgentBridgeModules,Tn as resolveAgentBridgeExposeConfig};
108
+ postMessage({ type: 'ready' });\n`}var U=class extends Error{constructor(e,t,n){super(t),this.code=e,this.details=n,this.name=`BusinessProgramRuntimeError`}},Fn=class{constructor(e,t=In){this.host=e,this.workerFactory=t,this.loaded=new Map,this.active=new Map,this.activeProgramLocks=new Map}async load(e){if(this.loaded.has(e.capsuleHash))return{loaded:!1};if(!/^[a-f0-9]{64}$/.test(e.capsuleHash))throw new U(`PROGRAM_HASH_INVALID`,`capsuleHash must be a SHA-256 hex string.`);if(await Ln(e),await zn(Rn(e))!==e.capsuleHash)throw new U(`PROGRAM_HASH_INVALID`,`Business Program capsuleHash mismatch.`);return this.validatePermissions(e.manifest),this.loaded.set(e.capsuleHash,{manifest:structuredClone(e.manifest),bundle:e.bundle,data:structuredClone(e.data)}),{loaded:!0}}async start(e,t){if(this.active.has(e.executionId))throw new U(`PROGRAM_EXECUTION_EXISTS`,`Execution "${e.executionId}" already exists.`);let n=this.loaded.get(e.capsuleHash);if(!n)throw new U(`PROGRAM_NOT_LOADED`,`Business Program capsule is not loaded.`);let r=this.activeProgramLocks.get(n.manifest.programId);if(r)throw new U(`PROGRAM_LOCK_CONFLICT`,`Business Program "${n.manifest.programId}" is already running.`,{executionId:r});let i;try{i=this.workerFactory(Pn(n.bundle))}catch(e){throw new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker could not be created. Check the page CSP worker-src policy.`,Gn(e))}let a={};Object.assign(a,{request:e,program:n,worker:i,onEvent:t,timeout:setTimeout(()=>{this.finishExecution(a,`failed`,`Business Program execution timed out.`)},n.manifest.limits.timeoutMs),sdkCallCount:0,totalDelayMs:0,emittedEventCount:0,pendingDelays:new Set,streams:new Map,nextStreamId:1,terminal:!1}),this.active.set(e.executionId,a),this.activeProgramLocks.set(n.manifest.programId,e.executionId);try{return await this.waitForWorkerReady(a),i.postMessage({type:`start`,inputs:structuredClone(e.inputs),data:structuredClone(n.data)}),this.emit(a,{type:`started`},!1,`running`),{executionId:e.executionId,state:`running`}}catch(e){throw this.finishExecution(a,`failed`,e instanceof Error?e.message:String(e)),e}}cancel(e){let t=this.active.get(e.executionId);return t&&this.finishExecution(t,`cancelled`,e.reason??`Business Program cancelled.`),{executionId:e.executionId,state:`cancelled`}}cancelAll(e=`Business Program runtime disposed.`){for(let t of[...this.active.values()])this.finishExecution(t,`cancelled`,e)}validatePermissions(e){let t=new Set;for(let n of e.permissions.methods){let e=`${n.module}\u0000${n.method}\u0000${n.mode}`;if(t.has(e))throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program permissions must be unique.`);t.add(e);let r=this.host.getMethodMetadata(n.module,n.method);if(!r)throw new U(`PROGRAM_PERMISSION_INVALID`,`Business Program method "${n.module}.${n.method}" is not exposed.`);if(n.mode===`query`&&(r.responseMode!==`single`||r.sideEffects.some(e=>e!==`read`)))throw new U(`PROGRAM_PERMISSION_INVALID`,`Query permission requires a read-only single method: ${n.module}.${n.method}.`);if(n.mode===`stage`&&r.responseMode!==`single`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stage permission requires responseMode=single: ${n.module}.${n.method}.`);if(n.mode===`stream`&&r.responseMode!==`stream`)throw new U(`PROGRAM_PERMISSION_INVALID`,`Stream permission requires responseMode=stream: ${n.module}.${n.method}.`)}}waitForWorkerReady(e){return new Promise((t,n)=>{let r=setTimeout(()=>n(new U(`PROGRAM_WORKER_UNAVAILABLE`,`Business Program Worker did not become ready in 5 seconds.`)),5e3);e.worker.onmessage=n=>{G(n.data)?.type===`ready`&&(clearTimeout(r),e.worker.onmessage=t=>{this.handleWorkerMessage(e,t.data)},e.worker.onerror=t=>{this.finishExecution(e,`failed`,t.message||`Business Program Worker failed.`)},t())},e.worker.onerror=e=>{clearTimeout(r),n(new U(`PROGRAM_WORKER_ERROR`,e.message||`Business Program Worker failed.`))}})}async handleWorkerMessage(e,t){if(e.terminal)return;let n=G(t);if(!(!n||typeof n.type!=`string`)){if(n.type===`host-request`&&typeof n.id==`string`&&typeof n.operation==`string`){try{let t=await this.handleHostRequest(e,n.operation,n.payload);if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!0,result:t})}catch(t){if(e.terminal)return;e.worker.postMessage({type:`host-response`,id:n.id,ok:!1,error:Gn(t)})}return}if(n.type===`emit`){let t=G(n.event);this.emit(e,{type:t?.type===`action`?`action`:`progress`,phase:typeof t?.phase==`string`?t.phase:void 0,message:typeof t?.message==`string`?t.message:void 0,data:t?.data},!1,`running`);return}if(n.type===`complete`){this.finishExecution(e,`completed`,void 0,n.result);return}if(n.type===`fail`){let t=G(n.error);this.finishExecution(e,`failed`,typeof t?.message==`string`?t.message:`Business Program failed.`,t?.details)}}}async handleHostRequest(e,t,n){if(t===`query`){let t=Hn(n);this.requirePermission(e.program.manifest,t,`query`),this.incrementSdkCalls(e,1);let r=await this.host.invoke(t);if(!r.ok)throw new U(r.error.code,r.error.message,r.error.details);return r.data}if(t===`execute-stage`)return this.executeStage(e,n);if(t===`open-stream`)return this.openStream(e,n);if(t===`stream-next`)return this.nextStreamEvent(e,n);if(t===`close-stream`)return this.closeStream(e,n);if(t===`delay`){let t=G(n)?.delayMs;if(!Number.isInteger(t)||t<0)throw new U(`PROGRAM_REQUEST_INVALID`,`delayMs must be a non-negative integer.`);return await this.controlledDelay(e,t),null}throw new U(`PROGRAM_REQUEST_INVALID`,`Unsupported host operation "${t}".`)}async executeStage(e,t){let n=G(t)?.actions;if(!Array.isArray(n)||n.length===0||n.length>e.program.manifest.limits.maxStageActions)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action count is invalid.`);let r=Wn(n),i=r.filter(e=>e.type===`invoke`);for(let t of i)this.requirePermission(e.program.manifest,Un(t),`stage`);this.incrementSdkCalls(e,i.length);let a=this.host.validateActions({actions:i.map(e=>({id:e.id,...Un(e),responseMode:`single`}))});if(!a.ok)throw new U(a.error.code,a.error.message,a.error.details);let o=a.data.items.find(e=>!e.valid);if(!a.data.valid||o)throw new U(o?.error?.code??`INVALID_PAYLOAD`,o?.error?.message??`Business Program stage preflight failed.`,o?.error?.details);let s=[],c={};for(let[t,n]of r.entries()){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(n.type===`delay`)await this.controlledDelay(e,n.delayMs);else{let e=await this.host.invoke(Un(n));if(!e.ok)return{state:`failed`,completedActionIds:s,skippedActionIds:r.slice(t+1).map(e=>e.id),results:c,failedAction:{id:n.id,...e.error}};n.saveAs&&(c[n.saveAs]=e.data)}s.push(n.id)}return{state:`completed`,completedActionIds:s,skippedActionIds:[],results:c}}async openStream(e,t){let n=Hn(t);this.requirePermission(e.program.manifest,n,`stream`),this.incrementSdkCalls(e,1);let r=`${e.request.executionId}:stream:${e.nextStreamId++}`,i={streamId:r,requestId:``,events:[],waiters:[],terminal:!1};e.streams.set(r,i);let a=await this.host.startStream({...n,streamId:r},t=>{this.pushStreamEvent(e,i,t)});if(!a.ok)throw e.streams.delete(r),new U(a.error.code,a.error.message,a.error.details);return i.requestId=a.data.requestId,a.data}nextStreamEvent(e,t){let n=this.requireProgramStream(e,t),r=n.events.shift();return r?(r.terminal&&e.streams.delete(n.streamId),Promise.resolve(r)):n.terminal?(e.streams.delete(n.streamId),Promise.reject(new U(`PROGRAM_STREAM_CLOSED`,`Stream "${n.streamId}" is closed.`))):new Promise((e,t)=>{n.waiters.push({resolve:e,reject:t})})}async closeStream(e,t){let n=this.requireProgramStream(e,t),r=G(t)?.reason,i=await this.host.closeStream({streamId:n.streamId,reason:typeof r==`string`?r:`Business Program closed stream.`});if(!i.ok)throw new U(i.error.code,i.error.message,i.error.details);return this.disposeProgramStream(e,n,`Business Program closed stream.`,!1),{streamId:n.streamId,closed:!0}}requireProgramStream(e,t){let n=G(t)?.streamId,r=typeof n==`string`?e.streams.get(n):void 0;if(!r)throw new U(`PROGRAM_STREAM_NOT_FOUND`,`Business Program stream does not exist.`);return r}pushStreamEvent(e,t,n){if(e.terminal||!e.streams.has(t.streamId))return;t.terminal=n.terminal;let r=t.waiters.shift();r?(r.resolve(n),n.terminal&&e.streams.delete(t.streamId)):t.events.push(n)}disposeProgramStream(e,t,n,r=!0){e.streams.delete(t.streamId),t.terminal=!0;for(let e of t.waiters.splice(0))e.reject(new U(`PROGRAM_CANCELLED`,n));r&&this.host.closeStream({streamId:t.streamId,reason:n})}async controlledDelay(e,t){if(e.terminal)throw new U(`PROGRAM_CANCELLED`,`Business Program execution is no longer active.`);if(e.totalDelayMs+=t,e.totalDelayMs>e.program.manifest.limits.maxTotalDelayMs)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program total delay limit exceeded.`);await new Promise((n,r)=>{let i={};i.reject=r,i.timer=setTimeout(()=>{e.pendingDelays.delete(i),n()},t),e.pendingDelays.add(i)})}requirePermission(e,t,n){if(!e.permissions.methods.some(e=>e.module===t.moduleName&&e.method===t.methodName&&e.mode===n))throw new U(`PROGRAM_PERMISSION_DENIED`,`Business Program cannot use ${t.moduleName}.${t.methodName} as ${n}.`)}incrementSdkCalls(e,t){if(e.sdkCallCount+=t,e.sdkCallCount>e.program.manifest.limits.maxSdkCalls)throw new U(`PROGRAM_LIMIT_EXCEEDED`,`Business Program SDK call limit exceeded.`)}emit(e,t,n,r){if(e.emittedEventCount+=1,e.emittedEventCount>e.program.manifest.limits.maxEventCount){this.finishExecution(e,`failed`,`Business Program event limit exceeded.`);return}e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:t,terminal:n,state:r})}finishExecution(e,t,n,r){if(!e.terminal){e.terminal=!0,clearTimeout(e.timeout);for(let t of e.pendingDelays)clearTimeout(t.timer),t.reject(new U(`PROGRAM_CANCELLED`,n??`Business Program stopped.`));e.pendingDelays.clear();for(let r of[...e.streams.values()])this.disposeProgramStream(e,r,n??`Business Program ${t}.`);e.worker.terminate(),this.active.delete(e.request.executionId),this.activeProgramLocks.get(e.program.manifest.programId)===e.request.executionId&&this.activeProgramLocks.delete(e.program.manifest.programId),e.onEvent({executionId:e.request.executionId,traceId:e.request.traceId,event:{type:t,message:n,data:r},terminal:!0,state:t})}}};function In(e){let t=URL.createObjectURL(new Blob([e],{type:`text/javascript`}));try{return new Worker(t)}finally{URL.revokeObjectURL(t)}}async function Ln(e){if(await zn(e.bundle)!==e.manifest.entry.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program entry sha256 mismatch.`);for(let t of e.manifest.data){let n=e.data[t.name];if(typeof n!=`string`||await zn(n)!==t.sha256)throw new U(`PROGRAM_HASH_INVALID`,`Business Program data "${t.name}" sha256 mismatch.`)}}function Rn(e){return JSON.stringify(e.manifest)+e.bundle+e.manifest.data.map(t=>e.data[t.name]??``).join(``)}async function zn(e){let t=new TextEncoder().encode(e);if(typeof crypto<`u`&&crypto.subtle){let e=await crypto.subtle.digest(`SHA-256`,t);return Vn(new Uint8Array(e))}return Vn(Bn(t))}function Bn(e){let t=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),n=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),r=Math.ceil((e.length+9)/64)*64,i=new Uint8Array(r);i.set(e),i[e.length]=128;let a=e.length*8,o=new DataView(i.buffer);o.setUint32(r-8,Math.floor(a/4294967296)),o.setUint32(r-4,a>>>0);let s=new Uint32Array(64);for(let e=0;e<r;e+=64){for(let t=0;t<16;t+=1)s[t]=o.getUint32(e+t*4);for(let e=16;e<64;e+=1){let t=W(s[e-15],7)^W(s[e-15],18)^s[e-15]>>>3,n=W(s[e-2],17)^W(s[e-2],19)^s[e-2]>>>10;s[e]=s[e-16]+t+s[e-7]+n>>>0}let[r,i,a,c,l,u,d,f]=n;for(let e=0;e<64;e+=1){let n=W(l,6)^W(l,11)^W(l,25),o=l&u^~l&d,p=f+n+o+t[e]+s[e]>>>0,m=(W(r,2)^W(r,13)^W(r,22))+(r&i^r&a^i&a)>>>0;f=d,d=u,u=l,l=c+p>>>0,c=a,a=i,i=r,r=p+m>>>0}n[0]=n[0]+r>>>0,n[1]=n[1]+i>>>0,n[2]=n[2]+a>>>0,n[3]=n[3]+c>>>0,n[4]=n[4]+l>>>0,n[5]=n[5]+u>>>0,n[6]=n[6]+d>>>0,n[7]=n[7]+f>>>0}let c=new Uint8Array(32),l=new DataView(c.buffer);return n.forEach((e,t)=>l.setUint32(t*4,e)),c}function W(e,t){return e>>>t|e<<32-t}function Vn(e){return Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function Hn(e){let t=G(e);if(!t||typeof t.module!=`string`||typeof t.method!=`string`)throw new U(`PROGRAM_REQUEST_INVALID`,`SDK request requires module and method.`);return{moduleName:t.module,methodName:t.method,payload:t.payload}}function Un(e){return{moduleName:e.module,methodName:e.method,payload:e.payload}}function Wn(e){let t=new Map,n=new Set;for(let r of e){if(!r||typeof r.id!=`string`||!r.id||t.has(r.id))throw new U(`PROGRAM_STAGE_INVALID`,`Program stage action IDs must be unique.`);if(r.type!==`invoke`&&r.type!==`delay`)throw new U(`PROGRAM_STAGE_INVALID`,`Unsupported Program stage action type.`);if(r.type===`invoke`){if(!r.module||!r.method||r.responseMode!==`single`)throw new U(`PROGRAM_STAGE_INVALID`,`Invoke action "${r.id}" is invalid.`);if(r.saveAs&&(n.has(r.saveAs)||!/^[A-Za-z][A-Za-z0-9-]*$/.test(r.saveAs)))throw new U(`PROGRAM_STAGE_INVALID`,`saveAs "${r.saveAs}" is invalid or duplicated.`);r.saveAs&&n.add(r.saveAs)}else if(!Number.isInteger(r.delayMs)||r.delayMs<0)throw new U(`PROGRAM_STAGE_INVALID`,`Delay action "${r.id}" is invalid.`);t.set(r.id,r)}for(let n of e)for(let e of n.dependsOn??[])if(!t.has(e)||e===n.id)throw new U(`PROGRAM_STAGE_INVALID`,`Action "${n.id}" has an invalid dependency.`);let r=[],i=new Set;for(;r.length<e.length;){let t=e.find(e=>!i.has(e.id)&&(e.dependsOn??[]).every(e=>i.has(e)));if(!t)throw new U(`PROGRAM_STAGE_INVALID`,`Program stage dependency graph contains a cycle.`);r.push(t),i.add(t.id)}return r}function G(e){return typeof e==`object`&&e?e:void 0}function Gn(e){return e instanceof U?{name:e.name,message:e.message,code:e.code,details:e.details}:e instanceof Error?{name:e.name,message:e.message}:{name:`Error`,message:String(e)}}function Kn(){return typeof crypto<`u`&&typeof crypto.randomUUID==`function`?`sdk3_${crypto.randomUUID()}`:`sdk3_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function K(e){return{ok:!0,data:e,ts:Date.now()}}function q(e,t,n){return{ok:!1,error:{code:e,message:t,moduleName:n?.moduleName,methodName:n?.methodName,details:n?.details},ts:Date.now()}}function qn(){return typeof document>`u`?void 0:document.title}function Jn(){return typeof window>`u`?void 0:window.location.href}function Yn(e){return e.runtimeName??e.engineConfig?.sceneName??qn()??e.engineConfig?.engineUuid}function Xn(e){if(e)return{sceneName:e.sceneName,engineUuid:e.engineUuid,mapType:e.mapType,operationType:e.operationType,viewMode:e.viewMode,centerIP:e.centerIP,signalingServer:e.signalingServer,codec:e.codec}}function Zn(e){return typeof e==`object`&&!!e}function Qn(e){return Zn(e)&&Object.keys(e).length===0}function $n(e){return Zn(e)&&e.ok===!1&&typeof e.ts==`number`}function er(e){return new Promise(t=>{setTimeout(t,e)})}function tr(e,t){let n=t?.fields.filter(e=>e.required)??[];if(n.length!==0)return Zn(e)?n.find(t=>e[t.name]===void 0):n[0]}function nr(e){return e instanceof d?e.toJSON():e instanceof Error?{name:e.name,message:e.message}:e}function rr(e){if(typeof e!=`object`&&typeof e!=`function`||e===null)return!1;let t=e;return typeof t.then==`function`&&typeof t.cancel==`function`&&typeof t.requestId==`string`}function ir(e){if(!(!Zn(e)||typeof e.id!=`string`))return{parentId:typeof e.parentId==`string`?e.parentId:``,id:e.id}}function ar(e){if(typeof e!=`string`)return e;try{return JSON.parse(e)}catch{return}}function or(e){let t=e.response,n=ar(t?.param??t?.params??e.param??e.params);return Zn(n)&&n.status===`finished`}function sr(e,t={},n={}){let r=t.bridgeId??Kn(),i=Dn(t.expose),a=new Map,o=!1,s=()=>{o=!0},c=()=>{o=!1};e.on(e.Events.WebRtcConnected,s),e.on(e.Events.WebRtcDisconnected,c),e.on(e.Events.WebRtcFailed,c);function l(){return{bridgeId:r,connected:o,runtimeName:Yn(t),title:qn(),pageUrl:Jn(),sdkVersion:t.sdkVersion,metadata:t.metadata,engine:Xn(t.engineConfig)}}function u(e){return En(e)?On(e,i)?e:q(`API_NOT_EXPOSED`,`API module "${e}" is not exposed by agentBridge.expose.`,{moduleName:e}):q(`API_NOT_FOUND`,`API module "${e}" does not exist.`,{moduleName:e})}function p(t,n){if(!kn(t,n,i))return q(`API_NOT_EXPOSED`,`API method "${t}.${n}" is not exposed.`,{moduleName:t,methodName:n});let r=e[t];return!Zn(r)||typeof r[n]!=`function`?q(`API_NOT_FOUND`,`API method "${t}.${n}" does not exist.`,{moduleName:t,methodName:n}):r}function m(e,t=!0){let n=u(e.moduleName);if(typeof n!=`string`)return n;let r=p(n,e.methodName);if($n(r))return r;let a=Mn(n,e.methodName,i);if(!a)return q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${e.methodName}" is not available.`,{moduleName:n,methodName:e.methodName});let o=l();if(!o.connected)return q(`SDK_NOT_READY`,`DTCEngine is not connected yet.`,{moduleName:n,methodName:e.methodName,details:o});if(t&&a.payloadKind===`none`&&e.payload!==void 0&&!Qn(e.payload))return q(`INVALID_PAYLOAD`,`API method "${n}.${e.methodName}" does not accept payload.`,{moduleName:n,methodName:e.methodName,details:e.payload});let s=t?tr(e.payload,a):void 0;if(s)return q(`INVALID_PAYLOAD`,`Missing required payload field "${s.name}".`,{moduleName:n,methodName:e.methodName,details:{field:s.name}});let c=r[e.methodName];return typeof c==`function`?{resolvedModule:n,resolvedMethod:r,methodRef:c,schema:a}:q(`API_NOT_FOUND`,`API method "${n}.${e.methodName}" does not exist.`,{moduleName:n,methodName:e.methodName})}function h(e){return{type:e.type,requestId:e.requestId,response:e.response,...e.error?{error:{name:e.error.name,message:e.error.message}}:{}}}function g(e,t,n){let r=e.request.streamId;a.get(r)===e&&(a.delete(r),e.onEvent({streamId:r,requestId:e.promise.requestId,moduleName:e.request.moduleName,methodName:e.request.methodName,event:{type:`cancel`,requestId:e.promise.requestId,error:{name:`StreamClosedError`,message:n}},terminal:!0,terminalReason:t}),e.promise.cancel(n))}function _(e,t){let n=a.get(e);if(!n)return;let r=n.request.moduleName===`PathPatrol`&&n.request.methodName===`add`&&or(t),i=r||t.type===`done`||t.type===`error`||t.type===`cancel`,o=r?`finished`:t.type===`done`?`completed`:t.type===`error`?`error`:t.type===`cancel`?`cancelled`:void 0;n.onEvent({streamId:e,requestId:t.requestId||n.promise.requestId,moduleName:n.request.moduleName,methodName:n.request.methodName,event:h(t),terminal:i,terminalReason:o}),i&&(a.delete(e),r&&t.type!==`done`&&n.promise.cancel(`PathPatrol.add reported status=finished`))}function ee(e){let t=ir(e);if(t)for(let e of[...a.values()]){let n=ir(e.request.payload);e.request.moduleName===`PathPatrol`&&e.request.methodName===`add`&&n?.id===t.id&&n.parentId===t.parentId&&g(e,`stopped`,`Matching PathPatrol.stop succeeded`)}}function te(e=`Agent bridge disconnected`){for(let t of[...a.values()])g(t,`bridge-disconnected`,e)}let v,y=new Fn({getMethodMetadata(e,t){if(!En(e)||!On(e,i))return;let n=jn(e,i).find(e=>e.methodName===t);return n?{responseMode:n.responseMode,sideEffects:n.sideEffects}:void 0},validateActions(e){return v.validateActions(e)},invoke(e){return v.invoke(e)},startStream(e,t){return v.startStream(e,t)},closeStream(e){return v.closeStream(e)}},n.businessProgramWorkerFactory);return v={getSnapshot:l,dispose(){te(`Agent bridge runtime disposed`),y.cancelAll(`Agent bridge runtime disposed`),e.off(e.Events.WebRtcConnected,s),e.off(e.Events.WebRtcDisconnected,c),e.off(e.Events.WebRtcFailed,c)},closeAllStreams:te,cancelAllPrograms(e){y.cancelAll(e)},listModules(){return An(i)},listMethods(e){let t=u(e);return typeof t==`string`?K(jn(t,i)):t},getMethodSchema(e,t){let n=u(e);if(typeof n!=`string`)return n;if(!kn(n,t,i))return q(`API_NOT_EXPOSED`,`API method "${n}.${t}" is not exposed.`,{moduleName:n,methodName:t});let r=Mn(n,t,i);return r?K(r):q(`METHOD_SCHEMA_NOT_FOUND`,`Schema for "${n}.${t}" is not available.`,{moduleName:n,methodName:t})},validateActions(e){let t=e.actions.map(e=>{let t=m(e,!1);if($n(t))return{id:e.id,valid:!1,error:t.error};if(t.schema.responseMode!==e.responseMode)return{id:e.id,valid:!1,error:{code:`STREAM_INVOKE_REQUIRED`,message:`API method "${t.resolvedModule}.${e.methodName}" is ${t.schema.responseMode}, not ${e.responseMode}.`,moduleName:t.resolvedModule,methodName:e.methodName,details:{expected:e.responseMode,actual:t.schema.responseMode}}};let n=Nn(t.resolvedModule,e.methodName,i);if(!n)return{id:e.id,valid:!1,error:{code:`METHOD_SCHEMA_NOT_FOUND`,message:`Validation schema for "${t.resolvedModule}.${e.methodName}" is not available.`,moduleName:t.resolvedModule,methodName:e.methodName}};try{return f(n,t.schema.payloadKind===`none`?void 0:e.payload,t.resolvedModule,e.methodName),{id:e.id,valid:!0}}catch(n){return{id:e.id,valid:!1,error:{code:`INVALID_PAYLOAD`,message:n instanceof Error?n.message:String(n),moduleName:t.resolvedModule,methodName:e.methodName,details:nr(n)}}}});return K({valid:t.every(e=>e.valid),items:t})},async invoke(e){let n=m(e);if($n(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:a,schema:o}=n;if(o.responseMode===`stream`)return q(`STREAM_INVOKE_REQUIRED`,`API method "${r}.${e.methodName}" requires a streaming invoke.`,{moduleName:r,methodName:e.methodName,details:{responseMode:o.responseMode,tool:`sdk3_invoke_stream`}});if(t.mockInvoke===!0)return await er(100),K({success:!0,code:`MOCK_OK`,message:`mock invoke success`,data:null});try{let t=o.payloadKind===`none`||e.payload===void 0?await a.call(i):await a.call(i,e.payload);return r===`PathPatrol`&&e.methodName===`stop`&&(!Zn(t)||t.success!==!1)&&ee(e.payload),K(t)}catch(t){return t instanceof d?q(`INVALID_PAYLOAD`,t.message,{moduleName:r,methodName:e.methodName,details:t.toJSON()}):q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed.`,{moduleName:r,methodName:e.methodName,details:nr(t)})}},async startStream(e,t){if(a.has(e.streamId))return q(`INVALID_PAYLOAD`,`Stream "${e.streamId}" already exists.`,{moduleName:e.moduleName,methodName:e.methodName});let n=m(e);if($n(n))return n;let{resolvedModule:r,resolvedMethod:i,methodRef:o,schema:s}=n;if(s.responseMode!==`stream`)return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" is not streaming.`,{moduleName:r,methodName:e.methodName});try{let n,c=[],l=!1,u=t=>{if(!l){c.push(t);return}_(e.streamId,t)};if(n=s.payloadKind===`none`||e.payload===void 0?o.call(i,u):o.call(i,e.payload,u),!rr(n))return q(`API_NOT_STREAMING`,`API method "${r}.${e.methodName}" did not return a stream handle.`,{moduleName:r,methodName:e.methodName});let d={request:e,promise:n,onEvent:t};a.set(e.streamId,d),l=!0,n.catch(()=>void 0),c.forEach(t=>_(e.streamId,t));let f=c.find(e=>e.type===`error`);return f?q(`INVALID_PAYLOAD`,f.error?.message??`API method "${r}.${e.methodName}" failed before stream start.`,{moduleName:r,methodName:e.methodName,details:nr(f.error)}):K({streamId:e.streamId,requestId:n.requestId})}catch(t){return q(`API_EXECUTION_FAILED`,`API method "${r}.${e.methodName}" failed to start a stream.`,{moduleName:r,methodName:e.methodName,details:nr(t)})}},async closeStream(e){let t=a.get(e.streamId);return t?(g(t,`cancelled`,e.reason?.trim()||`Stream closed by MCP client`),K({streamId:e.streamId,closed:!0})):K({streamId:e.streamId,closed:!1})},async loadProgram(e){try{return K(await y.load(e))}catch(e){return q(`PROGRAM_INVALID`,e instanceof Error?e.message:String(e),{details:cr(e)})}},async startProgram(e,t){if(!o)return q(`SDK_NOT_READY`,`SDK runtime is not connected.`);try{return K(await y.start(e,t))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:cr(e)})}},async cancelProgram(e){try{return K(y.cancel(e))}catch(e){return q(`PROGRAM_EXECUTION_FAILED`,e instanceof Error?e.message:String(e),{details:cr(e)})}}},v}function cr(e){return e instanceof U?{code:e.code,message:e.message,details:e.details}:nr(e)}function lr(){return typeof globalThis<`u`&&typeof globalThis.location?.href==`string`?globalThis.location?.href??``:``}function ur(){return typeof globalThis<`u`&&typeof globalThis.navigator?.userAgent==`string`?globalThis.navigator?.userAgent??``:``}const dr=r.string().min(1),fr=[`bs`,`cs`],pr=r.custom(e=>typeof e==`object`&&!!e,`dom must be a valid HTMLDivElement`),mr={centerHeartbeatIntervalMs:5e3,centerHeartbeatTimeoutMs:5e4},J={runMode:`RunMode/`,centerIP:`CenterIP/`,privateKey:`PrivateKey/`,showProgressBar:`showProgressBar/`},hr=r.object({centerIP:dr.optional(),signalingServer:dr.optional(),sceneName:dr.optional(),token:dr.optional(),dom:pr.optional(),showProgressBar:r.boolean().optional().default(!0),codec:r.string().optional().default(`H264`),viewMode:r.enum(fr).optional().default(`bs`),turnServer:r.string().optional(),turnUser:r.string().optional(),turnPwd:r.string().optional(),privateKey:r.string().optional(),engineUuid:r.string().optional(),mapType:r.string().optional().default(`web`),operationType:r.string().optional().default(`viewer`),freeCheckInterval:r.number().int().min(0).optional().default(0),initialSettings:r.record(r.unknown()).optional().default({}),logger:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`info`),includeStack:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),pixelStreamingLogger:r.enum([`silent`,`error`,`warn`,`info`,`debug`]).optional().default(`warn`),centerHeartbeatIntervalMs:r.never().optional(),centerHeartbeatTimeoutMs:r.never().optional()}).strict().superRefine((e,t)=>{!e.centerIP&&!e.signalingServer&&t.addIssue({code:r.ZodIssueCode.custom,path:[`centerIP`],message:`one of centerIP, signalingServer is required`}),e.sceneName||t.addIssue({code:r.ZodIssueCode.custom,path:[`sceneName`],message:`sceneName is required`}),e.token||t.addIssue({code:r.ZodIssueCode.custom,path:[`token`],message:`token is required`}),e.dom||t.addIssue({code:r.ZodIssueCode.custom,path:[`dom`],message:`dom is required`})});function gr(e){let t={};return e.split(` `).forEach(e=>{if(e.startsWith(J.runMode)){t.viewMode=e.slice(J.runMode.length);return}if(e.startsWith(J.centerIP)){t.centerIP=e.slice(J.centerIP.length);return}if(e.startsWith(J.privateKey)){t.privateKey=e.slice(J.privateKey.length);return}if(e.startsWith(J.showProgressBar)){let n=e.slice(J.showProgressBar.length);n===`true`?t.showProgressBar=!0:n===`false`&&(t.showProgressBar=!1)}}),t}function _r(e){let t=ur()||void 0;if(!t)return e;let n=gr(t);return Object.keys(n).length===0?e:{...e,...n}}function vr(e){let t=_r(e),n=hr.safeParse(t);if(!n.success)throw new d(`Core`,`DTCEngine.constructor`,n.error.issues.map(e=>({field:e.path.length>0?e.path.join(`.`):`<root>`,reason:e.message,code:e.code})));let r=n.data;return{centerIP:r.centerIP??``,signalingServer:r.signalingServer,sceneName:r.sceneName??``,token:r.token??``,dom:r.dom,showProgressBar:r.showProgressBar,codec:r.codec,viewMode:r.viewMode,turnServer:r.turnServer,turnUser:r.turnUser,turnPwd:r.turnPwd,privateKey:r.privateKey??``,engineUuid:r.engineUuid,mapType:r.mapType,operationType:r.operationType,freeCheckInterval:r.freeCheckInterval,initialSettings:r.initialSettings,logger:r.logger,includeStack:r.includeStack,pixelStreamingLogger:r.pixelStreamingLogger,centerHeartbeatIntervalMs:mr.centerHeartbeatIntervalMs,centerHeartbeatTimeoutMs:mr.centerHeartbeatTimeoutMs}}const yr=[`token`,`privatekey`,`authorization`,`cookie`,`set-cookie`],br={enabled:!1,endpoint:``,apiKey:``,app:{name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`},batching:{enabled:!0,itemLimit:20,sendTimeoutMs:3e4},retry:{maxAttempts:2},failure:{disableAfterConsecutiveFailures:5,warningIntervalMs:3e4},redactKeys:yr},xr=r.object({enabled:r.boolean().default(!1),endpoint:r.string().optional(),apiKey:r.string().optional(),app:r.object({name:r.string().min(1).default(`@nnepoch/dtc-sdk`),version:r.string().min(1).default(`0.1.0`),environment:r.string().min(1).default(`production`)}).default({name:`@nnepoch/dtc-sdk`,version:`0.1.0`,environment:`production`}),batching:r.object({enabled:r.boolean().default(!0),itemLimit:r.number().int().min(1).default(20),sendTimeoutMs:r.number().int().min(200).default(3e3)}).default({enabled:!0,itemLimit:20,sendTimeoutMs:3e3}),retry:r.object({maxAttempts:r.number().int().min(1).max(5).default(2)}).default({maxAttempts:2}),failure:r.object({disableAfterConsecutiveFailures:r.number().int().min(1).default(5),warningIntervalMs:r.number().int().min(1e3).default(3e4)}).default({disableAfterConsecutiveFailures:5,warningIntervalMs:3e4}),redactKeys:r.array(r.string().min(1)).default(yr)}).superRefine((e,t)=>{let n=typeof e.endpoint==`string`?e.endpoint.trim():``,i=n.length>0;if(e.enabled&&!i){t.addIssue({code:r.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting enabled requires endpoint`});return}e.enabled&&i&&!r.string().url().safeParse(n).success&&t.addIssue({code:r.ZodIssueCode.custom,path:[`endpoint`],message:`qos reporting endpoint must be a valid url`})});function Sr(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Cr(e,t){let n={...e};return Object.entries(t).forEach(([e,t])=>{if(t!==void 0){if(Sr(t)&&Sr(n[e])){n[e]=Cr(n[e],t);return}n[e]=t}}),n}function wr(){let e=Sr(globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__)?{...globalThis.__ENGINE3_INTERNAL_QOS_REPORTING__}:{};typeof e.endpoint==`string`&&e.endpoint.trim().length===0&&delete e.endpoint,typeof e.apiKey==`string`&&e.apiKey.trim().length===0&&delete e.apiKey;let t=Cr(br,e);return xr.parse(t)}function Tr(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}function Er(e){if(typeof e==`string`)return e;if(e===void 0)return`undefined`;if(e===null)return`null`;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function Dr(e,t){let n=new WeakSet,r=(e,i)=>{if(i&&Tr(i,t.redactKeys))return`[REDACTED]`;if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(typeof e==`bigint`)return e.toString();if(e===void 0)return`undefined`;if(typeof e==`function`||typeof e==`symbol`)return String(e);if(e instanceof Date)return e.toISOString();if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack};if(Array.isArray(e))return e.map(e=>r(e));if(typeof e==`object`&&e){if(n.has(e))return`[CIRCULAR]`;n.add(e);let t=Object.entries(e),i={};return t.forEach(([e,t])=>{i[e]=r(t,e)}),i}return Er(e)};return r(e)}function Or(e){let t=e.toLowerCase();return t.includes(`auth`)?`auth`:t.includes(`center`)?`center`:t.includes(`sessionadapter`)||t.includes(`webrtc`)||t.includes(`pixelstreaming`)?`webrtc`:t.includes(`enginestatus`)||t.includes(`stream`)?`media`:t.includes(`requestbridge`)||t.includes(`camera`)||t.includes(`scene`)||t.includes(`model`)||t.includes(`poi`)||t.includes(`weather`)||t.includes(`timeline`)||t.includes(`popup`)||t.includes(`animation`)?`ue_api`:`session`}function kr(e){if(typeof e!=`string`)return;let t=e.trim();return t.length>0?t:void 0}function Ar(e){return e.trim().replace(/\s+/g,`_`).slice(0,64)}function jr(e){if(!Sr(e))return;let t=kr(e.code)??kr(e.errorCode)??kr(e.status);if(t)return Ar(t);let n=e.error;if(Sr(n)){let e=kr(n.code)??kr(n.errorCode)??kr(n.status);if(e)return Ar(e)}}var Mr=class{constructor(e,t){this.config=e,this.deps=t}async send(e){let t=typeof AbortController<`u`?new AbortController:void 0,n=t?setTimeout(()=>{t.abort()},this.config.batching.sendTimeoutMs):void 0;try{let n=await this.deps.fetchImpl(this.config.endpoint??``,{method:`POST`,headers:{"Content-Type":`application/json`,...this.config.apiKey?{"x-api-key":this.config.apiKey}:{}},body:JSON.stringify(e),signal:t?.signal});if(!n.ok)throw Error(`qos reporting request failed: ${n.status}`)}finally{n&&clearTimeout(n)}}};function Nr(){return typeof fetch==`function`}var Pr=class{constructor(e,t,n,r,i={}){if(this.config=e,this.session=t,this.runtime=n,this.onWarning=r,this.queue=[],this.flushing=!1,this.consecutiveFailures=0,this.lastWarningAt=0,this.disabledByFailure=!1,this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts=new Map,this.now=i.now??Date.now,this.setTimeoutImpl=i.setTimeoutImpl??setTimeout,this.clearTimeoutImpl=i.clearTimeoutImpl??clearTimeout,!e.enabled){this.enabled=!1,this.transport=void 0;return}if(this.enabled=!0,i.createTransport){this.transport=i.createTransport(e);return}if(!Nr()){this.transport=void 0,this.warnLimited(`qos reporting skipped: fetch unavailable`);return}this.transport=new Mr(e,{fetchImpl:fetch})}startSession(e){this.resetWarnErrorSummary(),this.recordEvent({eventName:`session_start`,stage:`session`,status:`start`,attrs:e})}endSession(e){this.recordEvent({eventName:`session_end`,stage:`session`,status:`end`,attrs:e,metrics:{summary:this.getWarnErrorSummary()}}),this.flush()}recordEvent(e){if(!this.enabled||!this.transport||this.disabledByFailure)return;let t=e.attrs?Dr(e.attrs,this.config):void 0,n=e.metrics?Dr(e.metrics,this.config):void 0;if(this.queue.push({eventName:e.eventName,stage:e.stage,status:e.status,ts:e.ts??this.now(),level:e.level??(e.status===`failed`?`error`:`info`),durationMs:e.durationMs,errorCode:e.errorCode,errorMessage:e.errorMessage,attrs:t,metrics:n}),!this.config.batching.enabled||this.queue.length>=this.config.batching.itemLimit){this.flush();return}this.flushTimer||=this.setTimeoutImpl(()=>{this.flushTimer=void 0,this.flush()},this.config.batching.sendTimeoutMs)}recordLogSignal(e){if(e.level===`warn`){this.warnCount+=1;return}this.errorCount+=1;let t=Or(e.moduleName);this.errorByStage[t]=(this.errorByStage[t]??0)+1;let n=jr(e.meta)??`UNKNOWN`;this.errorCodeCounts.set(n,(this.errorCodeCounts.get(n)??0)+1)}getWarnErrorSummary(){let e=Array.from(this.errorCodeCounts.entries()).sort((e,t)=>t[1]-e[1]).map(([e,t])=>({code:e,count:t}));return{logWarnCount:this.warnCount,logErrorCount:this.errorCount,logErrorByStage:{...this.errorByStage},logErrorTopCodes:e}}async flush(){if(this.flushing||this.queue.length===0||!this.transport||this.disabledByFailure)return;this.flushing=!0,this.flushTimer&&=(this.clearTimeoutImpl(this.flushTimer),void 0);let e=this.config.batching.enabled?this.config.batching.itemLimit:this.queue.length,t=this.queue.splice(0,e),n={schemaVersion:`1.0.0`,source:`enginesdk3`,sdkVersion:this.config.app.version,sentAt:this.now(),session:this.session,context:this.runtime,events:t};try{await this.sendWithRetry(n),this.consecutiveFailures=0}catch(e){this.onFailure(e,`send qos payload failed`)}finally{this.flushing=!1,this.queue.length>0&&!this.disabledByFailure&&this.flush()}}async sendWithRetry(e){let t=Math.max(1,this.config.retry.maxAttempts),n;for(let r=1;r<=t;r+=1)try{await this.transport?.send(e);return}catch(e){n=e}throw n instanceof Error?n:Error(String(n))}onFailure(e,t){this.consecutiveFailures+=1,this.warnLimited(t,{consecutiveFailures:this.consecutiveFailures,error:e instanceof Error?`${e.name}: ${e.message}`:String(e)}),this.consecutiveFailures>=this.config.failure.disableAfterConsecutiveFailures&&(this.disabledByFailure=!0,this.warnLimited(`qos reporting disabled after repeated failures`))}warnLimited(e,t){let n=this.now();n-this.lastWarningAt<this.config.failure.warningIntervalMs||(this.lastWarningAt=n,this.onWarning(e,t))}resetWarnErrorSummary(){this.warnCount=0,this.errorCount=0,this.errorByStage={},this.errorCodeCounts.clear()}},Fr=class{constructor(){this.listeners=new Map,this.debugMode=!1}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),this.debugMode&&console.log(`[EventBus] Subscribed to "${String(e)}"`)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e)),this.debugMode&&console.log(`[EventBus] Unsubscribed from "${String(e)}"`)}emit(e,t){let n=this.listeners.get(e);this.debugMode&&console.log(`[EventBus] Emitting "${String(e)}"`,t),!(!n||n.size===0)&&n.forEach(n=>{try{n(t)}catch(t){console.error(`[EventBus] Error in handler for "${String(e)}":`,t)}})}once(e,t){let n=r=>{this.off(e,n),t(r)};this.on(e,n)}removeAllListeners(e){e===void 0?(this.listeners.clear(),this.debugMode&&console.log(`[EventBus] Removed all listeners`)):(this.listeners.delete(e),this.debugMode&&console.log(`[EventBus] Removed all listeners for "${String(e)}"`))}listenerCount(e){return this.listeners.get(e)?.size??0}eventNames(){return Array.from(this.listeners.keys())}setDebugMode(e){this.debugMode=e}};const Ir=[`webRtcConnected`,`webRtcDisconnected`,`webRtcConnecting`,`webRtcFailed`,`statsReceived`,`subscribeFailed`,`streamerAssigned`];var Lr=class{constructor(){this.mode=`bs`,this.forwardEvents=[...Ir,`streamLoading`]}applyInitialSettings(e){return{[o.KeyboardInput]:!0,[o.MouseInput]:!0,[o.TouchInput]:!0,[o.GamepadInput]:!0,[o.XRControllerInput]:!0,[o.HoveringMouseMode]:!0,[o.AutoPlayVideo]:!0,[o.MatchViewportResolution]:!0,[o.StartVideoMuted]:!0,[s.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for bs mode`)}onAfterConnect(e){e.info(`session connect triggered for bs mode`)}},Rr=class{constructor(){this.mode=`cs`,this.forwardEvents=Ir}applyInitialSettings(e){return{[o.KeyboardInput]:!0,[o.MouseInput]:!1,[o.TouchInput]:!1,[o.GamepadInput]:!1,[o.XRControllerInput]:!1,[o.HoveringMouseMode]:!0,[o.AutoPlayVideo]:!0,[o.MatchViewportResolution]:!0,[o.StartVideoMuted]:!0,[s.MaxReconnectAttempts]:0,...e}}onBeforeConnect(e){e.info(`session connect preparing for cs mode`)}onAfterConnect(e){e.info(`session connect triggered for cs mode`)}};function zr(e){return e===`cs`?new Rr:new Lr}var Br=class{constructor(e,t,n=h){this.logger=n,this.streamerAssignedListeners=new Set,this.handlePoiCursorResponse=e=>{try{let t=JSON.parse(e);if(t.uuid!==`POICursor`)return;this.setVideoCursor(t.param===`pointer`?`pointer`:`default`)}catch{}},this.videoElementParent=t,this.modeStrategy=zr(e.viewMode);let r=this.modeStrategy.applyInitialSettings(e.initialSettings??{});this.psConfig=new a({initialSettings:{...r}}),t?.classList?.add(`fixed-size`),t&&getComputedStyle(t).position===`static`&&(t.style.position=`relative`),this.stream=new l(this.psConfig,t?{videoElementParent:t}:void 0),this.stream.addResponseEventListener(`enginesdk_poi_cursor_listener`,this.handlePoiCursorResponse),this.setupStreamerAssignedListener(),this.logger.info(`session initialized`,{hasVideoParent:!!t,viewMode:this.modeStrategy.mode})}connect(){this.modeStrategy.onBeforeConnect(this.logger),this.logger.info(`connect`),this.stream.connect(),this.modeStrategy.onAfterConnect(this.logger)}reconnect(){this.logger.info(`reconnect`),this.stream.reconnect()}disconnect(){this.logger.info(`disconnect`),this.setVideoCursor(`default`),this.stream.disconnect()}beginPointEditorMouseInput(){let e=[o.MouseInput,o.HoveringMouseMode],t=e.map(e=>this.psConfig.isFlagEnabled(e));e.forEach(e=>this.psConfig.setFlagEnabled(e,!0));let n=!1;return()=>{n||(n=!0,e.forEach((e,n)=>this.psConfig.setFlagEnabled(e,t[n])))}}setSignallingUrlBuilder(e){this.logger.info(`setSignallingUrlBuilder configured`),this.stream.setSignallingUrlBuilder(e)}emitUIInteraction(e){let t=this.stream.emitUIInteraction(e);return t?this.logger.debug(`emitUIInteraction sent`):this.logger.warn(`emitUIInteraction failed`),t}emitCommand(e){let t=this.stream.emitCommand(e);return t?this.logger.debug(`emitCommand sent`):this.logger.warn(`emitCommand failed`),t}addResponseEventListener(e,t){this.logger.debug(`addResponseEventListener`,{name:e}),this.stream.addResponseEventListener(e,t)}removeResponseEventListener(e){this.logger.debug(`removeResponseEventListener`,{name:e}),this.stream.removeResponseEventListener(e)}addEventListener(e,t){if(this.logger.debug(`addEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.add(t);return}this.stream.addEventListener(e,t)}removeEventListener(e,t){if(this.logger.debug(`removeEventListener`,{event:e}),e===`streamerAssigned`){this.streamerAssignedListeners.delete(t);return}this.stream.removeEventListener(e,t)}getForwardEvents(){return this.modeStrategy.forwardEvents}getViewMode(){return this.modeStrategy.mode}isReconnecting(){return this.stream.isReconnecting()}setVideoCursor(e){this.videoElementParent&&(this.videoElementParent.style.cursor=e,this.videoElementParent.querySelectorAll(`video`).forEach(t=>{t.style.cursor=e}))}setupStreamerAssignedListener(){try{let e=this.stream.webRtcController?.protocol;if(!e||typeof e.addListener!=`function`){this.logger.warn(`webRtcController.protocol not available, streamerAssigned listener not registered`);return}e.addListener(`streamerAssigned`,e=>{if(this.logger.info(`streamerAssigned received`,{streamerId:e.streamerId}),e.streamerId)try{this.psConfig.setOptionSettingValue(c.StreamerId,e.streamerId),this.logger.info(`StreamerId configured`,{streamerId:e.streamerId})}catch(t){this.logger.error(`Failed to set StreamerId`,{streamerId:e.streamerId,error:t instanceof Error?t.message:String(t)})}else this.logger.warn(`streamerAssigned received without streamerId`,{msg:e});this.streamerAssignedListeners.forEach(t=>{try{t(e)}catch(e){this.logger.error(`streamerAssigned listener error`,{error:e instanceof Error?e.message:String(e)})}})}),this.logger.debug(`streamerAssigned listener registered`)}catch(e){this.logger.error(`Failed to setup streamerAssigned listener`,{error:e instanceof Error?e.message:String(e)})}}};const Y={SignallingBootstrapFailed:`SIGNALLING_BOOTSTRAP_FAILED`,CenterUnavailable:`CENTER_UNAVAILABLE`,CenterProtocolInvalid:`CENTER_PROTOCOL_INVALID`,ConnectResultFailed:`CONNECT_RESULT_FAILED`,ServiceAllocationFailed:`SERVICE_ALLOCATION_FAILED`,ResourceWaiting:`RESOURCE_WAITING`,AuthorizeFailed:`AUTHORIZE_FAILED`,TokenInvalid:`TOKEN_INVALID`,TokenExpired:`TOKEN_EXPIRED`,SignallingUrlMissing:`SIGNALLING_URL_MISSING`,HeartbeatTimeout:`HEARTBEAT_TIMEOUT`,CenterDisconnected:`CENTER_DISCONNECTED`};var X=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.retryable=n,this.details=r,this.name=`SDKAuthError`}toErrorInfo(){return{code:this.code,message:this.message,retryable:this.retryable}}};function Vr(e){return e instanceof X?e:e instanceof Error?new X(Y.CenterUnavailable,e.message,!0,{cause:e.message}):new X(Y.CenterUnavailable,String(e),!0)}var Hr=class{constructor(t,n=h,r){this.config=t,this.logger=n,this.authEvents=r,this.textEncoder=new TextEncoder,this.connectId=``,this.events=new e,this.manualClose=!1}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}isConnected(){return this.socket?.readyState===WebSocket.OPEN}getConnectId(){return this.connectId}async connect(){if(this.isConnected())return;this.disposeSocket(),this.connectId=this.generateConnectId();let e=this.buildCenterWsUrl(this.connectId),t=this.defaultWebSocketFactory;return this.logger.info(`center connecting`,{wsUrl:e}),this.manualClose=!1,this.closeReasonError=void 0,new Promise((n,r)=>{try{let i=t(e);this.socket=i,i.onopen=()=>{this.startHeartbeatLoops(),this.sendHeartbeat(),this.logger.info(`center connected`),i.binaryType=`arraybuffer`,n()},i.onmessage=e=>{this.handleIncomingData(e.data)},i.onerror=()=>{},i.onclose=()=>{this.stopHeartbeatLoops(),this.socket=void 0;let e=this.closeReasonError??new X(Y.CenterDisconnected,`Center websocket disconnected`,!0);this.manualClose||(this.events.emit(`disconnected`,e),r(e)),this.closeReasonError=void 0}}catch(e){this.authEvents.emit(`progress`,{kind:`loading`,message:b.ServiceUrlInValid,key:`ServiceUrlInValid`,isClose:!0}),r(new X(Y.CenterUnavailable,`Failed to create center websocket: ${e instanceof Error?e.message:String(e)}`,!0,{cause:e instanceof Error?e.message:String(e)}))}})}disconnect(){this.manualClose=!0,this.closeReasonError=void 0,this.disposeSocket()}sendApiData(e,t,n){if(!this.socket||this.socket.readyState!==WebSocket.OPEN)throw new X(Y.CenterDisconnected,`Center websocket is not connected`,!0);let r={projectKey:this.config.sceneName,cls:`WebAPI`,method:e,param:t,fn:n},i=JSON.stringify(r),a=this.textEncoder.encode(i),o=new Uint8Array(a.length+1);o.set(a),this.socket.send(o.buffer),e!==`Heart`&&this.logger.debug(`center send`,{method:e,callbackName:n})}defaultWebSocketFactory(e){if(typeof WebSocket>`u`)throw Error(`WebSocket is not available in current runtime.`);return new WebSocket(e)}startHeartbeatLoops(){this.stopHeartbeatLoops(),this.heartbeatTimer=setInterval(()=>{try{this.isConnected()&&this.sendHeartbeat()}catch(e){this.logger.warn(`send heartbeat failed`,{error:e instanceof Error?e.message:String(e)})}},this.config.centerHeartbeatIntervalMs)}sendHeartbeat(){this.sendApiData(`Heart`),this.armHeartbeatTimeout()}stopHeartbeatLoops(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),void 0),this.clearHeartbeatTimeout()}armHeartbeatTimeout(){this.heartbeatTimeoutTimer||=setTimeout(()=>{this.heartbeatTimeoutTimer=void 0;let e=new X(Y.HeartbeatTimeout,`Center heartbeat timed out after ${this.config.centerHeartbeatTimeoutMs}ms`,!0);this.closeReasonError=e,this.events.emit(`heartbeatTimeout`,e),this.socket?.close()},this.config.centerHeartbeatTimeoutMs)}clearHeartbeatTimeout(){this.heartbeatTimeoutTimer&&=(clearTimeout(this.heartbeatTimeoutTimer),void 0)}disposeSocket(){this.stopHeartbeatLoops(),this.socket&&=(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,this.socket.close(),void 0)}async handleIncomingData(e){this.clearHeartbeatTimeout();let t=await this.decodeToBytes(e);if(!t)return;let n;try{n=u(t,{to:`string`})}catch{this.logger.warn(`center message inflate failed`);return}if(!n)return;let r;try{r=JSON.parse(n)}catch{this.logger.warn(`center message parse failed`);return}if(!r.fn){this.logger.warn(`center message missing fn`);return}r.fn!==`Heart`&&this.events.emit(`message`,r)}async decodeToBytes(e){if(e instanceof ArrayBuffer)return new Uint8Array(e);if(ArrayBuffer.isView(e))return new Uint8Array(e.buffer,e.byteOffset,e.byteLength);if(typeof Blob<`u`&&e instanceof Blob){let t=await e.arrayBuffer();return new Uint8Array(t)}return typeof e==`string`?this.textEncoder.encode(e):(this.logger.warn(`unsupported center message format`),null)}buildCenterWsUrl(e){return`${this.config.centerIP.replace(/^https:/i,`wss:`).replace(/^http:/i,`ws:`).replace(/\/+$/,``)}/${[this.config.mapType,e,this.config.sceneName,this.config.token,this.config.operationType].map(e=>encodeURIComponent(e)).join(`/`)}`}generateConnectId(){return`w_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}};function Ur(e,t,n){let r=e.endsWith(`/`)?e:`${e}/`,i=new URL(`api/v1/allocate`,r);return i.searchParams.set(`token`,t),i.searchParams.set(`proj`,n),i.toString()}function Wr(e){if(typeof e.signalingAddress==`string`&&e.signalingAddress.trim().length>0)return e.signalingAddress.trim();if(typeof e.signallingAddress==`string`&&e.signallingAddress.trim().length>0)return e.signallingAddress.trim()}function Gr(e,t){return new X(Y.SignallingBootstrapFailed,`Signalling allocate request timed out after ${t}ms`,!0,{endpoint:e,timeoutMs:t})}async function Kr(e,t=h){if(typeof fetch!=`function`)throw new X(Y.SignallingBootstrapFailed,`Fetch API is not available for signalling allocation`,!1);let n=Ur(e.signalingServer,e.token,e.proj),r=e.timeoutMs??15e3,i=typeof AbortController==`function`?new AbortController:void 0,a=!1,o,s=i?void 0:new Promise((e,t)=>{o=t}),c;c=setTimeout(()=>{if(a=!0,i){i.abort();return}o?.(Gr(n,r))},r);try{let e=fetch(n,{method:`GET`,...i?{signal:i.signal}:{}}),r=i?await e:await Promise.race([e,s]);if(!r.ok)throw new X(Y.SignallingBootstrapFailed,`Signalling allocate request failed with status ${r.status}`,!0,{endpoint:n,status:r.status});let a;try{a=await r.json()}catch(e){throw new X(Y.SignallingBootstrapFailed,`Signalling allocate response is not valid JSON`,!1,{endpoint:n,cause:e instanceof Error?e.message:String(e)})}let o=Wr(a);if(!o)throw new X(Y.SignallingUrlMissing,`Signalling allocate response missing signalingAddress`,!1,a);return t.info(`signalling allocate resolved url`,{endpoint:n}),o}catch(e){throw a?Gr(n,r):e instanceof X?e:new X(Y.SignallingBootstrapFailed,e instanceof Error?e.message:`Signalling allocate request failed`,!0,{endpoint:n,cause:e})}finally{c!==void 0&&clearTimeout(c)}}var qr=class{constructor(t,n,r=h){this.config=t,this.session=n,this.logger=r,this.events=new e,this.handleWebRtcDisconnected=()=>{this.recoverFromWebRtcDisconnection()},this.nextOperationId=0,this.phase=`idle`,this.stopRequested=!1,this.reconnecting=!1,this.snapshot={state:`idle`,reconnecting:!1,updatedAt:Date.now()},this.centerClient=new Hr(t,r,this.events),this.centerClient.on(`heartbeatTimeout`,e=>{this.logger.warn(`center heartbeat timeout`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`disconnected`,e=>{this.logger.warn(`center disconnected`,{message:e.message}),this.handleCenterInterruption(e)}),this.centerClient.on(`message`,e=>{this.handleCenterMessage(e)}),this.session.addEventListener(`webRtcDisconnected`,this.handleWebRtcDisconnected)}on(e,t){this.events.on(e,t)}off(e,t){this.events.off(e,t)}getSnapshot(){return{...this.snapshot,reconnecting:this.reconnecting||this.session.isReconnecting()}}start(){return this.runningFlow?this.runningFlow.promise:this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!1,disconnectSession:!1,resolveOnStop:!0})}reconnect(){return this.startFlow({route:this.shouldUseDirectSignallingBootstrap()?`direct`:`center`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!0})}reconnectSignalling(){let e=this.signallingAllocationSource;return e?this.startFlow({route:`signalling`,reconnecting:!0,disconnectSession:!0,resolveOnStop:!1,signallingSource:e}):this.reconnect()}startFlow(e){if(this.runningFlow)return e.reconnecting&&(this.reconnecting=!0),e.disconnectSession&&this.session.disconnect(),this.runningFlow.promise;e.disconnectSession&&this.session.disconnect(),this.stopRequested=!1,this.reconnecting=e.reconnecting;let t=this.advanceOperation(),n=this.createRunningFlow(t,e.resolveOnStop);return this.runningFlow=n,this.phase=e.route===`signalling`?`settling`:`starting`,n.promise=this.decorateRunningFlow(n),(e.route===`center`||e.route===`direct`)&&this.prepareAuthBootstrap(t),this.runFlowRoute(e,t),n.promise}runFlowRoute(e,t){switch(e.route){case`center`:this.runCenterFlow(t);return;case`direct`:this.runDirectFlow(t);return;case`signalling`:this.runSignallingFlow(e.signallingSource,t);return}}prepareAuthBootstrap(e){this.centerClient.disconnect(),this.clearRunningContext(),this.pendingCenterInterruption=void 0,this.updateSnapshot(`centerConnecting`,{lastError:void 0,signallingUrl:void 0,engineToken:void 0,webToken:void 0}),this.isCurrentOperation(e)}runCenterFlow(e){this.runAuthFlowOnce(e)}runDirectFlow(e){this.startDirectSignallingBootstrap(e).catch(t=>{this.rejectActiveFlow(t,e)})}runSignallingFlow(e,t){if(!e){this.rejectActiveFlow(new X(Y.SignallingBootstrapFailed,`Signalling bootstrap source is missing`,!1),t);return}this.signallingAllocationSource=e,this.resolveAndConnectSignalling(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}disconnect(){let e=this.runningFlow;this.advanceOperation(),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!0,this.pendingCenterInterruption=void 0,this.phase=`idle`;let t=new X(Y.CenterDisconnected,`Auth workflow disconnected by user`,!0);e&&(e.stopRequested=!0,e.reject?.(t),e.resolve=void 0,e.reject=void 0),this.centerClient.disconnect(),this.session.disconnect(),this.updateSnapshot(`idle`,{webToken:void 0,engineToken:void 0,signallingUrl:void 0,lastError:void 0}),e&&(e.stopSnapshot=this.getSnapshot())}disconnectAndWait(){let e=this.runningFlow?.promise;return this.disconnect(),e?e.then(()=>void 0,()=>void 0):Promise.resolve()}runAuthFlowOnce(e){this.isCurrentOperation(e)&&this.centerClient.connect().then(()=>{this.isCurrentOperation(e)&&(this.updateSnapshot(`centerConnected`),this.expectMessage(`ConnectResult`))}).catch(t=>{this.rejectActiveFlow(t,e)})}shouldUseDirectSignallingBootstrap(){return!!this.config.signalingServer}async startDirectSignallingBootstrap(e){if(!this.isCurrentOperation(e))return;this.setPhase(`settling`,e);let t=this.resolveDirectSignallingAllocationSource();this.signallingAllocationSource=t,await this.resolveAndConnectSignalling(t,e)}resolveDirectSignallingAllocationSource(){if(this.config.signalingServer)return{signalingServer:this.config.signalingServer,token:this.config.token,proj:this.config.sceneName};throw new X(Y.SignallingBootstrapFailed,`No signalling bootstrap source configured`,!1)}handleCenterMessage(e){switch(e.fn){case`ConnectResult`:this.emitCenterEvent(`ConnectResult`,e),this.handleConnectResult(e);return;case`EngineServiceInit`:this.emitCenterEvent(`EngineServiceInit`,e),this.handleEngineServiceInit(e);return;case`TokenAuthorize`:this.emitCenterEvent(`TokenAuthorize`,e),this.handleTokenAuthorize(e);return;case`CenterCloseMessage`:this.emitCenterEvent(`CenterCloseMessage`,e),this.handleCenterCloseMessage(e);return;case`EngineSocketClose`:this.emitCenterEvent(`EngineSocketClose`,e),this.handleEngineSocketClose(e);return;case`TokenWillExpired`:this.emitCenterEvent(`TokenWillExpired`,e),this.handleTokenWillExpired(e);return;case`Offer`:case`Answer`:case`IceCandidate`:this.logger.debug(`center message ignored by current change scope`,{fn:e.fn});return;default:this.logger.debug(`unhandled center message`,{fn:e.fn})}}handleConnectResult(e){if(this.isExpecting(`ConnectResult`))try{if(e.success===!1){this.logger.warn(`connect result failed`,{status:e.status??``,message:e.message??``});return}let t=this.parseValues(e),n=t.webToken;if(!n)throw new X(Y.ConnectResultFailed,`ConnectResult missing webToken`,!0,e);this.connectResult=t,this.emitCenterEvent(`Connect`,e),this.emitLoadingProgress(b.EngineIniting,`EngineIniting`),this.updateSnapshot(`serviceAllocating`,{webToken:n}),this.centerClient.sendApiData(`GetServiceInfo`,this.config.privateKey||void 0),this.expectMessage(`EngineServiceInit`)}catch(e){this.rejectActiveFlow(e)}}handleEngineServiceInit(e){if(this.isExpecting(`EngineServiceInit`))try{if(e.success===!1){let t=e.message??``;this.emitWaitingProgress(t),this.config.viewMode!==`cs`&&this.emitCenterEvent(`EngineServiceInitWait`,e),this.updateSnapshot(`waiting`);return}let t=this.parseValues(e),n=t.token;if(!n)throw new X(Y.ServiceAllocationFailed,`EngineServiceInit missing engine token`,!0,e);this.serviceInfo=t,this.emitLoadingProgress(b.EngineTockenChecking,`EngineTockenChecking`),this.updateSnapshot(`authorizing`,{engineToken:n});let r=JSON.stringify({engineToken:n,webUuid:this.centerClient.getConnectId(),webToken:this.snapshot.webToken});this.centerClient.sendApiData(`AuthorizeToken`,r,`TokenAuthorize`),this.expectMessage(`TokenAuthorize`)}catch(e){this.rejectActiveFlow(e)}}handleTokenAuthorize(e){if(!this.isExpecting(`TokenAuthorize`))return;if(e.success===!1){this.logger.warn(`token authorize failed, wait center close message`,{status:e.status??``,message:e.message??``});return}let t=this.runningFlow?.operationId;t!==void 0&&this.handleTokenAuthorizeSuccess(e,t).catch(e=>{this.rejectActiveFlow(e,t)})}async handleTokenAuthorizeSuccess(e,t){if(!this.isCurrentOperation(t))return;this.setPhase(`settling`,t);let n=(this.tryParseValues(e)??{}).signalingServer?.trim();if(!n)throw new X(Y.SignallingUrlMissing,`TokenAuthorize missing signalingServer`,!1,e);let r=this.snapshot.engineToken;if(!r)throw new X(Y.ServiceAllocationFailed,`Engine token is missing before signaling allocation`,!1,e);let i={signalingServer:n,token:r,proj:this.config.sceneName};this.signallingAllocationSource=i,await this.resolveAndConnectSignalling(i,t)}async resolveAndConnectSignalling(e,t){let n=await Kr(e,this.logger);if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling allocation result`,{operationId:t});return}this.connectWithSignallingUrl(n,t)}connectWithSignallingUrl(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale signalling connect result`,{operationId:t});return}if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url is missing before connect`,!1);this.session.setSignallingUrlBuilder(()=>{let e=this.snapshot.signallingUrl;if(!e)throw new X(Y.SignallingUrlMissing,`Signalling url not ready before connect`,!1);return e}),this.emitLoadingProgress(b.EngineConnectioning,`EngineConnectioning`),this.updateSnapshot(`webrtcConnecting`,{signallingUrl:e}),this.session.connect(),this.setPhase(`connected`,t),this.updateSnapshot(`connected`),this.completeRunningFlow(this.getSnapshot(),t)}handleCenterCloseMessage(e){let t=e.message??`CenterCloseMessage received`;if(e.status===`TokenInValid`){this.emitLoadingProgress(b.TokenInValid,`TokenInValid`);let n=new X(Y.TokenInvalid,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}if(e.status===`TokenExpired`){this.emitLoadingProgress(b.TokenExpired,`TokenExpired`);let n=new X(Y.TokenExpired,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n),this.centerClient.disconnect();return}this.emitLoadingProgress(b.EngineTokenCheckFail,`EngineTokenCheckFail`);let n=new X(Y.AuthorizeFailed,t,!1,e);this.rejectActiveFlow(n)||this.publishFailure(n)}handleEngineSocketClose(e){let t=this.snapshot.engineToken,n=this.extractEngineSocketCloseToken(e.values);if(!t||!n||t!==n){this.logger.debug(`ignore EngineSocketClose for non-current session`,{currentToken:t,closedToken:n});return}let r=new X(Y.CenterDisconnected,e.message??`Engine socket closed`,!0,e);this.emitLoadingProgress(b.EngineClose,`EngineClose`),this.handleCenterInterruption(r)}handleTokenWillExpired(e){this.logger.warn(`token will expire soon`,{message:e.message??``}),this.emitTokenWillExpireProgress(e.message??``)}expectMessage(e){this.expectedCenterFn=e}isExpecting(e){return this.expectedCenterFn===e&&this.hasActiveRunningFlow()}advanceOperation(){return this.nextOperationId+=1,this.nextOperationId}isCurrentOperation(e){return this.runningFlow?.operationId===e}setPhase(e,t){return this.isCurrentOperation(t)?(this.phase=e,!0):!1}createRunningFlow(e,t=!1){let n=()=>void 0,r=()=>void 0;return{operationId:e,promise:new Promise((e,t)=>{n=e,r=t}),resolve:n,reject:r,stopRequested:!1,resolveOnStop:t}}decorateRunningFlow(e){return e.promise.then(t=>e.stopRequested?e.stopSnapshot??this.getSnapshot():(this.reconnecting=!1,this.events.emit(`connected`,t),t)).catch(t=>{if(e.stopRequested){if(e.resolveOnStop)return e.stopSnapshot??this.getSnapshot();throw Vr(t)}let n=Vr(t);throw this.isCurrentOperation(e.operationId)&&(this.updateSnapshot(`failed`,{lastError:n.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())),n}).finally(()=>{if(!this.isCurrentOperation(e.operationId))return;let t=e.stopRequested||this.stopRequested;this.setPhase(this.snapshot.state===`connected`?`connected`:`idle`,e.operationId),this.runningFlow=void 0,this.reconnecting=!1,this.stopRequested=!1,this.flushPendingCenterInterruption(t,e.operationId)})}completeRunningFlow(e,t){if(!this.isCurrentOperation(t)){this.logger.debug(`ignore stale auth flow completion`,{operationId:t});return}let n=this.runningFlow;this.clearRunningContext(t),n?.resolve?.(e),n&&(n.resolve=void 0,n.reject=void 0)}rejectActiveFlow(e,t){let n=Vr(e),r=this.runningFlow;if(!r||t!==void 0&&r.operationId!==t)return this.logger.debug(`ignore stale auth flow failure`,{operationId:t,currentOperationId:r?.operationId,code:n.code,message:n.message}),!1;let i=r.reject;return i?(this.clearRunningContext(r.operationId),r.resolve=void 0,r.reject=void 0,i(n),!0):(this.logger.debug(`ignore auth flow failure without active deferred`,{operationId:r.operationId,code:n.code,message:n.message}),!1)}publishFailure(e){this.updateSnapshot(`failed`,{lastError:e.toErrorInfo()}),this.events.emit(`failed`,this.getSnapshot())}hasActiveRunningFlow(){return!!this.runningFlow?.reject}clearRunningContext(e){e!==void 0&&!this.isCurrentOperation(e)||(this.expectedCenterFn=void 0,this.connectResult=void 0,this.serviceInfo=void 0)}isWaitingMessage(e){return[`坐席已满`,`服务已满`,`排队`,`没有服务资源`,`资源`].some(t=>e.includes(t))}parseValues(e){if(!e.values)return{};try{return JSON.parse(e.values)}catch(t){throw new X(Y.CenterProtocolInvalid,`Invalid center values json for ${e.fn}`,!1,{envelope:e,cause:t instanceof Error?t.message:String(t)})}}tryParseValues(e){if(e.values)try{return JSON.parse(e.values)}catch(t){this.logger.warn(`center values parse failed, fallback to empty payload`,{fn:e.fn,cause:t instanceof Error?t.message:String(t)});return}}extractEngineSocketCloseToken(e){if(!e)return;let t=e.trim();if(t){try{let e=JSON.parse(t);if(typeof e==`string`)return e;if(e&&typeof e.token==`string`&&e.token.trim().length>0)return e.token}catch{}return t}}handleCenterInterruption(e){let t=this.decideCenterInterruption();switch(t.kind){case`ignore`:return;case`reject`:this.rejectActiveFlow(e,t.operationId);return;case`defer`:this.deferCenterInterruption(e,t.operationId);return;case`recover`:this.recoverFromCenterInterruption(e);return}}decideCenterInterruption(){if(this.isTerminalSnapshot())return{kind:`ignore`};let e=this.runningFlow;return e?this.phase===`settling`?{kind:`defer`,operationId:e.operationId}:this.hasActiveRunningFlow()?{kind:`reject`,operationId:e.operationId}:{kind:`defer`,operationId:e.operationId}:{kind:`recover`}}isTerminalSnapshot(){return this.isTerminalSnapshotState(this.snapshot.state)}deferCenterInterruption(e,t){if(this.isCurrentOperation(t)){if(this.pendingCenterInterruption){this.logger.debug(`center interruption already deferred during flow settlement`,{currentCode:this.pendingCenterInterruption.error.code,incomingCode:e.code});return}this.pendingCenterInterruption={operationId:t,error:e},this.logger.debug(`defer center interruption until current flow settles`,{operationId:t,code:e.code,message:e.message})}}flushPendingCenterInterruption(e,t){let n=this.pendingCenterInterruption;if(!(!n||n.operationId!==t)){if(this.pendingCenterInterruption=void 0,e||this.snapshot.state===`idle`||this.snapshot.state===`failed`||this.runningFlow){this.logger.debug(`drop deferred center interruption`,{skip:e,state:this.snapshot.state,code:n.error.code,operationId:t});return}this.recoverFromCenterInterruption(n.error)}}recoverFromWebRtcDisconnection(){let e=this.snapshot.state;if(this.shouldIgnoreWebRtcDisconnection(e)){this.logger.debug(`ignore WebRTC disconnection for current workflow state`,{stopRequested:this.stopRequested,reconnecting:this.reconnecting,hasRunningPromise:!!this.runningFlow,state:e});return}this.logger.warn(`WebRTC disconnected, reconnect signalling`,{state:e}),this.reconnectSignalling().catch(e=>{let t=Vr(e);this.publishFailure(t)})}shouldIgnoreWebRtcDisconnection(e){return this.stopRequested||this.reconnecting||!!this.runningFlow||this.isTerminalSnapshotState(e)}isTerminalSnapshotState(e){return e===`idle`||e===`failed`}recoverFromCenterInterruption(e){this.logger.warn(`center interruption detected, start reconnect`,{state:this.snapshot.state,code:e.code,message:e.message}),this.emitCenterEvent(`UnConnect`,{code:e.code,message:e.message}),this.emitLoadingProgress(b.SerriceError,`SerriceError`),this.reconnect().catch(e=>{let t=Vr(e);this.publishFailure(t)})}updateSnapshot(e,t){this.snapshot={...this.snapshot,...t,state:e,reconnecting:this.reconnecting||this.session.isReconnecting(),updatedAt:Date.now()},this.events.emit(`stateChanged`,this.getSnapshot())}emitLoadingProgress(e,t,n=!0){this.events.emit(`progress`,{kind:`loading`,message:e,key:t,isClose:n})}emitTokenWillExpireProgress(e,t=!0){this.events.emit(`progress`,{kind:`tokenWillExpire`,message:e,key:`TokenWillExpired`,isClose:t})}emitCenterEvent(e,t){this.events.emit(`centerEvent`,{eventName:e,payload:t})}emitWaitingProgress(e){if(this.config.viewMode!==`cs`){if(e.includes(`云渲染服务坐席已满`)||e.includes(`坐席已满`)||e.includes(`当前服务已满`)){this.emitLoadingProgress(e,`EngineWaiting`);return}e.includes(`没有服务资源`)&&this.emitLoadingProgress(b.SerriceUnAvaible,`SerriceUnAvaible`)}}};function Jr(e){return typeof e==`object`&&!!e}var Yr=class{constructor(e,t=h,n={},r={}){this.session=e,this.logger=t,this.hooks=n,this.pending=new Map,this.sendRetries=new Map,this.listenerName=`enginesdk3_response_listener`,this.disconnectEvents=[`webRtcDisconnected`,`webRtcFailed`],this.onResponse=this.handleResponse.bind(this),this.onSessionDisconnected=()=>{this.cleanupPendingOnDisconnect()},this.retryOptions={enabled:r.enabled??!0,intervalMs:r.intervalMs??250,maxWaitMs:r.maxWaitMs??15e3},this.logger.debug(`register response listener`,{listenerName:this.listenerName}),this.session.addResponseEventListener(this.listenerName,this.onResponse),this.disconnectEvents.forEach(e=>{this.session.addEventListener(e,this.onSessionDisconnected)})}sendRequest(e,t,n){let{requestId:r,envelope:i}=this.createRequestEnvelope(e,t,n),a,o,s=new Promise((e,t)=>{a=e,o=t}),c={mode:`single`,module:e,method:t,sentAt:Date.now(),resolve:a,reject:o};return this.pending.set(r,c),this.handleSendAttempt(r,i,c,!1),s}sendStreamRequest(e,t,n,r){let{requestId:i,envelope:a}=this.createRequestEnvelope(e,t,n),o=r??(()=>void 0),s,c,l=new Promise((e,t)=>{s=e,c=t});Object.defineProperty(l,"requestId",{value:i,enumerable:!0}),l.cancel=e=>{this.cancelStreamRequest(i,e)};let u={mode:`stream`,module:e,method:t,sentAt:Date.now(),callback:o,isDone:e=>this.defaultStreamDonePredicate(e),resolve:s,reject:e=>c(e)};return this.pending.set(i,u),this.handleSendAttempt(i,a,u,!0),l}sendPendingRequest(e,t,n){if(this.logger.debug(`emit ${n.mode} request`,{requestId:e,module:n.module,method:n.method}),!this.session.emitUIInteraction(t)){let t=Error(`Failed to send ${n.mode} request: ${n.module}.${n.method}`);return this.logger.error(`emit request failed`,{requestId:e,module:n.module,method:n.method}),t}this.hooks.onRequestSent?.({requestId:e,module:n.module,method:n.method})}handleSendAttempt(e,t,n,r){let i=this.sendPendingRequest(e,t,n);if(i){if(!this.retryOptions.enabled){this.settlePendingFailure(e,n,i,{notifyStream:r});return}this.logger.warn(`emit request failed, will retry until transport ready`,{requestId:e,module:n.module,method:n.method,error:i.message}),this.scheduleSendRetry(e,t,n,r,i)}}scheduleSendRetry(e,t,n,r,i){let a=this.sendRetries.get(e);if(a){a.lastError=i,a.timer===void 0&&(a.timer=setTimeout(()=>this.runSendRetry(a),this.retryOptions.intervalMs));return}let o={requestId:e,envelope:t,pending:n,notifyStream:r,queuedAt:Date.now(),lastError:i};this.sendRetries.set(e,o),o.timer=setTimeout(()=>this.runSendRetry(o),this.retryOptions.intervalMs)}runSendRetry(e){if(e.timer=void 0,this.sendRetries.get(e.requestId)!==e)return;let t=Date.now()-e.queuedAt;if(t>=this.retryOptions.maxWaitMs){this.sendRetries.delete(e.requestId);let{module:n,method:r,mode:i}=e.pending,a=Error(`Failed to send ${i} request: ${n}.${r} after retrying for ${t}ms (${e.lastError.message})`);this.logger.error(`send retry gave up`,{requestId:e.requestId,module:n,method:r,error:a.message}),this.settlePendingFailure(e.requestId,e.pending,a,{notifyStream:e.notifyStream});return}let n=this.sendPendingRequest(e.requestId,e.envelope,e.pending);if(!n){this.sendRetries.delete(e.requestId),this.logger.info(`request sent after transport ready retry`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method});return}e.lastError=n,this.logger.debug(`send retry attempt failed, will retry again`,{requestId:e.requestId,module:e.pending.module,method:e.pending.method,error:n.message}),e.timer=setTimeout(()=>this.runSendRetry(e),this.retryOptions.intervalMs)}clearSendRetry(e){let t=this.sendRetries.get(e);t&&(t.timer!==void 0&&clearTimeout(t.timer),this.sendRetries.delete(e))}settlePendingFailure(e,t,n,r={}){this.pending.get(e)===t&&(this.pending.delete(e),this.clearSendRetry(e),t.mode===`stream`&&r.notifyStream&&this.emitStreamCallback(t,{type:`error`,requestId:e,response:r.response,error:n}),t.reject(n))}handleResponse(e){let t;try{t=JSON.parse(e)}catch(e){this.logger.warn(`response parse failed`,{error:p(e)});return}let n=t.requestId??t.uuid;if(!n){this.logger.warn(`response missing requestId`);return}t.requestId=n,t.param!==void 0&&t.params===void 0&&(t.params=t.param);let r=this.pending.get(n);if(!r){this.logger.debug(`response ignored, no pending request`,{requestId:n});return}if(r.mode===`single`){this.pending.delete(n),this.resolveSingleResponse(t,r);return}this.resolveStreamResponse(t,r)}createRequestEnvelope(e,t,n){let r=`r_${Date.now()}_${Math.random().toString(16).slice(2,10)}`;return{requestId:r,envelope:{AssemblyName:`EngineApi`,fn:r,ClassName:e,FunctionName:t,Value:JSON.stringify(n),ts:Date.now()}}}defaultStreamDonePredicate(e){if(typeof e.code==`string`){let t=e.code.trim().toUpperCase();if(t===`DONE`||t===`STREAM_DONE`)return!0}return!!this.hasDoneFlag(e)}hasDoneFlag(e){return[e,e.data].some(e=>Jr(e)?e.done===!0||e.isEnd===!0:!1)}resolveSingleResponse(e,t){if(e.success||!e.success&&e.errorMsg!=null){this.emitResponseReceivedHook(e,t),this.logger.info(`response success`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}this.logger.warn(`response failed`,{requestId:e.requestId,code:``,message:e.errorMsg}),t.reject(Error(` ${e.errorMsg}`))}resolveStreamResponse(e,t){if(!e.success){let n=Error(` ${e.errorMsg??e.message}`);this.logger.warn(`stream response failed`,{requestId:e.requestId,code:e.code,message:e.errorMsg??e.message}),this.settlePendingFailure(e.requestId,t,n,{response:e,notifyStream:!0});return}if(this.emitResponseReceivedHook(e,t),t.isDone(e)){this.pending.delete(e.requestId);let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`done`,e));if(n){t.reject(n);return}this.logger.info(`stream request done`,{requestId:e.requestId,code:e.code}),t.resolve(e);return}let n=this.emitStreamCallback(t,this.createStreamResponseEvent(`data`,e));n&&this.settlePendingFailure(e.requestId,t,n)}createStreamResponseEvent(e,t){return{...t,type:e,requestId:t.requestId,response:t,data:t.data,params:t.params,param:t.params??t.param,errorMsg:t.errorMsg}}emitResponseReceivedHook(e,t){this.hooks.onResponseReceived?.({requestId:e.requestId,module:t.module,method:t.method,durationMs:Math.max(0,Date.now()-t.sentAt),code:e.code})}emitStreamCallback(e,t){try{e.callback(t);return}catch(e){let n=e instanceof Error?e:Error(String(e));return this.logger.warn(`stream callback failed`,{requestId:t.requestId,type:t.type,error:n.message}),n}}cancelStreamRequest(e,t){let n=this.pending.get(e);if(!n||n.mode!==`stream`)return;this.pending.delete(e),this.clearSendRetry(e);let r=t?.trim()||`Stream request cancelled by client`,i=Error(r);this.logger.info(`stream request cancelled`,{requestId:e,module:n.module,method:n.method}),this.emitStreamCallback(n,{type:`cancel`,requestId:e,error:i}),n.reject(i)}cleanupPendingOnDisconnect(){if(this.sendRetries.forEach(e=>{e.timer!==void 0&&clearTimeout(e.timer)}),this.sendRetries.clear(),this.pending.size===0)return;let e=Error(`Session disconnected before request completed`);this.pending.forEach((t,n)=>{t.mode===`single`||this.emitStreamCallback(t,{type:`error`,requestId:n,error:e}),t.reject(e),this.logger.warn(`pending request cleared on disconnect`,{requestId:n,mode:t.mode})}),this.pending.clear()}};function Xr(e){return typeof e==`object`&&!!e}function Z(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Zr(e){if(!Xr(e))return;let t=e.data;if(!Xr(t))return;let n=t.aggregatedStats;if(Xr(n))return n}function Qr(e,t,n){if(e===void 0||t===void 0)return{packetLossRate:void 0,next:n};let r={packetsLost:e,packetsReceived:t};if(!n)return{packetLossRate:void 0,next:r};let i=e-n.packetsLost,a=t-n.packetsReceived;if(i<0||a<0)return{packetLossRate:void 0,next:r};let o=i+a;if(o<=0)return{packetLossRate:void 0,next:r};let s=i/o;return{packetLossRate:Math.max(0,Math.min(1,s)),next:r}}function $r(e){let t=e.getActiveCandidatePair;if(typeof t!=`function`)return;let n=t.call(e);if(!Xr(n))return;let r=Z(n.currentRoundTripTime);return r===void 0?void 0:r*1e3}function ei(e,t){let n=Zr(e);if(!n)return;let r=Xr(n.inboundVideoStats)?n.inboundVideoStats:{},i=Z(r.bitrate),a=Qr(Z(r.packetsLost),Z(r.packetsReceived),t);return{aggregatedStats:n,inboundVideoStats:r,metrics:{fps:Z(r.framesPerSecond),bitrateKbps:i===void 0?void 0:i/1e3,packetLossRate:a.packetLossRate,jitterMs:(()=>{let e=Z(r.jitter);return e===void 0?void 0:e*1e3})(),rttMs:$r(n),frameWidth:Z(r.frameWidth),frameHeight:Z(r.frameHeight)},packetCounters:a.next}}function ti(){return{CameraHeight:`-`,FPS:`-`,Width:`-`,Height:`-`,runTime:`-`,bytePerSecond:`-`,lostPacketsRate:`-`,delayTime:`-`,Codec:`-`}}function ni(e){if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`)return String(e)}function ri(e){if(e<=0||!Number.isFinite(e))return`00:00:00`;let t=Math.floor(e/1e3);return[Math.floor(t/3600),Math.floor(t%3600/60),t%60].map(e=>String(e).padStart(2,`0`)).join(`:`)}var ii=class{constructor(e,t,n=h,r){this.session=e,this.onStatus=t,this.logger=n,this.onSample=r,this.connected=!1,this.status=ti(),this.onWebRtcConnected=()=>{this.connected=!0,this.firstStatsTimestampMs=void 0,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector started`)},this.onWebRtcDisconnected=()=>{this.pause(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.pause(`webRtcFailed`)},this.onWebRtcConnecting=()=>{this.pause(`webRtcConnecting`)},this.onStatsReceived=e=>{if(!this.connected)return;let t=ei(e,this.packetCounters);t&&(this.packetCounters=t.packetCounters,this.status=this.patchByStats(this.status,t),this.onSample?.(this.extractMediaSample(t)),this.emit())},this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`statsReceived`,this.onStatsReceived)}stop(){this.pause(`manualStop`)}dispose(){this.stop(),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`statsReceived`,this.onStatsReceived)}pause(e){this.connected&&(this.connected=!1,this.lastStatsTimestamp=void 0,this.packetCounters=void 0,this.logger.info(`engine status collector paused`,{reason:e}))}patchByStats(e,t){let n=t.aggregatedStats,r=t.inboundVideoStats,i={...e},a=t.metrics.frameWidth;a!==void 0&&(i.Width=String(a));let o=t.metrics.frameHeight;o!==void 0&&(i.Height=String(o));let s=t.metrics.fps;s!==void 0&&(i.FPS=String(s));let c=t.metrics.bitrateKbps;c!==void 0&&(i.bytePerSecond=`${Math.round(c)} kb/s`),i.lostPacketsRate=t.metrics.packetLossRate===void 0?`-`:`${(t.metrics.packetLossRate*100).toFixed(2)}%`;let l=Z(r.timestamp);if(l!==void 0){if(this.lastStatsTimestamp!==void 0){let e=l-this.lastStatsTimestamp;i.delayTime=`${Math.max(0,1e3-e).toFixed(2)} ms`}this.lastStatsTimestamp=l}this.firstStatsTimestampMs===void 0&&(this.firstStatsTimestampMs=Date.now()),i.runTime=ni(n.sessionStats?.runTime)??ri(Date.now()-this.firstStatsTimestampMs);let u=ni(r.codecId),d=u?this.getCodecMimeType(n,u):void 0;return d&&(i.Codec=d),i}extractMediaSample(e){return{...e.metrics,bitrateKbps:e.metrics.bitrateKbps===void 0?void 0:Math.round(e.metrics.bitrateKbps)}}getCodecMimeType(e,t){let n=e.codecs;if(!n)return;let r;(n instanceof Map||typeof n.get==`function`)&&(r=n.get(t));let i=r?.mimeType;return typeof i==`string`&&i.length>0?i:void 0}emit(){this.onStatus({...this.status})}};const ai=[`Normal`,`Mild`,`Moderate`,`Severe`];function oi(e){return ai.indexOf(e)}function si(e,t){return oi(e)>=oi(t)?e:t}function ci(e,t){let n=oi(t);return e.filter(e=>oi(e)>=n).length}function li(e){return e===`Severe`?`Moderate`:e===`Moderate`?`Mild`:`Normal`}function ui(e){return e===void 0?`Normal`:e>=.1?`Severe`:e>=.06?`Moderate`:e>=.03?`Mild`:`Normal`}function di(e){return e===void 0?`Normal`:e>=240?`Severe`:e>=180?`Moderate`:e>=120?`Mild`:`Normal`}function fi(e){return e===void 0?`Normal`:e>=80?`Severe`:e>=50?`Moderate`:e>=25?`Mild`:`Normal`}function pi(e){return e===void 0?`Normal`:e<=12?`Severe`:e<=20?`Moderate`:e<=28?`Mild`:`Normal`}function mi(e){let t=ui(e.packetLossRate),n=si(di(e.rttMs),fi(e.jitterMs)),r=[t,n,pi(e.fps)],i=[t,n];return r.some(e=>e===`Severe`)?`Severe`:ci(r,`Moderate`)>=2||ci(i,`Moderate`)>=1&&ci(r,`Mild`)>=2?`Moderate`:ci(r,`Mild`)>=2||ci(i,`Moderate`)>=1?`Mild`:`Normal`}function hi(e,t,n,r,i=e){return{measuredLevel:t,outcome:n,reason:r,degradeStreak:i.degradeStreak,recoverStreak:i.recoverStreak}}const gi=[{evaluate(e,t){if(!(e.connected&&e.metrics.connected))return hi(e,t,`hold`,`session not connected, skip adaptation`)}},{evaluate(e,t){if(e.actionInFlight)return hi(e,t,`hold`,`action in flight`)}},{evaluate(e,t){if(!(e.now>=e.cooldownUntil))return hi(e,t,`skip_cooldown`,`cooldown until ${e.cooldownUntil}`)}},{evaluate(e,t){if(oi(t)<=oi(e.stableLevel))return;let n=e.degradeStreak+1,r=t===`Severe`?1:2;return n<r?hi(e,t,`skip_hysteresis`,`degrade streak ${n}/${r}`,{degradeStreak:n,recoverStreak:0}):{measuredLevel:t,outcome:`downgrade`,targetLevel:t,reason:`measured ${t}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){if(t!==`Normal`||e.stableLevel===`Normal`)return;let n=e.recoverStreak+1;if(n<4)return hi(e,t,`skip_hysteresis`,`recover streak ${n}/4`,{degradeStreak:0,recoverStreak:n});let r=li(e.stableLevel);return{measuredLevel:t,outcome:`recover`,targetLevel:r,reason:`recover to ${r}`,degradeStreak:0,recoverStreak:0}}},{evaluate(e,t){return hi(e,t,`hold`,`no transition`,{degradeStreak:0,recoverStreak:t===`Normal`?e.recoverStreak:0})}}];function _i(e){let t=mi(e.metrics);for(let n of gi){let r=n.evaluate(e,t);if(r)return r}return hi(e,t,`hold`,`no transition`)}const vi={Normal:{bitrate:12e6,fps:60,width:1920,height:1080},Mild:{bitrate:8e6,fps:45,width:1600,height:900},Moderate:{bitrate:4e6,fps:30,width:1280,height:720},Severe:{bitrate:2e6,fps:20,width:960,height:540}};function yi(e){let t=e.filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length!==0)return t.reduce((e,t)=>e+t,0)/t.length}var bi=class{constructor(e){this.metricsWindow=[],this.traces=[],this.connected=!1,this.mode=`auto`,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.diagnosticsVisible=!1,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.lastAppliedProfileKey=``,this.transitionGeneration=0,this.onStatsReceived=e=>{this.handleStatsReceived(e)},this.onWebRtcConnected=()=>{this.connected=!0,this.metricsWindow.length=0,this.degradeStreak=0,this.recoverStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.lastMetrics=void 0,this.currentLevel=`Normal`,this.stableLevel=`Normal`,this.lastAppliedProfileKey=``,this.transitionGeneration+=1,this.logger.info(`network adaptation received webRtcConnected`),this.pushTrace({outcome:`hold`,reason:`webrtc connected, resume adaptation`}),this.emitDiagnosticsSnapshot()},this.onWebRtcConnecting=()=>{this.handleConnectionInterrupted(`webRtcConnecting`)},this.onWebRtcDisconnected=()=>{this.handleConnectionInterrupted(`webRtcDisconnected`)},this.onWebRtcFailed=()=>{this.handleConnectionInterrupted(`webRtcFailed`)},this.session=e.session,this.screen=e.screen,this.logger=e.logger??h,this.onStateChange=e.onStateChange,this.onAction=e.onAction,this.onDiagnostics=e.onDiagnostics}start(){this.session.addEventListener(`statsReceived`,this.onStatsReceived),this.session.addEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.addEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.addEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.addEventListener(`webRtcFailed`,this.onWebRtcFailed)}dispose(){this.session.removeEventListener(`statsReceived`,this.onStatsReceived),this.session.removeEventListener(`webRtcConnected`,this.onWebRtcConnected),this.session.removeEventListener(`webRtcConnecting`,this.onWebRtcConnecting),this.session.removeEventListener(`webRtcDisconnected`,this.onWebRtcDisconnected),this.session.removeEventListener(`webRtcFailed`,this.onWebRtcFailed)}setMode(e){this.mode!==e&&(this.mode=e,this.pushTrace({outcome:`manual`,reason:`mode switched to ${e}`}),this.emitDiagnosticsSnapshot(),e===`auto`&&this.lastMetrics&&this.evaluateAutoStrategy(this.lastMetrics))}setManualLevel(e){this.setMode(`manual`),this.transitionToLevel(e,`manual`,`manual override to ${e}`,!0)}setDiagnosticsVisible(e){this.diagnosticsVisible=e,this.emitDiagnosticsSnapshot()}getDiagnosticsSnapshot(){return{ts:Date.now(),visible:this.diagnosticsVisible,mode:this.mode,currentLevel:this.currentLevel,connected:this.connected,lastMetrics:this.lastMetrics,lastAction:this.lastAction,traces:[...this.traces]}}handleStatsReceived(e){let t=ei(e,this.packetCounters);if(!t)return;this.packetCounters=t.packetCounters;let n={ts:Date.now(),connected:this.connected,...t.metrics};this.lastMetrics=this.pushMetrics(n),this.emitDiagnosticsSnapshot(),this.mode!==`manual`&&this.evaluateAutoStrategy(this.lastMetrics)}handleConnectionInterrupted(e){this.connected=!1,this.logger.warn(`network adaptation connection interrupted`,{source:e}),this.metricsWindow.length=0,this.recoverStreak=0,this.degradeStreak=0,this.cooldownUntil=0,this.actionInFlight=!1,this.packetCounters=void 0,this.transitionGeneration+=1,this.pushTrace({outcome:`hold`,reason:`${e}; session disconnected, pause adaptation`}),this.emitDiagnosticsSnapshot()}pushMetrics(e){return this.metricsWindow.push(e),this.metricsWindow.length>5&&this.metricsWindow.shift(),{ts:e.ts,connected:e.connected,fps:yi(this.metricsWindow.map(e=>e.fps)),bitrateKbps:yi(this.metricsWindow.map(e=>e.bitrateKbps)),packetLossRate:yi(this.metricsWindow.map(e=>e.packetLossRate)),jitterMs:yi(this.metricsWindow.map(e=>e.jitterMs)),rttMs:yi(this.metricsWindow.map(e=>e.rttMs)),frameWidth:yi(this.metricsWindow.map(e=>e.frameWidth)),frameHeight:yi(this.metricsWindow.map(e=>e.frameHeight))}}evaluateAutoStrategy(e){let t=_i({connected:this.connected,metrics:e,currentLevel:this.currentLevel,stableLevel:this.stableLevel,mode:this.mode,actionInFlight:this.actionInFlight,cooldownUntil:this.cooldownUntil,now:Date.now(),degradeStreak:this.degradeStreak,recoverStreak:this.recoverStreak});this.applyStrategyDecision(t,e)}applyStrategyDecision(e,t){if(this.degradeStreak=e.degradeStreak,this.recoverStreak=e.recoverStreak,e.outcome===`downgrade`||e.outcome===`recover`){this.transitionToLevel(e.targetLevel??e.measuredLevel,e.outcome,e.reason,!1,t);return}this.pushTrace({measuredLevel:e.measuredLevel,currentLevel:this.currentLevel,mode:this.mode,metrics:t,outcome:e.outcome,reason:e.reason})}transitionToLevel(e,t,n,r,i=this.lastMetrics){if(console.log(`transitionToLevel`,e,t,n,r,i),!r&&e===this.stableLevel){this.pushTrace({measuredLevel:mi(i??{ts:Date.now(),connected:!1}),currentLevel:this.currentLevel,mode:this.mode,metrics:i,outcome:`hold`,reason:`target level equals current level`});return}let a=this.transitionGeneration;this.actionInFlight=!0,this.runTransition(e,t,n,a,i).finally(()=>{a===this.transitionGeneration&&(this.actionInFlight=!1)})}async runTransition(e,t,n,r,i=this.lastMetrics){if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition ignored before start`,{targetLevel:e,reason:n});return}let a=this.currentLevel,o=this.stableLevel,s=mi(i??{ts:Date.now(),connected:!1});t===`recover`&&this.currentLevel!==`Recovering`&&(this.currentLevel=`Recovering`,this.onStateChange?.({from:a,to:`Recovering`,mode:this.mode,reason:`enter recovering before ${e}`,ts:Date.now(),metrics:i}));let c=await this.applyLevelProfile(e,n);if(r!==this.transitionGeneration){this.logger.info(`network adaptation transition discarded after action (stale generation)`,{targetLevel:e,reason:n}),this.pushTrace({measuredLevel:s,currentLevel:this.currentLevel,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; stale transition discarded`}),this.emitDiagnosticsSnapshot();return}if(this.lastAction=c,this.onAction?.(c),!c.success){this.logger.warn(`network adaptation transition not committed due to action failure`,{targetLevel:e,reason:n});let t=this.currentLevel;this.currentLevel=o,t!==this.currentLevel&&this.onStateChange?.({from:t,to:this.currentLevel,mode:this.mode,reason:`${n}; action failed rollback`,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:t,mode:this.mode,targetLevel:e,metrics:i,outcome:`hold`,reason:`${n}; action failed, keep ${o}`}),this.emitDiagnosticsSnapshot();return}let l=this.currentLevel;this.stableLevel=e,this.currentLevel=e,this.cooldownUntil=Date.now()+6e3,this.onStateChange?.({from:l,to:e,mode:this.mode,reason:n,ts:Date.now(),metrics:i}),this.pushTrace({measuredLevel:s,currentLevel:l,mode:this.mode,targetLevel:e,metrics:i,outcome:t,reason:n}),this.emitDiagnosticsSnapshot()}async applyLevelProfile(e,t){let n=vi[e],r=`${n.bitrate}-${n.fps}-${n.width}x${n.height}`;if(r===this.lastAppliedProfileKey)return{level:e,mode:this.mode,success:!0,skipped:!0,reason:`${t}; profile already applied`,ts:Date.now(),steps:[]};let i=[];i.push(await this.runActionStep(`SetSceneRenderBitrate`,{bitrate:n.bitrate})),i.push(await this.runActionStep(`SetSceneFPS`,{fps:n.fps})),i.push(await this.runActionStep(`SetScreenResolution`,{width:n.width,height:n.height}));let a=i.every(e=>e.success);return a&&(this.lastAppliedProfileKey=r),{level:e,mode:this.mode,success:a,skipped:!1,reason:t,ts:Date.now(),steps:i}}async runActionStep(e,t){try{return this.logger.info(`network adaptation action success`,{type:e,payload:t}),{type:e,payload:t,success:!0}}catch(n){let r=n instanceof Error?n.message:String(n);return this.logger.warn(`network adaptation action failed`,{type:e,payload:t,error:r}),{type:e,payload:t,success:!1,error:r}}}pushTrace(e){let t={ts:Date.now(),mode:e.mode??this.mode,currentLevel:e.currentLevel??this.currentLevel,measuredLevel:e.measuredLevel??mi(this.lastMetrics??{ts:Date.now(),connected:this.connected}),targetLevel:e.targetLevel,outcome:e.outcome,reason:e.reason,metrics:e.metrics};this.traces.unshift(t),this.traces.length>30&&(this.traces.length=30),this.emitDiagnosticsSnapshot()}emitDiagnosticsSnapshot(){this.onDiagnostics?.(this.getDiagnosticsSnapshot())}},xi=class{constructor(e){this.visible=!1,this.onKeyDown=e=>{e.ctrlKey&&e.altKey&&e.code===`KeyD`&&(e.preventDefault(),this.toggle())},this.options=e,this.logger=e.logger??h,typeof window<`u`&&window.addEventListener(`keydown`,this.onKeyDown)}dispose(){typeof window<`u`&&window.removeEventListener(`keydown`,this.onKeyDown),this.root?.remove(),this.root=void 0}update(e){this.snapshot=e,this.visible&&(this.ensureRoot(),this.render())}setVisible(e){this.visible!==e&&(this.visible=e,this.ensureRoot(),this.root&&(this.root.style.display=e?`block`:`none`),e&&this.render(),this.options.onVisibilityChange?.(e))}toggle(){this.setVisible(!this.visible)}ensureRoot(){if(this.root||typeof document>`u`||!document.body)return;let e=document.createElement(`div`);e.id=`enginesdk3-network-diagnostics-panel`,e.style.position=`fixed`,e.style.right=`16px`,e.style.bottom=`16px`,e.style.zIndex=`2147483647`,e.style.width=`360px`,e.style.maxWidth=`calc(100vw - 32px)`,e.style.maxHeight=`70vh`,e.style.overflow=`auto`,e.style.padding=`12px`,e.style.borderRadius=`8px`,e.style.boxShadow=`0 6px 24px rgba(0, 0, 0, 0.35)`,e.style.background=`rgba(12, 17, 24, 0.94)`,e.style.color=`#e8f0ff`,e.style.fontFamily=`Menlo, Consolas, Monaco, monospace`,e.style.fontSize=`12px`,e.style.lineHeight=`1.4`,e.style.display=this.visible?`block`:`none`;let t=document.createElement(`div`);t.style.display=`flex`,t.style.justifyContent=`space-between`,t.style.alignItems=`center`,t.style.marginBottom=`8px`;let n=document.createElement(`strong`);n.textContent=`Network Diagnostics`,t.appendChild(n),this.levelLabel=document.createElement(`span`),this.levelLabel.style.color=`#7ee787`,this.levelLabel.textContent=`Normal`,t.appendChild(this.levelLabel),e.appendChild(t);let r=document.createElement(`div`);r.style.display=`flex`,r.style.alignItems=`center`,r.style.gap=`8px`,r.style.marginBottom=`8px`;let i=document.createElement(`span`);i.textContent=`Mode`,r.appendChild(i),this.modeSelect=document.createElement(`select`),this.modeSelect.style.flex=`1`,this.modeSelect.innerHTML=`<option value="auto">Auto</option><option value="manual">Manual</option>`,this.modeSelect.onchange=()=>{let e=this.modeSelect?.value===`manual`?`manual`:`auto`;this.options.onModeChange(e)},r.appendChild(this.modeSelect),e.appendChild(r);let a=document.createElement(`div`);a.style.display=`flex`,a.style.alignItems=`center`,a.style.gap=`8px`,a.style.marginBottom=`8px`;let o=document.createElement(`span`);o.textContent=`Manual Level`,a.appendChild(o),this.levelSelect=document.createElement(`select`),this.levelSelect.style.flex=`1`,this.levelSelect.innerHTML=[`<option value="Normal">Normal</option>`,`<option value="Mild">Mild</option>`,`<option value="Moderate">Moderate</option>`,`<option value="Severe">Severe</option>`].join(``),this.levelSelect.onchange=()=>{let e=this.levelSelect?.value??`Normal`;this.options.onManualLevelChange(e)},a.appendChild(this.levelSelect),e.appendChild(a),this.metricsPre=document.createElement(`pre`),this.metricsPre.style.margin=`0 0 8px 0`,this.metricsPre.style.padding=`8px`,this.metricsPre.style.background=`rgba(255, 255, 255, 0.06)`,this.metricsPre.style.borderRadius=`6px`,this.metricsPre.style.whiteSpace=`pre-wrap`,this.metricsPre.style.wordBreak=`break-word`,e.appendChild(this.metricsPre);let s=document.createElement(`div`);s.style.marginBottom=`6px`,s.textContent=`Recent Decisions`,e.appendChild(s),this.traceList=document.createElement(`div`),this.traceList.style.display=`flex`,this.traceList.style.flexDirection=`column`,this.traceList.style.gap=`4px`,e.appendChild(this.traceList),document.body.appendChild(e),this.root=e,this.logger.info(`network diagnostics panel ready`)}render(){!this.root||!this.snapshot||(this.levelLabel&&(this.levelLabel.textContent=this.snapshot.currentLevel,this.levelLabel.style.color=this.snapshot.currentLevel===`Severe`?`#ff7b72`:`#7ee787`),this.modeSelect&&(this.modeSelect.value=this.snapshot.mode),this.levelSelect&&(this.levelSelect.disabled=this.snapshot.mode!==`manual`),this.metricsPre&&(this.metricsPre.textContent=this.buildMetricsText(this.snapshot)),this.traceList&&(this.traceList.innerHTML=``,this.snapshot.traces.slice(0,10).forEach(e=>{let t=document.createElement(`div`);t.style.padding=`6px`,t.style.borderRadius=`6px`,t.style.background=`rgba(255, 255, 255, 0.04)`,t.textContent=`${new Date(e.ts).toLocaleTimeString()} | ${e.outcome} | ${e.reason}`,this.traceList?.appendChild(t)})))}buildMetricsText(e){let t=e.lastMetrics;if(!t)return`No metrics yet`;let n=t.packetLossRate===void 0?`-`:`${(t.packetLossRate*100).toFixed(2)}%`;return[`connected: ${e.connected}`,`mode: ${e.mode}`,`level: ${e.currentLevel}`,`fps: ${t.fps?.toFixed(2)??`-`}`,`bitrate(kbps): ${t.bitrateKbps?.toFixed(2)??`-`}`,`packetLoss: ${n}`,`rtt(ms): ${t.rttMs?.toFixed(2)??`-`}`,`jitter(ms): ${t.jitterMs?.toFixed(2)??`-`}`,`resolution: ${t.frameWidth??`-`}x${t.frameHeight??`-`}`,`lastAction: ${e.lastAction?`${e.lastAction.level} (${e.lastAction.success?`ok`:`fail`})`:`-`}`].join(`
109
+ `)}},Si=class{constructor(e){this.disconnected=!1,this.hasEverConnected=!1,this.authWorkflow=e.authWorkflow,this.logger=e.logger}async connect(){if(this.disconnected)throw Error(`Cannot connect after disconnect. Use restart() instead.`);this.logger.info(`Starting connection flow`);try{let e=await this.authWorkflow.start();return this.logger.info(`Connection established`,{engineToken:e.engineToken?.substring(0,16)+`...`}),e}catch(e){throw this.logger.error(`Connection failed`,{error:e}),e}}async disconnect(){return this.disconnected?(this.logger.info(`Already disconnected, skipping`),this.disconnectPromise||Promise.resolve()):(this.logger.info(`Disconnecting...`),this.disconnected=!0,this.disconnectPromise=(async()=>{try{await this.authWorkflow.disconnectAndWait(),this.logger.info(`Disconnected successfully`)}catch(e){throw this.logger.error(`Error during disconnect`,{error:e}),e}})(),this.disconnectPromise)}async prepareConnectAfterDisconnect(){this.disconnectPromise&&await this.disconnectPromise,this.disconnected=!1,this.disconnectPromise=void 0,this.hasEverConnected=!1}async restart(){return this.logger.info(`Restarting connection...`),await this.disconnect(),await this.prepareConnectAfterDisconnect(),this.connect()}getStatus(){return{disconnected:this.disconnected,hasEverConnected:this.hasEverConnected}}hasConnectedBefore(){return this.hasEverConnected}markConnected(){this.hasEverConnected=!0}},Q=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.moduleName=n,this.dependencyName=r,this.name=`ApiRegistryError`}};function Ci(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function wi(e,t){return Ci(e)&&typeof e[t]==`function`}function Ti(e){if(!Ci(e))throw new Q(`CONTEXT_INVALID`,`API registry context must be an object`);let t=[[`bridge`,e.bridge,`sendRequest`],[`authWorkflow`,e.authWorkflow,`getSnapshot`],[`connectionLifecycle`,e.connectionLifecycle,`connect`],[`createLogger`,e.createLogger,void 0]];for(let[e,n,r]of t)if(!(r?wi(n,r):typeof n==`function`||n!=null))throw new Q(`CONTEXT_INVALID`,`API registry context dependency '${e}'${r?` with ${r}()`:``} is required`,void 0,e)}function Ei(e){if(!Ci(e))throw new Q(`REGISTRY_INVALID`,`API registry must be a non-null object`);let t=Object.keys(e).find(e=>!dn.includes(e));if(t)throw new Q(`REGISTRY_UNKNOWN_MODULE`,`API registry contains unknown module '${t}'`,t);let n=dn.find(t=>!(t in e));if(n)throw new Q(`REGISTRY_INCOMPLETE`,`API registry is missing module '${n}'`,n);for(let t of dn)if(typeof e[t]!=`function`)throw new Q(`FACTORY_INVALID`,`API registry factory for '${t}' must be a function`,t)}function Di(e,t,n,r){let i;try{i=t[r](n)}catch(e){throw new Q(`FACTORY_FAILED`,`API registry factory for '${r}' failed: ${e instanceof Error?e.message:String(e)}`,r,void 0)}if(i==null)throw new Q(`FACTORY_EMPTY_RESULT`,`API registry factory for '${r}' returned ${i===null?`null`:`undefined`}`,r);e[r]=i}function Oi(e,t=un){if(Ti(e),Ei(t),typeof t.Popup==`function`&&(e.popupManager===null||e.popupManager===void 0))throw new Q(`CONTEXT_INVALID`,`API registry context dependency 'popupManager' is required by the Popup module`,`Popup`,`popupManager`);let n={};return dn.forEach(r=>{Di(n,t,e,r)}),n}const ki=.78;var $=class extends Error{constructor(e,t,n,r){super(t),this.code=e,this.buildingId=n,this.floorId=r,this.name=`BuildingFloorError`}};function Ai(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ji(e){return Ai(e)&&typeof e.x==`number`&&Number.isFinite(e.x)&&typeof e.y==`number`&&Number.isFinite(e.y)&&typeof e.z==`number`&&Number.isFinite(e.z)}function Mi(e){return{position:Ni(e.position),target:Ni(e.target),fov:e.fov,time:e.time}}function Ni(e){return new C(e.x,e.y,e.z,e.ePSGType)}var Pi=class{constructor(e,t){this.dependencies=e,this.buildings=new Map,this.logger=t?.logger??h}async register(e){let t=Array.isArray(e)?e:[e],n=this.normalizeRegistrations(t),r=await Promise.all(n.map(async e=>({definition:e,positions:await this.measureFloorPositions(e)})));this.assertBuildingsRemainAvailable(n),r.forEach(({definition:e,positions:t})=>{this.buildings.set(e.buildingId,{definition:e,originalPositions:t,explodedDistances:new Map,visibleFloorIds:e.floors.map(e=>e.id),transitionId:0,status:`overview`,activeMoves:new Set})});let i=n.map(e=>e.buildingId);return this.logger.info(`building floors registered`,{buildingIds:i}),{buildingIds:i}}async switchTo(e){let t=this.requireBuilding(e.buildingId),n=t.definition.floors.findIndex(t=>t.id===e.floorId);if(n<0)throw new $(`FLOOR_NOT_FOUND`,`Floor "${e.floorId}" is not registered for building "${e.buildingId}".`,e.buildingId,e.floorId);let r=t.definition.floors[n];return this.transition(t,{floorId:r.id,visibleFloorIds:t.definition.floors.slice(0,n+1).map(e=>e.id),hiddenFloorIds:t.definition.floors.slice(n+1).map(e=>e.id),viewPoint:r.viewPoint,objectIds:r.objects??[],overview:!1,focus:e.focus===!0})}async showOverview(e){let t=this.requireBuilding(e.buildingId);return this.transition(t,{visibleFloorIds:t.definition.floors.map(e=>e.id),hiddenFloorIds:[],viewPoint:t.definition.overview.viewPoint,objectIds:t.definition.overview.objects??[],overview:!0,focus:e.focus===!0})}async cancel(e){let t=this.requireBuilding(e.buildingId);t.transitionId+=1,await this.stopActiveTransition(t),t.currentFloorId=void 0,t.status=`cancelled`,this.logger.info(`building floor transition cancelled`,{buildingId:e.buildingId})}getState(e){let t=this.requireBuilding(e.buildingId);return{buildingId:t.definition.buildingId,status:t.status,currentFloorId:t.currentFloorId,visibleFloorIds:[...t.visibleFloorIds],transitionId:t.transitionId}}normalizeRegistrations(e){if(e.length===0)throw new $(`INVALID_REGISTRATION`,`At least one building is required.`);let t=new Set;return e.map(e=>{let n=this.requireNonEmptyString(e?.buildingId,`buildingId`),r=this.requireNonEmptyString(e?.parentId,`parentId`,n);if(t.has(n))throw new $(`INVALID_REGISTRATION`,`Building "${n}" is duplicated in the registration batch.`,n);if(this.buildings.has(n))throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${n}" is already registered.`,n);if(t.add(n),!Array.isArray(e.floors)||e.floors.length===0)throw new $(`INVALID_REGISTRATION`,`Building "${n}" must contain at least one floor.`,n);let i=new Set,a=e.floors.map((e,t)=>{let r=this.normalizeFloor(e,n,t);if(i.has(r.id))throw new $(`INVALID_REGISTRATION`,`Floor "${r.id}" is duplicated in building "${n}".`,n,r.id);return i.add(r.id),r}),o=e.overview??{},s=o.objects??[];if(!Array.isArray(s)||s.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Building "${n}" overview objects must contain non-empty IDs.`,n);return o.viewPoint&&this.validateViewPoint(o.viewPoint,n,`overview`),{buildingId:n,parentId:r,floors:a,overview:{objects:[...s],viewPoint:o.viewPoint?Mi(o.viewPoint):void 0}}})}normalizeFloor(e,t,n){let r=typeof e==`string`?{id:e}:e;if(!Ai(r))throw new $(`INVALID_REGISTRATION`,`Floor at index ${n} in building "${t}" must be a string or object.`,t);let i=this.requireNonEmptyString(r.id,`floors[${n}].id`,t),a=r.viewPoint;return a!==void 0&&this.validateViewPoint(a,t,i),{id:i,viewPoint:a?Mi(a):void 0,objects:this.normalizeObjectIds(r.objects,t,i)}}normalizeObjectIds(e,t,n){if(e!==void 0){if(!Array.isArray(e)||e.some(e=>typeof e!=`string`||e.trim()===``))throw new $(`INVALID_REGISTRATION`,`Objects for "${t}@${n}" must contain non-empty IDs.`,t,n);return[...e]}}validateViewPoint(e,t,n){if(!Ai(e)||!ji(e.position)||!ji(e.target))throw new $(`INVALID_REGISTRATION`,`View point for "${t}@${n}" requires valid position and target vectors.`,t,n);if(e.fov!==void 0&&(!Number.isFinite(e.fov)||e.fov<10||e.fov>150))throw new $(`INVALID_REGISTRATION`,`View point fov for "${t}@${n}" must be between 10 and 150.`,t,n);if(e.time!==void 0&&(!Number.isFinite(e.time)||e.time<0))throw new $(`INVALID_REGISTRATION`,`View point time for "${t}@${n}" must be a non-negative number.`,t,n)}requireNonEmptyString(e,t,n){if(typeof e!=`string`||e.trim()===``)throw new $(`INVALID_REGISTRATION`,`${t} must be a non-empty string.`,n);return e}assertBuildingsRemainAvailable(e){let t=e.find(e=>this.buildings.has(e.buildingId));if(t)throw new $(`BUILDING_ALREADY_REGISTERED`,`Building "${t.buildingId}" was registered while its model information was loading.`,t.buildingId)}async measureFloorPositions(e){let t=await Promise.all(e.floors.map(async t=>{let n=await this.dependencies.model.getModelInfo({parentId:e.parentId,id:t.id});return[t.id,this.extractPosition(n,e.buildingId,t.id)]}));return new Map(t)}extractPosition(e,t,n){let r=e,i=e.params??e.data??r.param;if(Ai(i)&&(`param`in i||`params`in i)&&(i=i.param??i.params),typeof i==`string`)try{i=JSON.parse(i)}catch{i=void 0}let a=Ai(i)?i.position:void 0;if(!ji(a))throw new $(`MODEL_INFO_INVALID`,`Model information for "${t}@${n}" does not contain a valid position.`,t,n);return{x:a.x,y:a.y,z:a.z,ePSGType:typeof a.ePSGType==`string`&&a.ePSGType!==``?a.ePSGType:`0000`}}requireBuilding(e){let t=this.buildings.get(e);if(!t)throw new $(`BUILDING_NOT_REGISTERED`,`Building "${e}" is not registered.`,e);return t}async transition(e,t){let n=e.transitionId+1;if(e.transitionId=n,await this.stopActiveTransition(e),n!==e.transitionId)return this.createResult(e,t,`cancelled`,`none`);e.status=`switching`;let r=t.visibleFloorIds.filter(t=>e.explodedDistances.has(t)),i=t.hiddenFloorIds.filter(t=>!e.explodedDistances.has(t)),a=t.hiddenFloorIds.filter(t=>e.explodedDistances.has(t));try{let r=this.getAccessoryObjectIds(e.definition);if(r.length>0&&(await this.dependencies.model.setVisible({id:r,visible:!1}),n!==e.transitionId)||t.visibleFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:t.visibleFloorIds,visible:!0}),n!==e.transitionId))return this.createResult(e,t,`cancelled`,`none`);a.length>0&&await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:a,visible:!1})}catch(t){throw n===e.transitionId&&(e.status=`cancelled`),t}return n===e.transitionId?new Promise((a,o)=>{let s={id:n,timers:new Set,pendingActions:new Set,settled:!1,resolve:a,reject:o};e.activeTransition=s,r.forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let n=e.originalPositions.get(t),r=this.getHideOffset(e),i=Math.max(r*.035,.5),a=e.explodedDistances.get(t)??r;e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(n,n.z-i),this.positionAtZ(n,n.z)],speed:this.getMotionSpeed(a+i*2),linear:6,isLookAtTarget:!1,needDirection:!1})})}),[...i].reverse().forEach((t,n)=>{this.schedule(e,s,n*105,async()=>{let r=e.originalPositions.get(t),i=this.getHideOffset(e),a=Math.max(i*.045,.6),o=i*(1+.24*n);e.explodedDistances.set(t,o),e.activeMoves.add(t),await this.dependencies.modelTransform.startMoveByNodes({parentId:e.definition.parentId,id:t,nodes:[this.positionAtZ(r,r.z-a),this.positionAtZ(r,r.z+o)],speed:this.getMotionSpeed(o+a*2),linear:5,isLookAtTarget:!1,needDirection:!1})})});let c=Math.max(this.getBatchDurationMs(r.length),this.getBatchDurationMs(i.length));this.scheduleCompletion(e,s,c,t)}):this.createResult(e,t,`cancelled`,`none`)}schedule(e,t,n,r){let i=setTimeout(()=>{if(t.timers.delete(i),t.settled||t.id!==e.transitionId)return;let n=Promise.resolve().then(()=>{if(!(t.settled||t.id!==e.transitionId))return r()});t.pendingActions.add(n),n.then(()=>{t.pendingActions.delete(n)}).catch(r=>{t.pendingActions.delete(n),this.failTransition(e,t,r)})},n);t.timers.add(i)}scheduleCompletion(e,t,n,r){let i=setTimeout(()=>{t.timers.delete(i),!(t.settled||t.id!==e.transitionId)&&Promise.all([...t.pendingActions]).then(()=>this.completeTransition(e,t,r)).catch(n=>{this.failTransition(e,t,n)})},n);t.timers.add(i)}async completeTransition(e,t,n){if(!(t.settled||t.id!==e.transitionId))try{if(n.hiddenFloorIds.length>0&&(await this.dependencies.model.setVisible({parentId:e.definition.parentId,id:n.hiddenFloorIds,visible:!1}),t.settled||t.id!==e.transitionId)||(n.visibleFloorIds.forEach(t=>e.explodedDistances.delete(t)),e.activeMoves.clear(),e.visibleFloorIds=[...n.visibleFloorIds],e.currentFloorId=n.floorId,e.status=n.overview?`overview`:`floor`,n.objectIds.length>0&&(await this.dependencies.model.setVisible({id:n.objectIds,visible:!0}),t.settled||t.id!==e.transitionId)))return;let r=await this.focusTarget(e,n);if(t.settled||t.id!==e.transitionId)return;this.settleTransition(e,t,this.createResult(e,n,`completed`,r))}catch(n){this.failTransition(e,t,n)}}async focusTarget(e,t){return t.focus?t.viewPoint?(await this.dependencies.camera.flyToTarget({point:t.viewPoint.position,target:t.viewPoint.target,fov:t.viewPoint.fov,time:t.viewPoint.time??.2}),`viewPoint`):(await this.dependencies.camera.lookAt({parentId:e.definition.parentId,id:t.visibleFloorIds,time:.2,isRotate:!1,isHighlight:!1}),`bounds`):`none`}failTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),e.status===`switching`&&(e.currentFloorId=void 0,e.status=`cancelled`),this.stopActiveMoves(e),this.logger.warn(`building floor transition failed`,{buildingId:e.definition.buildingId,error:n}),t.reject(n))}settleTransition(e,t,n){t.settled||(t.settled=!0,t.timers.forEach(e=>clearTimeout(e)),t.timers.clear(),e.activeTransition===t&&(e.activeTransition=void 0),t.resolve(n))}async stopActiveTransition(e){let t=e.activeTransition;t&&this.settleTransition(e,t,{buildingId:e.definition.buildingId,status:`cancelled`,visibleFloorIds:[...e.visibleFloorIds],focusMode:`none`,completion:`estimated`}),await this.stopActiveMoves(e)}async stopActiveMoves(e){let t=[...e.activeMoves];e.activeMoves.clear(),t.forEach(t=>{this.dependencies.modelTransform.endMove({parentId:e.definition.parentId,id:t}).catch(n=>{this.logger.warn(`failed to stop building floor move`,{buildingId:e.definition.buildingId,floorId:t,error:n})})}),await Promise.resolve()}createResult(e,t,n,r){return{buildingId:e.definition.buildingId,floorId:t.floorId,status:n,visibleFloorIds:n===`completed`?[...t.visibleFloorIds]:[...e.visibleFloorIds],focusMode:r,completion:`estimated`}}getHideOffset(e){let t=[...e.originalPositions.values()].map(e=>e.z);return t.length<2?2e3:Math.max(Math.max(...t)-Math.min(...t),1)*2.2}getAccessoryObjectIds(e){let t=new Set(e.overview.objects??[]);return e.floors.forEach(e=>{e.objects?.forEach(e=>t.add(e))}),[...t]}getBatchDurationMs(e){return e===0?0:(e-1)*105+ki*1e3}getMotionSpeed(e){return Math.max(e/ki,1)}positionAtZ(e,t){return{x:e.x,y:e.y,z:t,ePSGType:e.ePSGType}}},Fi=class{bind(e){this.lifecycle=e}connect(){return this.getLifecycle().connect()}disconnect(){return this.getLifecycle().disconnect()}reconnect(){return this.getLifecycle().reconnect()}getLifecycle(){if(!this.lifecycle)throw Error(`Connection lifecycle is not bound`);return this.lifecycle}};function Ii(e){return`${e}_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}var Li=class{withConfig(e){return this.userConfig=e,this}withOptions(e){return this.videoElementParent=e?.videoElementParent,this}build(){if(!this.userConfig)throw Error(`Config must be set via withConfig() before calling build()`);let e=vr(this.userConfig),t=Ii(`sess`),n=Ii(`trace`);te(e.pixelStreamingLogger);let r=new ae(e.logger,void 0,{includeStack:e.includeStack}),i=r.child(`QoS`),a=wr(),o=new Pr(a,{sessionId:t,traceId:n,runMode:e.viewMode,viewMode:e.viewMode},{appId:e.sceneName,env:a.app.environment,pageUrl:lr(),userAgent:ur()},(e,t)=>{i.warn(e,t)});r.setReporter(o);let s=new Fr,c=r.child(`Core`);c.info(`engine init`,{logLevel:r.level,qosReportingEnabled:a.enabled}),o.startSession({engineUuid:e.engineUuid??``});let l=new Br(e,e.dom||this.videoElementParent,r.child(`SessionAdapter`)),u=new qr(e,l,r.child(`AuthWorkflow`)),d=new Yr(l,r.child(`RequestBridge`),{onRequestSent:({requestId:e,module:t,method:n})=>{o.recordEvent({eventName:`ue_request_sent`,stage:`ue_api`,status:`start`,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n}})},onResponseReceived:({requestId:e,module:t,method:n,durationMs:r,code:i})=>{o.recordEvent({eventName:`ue_response_received`,stage:`ue_api`,status:`success`,durationMs:r,attrs:{requestId:e,apiName:`${t}.${n}`,module:t,method:n},metrics:{ueApiRttMs:r,code:i}})}}),f=new Si({authWorkflow:u,logger:r.child(`ConnectionManager`)}),p=new Fi,m=new oe({enabled:e.showProgressBar,hostElement:e.dom,emit:e=>{s.emit(`LoadingProgress`,e)},logger:r.child(`LoadingProgress`)}),h=new ii(l,e=>{s.emit(`EngineStatus`,e)},r.child(`EngineStatus`),e=>{o.recordEvent({eventName:`media_stats_sample`,stage:`media`,status:`update`,metrics:e})}),g=new Qt({getEngineConfig:()=>e,on:(e,t)=>s.on(e,t),off:(e,t)=>s.off(e,t)}),_=Oi({bridge:d,authWorkflow:u,connectionLifecycle:p,createLogger:e=>r.child(e),popupManager:g,videoElementParent:e.dom||this.videoElementParent,beginPointEditorMouseInput:()=>l.beginPointEditorMouseInput()}),ee=new Pi({model:_.Model,modelTransform:_.ModelTransform,camera:_.Camera},{logger:r.child(`BuildingFloor`)}),v={},y=new bi({session:l,screen:_.Screen,logger:r.child(`NetworkAdaptation`),onStateChange:e=>{c.info(`network level changed`,e),s.emit(`networkLevelChanged`,e)},onAction:e=>{(e.success?c.info.bind(c):c.warn.bind(c))(`network adaptation action executed`,e),s.emit(`networkActionExecuted`,e)},onDiagnostics:e=>{s.emit(`networkDiagnosticsUpdated`,e),v.current?.update(e)}}),ne=new xi({logger:r.child(`NetworkDiagnosticsPanel`),onModeChange:e=>{c.info(`network mode changed`,{mode:e}),s.emit(`networkModeChanged`,{mode:e}),y.setMode(e)},onManualLevelChange:e=>{c.info(`network manual level set`,{level:e}),y.setManualLevel(e)},onVisibilityChange:e=>{c.info(`network diagnostics visibility changed`,{visible:e}),y.setDiagnosticsVisible(e),s.emit(`networkDiagnosticsVisibilityChanged`,{visible:e})}});return v.current=ne,{config:e,qosMonitor:o,loggerManager:r,eventBus:s,session:l,authWorkflow:u,bridge:d,connectionManager:f,connectionLifecycle:p,loadingProgress:m,engineStatus:h,networkAdaptation:y,networkDiagnosticsPanel:ne,popupManager:g,buildingFloor:ee,apiFacade:_,sessionId:t,traceId:n}}};const Ri={centerConnecting:`authConnecting`,waiting:`authWaiting`,authorizing:`authAuthorizing`,connected:`authConnected`,failed:`authFailed`};var zi=class{constructor(e,t){this.Events={WebRtcConnected:`webRtcConnected`,WebOnConnect:`webRtcConnected`,MapLoaded:`OnApiDataChannelStarted`,WebRtcDisconnected:`webRtcDisconnected`,WebOnDisconnect:`webRtcDisconnected`,DataChannelDisconnet:`webRtcDisconnected`,WebRtcConnecting:`webRtcConnecting`,WebRtcFailed:`webRtcFailed`,StatsReceived:`statsReceived`,EngineStatus:`EngineStatus`,StreamLoading:`streamLoading`,LoadingProgress:`LoadingProgress`,CenterConnected:`Connect`,CenterDisconnected:`UnConnect`,ConnectResult:`ConnectResult`,CenterCloseMessage:`CenterCloseMessage`,TokenAuthorize:`TokenAuthorize`,EngineServiceInit:`EngineServiceInit`,EngineServiceInitWait:`EngineServiceInitWait`,EngineSocketClose:`EngineSocketClose`,TokenWillExpired:`TokenWillExpired`,AuthStateChanged:`authStateChanged`,AuthConnecting:`authConnecting`,AuthWaiting:`authWaiting`,AuthAuthorizing:`authAuthorizing`,AuthConnected:`authConnected`,AuthFailed:`authFailed`,SessionModeReady:`sessionModeReady`,SessionModeFailed:`sessionModeFailed`,SceneConfig:`SceneConfig`,ModelClick:`ModelClick`,ModelUpdate:`ModelUpdate`,CameraHeight:`CameraHeight`,LeftClick:`MouseLeftButtonClick`,LeftDoubleClick:`MouseLeftButtonDoubleClick`,LeftLongPressed:`MouseLeftButtonLongPressed`,RightClick:`MouseRightButtonClick`,RightDoubleClick:`MouseRightButtonDoubleClick`,RightLongPressed:`MouseRightButtonLongPressed`,ModelTrigger:`ModelTrigger`,SyncPops:`SyncPops`,NetworkLevelChanged:`networkLevelChanged`,NetworkActionExecuted:`networkActionExecuted`,NetworkModeChanged:`networkModeChanged`,NetworkDiagnosticsVisibilityChanged:`networkDiagnosticsVisibilityChanged`,NetworkDiagnosticsUpdated:`networkDiagnosticsUpdated`,LoadMQTTDataFinished:`LoadMQTTDataFinished`,LoadMQTTDataProgress:`LoadMQTTDataProgress`,TrainsVisible:`TrainsVisible`,TrainsInfo:`TrainsInfo`},this.Enums={DlssQuality:w,FilterMode:Re,GizmoType:Ve,LayerEnum:Fe,ModelTransformType:Le,ScreenRenderBitratePreset:T,Season:Ie,TrainBehavior:ze,UIPopState:Be,VideoCodeType:Pe},this.uePushResponseListenerName=`enginesdk3_ue_push_listener`,this.uePushResponseHandler=this.handleUePushResponse.bind(this);let n=new Li().withConfig(e).withOptions({videoElementParent:t?.videoElementParent}).build();this.resolvedConfig=n.config,this.agentBridgeOptions=t?.agentBridge,this.eventBus=n.eventBus,this.qosMonitor=n.qosMonitor,this.session=n.session,this.authWorkflow=n.authWorkflow,this.connectionManager=n.connectionManager,this.loadingProgressController=n.loadingProgress,this.engineStatusCollector=n.engineStatus,this.networkAdaptation=n.networkAdaptation,this.networkDiagnosticsPanel=n.networkDiagnosticsPanel,this.popupManager=n.popupManager,n.connectionLifecycle.bind({connect:this.connect.bind(this),disconnect:()=>this.disconnectAndWait(),reconnect:this.restart.bind(this)});let r=n.loggerManager.child(`Core`),i=this.resolvedConfig;this.uePushEventNames=new Set([this.Events.MapLoaded,this.Events.ModelClick,this.Events.ModelUpdate,this.Events.CameraHeight,this.Events.LeftClick,this.Events.LeftDoubleClick,this.Events.LeftLongPressed,this.Events.RightClick,this.Events.RightDoubleClick,this.Events.RightLongPressed,this.Events.SceneConfig,this.Events.ModelTrigger,this.Events.SyncPops,this.Events.LoadMQTTDataFinished,this.Events.LoadMQTTDataProgress,this.Events.NetworkDiagnosticsUpdated,this.Events.TrainsVisible,this.Events.TrainsInfo]),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),i.viewMode===`cs`?this.loadingProgressController.show(b.SourcePreparing,`SourcePreparing`):this.loadingProgressController.show(b.EngineIniting,`EngineIniting`),this.mountApiFacade(n.apiFacade),this.BuildingFloor=n.buildingFloor,this.networkAdaptation.start(),this.networkDiagnosticsPanel.update(this.networkAdaptation.getDiagnosticsSnapshot()),this.initializeOptionalRuntimeExtensions(),this.setupEventListeners(r),this.bootstrapPromise=this.startAuthFlowWithQos().catch(e=>(r.error(`auto auth bootstrap failed`,{error:p(e)}),this.authWorkflow.getSnapshot()))}setupEventListeners(e){this.session.getForwardEvents().forEach(t=>{this.session.addEventListener(t,n=>{(t===`webRtcConnecting`||t===`webRtcDisconnected`||t===`webRtcFailed`)&&(this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime()),t===`webRtcConnected`&&(this.connectionManager.markConnected(),this.loadingProgressController.show(b.EngineConnectionSuccess,`EngineConnectionSuccess`,!1)),(t===`webRtcDisconnected`||t===`subscribeFailed`)&&this.loadingProgressController.show(b.EngineClose,`EngineClose`,!0),t===`streamerAssigned`&&(this.connectionManager.hasConnectedBefore()?(this.loadingProgressController.show(b.EngineConnectionSuccess,`EngineConnectionSuccess`,!1),e.info(`streamerAssigned during reconnect, showing success progress`)):e.info(`streamerAssigned during initial connect, skip progress (will show on webRtcConnected)`)),this.handleSessionForwardEventForQos(t),e.debug(`forward event`,{eventName:t}),this.eventBus.emit(t,n)})}),this.authWorkflow.on(`stateChanged`,t=>{this.handleAuthStateForQos(t.state),e.debug(`auth state changed`,{state:t.state}),this.eventBus.emit(this.Events.AuthStateChanged,t);let n=Ri[t.state];n&&this.eventBus.emit(n,t)}),this.authWorkflow.on(`progress`,e=>{this.handleProgressNotice(e)}),this.authWorkflow.on(`centerEvent`,({eventName:e,payload:t})=>{this.handleCenterEventForQos(e),this.eventBus.emit(e,t)}),this.authWorkflow.on(`failed`,t=>{let n=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_failed`,stage:`auth`,status:`failed`,durationMs:n,errorCode:t.lastError?.code,errorMessage:t.lastError?.message}),e.error(`auth workflow failed`,{error:t.lastError?JSON.stringify(t.lastError):`unknown`}),this.eventBus.emit(this.Events.SessionModeFailed,{mode:this.session.getViewMode(),snapshot:t})}),this.authWorkflow.on(`connected`,e=>{let t=this.durationFrom(this.authStartedAt);this.authStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_success`,stage:`auth`,status:`success`,durationMs:t}),this.eventBus.emit(this.Events.SessionModeReady,{mode:this.session.getViewMode(),snapshot:e})})}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}whenReady(){return this.bootstrapPromise}setNetworkAdaptationMode(e){this.handleNetworkModeChange(e)}setNetworkManualLevel(e){this.handleNetworkModeChange(`manual`),this.networkAdaptation.setManualLevel(e)}getNetworkDiagnosticsSnapshot(){return this.latestNetworkDiagnostics??this.networkAdaptation.getDiagnosticsSnapshot()}async disconnectAndWait(){this.connectionManager.getStatus().disconnected||(this.qosMonitor.endSession({reason:`disconnect`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,removeListener:!0}),await this.connectionManager.disconnect())}disconnect(){this.disconnectAndWait()}async connect(){return this.connectionManager.getStatus().disconnected?(await this.connectionManager.prepareConnectAfterDisconnect(),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`connect`}),this.startAuthFlowWithQos()):this.authWorkflow.getSnapshot()}async restart(){return this.qosMonitor.endSession({reason:`restart`}),this.stopRuntimeForLifecycle({disconnectAuth:!1,stopAgentBridge:!1,removeListener:!0}),this.session.addResponseEventListener(this.uePushResponseListenerName,this.uePushResponseHandler),this.initializeOptionalRuntimeExtensions(),this.qosMonitor.startSession({reason:`restart`}),this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.restart()}startAuthFlowWithQos(){return this.authStartedAt=Date.now(),this.centerConnectStartedAt=void 0,this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`auth_start`,stage:`auth`,status:`start`}),this.connectionManager.connect()}handleSessionForwardEventForQos(e){if(e===`webRtcConnecting`){this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}));return}if(e===`webRtcConnected`){let e=this.durationFrom(this.webrtcConnectStartedAt);this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_connected`,stage:`webrtc`,status:`success`,durationMs:e}),this.qosMonitor.recordEvent({eventName:`first_frame_rendered`,stage:`media`,status:`success`,durationMs:e});return}(e===`webRtcDisconnected`||e===`webRtcFailed`)&&(this.webrtcConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`webrtc_disconnected`,stage:`webrtc`,status:`failed`,attrs:{reason:e}}))}handleAuthStateForQos(e){if(e===`centerConnecting`){this.centerConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`center_connect_start`,stage:`center`,status:`start`});return}if(e===`centerConnected`){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e});return}e===`webrtcConnecting`&&this.webrtcConnectStartedAt===void 0&&(this.webrtcConnectStartedAt=Date.now(),this.qosMonitor.recordEvent({eventName:`webrtc_connect_start`,stage:`webrtc`,status:`start`}))}handleCenterEventForQos(e){if(this.qosMonitor.recordEvent({eventName:`center_message_received`,stage:`center`,status:`update`,attrs:{fn:e}}),e===this.Events.CenterDisconnected){this.qosMonitor.recordEvent({eventName:`center_disconnected`,stage:`center`,status:`failed`,attrs:{reason:e}});return}if(e===this.Events.CenterConnected&&this.centerConnectStartedAt!==void 0){let e=this.durationFrom(this.centerConnectStartedAt);this.centerConnectStartedAt=void 0,this.qosMonitor.recordEvent({eventName:`center_connected`,stage:`center`,status:`success`,durationMs:e})}}durationFrom(e){if(e===void 0)return;let t=Date.now()-e;return Number.isFinite(t)&&t>=0?t:void 0}handleProgressNotice(e){if(e.kind===`tokenWillExpire`){this.loadingProgressController.showTokenWillExpire(e.message,e.key,e.isClose);return}this.loadingProgressController.show(e.message,e.key,e.isClose)}handleNetworkModeChange(e){this.networkAdaptation.setMode(e);let t={mode:e,ts:Date.now(),diagnostics:this.networkAdaptation.getDiagnosticsSnapshot()};this.eventBus.emit(this.Events.NetworkModeChanged,t)}mountApiFacade(e){let t=this;Object.keys(e).forEach(n=>{this.setApiModule(t,e,n)})}setApiModule(e,t,n){e[n]=t[n]}initializeOptionalRuntimeExtensions(){if(this.agentBridge||!this.agentBridgeOptions?.enabled)return;let e={...this.agentBridgeOptions,serverUrl:this.agentBridgeOptions.serverUrl??`ws://127.0.0.1:8787/sdk3-bridge`},t=sr(this,{runtimeName:e.runtimeName,expose:e.expose,metadata:e.metadata,engineConfig:this.resolvedConfig,getAuthSnapshot:()=>this.authWorkflow.getSnapshot(),mockInvoke:e.mockInvoke});this.agentBridge=new fe(t,e),this.agentBridge.start()}stopRuntimeForLifecycle(e){this.PointEditor.cancelPlacement(),this.GizmosTool.resetRuntime(),e?.stopAgentBridge!==!1&&(this.agentBridge?.stop(`disconnect`),this.agentBridge=void 0),e?.removeListener!==!1&&this.session.removeResponseEventListener(this.uePushResponseListenerName),this.engineStatusCollector.stop(),e?.disconnectAuth!==!1&&this.authWorkflow.disconnect(),this.loadingProgressController.dispose(),this.qosMonitor.flush()}handleUePushResponse(e){let t=e,n;try{if(t=JSON.parse(e),typeof t==`object`&&t){let e=t,r=e.uuid??e.fn;typeof r==`string`&&r.length>0&&(n=r)}}catch{}if(n===`PointEditorGizmoEnded`){this.GizmosTool.finishFromEngine();return}!n&&this.uePushEventNames.has(e)&&(n=e),!(!n||!this.uePushEventNames.has(n))&&this.eventBus.emit(n,t)}getEngineConfig(){return this.resolvedConfig}};export{wn as AGENT_BRIDGE_API_METADATA,dn as API_MODULE_KEYS,fe as AgentRuntimeBridge,jt as Animation,Q as ApiRegistryError,Pi as BuildingFloor,$ as BuildingFloorError,Mt as Camera,Nt as Connect,zi as DTCEngine,Pt as Dlss,w as DlssQuality,Re as FilterMode,Ve as GizmoType,Oe as GizmosTool,Ft as HeatMap,It as HighLighterEffect,zt as Layer,Fe as LayerEnum,Bt as Model,Vt as ModelPOI,Ht as ModelTransform,Le as ModelTransformType,Ut as Navigation,Wt as PathPatrol,kt as PendingValidationSchemaMap,Xt as PointEditor,qt as PointIcon,en as Popup,d as SDKValidationError,nn as Scene,tn as Screen,T as ScreenRenderBitratePreset,Me as ScreenRenderBitratePresetOptions,Ie as Season,rn as SpatialQuery,an as TimeLine,ze as TrainBehavior,on as TrainSimulate,sn as UIPOI,Pe as VideoCodeType,ln as WeatherSystem,cn as WebView,un as apiRegistry,Tn as createAgentBridgeMetadata,Oi as createApiFacade,sr as createBridgeRuntime,Mn as getAgentBridgeMethodSchema,kn as isAgentBridgeMethodExposed,On as isAgentBridgeModuleExposed,En as isAgentBridgeModuleName,jn as listAgentBridgeMethods,An as listAgentBridgeModules,Dn as resolveAgentBridgeExposeConfig};