gaesup-world 1.0.21 → 1.0.22

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/network.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react"),be=require("@react-three/fiber"),Me=require("./gaesupStore-2zKBYTYo.cjs"),He=require("three"),Ge=require("./types-DgS5FYTs.cjs"),le=require("./authority-BOPCXUrV.cjs"),o=require("react/jsx-runtime"),H=require("@react-three/drei"),xe=require("@react-three/rapier"),Ye=require("three-stdlib"),Ke=require("./sfe-CpgzdMyB.cjs"),Ue=require("./index-BhSman4a.cjs");require("reflect-metadata");const ze=require("./index-syAx2qzT.cjs"),ve=require("./index-CHoKlv0U.cjs"),Be=require("zustand"),pe=require("./index-CJj-Z7Jr.cjs"),Xe=require("./snapshot-DRqZrbCu.cjs");function Ze(l){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const t in l)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(l,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>l[t]})}}return e.default=l,Object.freeze(e)}const E=Ze(He);class Fe{availableConnections=[];activeConnections=new Map;connectionIdCounter=1;maxPoolSize;defaultOptions;constructor(e=50,t){this.maxPoolSize=e,this.defaultOptions={timeout:3e4,retries:3,bandwidth:1e3,encryption:!1,...t}}createConnection(e,t,n){const s={...this.defaultOptions,...n};return{id:`conn_${this.connectionIdCounter++}`,nodeA:e,nodeB:t,strength:1,latency:Math.random()*50+10,bandwidth:s.bandwidth,status:"establishing",lastActivity:Date.now()}}getConnection(e,t,n){const s={...this.defaultOptions,...n},r=this.availableConnections.pop();if(r)return r.nodeA=e,r.nodeB=t,r.status="establishing",r.strength=1,r.latency=0,r.bandwidth=s.bandwidth,r.lastActivity=Date.now(),this.activeConnections.set(r.id,r),r;const c=this.createConnection(e,t,n);return this.activeConnections.set(c.id,c),c}releaseConnection(e){const t=this.activeConnections.get(e);return t?(this.activeConnections.delete(e),this.resetConnection(t),this.availableConnections.length<this.maxPoolSize&&this.availableConnections.push(t),!0):!1}resetConnection(e){e.nodeA="",e.nodeB="",e.status="disconnected",e.strength=0,e.latency=0,e.lastActivity=0}getActiveConnection(e){return this.activeConnections.get(e)||null}findActiveConnection(e,t){for(const n of this.activeConnections.values())if(n.nodeA===e&&n.nodeB===t||n.nodeA===t&&n.nodeB===e)return n;return null}updateConnectionStatus(e,t){const n=this.activeConnections.get(e);return n?(n.status=t,n.lastActivity=Date.now(),!0):!1}updateConnectionMetrics(e,t){const n=this.activeConnections.get(e);return n?(t.latency!==void 0&&(n.latency=t.latency),t.bandwidth!==void 0&&(n.bandwidth=t.bandwidth),t.strength!==void 0&&(n.strength=t.strength),n.lastActivity=Date.now(),!0):!1}cleanupInactiveConnections(e=3e5){const t=Date.now();let n=0;const s=[];for(const[r,c]of this.activeConnections.entries())t-c.lastActivity>e&&s.push(r);for(const r of s)this.releaseConnection(r)&&n++;return n}getPoolStats(){const e=this.availableConnections.length,t=this.activeConnections.size,n=e+t,s=n>0?t/n:0;return{available:e,active:t,total:n,maxSize:this.maxPoolSize,utilizationRate:s}}clear(){this.activeConnections.clear(),this.availableConnections=[],this.connectionIdCounter=1}disconnectNode(e){let t=0;const n=[];for(const[s,r]of this.activeConnections.entries())(r.nodeA===e||r.nodeB===e)&&n.push(s);return n.forEach(s=>{this.releaseConnection(s),t++}),t}updatePoolSettings(e,t){for(this.maxPoolSize=Math.max(0,e),t&&(this.defaultOptions={...this.defaultOptions,...t});this.availableConnections.length>this.maxPoolSize;)this.availableConnections.pop()}}class he{queues=new Map;maxSize;batchSize;enableBatching;totalSize=0;static prioritiesLowToHigh=["low","normal","high","critical"];static prioritiesHighToLow=["critical","high","normal","low"];constructor(e=1e3,t=10,n=!0){this.maxSize=Math.max(1,e),this.batchSize=t,this.enableBatching=n}getOrCreateQueue(e){const t=this.queues.get(e);if(t)return t;const n={items:[],head:0};return this.queues.set(e,n),n}getQueueSizeInternal(e){return e.items.length-e.head}compactQueueIfNeeded(e){if(e.head!==0){if(e.head>=e.items.length){e.items=[],e.head=0;return}e.head>64&&e.head*2>=e.items.length&&(e.items=e.items.slice(e.head),e.head=0)}}shiftOne(e){if(this.getQueueSizeInternal(e)<=0)return null;const t=e.items[e.head]??null;return e.head+=1,this.totalSize=Math.max(0,this.totalSize-1),this.compactQueueIfNeeded(e),t}enqueue(e){const t=e.priority;for(;this.totalSize>=this.maxSize;)if(!this.evictOne(t))return!1;return this.getOrCreateQueue(t).items.push(e),this.totalSize+=1,!0}evictOne(e){const t=he.prioritiesLowToHigh,n=t.indexOf(e);for(let r=0;r<n;r++){const c=t[r];if(!c)continue;const a=this.queues.get(c);if(a&&this.shiftOne(a))return!0}const s=this.queues.get(e);return!!(s&&this.shiftOne(s))}dequeue(){for(const e of he.prioritiesHighToLow){const t=this.queues.get(e);if(!t)continue;const n=this.shiftOne(t);if(n)return n}return null}dequeueBatch(){if(!this.enableBatching){const t=this.dequeue();return t?[t]:[]}const e=[];for(const t of he.prioritiesHighToLow){if(e.length>=this.batchSize)break;const n=this.queues.get(t);if(!n)continue;const s=this.batchSize-e.length,r=this.getQueueSizeInternal(n),c=Math.min(s,r);for(let a=0;a<c;a++){const p=this.shiftOne(n);if(!p)break;e.push(p)}}return e}getQueueSize(e){const t=this.queues.get(e);return t?this.getQueueSizeInternal(t):0}getTotalSize(){return this.totalSize}clear(){this.queues.clear(),this.totalSize=0}findMessage(e){for(const t of this.queues.values())for(let n=t.head;n<t.items.length;n++){const s=t.items[n];if(s&&s.id===e)return s}return null}removeMessage(e){for(const t of this.queues.values())for(let n=t.head;n<t.items.length;n++){const s=t.items[n];if(!(!s||s.id!==e))return n===t.head?(this.shiftOne(t),!0):(t.items.splice(n,1),this.totalSize=Math.max(0,this.totalSize-1),this.compactQueueIfNeeded(t),!0)}return!1}updateBatchSettings(e,t){this.batchSize=Math.max(1,e),this.enableBatching=t}updateMaxSize(e){for(this.maxSize=Math.max(1,e);this.totalSize>this.maxSize&&this.evictOne("critical"););}getStats(){const e={};for(const[t,n]of this.queues.entries())e[t]=this.getQueueSizeInternal(n);return{totalMessages:this.getTotalSize(),queueSizes:e,maxSize:this.maxSize,batchSize:this.batchSize,enableBatching:this.enableBatching}}}class Oe{nodes=new Map;groups=new Map;eventCallbacks=new Map;performanceMetrics;proximityRange;maxDistance;groupIdCounter=1;maxMessageQueueSize;gridCellSize;grid=new Map;nodeCellKey=new Map;scratchNearbyNodeIds=new Set;scratchDisconnectIds=[];scratchCenter=new E.Vector3;constructor(e=50,t=100,n=200){this.proximityRange=e,this.maxDistance=t,this.maxMessageQueueSize=n,this.gridCellSize=Math.max(1,e),this.performanceMetrics={messagesProcessed:0,averageLatency:0,bandwidth:0,connectionCount:0,errorRate:0,lastUpdate:Date.now()}}registerNode(e,t,n){const s=`node_${e}`;if(this.nodes.has(s))throw new Error(`Node ${s} is already registered`);const r={id:s,npcId:e,position:t.clone(),connections:new Set,messageQueue:[],lastUpdate:Date.now(),status:"active",communicationRange:n?.communicationRange||this.proximityRange,signalStrength:n?.signalStrength||1};return this.nodes.set(s,r),this.addToGrid(s,r.position),this.emitEvent({type:"nodeConnected",nodeId:s,data:{npcId:e,position:t},timestamp:Date.now()}),r}unregisterNode(e){const t=`node_${e}`;return this.nodes.get(t)?(this.disconnectAllConnections(t),this.leaveAllGroups(t),this.nodes.delete(t),this.removeFromGrid(t),this.emitEvent({type:"nodeDisconnected",nodeId:t,data:{npcId:e},timestamp:Date.now()}),!0):!1}updateNodePosition(e,t){const n=`node_${e}`,s=this.nodes.get(n);return s?(s.position.copy(t),s.lastUpdate=Date.now(),this.updateGridPosition(n,s.position),this.updateProximityConnections(n),!0):!1}connectNodes(e,t){const n=`node_${e}`,s=`node_${t}`,r=this.nodes.get(n),c=this.nodes.get(s);if(!r||!c)return!1;const a=this.maxDistance*this.maxDistance;return r.position.distanceToSquared(c.position)>a?!1:(r.connections.add(s),c.connections.add(n),this.performanceMetrics.connectionCount=this.getTotalConnections(),!0)}disconnectNodes(e,t){const n=`node_${e}`,s=`node_${t}`,r=this.nodes.get(n),c=this.nodes.get(s);return!r||!c?!1:(r.connections.delete(s),c.connections.delete(n),this.performanceMetrics.connectionCount=this.getTotalConnections(),!0)}disconnectAllConnections(e){const t=this.nodes.get(e);if(t){for(const n of t.connections){const s=this.nodes.get(n);s&&s.connections.delete(e)}t.connections.clear()}}updateProximityConnections(e){const t=this.nodes.get(e);if(!t)return;const n=(c,a)=>{const p=Math.min(c.communicationRange,a.communicationRange);return c.position.distanceToSquared(a.position)<=p*p},s=this.scratchDisconnectIds;s.length=0;for(const c of t.connections){const a=this.nodes.get(c);if(!a){s.push(c);continue}n(t,a)||s.push(c)}for(const c of s){t.connections.delete(c);const a=this.nodes.get(c);a&&a.connections.delete(e)}const r=this.getNearbyNodeIds(t,this.scratchNearbyNodeIds);for(const c of r){if(e===c||t.connections.has(c))continue;const a=this.nodes.get(c);a&&n(t,a)&&(t.connections.add(c),a.connections.add(e))}}resolveNodeId(e){return e.startsWith("node_")?e:`node_${e}`}getCellKey(e){const t=this.gridCellSize,n=Math.floor(e.x/t),s=Math.floor(e.z/t);return`${n},${s}`}addToGrid(e,t){const n=this.getCellKey(t),s=this.grid.get(n)??new Set;s.add(e),this.grid.set(n,s),this.nodeCellKey.set(e,n)}removeFromGrid(e){const t=this.nodeCellKey.get(e);if(!t)return;const n=this.grid.get(t);n&&(n.delete(e),n.size===0&&this.grid.delete(t)),this.nodeCellKey.delete(e)}updateGridPosition(e,t){const n=this.nodeCellKey.get(e),s=this.getCellKey(t);if(n===s)return;this.removeFromGrid(e);const r=this.grid.get(s)??new Set;r.add(e),this.grid.set(s,r),this.nodeCellKey.set(e,s)}collectNearbyNodeIdsByPosition(e,t,n){n.clear();const s=this.gridCellSize,r=Math.max(1,Math.ceil(Math.max(1,t)/s)),c=Math.floor(e.x/s),a=Math.floor(e.z/s);for(let p=-r;p<=r;p++)for(let u=-r;u<=r;u++){const y=`${c+p},${a+u}`,C=this.grid.get(y);C&&C.forEach(b=>n.add(b))}}getNearbyNodeIds(e,t){const n=t??new Set;return this.collectNearbyNodeIdsByPosition(e.position,e.communicationRange,n),n}enqueueMessage(e,t){e.messageQueue.length>=this.maxMessageQueueSize&&e.messageQueue.shift(),e.messageQueue.push(t)}sendMessage(e){return this.nodes.get(this.resolveNodeId(e.from))?e.to==="broadcast"?this.broadcastMessage(e):e.to==="group"&&e.groupId?this.sendGroupMessage(e):this.sendDirectMessage(e):!1}sendDirectMessage(e){const t=e.to.startsWith("node_")?e.to:`node_${e.to}`,n=this.nodes.get(t);if(!n)return!1;this.enqueueMessage(n,e);const s=Date.now();return this.performanceMetrics.messagesProcessed++,this.performanceMetrics.lastUpdate=s,this.emitEvent({type:"messageReceived",nodeId:t,data:e,timestamp:s}),!0}broadcastMessage(e){let t=0;const n=this.resolveNodeId(e.from);for(const r of this.nodes.values()){if(r.id===n)continue;const c={...e,to:r.id};this.enqueueMessage(r,c),t++}const s=Date.now();return this.performanceMetrics.messagesProcessed+=t,this.performanceMetrics.lastUpdate=s,t>0}sendGroupMessage(e){if(!e.groupId)return!1;const t=this.groups.get(e.groupId);if(!t)return!1;let n=0;const s=this.resolveNodeId(e.from);for(const c of t.members){if(c===s)continue;const a=this.nodes.get(c);if(a){const p={...e,to:c};this.enqueueMessage(a,p),n++}}const r=Date.now();return this.performanceMetrics.messagesProcessed+=n,this.performanceMetrics.lastUpdate=r,n>0}getMessages(e){const t=`node_${e}`,n=this.nodes.get(t);if(!n)return[];const s=[...n.messageQueue];return n.messageQueue=[],s}createGroup(e,t){const n=`group_${this.groupIdCounter++}`,s={id:n,type:e,members:new Set,maxMembers:t?.maxMembers||(e==="party"?8:e==="guild"?100:20),range:t?.range||(e==="proximity"?30:1e3),persistent:t?.persistent!==void 0?t.persistent:e==="guild",createdAt:Date.now(),lastActivity:Date.now()};return this.groups.set(n,s),s}joinGroup(e,t){const n=`node_${e}`,s=this.nodes.get(n),r=this.groups.get(t);return!s||!r||r.members.size>=r.maxMembers?!1:(r.members.add(n),r.lastActivity=Date.now(),this.emitEvent({type:"groupJoined",nodeId:n,data:{groupId:t},timestamp:Date.now()}),!0)}leaveGroup(e,t){const n=`node_${e}`,s=this.groups.get(t);return!s||!s.members.has(n)?!1:(s.members.delete(n),s.lastActivity=Date.now(),!s.persistent&&s.members.size===0&&this.groups.delete(t),this.emitEvent({type:"groupLeft",nodeId:n,data:{groupId:t},timestamp:Date.now()}),!0)}leaveAllGroups(e){for(const[t,n]of this.groups.entries())n.members.has(e)&&(n.members.delete(e),!n.persistent&&n.members.size===0&&this.groups.delete(t))}updateProximityGroups(){const e=this.scratchCenter,t=this.scratchNearbyNodeIds;for(const n of this.groups.values()){if(n.type!=="proximity"||n.members.size===0||n.range<=0)continue;let s=0,r=0,c=0,a=0;for(const u of n.members){const y=this.nodes.get(u);y&&(s+=y.position.x,r+=y.position.y,c+=y.position.z,a+=1)}if(a===0)continue;e.set(s/a,r/a,c/a),this.collectNearbyNodeIdsByPosition(e,n.range,t);const p=n.range*n.range;for(const u of t){if(n.members.size>=n.maxMembers)break;if(n.members.has(u))continue;const y=this.nodes.get(u);if(!y)continue;const C=y.position.x-e.x,b=y.position.y-e.y,R=y.position.z-e.z;C*C+b*b+R*R<=p&&n.members.add(u)}}}addEventListener(e,t){this.eventCallbacks.has(e)||this.eventCallbacks.set(e,[]),this.eventCallbacks.get(e).push(t)}removeEventListener(e,t){const n=this.eventCallbacks.get(e);if(n){const s=n.indexOf(t);s!==-1&&n.splice(s,1)}}emitEvent(e){const t=this.eventCallbacks.get(e.type);t&&t.forEach(n=>{try{n(e)}catch(s){console.error("Error in event callback:",s)}})}getTotalConnections(){let e=0;for(const t of this.nodes.values())e+=t.connections.size;return e/2}getPerformanceMetrics(){return{...this.performanceMetrics}}getNode(e){const t=`node_${e}`;return this.nodes.get(t)||null}getAllNodes(){return Array.from(this.nodes.values())}forEachNode(e){for(const t of this.nodes.values())e(t)}getGroup(e){return this.groups.get(e)||null}getAllGroups(){return Array.from(this.groups.values())}forEachGroup(e){for(const t of this.groups.values())e(t)}clear(){this.nodes.clear(),this.groups.clear(),this.eventCallbacks.clear(),this.grid.clear(),this.nodeCellKey.clear(),this.performanceMetrics={messagesProcessed:0,averageLatency:0,bandwidth:0,connectionCount:0,errorRate:0,lastUpdate:Date.now()},this.groupIdCounter=1}updateSettings(e,t){e!==void 0&&(this.proximityRange=Math.max(0,e)),t!==void 0&&(this.maxDistance=Math.max(0,t))}getNetworkStats(){const e=this.nodes.size,t=this.getTotalConnections(),n=this.groups.size,s=e>0?t/e:0;let r=0;for(const c of this.nodes.values())r+=c.messageQueue.length;return{nodeCount:e,connectionCount:t,groupCount:n,averageConnections:s,totalMessages:r}}}class _e{state;npcManager;messageQueue;connectionPool;config;lastCleanupTime=0;lastStatsUpdateAt=0;updateTimer;scratchNodeIds=new Set;scratchGroupIds=new Set;scratchRemoveIds=[];messageQueueSig=new Map;constructor(e){this.config={...e},this.npcManager=new Oe(e.proximityRange,e.maxDistance),this.messageQueue=new he(e.messageQueueSize,e.batchSize,e.enableBatching),this.connectionPool=new Fe(e.connectionPoolSize),this.state={nodes:new Map,connections:new Map,groups:new Map,messageQueues:new Map,stats:{totalNodes:0,activeConnections:0,messagesPerSecond:0,averageLatency:0,bandwidth:0,lastUpdate:Date.now()},isRunning:!1,lastUpdate:Date.now()}}start(){this.state.isRunning||(this.state.isRunning=!0,this.lastCleanupTime=Date.now(),this.startUpdateLoop())}stop(){this.state.isRunning&&(this.state.isRunning=!1,this.updateTimer&&(clearTimeout(this.updateTimer),this.updateTimer=void 0))}startUpdateLoop(){this.updateTimer&&clearTimeout(this.updateTimer);const e=Math.max(1,this.config.updateFrequency),t=Math.max(1,Math.floor(1e3/e));let n=Date.now()+t;const s=()=>{if(!this.state.isRunning)return;this.update();const r=Date.now();n+=t,n<r&&(n=r+t);const c=Math.max(0,n-Date.now());this.updateTimer=setTimeout(s,c)};this.updateTimer=setTimeout(s,t)}update(){if(!this.state.isRunning)return;const e=Date.now();this.processMessageBatch(),this.npcManager.updateProximityGroups(),e-this.lastCleanupTime>=this.config.connectionTimeout&&(this.connectionPool.cleanupInactiveConnections(this.config.connectionTimeout),this.lastCleanupTime=e),this.updateStatistics(e),this.syncState(),this.state.lastUpdate=e}processMessageBatch(){const e=this.messageQueue.dequeueBatch();for(const t of e)try{this.npcManager.sendMessage(t)}catch(n){console.error("Error processing message:",n)}}updateStatistics(e){const t=Math.max(0,this.config.debugUpdateInterval??250);if(t>0&&e-this.lastStatsUpdateAt<t)return;this.lastStatsUpdateAt=e;const n=this.npcManager.getNetworkStats(),s=this.npcManager.getPerformanceMetrics();this.state.stats={totalNodes:n.nodeCount,activeConnections:n.connectionCount,messagesPerSecond:this.calculateMessagesPerSecond(s),averageLatency:s.averageLatency,bandwidth:s.bandwidth,lastUpdate:e}}calculateMessagesPerSecond(e){const t=(Date.now()-e.lastUpdate)/1e3,n=Math.max(.001,t);return e.messagesProcessed/n}syncState(){const e=this.scratchNodeIds;e.clear(),this.npcManager.forEachNode(s=>{e.add(s.id),this.state.nodes.set(s.id,s)});const t=this.scratchRemoveIds;t.length=0;for(const s of this.state.nodes.keys())e.has(s)||t.push(s);for(const s of t)this.state.nodes.delete(s);const n=this.scratchGroupIds;n.clear(),this.npcManager.forEachGroup(s=>{n.add(s.id),this.state.groups.set(s.id,s)}),t.length=0;for(const s of this.state.groups.keys())n.has(s)||t.push(s);for(const s of t)this.state.groups.delete(s);for(const s of e){const r=this.state.nodes.get(s);if(!r||r.messageQueue.length===0){this.state.messageQueues.delete(s),this.messageQueueSig.delete(s);continue}const c=r.messageQueue,a=c[c.length-1]?.id??null,p=this.messageQueueSig.get(s);p&&p.len===c.length&&p.tailId===a||(p?(p.len=c.length,p.tailId=a):this.messageQueueSig.set(s,{len:c.length,tailId:a}),this.state.messageQueues.set(s,c.slice()))}t.length=0;for(const s of this.state.messageQueues.keys())e.has(s)||t.push(s);for(const s of t)this.state.messageQueues.delete(s),this.messageQueueSig.delete(s)}executeCommand(e){try{switch(e.type){case"registerNPC":return this.registerNPC(e.npcId,e.position,e.options),!0;case"unregisterNPC":return this.unregisterNPC(e.npcId);case"updateNPCPosition":return this.updateNPCPosition(e.npcId,e.position);case"connect":return this.npcManager.connectNodes(e.npcId,e.targetId);case"disconnect":return e.targetId?this.npcManager.disconnectNodes(e.npcId,e.targetId):this.npcManager.unregisterNode(e.npcId);case"sendMessage":return this.messageQueue.enqueue(e.message),!0;case"broadcast":const t={...e.message,to:"broadcast"};return this.messageQueue.enqueue(t),!0;case"joinGroup":return this.npcManager.joinGroup(e.npcId,e.groupId);case"leaveGroup":return this.npcManager.leaveGroup(e.npcId,e.groupId);case"createGroup":return!!this.npcManager.createGroup(e.group.type,{maxMembers:e.group.maxMembers,range:e.group.range,persistent:e.group.persistent});case"updateSettings":return this.updateConfig(e.settings),!0;case"updateConfig":return this.updateConfig(e.data.config),!0;case"startMonitoring":return!0;case"stopMonitoring":return!0;default:return console.warn("Unknown network command:",e),!1}}catch(t){return console.error("Error executing network command:",t),!1}}createSnapshot(){return{nodeCount:this.state.stats.totalNodes,connectionCount:this.state.stats.activeConnections,activeGroups:this.state.groups.size,messagesPerSecond:this.state.stats.messagesPerSecond,averageLatency:this.state.stats.averageLatency,lastUpdate:this.state.lastUpdate}}updateConfig(e){this.config={...this.config,...e},(e.messageQueueSize||e.batchSize||e.enableBatching)&&(this.messageQueue.updateBatchSettings(this.config.batchSize,this.config.enableBatching),this.messageQueue.updateMaxSize(this.config.messageQueueSize)),e.connectionPoolSize&&this.connectionPool.updatePoolSettings(this.config.connectionPoolSize),(e.proximityRange||e.maxDistance)&&this.npcManager.updateSettings(this.config.proximityRange,this.config.maxDistance),e.updateFrequency&&this.state.isRunning&&this.startUpdateLoop()}registerNPC(e,t,n){return this.npcManager.registerNode(e,t,n)}unregisterNPC(e){return this.npcManager.unregisterNode(e)}updateNPCPosition(e,t){return this.npcManager.updateNodePosition(e,t)}getMessages(e){return this.npcManager.getMessages(e)}getState(){return{...this.state}}getConfig(){return{...this.config}}dispose(){this.stop(),this.npcManager.clear(),this.messageQueue.clear(),this.connectionPool.clear(),this.state.nodes.clear(),this.state.connections.clear(),this.state.groups.clear(),this.state.messageQueues.clear()}addEventListener(e,t){this.npcManager.addEventListener(e,t)}removeEventListener(e,t){this.npcManager.removeEventListener(e,t)}getDebugInfo(){return{isRunning:this.state.isRunning,config:this.config,stats:this.state.stats,networkStats:this.npcManager.getNetworkStats(),performanceMetrics:this.npcManager.getPerformanceMetrics(),poolStats:this.connectionPool.getPoolStats(),messageQueueStats:this.messageQueue.getStats()}}}const et=l=>typeof l!="object"||l===null?!1:"text"in l&&typeof l.text=="function";class Ne{ws=null;url;roomId;playerName;playerColor;players=new Map;localPlayerId=null;isConnected=!1;isConnecting=!1;logLevel;logToConsole;reconnectAttemptsMax;reconnectDelayMs;reconnectAttemptsUsed=0;reconnectTimer=null;shouldReconnect=!1;pingIntervalMs;pingTimer=null;lastPingSentAt=0;updateRateLimitMs;lastUpdateSentAt=0;pendingUpdate=null;updateFlushTimer=null;offlineQueueSize;pendingChats=[];enableAck;reliableTimeoutMs;reliableRetryCount;ackIdCounter=1;pendingAcks=new Map;onConnect;onDisconnect;onWelcome;onPlayerJoin;onPlayerUpdate;onPlayerLeave;onChat;onPing;onReliableFailed;onError;constructor(e){this.url=e.url,this.roomId=e.roomId,this.playerName=e.playerName,this.playerColor=e.playerColor,this.reconnectAttemptsMax=Math.max(0,Math.floor(e.reconnectAttempts??0)),this.reconnectDelayMs=Math.max(0,Math.floor(e.reconnectDelay??1e3)),this.pingIntervalMs=Math.max(0,Math.floor(e.pingInterval??0)),this.updateRateLimitMs=Math.max(0,Math.floor(e.sendRateLimit??0)),this.offlineQueueSize=Math.max(0,Math.floor(e.offlineQueueSize??50)),this.enableAck=!!e.enableAck,this.reliableTimeoutMs=Math.max(0,Math.floor(e.reliableTimeout??5e3)),this.reliableRetryCount=Math.max(0,Math.floor(e.reliableRetryCount??0)),this.logLevel=e.logLevel??"none",this.logToConsole=e.logToConsole??!1,e.onConnect&&(this.onConnect=e.onConnect),e.onDisconnect&&(this.onDisconnect=e.onDisconnect),e.onWelcome&&(this.onWelcome=e.onWelcome),e.onPlayerJoin&&(this.onPlayerJoin=e.onPlayerJoin),e.onPlayerUpdate&&(this.onPlayerUpdate=e.onPlayerUpdate),e.onPlayerLeave&&(this.onPlayerLeave=e.onPlayerLeave),e.onChat&&(this.onChat=e.onChat),e.onPing&&(this.onPing=e.onPing),e.onReliableFailed&&(this.onReliableFailed=e.onReliableFailed),e.onError&&(this.onError=e.onError)}shouldLog(e){if(!this.logToConsole)return!1;const t={none:0,error:1,warn:2,info:3,debug:4};return t[e]<=t[this.logLevel]}debug(e,...t){this.shouldLog("debug")&&console.log(e,...t)}info(e,...t){this.shouldLog("info")&&console.info(e,...t)}warn(e,...t){this.shouldLog("warn")&&console.warn(e,...t)}error(e,...t){this.shouldLog("error")&&console.error(e,...t)}getConnectionStatus(){return this.isConnected}connect(){if(this.ws&&this.ws.readyState===WebSocket.OPEN){this.warn("[PlayerNetworkManager] Already connected");return}if(this.ws&&this.ws.readyState===WebSocket.CONNECTING){this.warn("[PlayerNetworkManager] Already connecting");return}if(this.isConnecting){this.warn("[PlayerNetworkManager] Already connecting");return}this.shouldReconnect=this.reconnectAttemptsMax>0,this.clearReconnectTimer(),this.isConnecting=!0,this.info("[PlayerNetworkManager] Connecting WebSocket",this.url);let e;try{e=new WebSocket(this.url)}catch{this.isConnecting=!1,this.isConnected=!1,this.onError?.("WebSocket 연결 실패");return}this.ws=e,e.onopen=()=>{this.info("[PlayerNetworkManager] WebSocket connected"),this.isConnected=!0,this.isConnecting=!1,this.reconnectAttemptsUsed=0,this.startPingLoop(),e.send(JSON.stringify({type:"Join",room_id:this.roomId,name:this.playerName,color:this.playerColor})),this.flushOfflineQueue(),this.resumePendingAcks(),this.onConnect&&this.onConnect()},e.onmessage=t=>{const n=r=>{try{const c=JSON.parse(r);this.handleServerMessage(c)}catch{this.onError?.("서버 메시지 파싱 실패")}},s=t.data;if(typeof s=="string"){n(s);return}if(et(s)){s.text().then(r=>n(r)).catch(()=>this.onError?.("서버 메시지 수신 실패"));return}if(s instanceof ArrayBuffer)try{const r=new TextDecoder().decode(new Uint8Array(s));n(r)}catch{this.onError?.("서버 메시지 디코딩 실패")}},e.onerror=t=>{this.error("[PlayerNetworkManager] WebSocket error",t),this.isConnected=!1,this.isConnecting=!1,this.onError&&this.onError("WebSocket 연결 에러")},e.onclose=t=>{this.info("[PlayerNetworkManager] WebSocket closed",{code:t.code,reason:t.reason});const n=this.isConnected||this.isConnecting;this.isConnected=!1,this.isConnecting=!1,this.stopPingLoop(),this.pausePendingAcks(),this.players.clear(),this.localPlayerId=null,this.onDisconnect&&this.onDisconnect(),(t.code===1e3||t.code===1001)&&(this.shouldReconnect=!1),n&&this.tryReconnect()}}disconnect(){if(this.shouldReconnect=!1,this.clearReconnectTimer(),this.stopPingLoop(),this.clearUpdateFlushTimer(),this.clearAllPendingAcks(!0),!this.ws){this.players.clear(),this.isConnected=!1,this.isConnecting=!1,this.localPlayerId=null,this.onDisconnect?.();return}const e=this.ws;if(e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null,e.readyState===WebSocket.OPEN)try{e.send(JSON.stringify({type:"Leave"}))}catch{}try{e.close()}catch{}this.ws=null,this.players.clear(),this.isConnected=!1,this.isConnecting=!1,this.localPlayerId=null,this.pendingUpdate=null,this.pendingChats=[],this.onDisconnect?.()}updateLocalPlayer(e){this.pendingUpdate=this.pendingUpdate?{...this.pendingUpdate,...e}:{...e};const t=this.ws;if(!t||t.readyState!==WebSocket.OPEN)return;const n=Date.now();if(this.updateRateLimitMs<=0||n-this.lastUpdateSentAt>=this.updateRateLimitMs){this.lastUpdateSentAt=n;const r=this.pendingUpdate;if(this.pendingUpdate=null,!r)return;t.send(JSON.stringify({type:"Update",state:r}));return}if(this.updateFlushTimer)return;const s=Math.max(0,this.updateRateLimitMs-(n-this.lastUpdateSentAt));this.updateFlushTimer=setTimeout(()=>{this.updateFlushTimer=null;const r=this.pendingUpdate;r&&this.updateLocalPlayer(r)},s)}sendChat(e,t){const n=String(e??"").trim().slice(0,200);if(!n)return;const s=this.ws;if(!s||s.readyState!==WebSocket.OPEN){if(this.offlineQueueSize<=0)return;this.pendingChats.length>=this.offlineQueueSize&&this.pendingChats.shift(),t?.range!==void 0?this.pendingChats.push({text:n,range:t.range}):this.pendingChats.push({text:n});return}const r={type:"Chat",text:n,...t?.range!==void 0?{range:t.range}:{}};if(this.enableAck){this.sendReliable(r);return}s.send(JSON.stringify(r))}handleServerMessage(e){switch(this.debug("[PlayerNetworkManager] Server message",e.type,e),e.type){case"Ack":{typeof e.ackId=="string"&&e.ackId&&this.ackReceived(e.ackId);break}case"Pong":{if(typeof e.ts=="number"&&e.ts>0){const t=Math.max(0,Date.now()-e.ts);this.onPing?.(t)}else if(this.lastPingSentAt>0){const t=Math.max(0,Date.now()-this.lastPingSentAt);this.onPing?.(t)}break}case"Welcome":if(this.localPlayerId=e.client_id,this.onWelcome?.(this.localPlayerId,e.room_state),e.room_state)for(const[t,n]of Object.entries(e.room_state))t!==this.localPlayerId&&(this.players.set(t,n),this.onPlayerJoin&&this.onPlayerJoin(t,n));break;case"PlayerJoined":this.debug("[PlayerNetworkManager] PlayerJoined",e.client_id),e.client_id!==this.localPlayerId&&(this.players.set(e.client_id,e.state),this.onPlayerJoin&&this.onPlayerJoin(e.client_id,e.state));break;case"PlayerLeft":this.debug("[PlayerNetworkManager] PlayerLeft",e.client_id),this.players.delete(e.client_id),this.onPlayerLeave&&this.onPlayerLeave(e.client_id);break;case"PlayerUpdate":this.debug("[PlayerNetworkManager] PlayerUpdate",e.client_id);{const t=this.players.get(e.client_id);if(t){const r={...t,...e.state};this.players.set(e.client_id,r),this.onPlayerUpdate?.(e.client_id,r);break}const n=e.state,s={name:n?.name??"Player",color:n?.color??"#ffffff",position:n?.position??[0,0,0],rotation:n?.rotation??[1,0,0,0],...n??{}};this.players.set(e.client_id,s),this.onPlayerJoin?.(e.client_id,s),this.onPlayerUpdate?.(e.client_id,s)}break;case"Chat":this.onChat?.(e.client_id,e.text,e.timestamp);break}}setCallbacks(e){e.onConnect&&(this.onConnect=e.onConnect),e.onDisconnect&&(this.onDisconnect=e.onDisconnect),e.onWelcome&&(this.onWelcome=e.onWelcome),e.onPlayerJoin&&(this.onPlayerJoin=e.onPlayerJoin),e.onPlayerUpdate&&(this.onPlayerUpdate=e.onPlayerUpdate),e.onPlayerLeave&&(this.onPlayerLeave=e.onPlayerLeave),e.onChat&&(this.onChat=e.onChat),e.onPing&&(this.onPing=e.onPing),e.onReliableFailed&&(this.onReliableFailed=e.onReliableFailed),e.onError&&(this.onError=e.onError)}getPlayers(){return new Map(this.players)}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}startPingLoop(){this.pingIntervalMs<=0||(this.stopPingLoop(),this.pingTimer=setInterval(()=>{const e=this.ws;if(!e||e.readyState!==WebSocket.OPEN)return;const t=Date.now();this.lastPingSentAt=t;try{e.send(JSON.stringify({type:"Ping",ts:t}))}catch{}},this.pingIntervalMs))}stopPingLoop(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null)}clearUpdateFlushTimer(){this.updateFlushTimer&&(clearTimeout(this.updateFlushTimer),this.updateFlushTimer=null)}flushOfflineQueue(){const e=this.ws;if(!(!e||e.readyState!==WebSocket.OPEN)){if(this.pendingChats.length>0){const t=this.pendingChats;this.pendingChats=[];for(const n of t)try{const s={type:"Chat",text:n.text,...n.range!==void 0?{range:n.range}:{}};this.enableAck?this.sendReliable(s):e.send(JSON.stringify(s))}catch{this.offlineQueueSize>0&&(this.pendingChats=t.slice(t.indexOf(n)));break}}if(this.pendingUpdate){const t=this.pendingUpdate;this.pendingUpdate=null,this.updateLocalPlayer(t)}}}tryReconnect(){if(!this.shouldReconnect||this.reconnectAttemptsMax<=0||this.reconnectAttemptsUsed>=this.reconnectAttemptsMax||this.isConnecting)return;const e=this.reconnectAttemptsUsed+1,t=this.reconnectDelayMs||0,n=Math.min(3e4,Math.floor(t*Math.pow(2,this.reconnectAttemptsUsed)));this.reconnectAttemptsUsed=e,this.warn("[PlayerNetworkManager] Reconnecting...",{attempt:e,delay:n}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.shouldReconnect&&this.connect()},n)}nextAckId(){const e=this.ackIdCounter++;return`ack_${Date.now()}_${e}`}sendReliable(e){const t=this.ws;if(!t||t.readyState!==WebSocket.OPEN)return;const n=this.nextAckId(),s=String(e.type??"Unknown"),r=JSON.stringify({...e,ackId:n});try{t.send(r)}catch{return}this.trackPendingAck({ackId:n,raw:r,messageType:s})}trackPendingAck(e){this.enableAck&&(this.stopAckTimer(e.ackId),this.pendingAcks.set(e.ackId,{raw:e.raw,messageType:e.messageType,retriesLeft:this.reliableRetryCount,timer:null}),this.scheduleAckTimeout(e.ackId))}scheduleAckTimeout(e){if(!this.enableAck)return;const t=this.pendingAcks.get(e);t&&(this.reliableTimeoutMs<=0||(t.timer=setTimeout(()=>{const n=this.pendingAcks.get(e);if(!n)return;const s=this.ws;if(!s||s.readyState!==WebSocket.OPEN){n.timer=null;return}if(n.retriesLeft<=0){this.pendingAcks.delete(e),this.onReliableFailed?.({ackId:e,messageType:n.messageType});return}n.retriesLeft-=1;try{s.send(n.raw)}catch{n.timer=null;return}this.scheduleAckTimeout(e)},this.reliableTimeoutMs)))}stopAckTimer(e){const t=this.pendingAcks.get(e);!t||!t.timer||(clearTimeout(t.timer),t.timer=null)}ackReceived(e){this.pendingAcks.get(e)&&(this.stopAckTimer(e),this.pendingAcks.delete(e))}pausePendingAcks(){for(const[e,t]of this.pendingAcks.entries())t.timer&&(clearTimeout(t.timer),t.timer=null),this.enableAck||this.pendingAcks.delete(e)}resumePendingAcks(){if(!this.enableAck)return;const e=this.ws;if(!(!e||e.readyState!==WebSocket.OPEN))for(const[t,n]of this.pendingAcks.entries()){try{e.send(n.raw)}catch{continue}this.scheduleAckTimeout(t)}}clearAllPendingAcks(e){for(const[t,n]of this.pendingAcks.entries())n.timer&&clearTimeout(n.timer),n.timer=null,e&&this.pendingAcks.delete(t);e&&this.pendingAcks.clear()}}class Qe{lastPosition=new E.Vector3;lastRotation=new E.Quaternion;lastAnimation="idle";velocity=new E.Vector3;lastUpdateTime=0;config;tempPos=new E.Vector3;tempRot=new E.Quaternion;tempSendRot=new E.Quaternion;tempEuler=new E.Euler;baseYaw=null;scratchUpdate={name:"",color:"",position:[0,0,0],rotation:[1,0,0,0],animation:"idle",velocity:[0,0,0]};constructor(e){this.config=e}trackPosition(e,t,n,s,r){if(!e.current)return null;const c=Date.now();if(c-this.lastUpdateTime<this.config.sendRateLimit)return null;const a=e.current.translation(),p=e.current.rotation();this.tempPos.set(a.x,a.y,a.z),this.tempRot.set(p.x,p.y,p.z,p.w);const u=e.current.linvel();if(u)this.velocity.set(u.x,u.y,u.z);else{const T=(c-this.lastUpdateTime)/1e3;T>0&&this.velocity.set((a.x-this.lastPosition.x)/T,(a.y-this.lastPosition.y)/T,(a.z-this.lastPosition.z)/T)}const y=this.velocity.length(),C=typeof r=="string"?r.trim():"",b=this.config.velocityThreshold,R=this.config.velocityThreshold*.6,M=this.lastAnimation==="run"?y<R?"idle":"run":y>b?"run":"idle",S=C.length>0?C:M;this.tempSendRot.copy(this.tempRot);const w=this.velocity.x,d=this.velocity.z;if(Math.hypot(w,d)>.05){this.baseYaw===null&&(this.tempEuler.setFromQuaternion(this.tempRot,"YXZ"),this.baseYaw=this.tempEuler.y+Math.PI);const T=Math.atan2(w,d)+(this.baseYaw??0);this.tempEuler.set(0,T,0,"YXZ"),this.tempSendRot.setFromEuler(this.tempEuler)}const h=!this.lastPosition.equals(this.tempPos),x=!this.lastRotation.equals(this.tempSendRot),m=this.lastAnimation!==S;if(!h&&!x&&!m)return null;const f=this.scratchUpdate;return f.name=t,f.color=n,f.position[0]=a.x,f.position[1]=a.y,f.position[2]=a.z,f.rotation[0]=this.tempSendRot.w,f.rotation[1]=this.tempSendRot.x,f.rotation[2]=this.tempSendRot.y,f.rotation[3]=this.tempSendRot.z,f.animation=S,f.velocity[0]=this.velocity.x,f.velocity[1]=this.velocity.y,f.velocity[2]=this.velocity.z,f.modelUrl=s,this.lastPosition.copy(this.tempPos),this.lastRotation.copy(this.tempSendRot),this.lastAnimation=S,this.lastUpdateTime=c,f}updateConfig(e){this.config={...this.config,...e}}reset(){this.lastPosition.set(0,0,0),this.lastRotation.set(0,0,0,1),this.lastAnimation="idle",this.velocity.set(0,0,0),this.lastUpdateTime=0,this.baseYaw=null}}function ue(l={}){const{systemId:e="main",config:t,enableAutoUpdate:n=!0}=l,s=i.useRef(null),[r,c]=i.useState(null),[a,p]=i.useState(!1);i.useEffect(()=>{s.current||(s.current=Me.BridgeFactory.getOrCreate("networks"));const M=s.current;return M?(e==="main"?M.ensureMainEngine():M.getEngine(e)||M.register(e),t&&Object.keys(t).length>0&&M.execute(e,{type:"updateConfig",data:{config:t}}),c(M),p(!0),()=>{}):(c(null),p(!1),()=>{})},[e,t]),be.useFrame((M,S)=>{n&&s.current&&a&&s.current.updateSystem(e,S)});const u=i.useCallback(M=>{s.current&&a&&s.current.execute(e,M)},[e,a]),y=i.useCallback(()=>s.current&&a?s.current.snapshot(e):null,[e,a]),C=i.useCallback(()=>s.current&&a?s.current.getNetworkStats(e):null,[e,a]),b=i.useCallback(()=>s.current&&a?s.current.getSystemState(e):null,[e,a]),R=i.useCallback(M=>{s.current&&a&&s.current.updateSystem(e,M)},[e,a]);return{bridge:r,executeCommand:u,getSnapshot:y,getNetworkStats:C,getSystemState:b,updateSystem:R,isReady:a}}function tt(l){const{npcId:e,initialOptions:t,...n}=l,{executeCommand:s,getSnapshot:r,isReady:c}=ue(n),a=i.useRef(!1),p=i.useRef(null),u=i.useRef(new Set);i.useEffect(()=>(c&&t&&!a.current&&y(t),()=>{a.current&&C()}),[c,t]);const y=i.useCallback(d=>{!c||a.current||(s({type:"registerNPC",npcId:e,position:d.position,...d.connectionRange!==void 0?{options:{communicationRange:d.connectionRange}}:{}}),a.current=!0,p.current=d.position.clone(),d.autoConnect)},[c,s,e]),C=i.useCallback(()=>{!c||!a.current||(s({type:"unregisterNPC",npcId:e}),a.current=!1,p.current=null,u.current.clear())},[c,s,e]),b=i.useCallback(d=>{!c||!a.current||(s({type:"updateNPCPosition",npcId:e,position:d}),p.current=d.clone())},[c,s,e]),R=i.useCallback((d,k)=>{!c||!a.current||(s({type:"connect",npcId:e,targetId:d}),u.current.add(d))},[c,s,e]),M=i.useCallback(d=>{!c||!a.current||(s({type:"disconnect",npcId:e,targetId:d}),u.current.delete(d))},[c,s,e]),S=i.useCallback(()=>Array.from(u.current),[]),w=i.useCallback(()=>p.current?p.current.clone():null,[]);return{registerNPC:y,unregisterNPC:C,updatePosition:b,connectTo:R,disconnectFrom:M,isRegistered:a.current,getConnections:S,getPosition:w,executeCommand:s,getSnapshot:r,isReady:c}}function nt(l){const{senderId:e,onMessageSent:t,...n}=l,{executeCommand:s,isReady:r}=ue(n),c=500,[a,p]=i.useState([]),[u,y]=i.useState([]),[C,b]=i.useState([]),R=i.useRef(0),M=i.useCallback((x,m,f="chat",T)=>{if(!r)return"";const D=`${e}-${++R.current}-${Date.now()}`,O=Date.now(),B={id:D,from:e,to:x,type:f==="action"||f==="state"||f==="system"?f:"chat",payload:m,priority:T?.priority??"normal",timestamp:O,reliability:T?.reliable?"reliable":"unreliable",...T?.retries!==void 0?{retryCount:T.retries}:{}};return s({type:"sendMessage",message:B}),y(v=>{const z=[...v,B];return z.length>c?z.slice(-c):z}),t?.(B),D},[r,s,e,t]),S=i.useCallback((x,m="chat",f)=>{if(!r)return"";const T=`${e}-broadcast-${++R.current}-${Date.now()}`,D=Date.now(),O={id:T,from:e,type:m==="action"||m==="state"||m==="system"?m:"chat",payload:x,priority:f?.priority??"normal",timestamp:D,reliability:f?.reliable?"reliable":"unreliable",...f?.groupId?{groupId:f.groupId}:{},...f?.retries!==void 0?{retryCount:f.retries}:{}};s({type:"broadcast",message:O});const B={...O,to:"broadcast"};return y(v=>{const z=[...v,B];return z.length>c?z.slice(-c):z}),t?.(B),T},[r,s,e,t]),w=i.useCallback(()=>{p([]),y([]),b([])},[]),d=i.useCallback(x=>x?[...a,...u].filter(m=>m.from===x||m.to===x||m.from===e&&m.to===x||m.to===e&&m.from===x).sort((m,f)=>m.timestamp-f.timestamp):[...a,...u].sort((m,f)=>m.timestamp-f.timestamp),[a,u,e]),k=i.useCallback(x=>[...a,...u].find(m=>m.id===x)||null,[a,u]),h=i.useCallback(()=>({totalSent:u.length,totalReceived:a.length,totalPending:C.length,averageLatency:0}),[u,a,C]);return{sendMessage:M,broadcastMessage:S,receivedMessages:a,sentMessages:u,pendingMessages:C,clearMessages:w,getMessageHistory:d,getMessageById:k,getMessageStats:h,isReady:r}}function st(l){const{npcId:e,onGroupJoined:t,onGroupLeft:n,onGroupMessage:s,onGroupMemberJoined:r,onGroupMemberLeft:c,...a}=l,{executeCommand:p,getSystemState:u,isReady:y}=ue(a),[C,b]=i.useState([]),[R,M]=i.useState([]),[S,w]=i.useState([]),[d,k]=i.useState(new Map),h=i.useRef(0),x=i.useRef(new Map),m=i.useRef(new Set),f=i.useRef([]);f.current=C;const T=i.useRef(new Set),D=i.useRef(""),O=i.useRef(null),B=2e3,v=500;i.useEffect(()=>{if(!y)return;const L=`node_${e}`,_=setInterval(()=>{const U=u();if(!U)return;const Z=Array.from(U.groups.values()),ne=Z.map(q=>`${q.id}:${q.members.size}:${q.lastActivity}`).join("|");if(ne!==D.current){D.current=ne,w(Z);const q=Z.filter(g=>g.members.has(L)).map(g=>g.id);T.current.clear();for(const g of q)T.current.add(g);const se=f.current,I=q.filter(g=>!se.includes(g)),P=se.filter(g=>!q.includes(g));if((I.length>0||P.length>0)&&(b(q),M(q),O.current=null,I.forEach(g=>{const A=Z.find(Q=>Q.id===g);A&&t?.(g,A)}),P.forEach(g=>n?.(g)),P.length>0)){for(const g of P)x.current.delete(g);k(g=>{const A=new Map(g);for(const Q of P)A.delete(Q);return A})}for(const g of Z){const A=new Set(Array.from(g.members).map(j=>j.startsWith("node_")?j.slice(5):j)),Q=x.current.get(g.id);if(Q){for(const j of A)Q.has(j)||r?.(j,g.id);for(const j of Q)A.has(j)||c?.(j,g.id)}x.current.set(g.id,A)}}const ee=U.messageQueues.get(L)??[];if(ee.length===0)return;const fe=ee[ee.length-1]?.id??null,ie=O.current;if(ie&&ie===fe)return;let ae=0;if(ie){for(let q=ee.length-1;q>=0;q--)if(ee[q]?.id===ie){ae=q+1;break}}O.current=fe,!(ae>=ee.length)&&T.current.size!==0&&k(q=>{const se=new Map(q),I=new Set;for(let P=ae;P<ee.length;P++){const g=ee[P];if(!g||g.to!=="group"||!g.groupId||!T.current.has(g.groupId)||m.current.has(g.id))continue;if(m.current.size>=B){const j=Array.from(m.current);m.current=new Set(j.slice(j.length-Math.floor(B/2)))}m.current.add(g.id);const A=se.get(g.groupId),Q=I.has(g.groupId)?A??[]:A?A.slice():[];I.has(g.groupId)||(I.add(g.groupId),se.set(g.groupId,Q)),Q.push(g),s?.(g,g.groupId)}if(I.size===0)return q;for(const P of I){const g=se.get(P);g&&g.length>v&&se.set(P,g.slice(-v))}return se})},250);return()=>clearInterval(_)},[y,u,e,t,n,s,r,c]);const z=i.useCallback((L,_=[],U)=>{if(!y)return;const Z=Date.now();p({type:"createGroup",group:{type:"party",members:new Set,maxMembers:U?.maxSize??20,range:1e3,persistent:!1,createdAt:Z,lastActivity:Z}})},[y,p,e]),N=i.useCallback(L=>{y&&p({type:"joinGroup",npcId:e,groupId:L})},[y,p,e]),G=i.useCallback(L=>{y&&p({type:"leaveGroup",npcId:e,groupId:L})},[y,p,e]),F=i.useCallback((L,_,U="chat")=>{if(!y||!C.includes(L))return"";const Z=`${e}-group-${++h.current}-${Date.now()}`,ne=Date.now();return p({type:"sendMessage",message:{id:Z,from:e,to:"group",groupId:L,type:U==="action"||U==="state"||U==="system"?U:"chat",payload:_,priority:"normal",timestamp:ne,reliability:"reliable"}}),Z},[y,p,e,C]),V=i.useCallback((L,_)=>{if(!y||!R.includes(L))return;const U={id:`invite-${Date.now()}`,from:e,to:_,type:"system",payload:{groupId:L,inviterId:e},priority:"normal",timestamp:Date.now(),reliability:"reliable"};p({type:"sendMessage",message:U})},[y,p,e,R]),Y=i.useCallback((L,_)=>{!y||!R.includes(L)||p({type:"leaveGroup",npcId:_,groupId:L})},[y,p,R]),$=i.useCallback(L=>S.find(_=>_.id===L)||null,[S]),K=i.useCallback(L=>{const _=$(L);return _?Array.from(_.members).map(U=>U.startsWith("node_")?U.slice(5):U):[]},[$]),X=i.useCallback(L=>d.get(L)||[],[d]);return{createGroup:z,joinGroup:N,leaveGroup:G,sendGroupMessage:F,inviteToGroup:V,kickFromGroup:Y,joinedGroups:C,ownedGroups:R,availableGroups:S,getGroupInfo:$,getGroupMembers:K,getGroupMessages:X,isReady:y}}function qe(l={}){const{updateInterval:e=1e3,enableRealTime:t=!0,trackHistory:n=!1,historyLength:s=100,...r}=l,{getSnapshot:c,getNetworkStats:a,getSystemState:p,isReady:u}=ue(r),[y,C]=i.useState(null),[b,R]=i.useState([]),[M,S]=i.useState(!1),[w,d]=i.useState(0),k=i.useCallback(()=>{if(!u)return null;const f=c(),T=a(),D=p();if(!f||!T)return null;const O=f.nodeCount,B=f.connectionCount,v=T.totalMessages??0,z=B,N=0,G=(B>0,100),F=f.messagesPerSecond,V={updateTime:0,messageProcessingTime:0,connectionProcessingTime:0},Y=D?Array.from(D.groups.values()):[],$=D?D.groups.size:f.activeGroups,K=$,X=$>0?Y.reduce((L,_)=>L+_.members.size,0)/$:0;return{totalNodes:O,totalConnections:B,totalMessages:v,averageLatency:f.averageLatency,messagesPerSecond:F,activeConnections:z,failedConnections:N,connectionSuccessRate:G,sentMessages:v,receivedMessages:v,failedMessages:0,messageSuccessRate:100,updateTime:V.updateTime,messageProcessingTime:V.messageProcessingTime,connectionProcessingTime:V.connectionProcessingTime,totalGroups:$,activeGroups:K,averageGroupSize:X}},[u,c,a,p,e]),h=i.useCallback(()=>{S(!0);const f=k();f&&(C(f),d(Date.now()),n&&R(T=>{const D=[...T,f];return D.length>s?D.slice(-s):D})),S(!1)},[k,n,s]);i.useEffect(()=>{if(!t||!u)return;const f=setInterval(()=>{h()},e);return()=>clearInterval(f)},[t,u,h,e]),i.useEffect(()=>{u&&h()},[u,h]);const x=i.useCallback(f=>b.length===0?0:b.reduce((D,O)=>D+O[f],0)/b.length,[b]),m=i.useCallback(f=>b.length===0?0:Math.max(...b.map(T=>T[f])),[b]);return{stats:y,statsHistory:n?b:[],refreshStats:h,getHistoricalAverage:x,getPeakValue:m,isLoading:M,lastUpdate:w,isReady:u}}function ot(l){const[e,t]=i.useState(!1),[n,s]=i.useState(new Map),[r,c]=i.useState(),a=i.useRef(null),p=i.useCallback(C=>{const b={...l,...C};a.current&&a.current.disconnect();const R=new Ne({url:b.url,roomId:b.roomId,playerName:b.playerName,playerColor:b.playerColor,onConnect:()=>{t(!0),c(void 0)},onDisconnect:()=>{t(!1),s(new Map)},onPlayerJoin:(M,S)=>{s(w=>{const d=new Map(w);return d.set(M,S),d})},onPlayerUpdate:(M,S)=>{s(w=>{const d=new Map(w);return d.set(M,S),d})},onPlayerLeave:M=>{s(S=>{const w=new Map(S);return w.delete(M),w})},onError:M=>{c(M)}});a.current=R,R.connect()},[l]),u=i.useCallback(()=>{a.current?.disconnect(),t(!1),s(new Map)},[]),y=i.useCallback(C=>{a.current?.updateLocalPlayer(C)},[]);return i.useEffect(()=>()=>{a.current?.disconnect(),a.current=null},[]),{isConnected:e,players:n,error:r,connect:p,disconnect:u,updateLocalPlayer:y}}function rt(l){const{config:e,characterUrl:t,rigidBodyRef:n}=l,s=Me.useGaesupStore(v=>v.mode?.type??"character"),r=Me.useGaesupStore(v=>v.animationState),[c,a]=i.useState({isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,roomId:null,error:null,ping:0,lastUpdate:0}),p=i.useRef(null),u=i.useRef(null),y=i.useRef(null),C=i.useRef(null),b=i.useRef(e),R=i.useRef(c),M=i.useRef(s),S=i.useRef(r);i.useEffect(()=>{R.current=c},[c]),i.useEffect(()=>{M.current=s},[s]),i.useEffect(()=>{S.current=r},[r]);const[w,d]=i.useState(()=>new Map),k=i.useRef(new Map);i.useEffect(()=>{k.current=w},[w]),i.useEffect(()=>{n&&(C.current=n)},[n]),i.useEffect(()=>{const v={updateRate:e.tracking.updateRate,velocityThreshold:e.tracking.velocityThreshold,sendRateLimit:e.tracking.sendRateLimit};y.current=new Qe(v)},[e.tracking]);const h=i.useCallback(v=>{u.current&&u.current.disconnect(),p.current={playerName:v.playerName,playerColor:v.playerColor},a(N=>({...N,connectionStatus:"connecting",error:null,roomId:v.roomId}));const z=new Ne({url:e.websocket.url,roomId:v.roomId,playerName:v.playerName,playerColor:v.playerColor,reconnectAttempts:e.websocket.reconnectAttempts,reconnectDelay:e.websocket.reconnectDelay,pingInterval:e.websocket.pingInterval,sendRateLimit:e.tracking.sendRateLimit,enableAck:e.enableAck,reliableTimeout:e.reliableTimeout,reliableRetryCount:e.reliableRetryCount,logLevel:e.logLevel,logToConsole:e.logToConsole,onConnect:()=>{a(N=>({...N,isConnected:!0,connectionStatus:"connected",error:null,lastUpdate:Date.now()}))},onWelcome:N=>{a(G=>({...G,localPlayerId:N,lastUpdate:Date.now()}))},onDisconnect:()=>{a(N=>({...N,isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,lastUpdate:Date.now()}))},onPlayerJoin:(N,G)=>{a(F=>{const V=new Map(F.players);return V.set(N,G),{...F,players:V,lastUpdate:Date.now()}})},onPlayerUpdate:(N,G)=>{a(F=>{const V=new Map(F.players);return V.set(N,G),{...F,players:V,lastUpdate:Date.now()}})},onPlayerLeave:N=>{a(G=>{const F=new Map(G.players);return F.delete(N),{...G,players:F,lastUpdate:Date.now()}})},onChat:(N,G,F)=>{d(Y=>{const $=new Map(Y);return $.set(N,{text:G,expiresAt:Date.now()+2500}),$})},onPing:N=>{a(G=>({...G,ping:N,lastUpdate:Date.now()}))},onError:N=>{a(G=>({...G,connectionStatus:"error",error:N,lastUpdate:Date.now()}))}});u.current=z,z.connect()},[e.websocket.url,e.websocket.reconnectAttempts,e.websocket.reconnectDelay,e.websocket.pingInterval,e.tracking.sendRateLimit,e.logLevel,e.logToConsole]),x=i.useCallback(()=>{u.current?.disconnect(),y.current?.reset(),C.current=null,d(new Map),a(v=>({...v,isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,roomId:null,error:null}))},[]),m=i.useCallback(v=>{C.current=v},[]),f=i.useCallback(()=>{C.current=null,y.current?.reset()},[]),T=i.useCallback(v=>{b.current={...b.current,...v},v.tracking&&y.current&&y.current.updateConfig(v.tracking)},[]),D=i.useCallback((v,z)=>{const N=u.current;if(!N)return;const G=z?.range??b.current.proximityRange;N.sendChat(v,{range:G});const F=c.localPlayerId;if(!F)return;const V=z?.ttlMs??2500,Y=String(v??"").trim().slice(0,200);Y&&d($=>{const K=new Map($);return K.set(F,{text:Y,expiresAt:Date.now()+V}),K})},[c.localPlayerId]);i.useEffect(()=>{if(!c.isConnected)return;const v=Math.max(15,Math.floor(1e3/Math.max(1,b.current.tracking.updateRate))),z=window.setInterval(()=>{if(!R.current.isConnected||!u.current||!y.current||!C.current?.current||!p.current)return;const{playerName:G,playerColor:F}=p.current,V=M.current,Y=S.current?.[V]?.current??"idle",$=y.current.trackPosition(C.current,G,F,t,Y);if($){const{modelUrl:K,...X}=$;u.current.updateLocalPlayer(K?{...X,modelUrl:K}:X)}if(k.current.size>0){const K=Date.now(),X=[];if(k.current.forEach((L,_)=>{L.expiresAt<=K&&X.push(_)}),X.length>0){const L=new Map(k.current);for(const _ of X)L.delete(_);d(L)}}},v);return()=>window.clearInterval(z)},[c.isConnected,t]),i.useEffect(()=>()=>{u.current?.disconnect()},[]);const O=i.useMemo(()=>{const v=new Map;return w.forEach((z,N)=>{v.set(N,z.text)}),v},[w]),B=c.localPlayerId?w.get(c.localPlayerId)?.text??null:null;return{...c,connect:h,disconnect:x,startTracking:m,stopTracking:f,updateConfig:T,sendChat:D,speechByPlayerId:O,localSpeechText:B}}function it(l,e){const t=[];for(const n of l.values())for(const s of n)t.length>=e&&t.shift(),t.push(s);return t}const at=({systemId:l="main",className:e,style:t,onClose:n})=>{const{getSnapshot:s,getSystemState:r,isReady:c}=ue({systemId:l}),{stats:a,refreshStats:p}=qe({systemId:l,enableRealTime:!0}),[u,y]=i.useState({snapshot:null,system:null,messages:[],isExpanded:!0,activeTab:"overview"});i.useEffect(()=>{if(!c)return;const d=setInterval(()=>{const k=s(),h=r();if(!k&&!h)return;const x=h?it(h.messageQueues,50):[];y(m=>({...m,snapshot:k??m.snapshot,system:h??m.system,messages:x}))},500);return()=>clearInterval(d)},[c,s,r]);const C=()=>{if(!u.snapshot)return o.jsx("div",{children:"No data available"});const{snapshot:d}=u,k=u.system?.groups.size??d.activeGroups;return o.jsxs("div",{style:{padding:"10px"},children:[o.jsx("h4",{children:"Network Overview"}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"10px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"Total Nodes:"})," ",d.nodeCount]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Total Connections:"})," ",d.connectionCount]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Total Groups:"})," ",k]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Recent Messages:"})," ",u.messages.length]})]}),a&&o.jsxs("div",{style:{marginTop:"15px"},children:[o.jsx("h5",{children:"Performance Metrics"}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"10px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"Messages/sec:"})," ",a.messagesPerSecond.toFixed(2)]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Avg Latency:"})," ",a.averageLatency.toFixed(2),"ms"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Connection Success:"})," ",a.connectionSuccessRate.toFixed(1),"%"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Update Time:"})," ",a.updateTime.toFixed(2),"ms"]})]})]})]})},b=()=>{const d=u.system;if(!d)return o.jsx("div",{children:"No data available"});const k=Array.from(d.nodes.values());return o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Network Nodes (",k.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:k.map(h=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",h.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Position:"})," (",h.position.x.toFixed(1),", ",h.position.y.toFixed(1),", ",h.position.z.toFixed(1),")"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Connections:"})," ",h.connections.size]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Groups:"})," ",Array.from(d.groups.values()).filter(x=>x.members.has(h.id)).map(x=>x.id).join(", ")||"None"]})]},h.id))})]})},R=()=>{const d=u.system;if(!d)return o.jsx("div",{children:"No data available"});const k=Array.from(d.connections.values());return o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Network Connections (",k.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:k.map(h=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",h.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"From:"})," ",h.nodeA," → ",o.jsx("strong",{children:"To:"})," ",h.nodeB]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Status:"})," ",h.status]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Latency:"})," ",h.latency.toFixed(1),"ms"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Last Activity:"})," ",new Date(h.lastActivity).toLocaleTimeString()]})]},h.id))})]})},M=()=>o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Recent Messages (",u.messages.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:u.messages.slice().reverse().map((d,k)=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px",backgroundColor:d.type==="system"?"#f0f8ff":"#ffffff"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",d.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Type:"})," ",d.type]}),o.jsxs("div",{children:[o.jsx("strong",{children:"From:"})," ",d.from," → ",o.jsx("strong",{children:"To:"})," ",d.to==="group"?`group:${d.groupId??"unknown"}`:d.to]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Time:"})," ",new Date(d.timestamp).toLocaleTimeString()]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Payload:"})," ",JSON.stringify(d.payload)]})]},`${d.id}-${k}`))})]}),S=()=>a?o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"10px"},children:[o.jsx("h4",{children:"Network Statistics"}),o.jsx("button",{onClick:p,children:"Refresh"})]}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"15px"},children:[o.jsxs("div",{children:[o.jsx("h5",{children:"Basic Stats"}),o.jsxs("div",{children:["Total Nodes: ",a.totalNodes]}),o.jsxs("div",{children:["Total Connections: ",a.totalConnections]}),o.jsxs("div",{children:["Total Messages: ",a.totalMessages]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Performance"}),o.jsxs("div",{children:["Messages/sec: ",a.messagesPerSecond.toFixed(2)]}),o.jsxs("div",{children:["Avg Latency: ",a.averageLatency.toFixed(2),"ms"]}),o.jsxs("div",{children:["Update Time: ",a.updateTime.toFixed(2),"ms"]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Connection Stats"}),o.jsxs("div",{children:["Active: ",a.activeConnections]}),o.jsxs("div",{children:["Failed: ",a.failedConnections]}),o.jsxs("div",{children:["Success Rate: ",a.connectionSuccessRate.toFixed(1),"%"]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Group Stats"}),o.jsxs("div",{children:["Total Groups: ",a.totalGroups]}),o.jsxs("div",{children:["Active Groups: ",a.activeGroups]}),o.jsxs("div",{children:["Avg Group Size: ",a.averageGroupSize.toFixed(1)]})]})]})]}):o.jsx("div",{children:"Loading stats..."}),w=()=>{switch(u.activeTab){case"overview":return C();case"nodes":return b();case"connections":return R();case"messages":return M();case"stats":return S();default:return C()}};return u.isExpanded?o.jsxs("div",{className:e,style:{position:"fixed",top:"10px",right:"10px",width:"600px",height:"500px",backgroundColor:"white",border:"1px solid #ccc",borderRadius:"8px",boxShadow:"0 4px 8px rgba(0,0,0,0.1)",zIndex:1e3,display:"flex",flexDirection:"column",...t},children:[o.jsxs("div",{style:{padding:"10px",borderBottom:"1px solid #ccc",display:"flex",justifyContent:"space-between",alignItems:"center"},children:[o.jsx("h3",{style:{margin:0},children:"Network Debug Panel"}),o.jsxs("div",{children:[o.jsx("button",{onClick:()=>y(d=>({...d,isExpanded:!1})),children:"−"}),n&&o.jsx("button",{onClick:n,style:{marginLeft:"5px"},children:"×"})]})]}),o.jsx("div",{style:{display:"flex",borderBottom:"1px solid #ccc",backgroundColor:"#f9f9f9"},children:["overview","nodes","connections","messages","stats"].map(d=>o.jsx("button",{style:{flex:1,padding:"8px 12px",border:"none",backgroundColor:u.activeTab===d?"white":"transparent",borderBottom:u.activeTab===d?"2px solid #007acc":"none",cursor:"pointer"},onClick:()=>y(k=>({...k,activeTab:d})),children:d.charAt(0).toUpperCase()+d.slice(1)},d))}),o.jsx("div",{style:{flex:1,overflow:"auto"},children:w()}),o.jsxs("div",{style:{padding:"5px 10px",borderTop:"1px solid #ccc",backgroundColor:"#f9f9f9",fontSize:"12px",color:"#666"},children:["Status: ",c?"Connected":"Disconnected"," | System: ",l," | Last Update: ",new Date().toLocaleTimeString()]})]}):o.jsx("div",{className:e,style:{position:"fixed",top:"10px",right:"10px",backgroundColor:"#f0f0f0",border:"1px solid #ccc",borderRadius:"4px",padding:"5px 10px",cursor:"pointer",zIndex:1e3,...t},onClick:()=>y(d=>({...d,isExpanded:!0})),children:"Network Debug"})},Ie=["#ff6b6b","#4ecdc4","#45b7d1","#96ceb4","#feca57","#ff9ff3","#54a0ff","#5f27cd","#00d2d3","#ff9f43"],Ce="#cccccc",Ae="#4a90e2",ct={active:"#00ff00",establishing:"#ffff00",unstable:"#ff9f43",disconnected:"#cccccc"},lt=l=>ct[l]??"#666666",ut=({systemId:l="main",showLabels:e=!0,showConnectionLines:t=!0,showGroups:n=!0,nodeSize:s=.5,connectionWidth:r=.05,updateInterval:c=100,maxRenderDistance:a=100})=>{const{getSystemState:p,isReady:u}=ue({systemId:l}),y=i.useRef(null),C=i.useRef(0),[b,R]=i.useState({nodes:[],connections:[],groups:new Map});be.useFrame(()=>{const h=Date.now();if(!u||h-C.current<c)return;const x=p();if(!x)return;const m=new Map;x.groups.forEach((f,T)=>{m.set(T,Array.from(f.members))}),R({nodes:Array.from(x.nodes.values()),connections:Array.from(x.connections.values()),groups:m}),C.current=h});const M=i.useMemo(()=>{const h=new Map;let x=0;return b.groups.forEach((m,f)=>{h.set(f,Ie[x%Ie.length]??Ce),x++}),h},[b.groups]),S=i.useMemo(()=>{const h=new Map;return b.groups.forEach((x,m)=>{for(const f of x){const T=h.get(f);T?T.push(m):h.set(f,[m])}}),h},[b.groups]),w=i.useMemo(()=>{const h=new Map;for(const x of b.nodes)h.set(x.id,x);return h},[b.nodes]),d=i.useMemo(()=>{const h=[];return b.groups.forEach((x,m)=>{const f=[];for(const v of x){const z=w.get(v);z&&f.push(z)}if(f.length<2)return;let T=0,D=0,O=0;for(const v of f)T+=v.position.x,D+=v.position.y,O+=v.position.z;T/=f.length,D/=f.length,O/=f.length;let B=0;for(const v of f){const z=v.position.x-T,N=v.position.y-D,G=v.position.z-O,F=z*z+N*N+G*G;F>B&&(B=F)}h.push({groupId:m,center:[T,D,O],radius:Math.sqrt(B)+1})}),h},[b.groups,w]);if(!u)return o.jsx(H.Text,{position:[0,0,0],fontSize:1,color:"#ff0000",anchorX:"center",anchorY:"middle",children:"Network not ready"});const k=h=>{if(!n)return Ae;const m=S.get(h)?.[0];return m?M.get(m)??Ce:Ae};return o.jsxs("group",{ref:y,children:[b.nodes.map(h=>{const x=k(h.id),m=S.get(h.id);return o.jsxs("group",{position:[h.position.x,h.position.y,h.position.z],children:[o.jsx(H.Sphere,{args:[s],position:[0,0,0],children:o.jsx("meshBasicMaterial",{color:x})}),h.connections.size>0&&o.jsx(H.Sphere,{args:[s*.3],position:[0,s+.2,0],children:o.jsx("meshBasicMaterial",{color:"#ffffff"})}),e&&o.jsx(H.Text,{position:[0,s+.5,0],fontSize:.3,color:"#ffffff",anchorX:"center",anchorY:"middle",children:h.id}),n&&m&&m.length>0&&o.jsx(H.Text,{position:[0,s+.8,0],fontSize:.2,color:x,anchorX:"center",anchorY:"middle",children:m.join(", ")})]},h.id)}),t&&b.connections.map(h=>{const x=w.get(h.nodeA),m=w.get(h.nodeB);return!x||!m?null:o.jsx(H.Line,{points:[[x.position.x,x.position.y,x.position.z],[m.position.x,m.position.y,m.position.z]],color:lt(h.status),lineWidth:r,transparent:!0,opacity:h.status==="active"?.8:.4},h.id)}),n&&d.map(({groupId:h,center:x,radius:m})=>{const f=M.get(h)??Ce;return o.jsxs("group",{children:[o.jsxs("mesh",{position:x,children:[o.jsx("ringGeometry",{args:[m-.1,m+.1,32]}),o.jsx("meshBasicMaterial",{color:f,transparent:!0,opacity:.3})]}),o.jsxs(H.Text,{position:[x[0],x[1]+m+.5,x[2]],fontSize:.4,color:f,anchorX:"center",anchorY:"middle",children:["Group: ",h]})]},`group-${h}`)}),o.jsxs("group",{position:[-10,10,0],children:[o.jsx(H.Text,{position:[0,2,0],fontSize:.5,color:"#ffffff",anchorX:"left",anchorY:"middle",children:"Network Visualization"}),o.jsxs(H.Text,{position:[0,1,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Nodes: ",b.nodes.length]}),o.jsxs(H.Text,{position:[0,.5,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Connections: ",b.connections.length]}),o.jsxs(H.Text,{position:[0,0,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Groups: ",b.groups.size]})]})]})};function Le(l){return"color"in l&&l.color instanceof E.Color}const Ve=i.memo(function({state:e,characterUrl:t,config:n,speechText:s}){const r=i.useRef(null),c=i.useRef(null),a=i.useRef(null);a.current||(a.current=[e.position[0],e.position[1],e.position[2]]);const p=i.useRef(new E.Vector3),u=i.useRef(new E.Quaternion),y=i.useRef(new E.Vector3),C=i.useRef(performance.now()),b=i.useRef(new E.Vector3),R=i.useRef(new E.Quaternion),M=i.useRef(new E.Vector3),S=i.useRef(new E.Vector3),w=i.useRef(new E.Vector3),d=i.useRef(new E.Quaternion),k=i.useRef(!1),h=i.useRef(new E.Vector3),x=i.useRef(new E.Vector3),m=i.useRef(new E.Vector3),f=i.useRef(new E.Vector3),T=i.useRef(new E.Vector3),D=i.useRef(new E.Vector3),O=i.useRef({x:0,y:0,z:0}),B=i.useRef({x:0,y:0,z:0,w:1}),v=i.useRef(0),z=i.useRef(0),N=t||e.modelUrl||"";if(!N)return null;const G=I=>{if(typeof I!="string")return null;const P=I.trim();if(!P)return null;const g=P.startsWith("#")?P:`#${P}`;return/^#[0-9a-fA-F]{3}$/.test(g)||/^#[0-9a-fA-F]{6}$/.test(g)?g:null},F=i.useMemo(()=>G(e.color),[e.color]),V=n?.tracking?.interpolationSpeed||.15,Y=n?.rendering?.characterScale||1,$=n?.rendering?.nameTagHeight||3.5,K=n?.rendering?.nameTagSize||.5,{scene:X,animations:L}=H.useGLTF(N),_=i.useMemo(()=>Ye.SkeletonUtils.clone(X),[X]),{actions:U,ref:Z}=H.useAnimations(L,c),ne=i.useRef([]),ee=i.useRef(null),fe=i.useRef(null),ie=i.useRef(performance.now()),ae=i.useRef(new E.Vector3);i.useEffect(()=>{for(const P of ne.current)try{P.dispose()}catch{}if(ne.current=[],!F)return;const I=P=>{if(!Le(P))return P;const g=P.clone();return Le(g)?(g.color.set(F),ne.current.push(g),g):P};return _.traverse(P=>{(P instanceof E.Mesh||P instanceof E.SkinnedMesh)&&P.material&&(Array.isArray(P.material)?P.material=P.material.map(g=>I(g)):P.material=I(P.material))}),()=>{for(const P of ne.current)try{P.dispose()}catch{}ne.current=[]}},[_,F]);const q=I=>{if(!U)return null;const P=U[I];if(P)return P;const g=I.toLowerCase(),A=Object.keys(U),Q=A.find(j=>j.toLowerCase().includes(g));if(Q)return U[Q]??null;if(g==="run"){const j=A.find(W=>W.toLowerCase().includes("walk"))??A[0];return j?U[j]??null:null}if(g==="idle"){const j=A.find(W=>W.toLowerCase().includes("idle"))??A[0];return j?U[j]??null:null}return A[0]?U[A[0]]??null:null},se=(I,P,g,A,Q,j,W)=>{const oe=Math.max(1e-4,A),ce=Math.max(0,j),J=2/oe,te=J*ce,we=1/(1+te+.48*te*te+.235*te*te*te);m.current.copy(P),h.current.copy(I).sub(P);const ge=Q*oe,re=h.current.length();re>ge&&re>0&&h.current.multiplyScalar(ge/re),f.current.copy(I).sub(h.current),x.current.copy(g).addScaledVector(h.current,J).multiplyScalar(ce),g.addScaledVector(x.current,-J).multiplyScalar(we),W.copy(h.current).add(x.current).multiplyScalar(we).add(f.current),T.current.copy(m.current).sub(I),D.current.copy(W).sub(m.current),T.current.dot(D.current)>0&&(W.copy(m.current),g.set(0,0,0))};return i.useEffect(()=>{if(!U)return;const I=n?.tracking?.velocityThreshold??.5,P=I,g=I*.6,A=180,Q=e.velocity?Math.hypot(e.velocity[0],e.velocity[1],e.velocity[2]):y.current.length(),j=e.animation?.trim(),W=(ee.current??"idle")==="run"?Q<g?"idle":"run":Q>P?"run":"idle",oe=(j&&j.length>0?j:W)||"idle";if(ee.current===oe)return;const ce=performance.now();if(ce-ie.current<A)return;const J=q(oe);if(!J)return;const te=fe.current;return J.enabled=!0,J.setEffectiveTimeScale(1),J.setEffectiveWeight(1),J.reset().play(),te&&te!==J?J.crossFadeFrom(te,.18,!0):J.fadeIn(.18),ee.current=oe,fe.current=J,ie.current=ce,()=>{}},[U,e.animation,e.velocity,n?.tracking?.velocityThreshold]),i.useEffect(()=>{if(C.current=performance.now(),p.current.set(e.position[0],e.position[1],e.position[2]),ae.current.set(e.position[0],e.position[1],e.position[2]),!k.current&&r.current){const A=p.current;k.current=!0,S.current.copy(A),w.current.set(0,0,0),d.current.copy(u.current);const Q=r.current,j=O.current;j.x=A.x,j.y=A.y,j.z=A.z,Q.setNextKinematicTranslation(j);const W=B.current;W.x=u.current.x,W.y=u.current.y,W.z=u.current.z,W.w=u.current.w,Q.setNextKinematicRotation(W)}const I=e.rotation,g=Math.abs(I[0])<1e-6&&Math.abs(I[1])<1e-6&&Math.abs(I[2])<1e-6&&Math.abs(I[3]-1)<1e-6?[1,0,0,0]:I;u.current.set(g[1],g[2],g[3],g[0]),e.velocity&&y.current.set(e.velocity[0],e.velocity[1],e.velocity[2])},[e.position,e.rotation,e.velocity]),be.useFrame((I,P)=>{if(!r.current||!c.current)return;const g=z.current;if(g>0){if(v.current+=Math.max(0,P),v.current<g)return;v.current=0}else v.current=0;const A=k.current?S.current:p.current,Q=I.camera.position.distanceTo(A),j=k.current?Ke.weightFromDistance(Q,25,140,4):1;z.current=j>=.7?0:j>=.4?1/30:j>=.2?1/15:1/8;const W=(performance.now()-C.current)/1e3,oe=Math.max(0,Math.min(.12,W));if(M.current.copy(p.current).addScaledVector(y.current,oe),!k.current){const ye=r.current.translation(),de=r.current.rotation();k.current=!0,S.current.set(ye.x,ye.y,ye.z),w.current.set(0,0,0),d.current.set(de.x,de.y,de.z,de.w)}const ce=Math.max(.01,Math.min(.9,V)),J=Math.max(.03,Math.min(.22,.03+(1-ce)*.19)),te=120;if(S.current.distanceTo(M.current)>10||P>.25)S.current.copy(M.current),w.current.set(0,0,0),d.current.copy(u.current);else{se(S.current,M.current,w.current,J,te,P,b.current),S.current.copy(b.current);const ye=Math.max(.025,J*.7),de=1-Math.exp(-Math.max(0,P)/ye);R.current.copy(d.current).slerp(u.current,de),d.current.copy(R.current)}ae.current.copy(S.current);const ge=r.current,re=O.current;re.x=S.current.x,re.y=S.current.y,re.z=S.current.z,ge.setNextKinematicTranslation(re);const me=B.current;me.x=d.current.x,me.y=d.current.y,me.z=d.current.z,me.w=d.current.w,ge.setNextKinematicRotation(me)}),o.jsxs("group",{children:[o.jsxs(xe.RigidBody,{ref:r,type:"kinematicPosition",position:a.current??void 0,colliders:!1,children:[o.jsx(xe.CapsuleCollider,{args:[.5,.5],position:[0,1.5,0]}),o.jsx("group",{ref:c,children:o.jsx("group",{ref:Z,scale:[Y,Y,Y],children:o.jsx("primitive",{object:_})})}),o.jsx(H.Text,{position:[0,$,0],fontSize:K,color:"white",anchorX:"center",anchorY:"middle",outlineWidth:.05,outlineColor:"black",children:e.name})]}),s?o.jsx(Ue.SpeechBalloon,{text:s,position:ae.current}):null]})});function dt({onConnect:l,error:e,isConnecting:t}){const[n,s]=i.useState(""),[r,c]=i.useState("room1"),[a]=i.useState(()=>`#${Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")}`),p=u=>{u.preventDefault(),n.trim()&&l({roomId:r,playerName:n.trim(),playerColor:a})};return o.jsx("div",{style:{width:"100vw",height:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#1a1a1a"},children:o.jsxs("form",{onSubmit:p,style:{background:"rgba(0, 0, 0, 0.8)",padding:"40px",borderRadius:"10px",color:"white",minWidth:"300px"},children:[o.jsx("h2",{style:{marginBottom:"20px",textAlign:"center"},children:"네트워크 멀티플레이어"}),o.jsxs("div",{style:{marginBottom:"15px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"플레이어 이름"}),o.jsx("input",{type:"text",placeholder:"이름을 입력하세요",value:n,onChange:u=>s(u.target.value),disabled:t,style:{width:"100%",padding:"10px",borderRadius:"5px",border:"1px solid #ccc",background:"#333",color:"white",fontSize:"14px"}})]}),o.jsxs("div",{style:{marginBottom:"20px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"방 코드"}),o.jsx("input",{type:"text",placeholder:"방 코드",value:r,onChange:u=>c(u.target.value),disabled:t,style:{width:"100%",padding:"10px",borderRadius:"5px",border:"1px solid #ccc",background:"#333",color:"white",fontSize:"14px"}})]}),o.jsxs("div",{style:{marginBottom:"20px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"플레이어 색상"}),o.jsx("div",{style:{width:"30px",height:"30px",backgroundColor:a,borderRadius:"50%",border:"2px solid #ccc"}})]}),o.jsx("button",{type:"submit",disabled:!n.trim()||t,style:{width:"100%",padding:"12px",borderRadius:"5px",border:"none",background:!n.trim()||t?"#666":"#4CAF50",color:"white",fontSize:"16px",cursor:!n.trim()||t?"not-allowed":"pointer",transition:"background-color 0.2s"},children:t?"연결 중...":"연결하기"}),e&&o.jsx("div",{style:{color:"#ff6b6b",marginTop:"15px",padding:"10px",background:"rgba(255, 107, 107, 0.1)",borderRadius:"5px",fontSize:"14px"},children:e})]})})}function ht({state:l,playerName:e,onDisconnect:t,onSendChat:n}){const{isConnected:s,connectionStatus:r,players:c,roomId:a,error:p,ping:u,localPlayerId:y,lastUpdate:C}=l,[b,R]=i.useState("");if(!s)return null;const M=i.useCallback(()=>{if(!n)return;const S=b.trim();S&&(n(S),R(""))},[n,b]);return o.jsxs("div",{style:{position:"fixed",top:10,left:10,background:"rgba(0, 0, 0, 0.8)",padding:"8px",borderRadius:"6px",color:"white",minWidth:"160px",backdropFilter:"blur(5px)",border:"1px solid rgba(255, 255, 255, 0.08)",lineHeight:1.2},children:[o.jsx("h3",{style:{marginTop:0,marginBottom:"6px",fontSize:"12px",borderBottom:"1px solid rgba(255, 255, 255, 0.2)",paddingBottom:"6px"},children:"네트워크 정보"}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"상태:"}),o.jsx("span",{style:{marginLeft:"8px",color:r==="connected"?"#4CAF50":"#ff6b6b"},children:r==="connected"?"연결됨":r==="connecting"?"연결 중":r==="error"?"오류":"연결 끊김"})]}),e&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"플레이어:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:e})]}),a&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"방:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:a})]}),y&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"내 ID:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:y})]}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"최근 업데이트:"}),o.jsx("span",{style:{marginLeft:"8px"},children:C?`${Math.max(0,Date.now()-C)}ms 전`:"-"})]}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"접속자:"}),o.jsxs("span",{style:{marginLeft:"8px"},children:[c.size+(s?1:0),"명"]})]}),u>0&&o.jsxs("div",{style:{marginBottom:"8px",fontSize:"12px"},children:[o.jsx("strong",{children:"핑:"}),o.jsxs("span",{style:{marginLeft:"8px",color:u<50?"#4CAF50":u<100?"#FFA726":"#ff6b6b"},children:[u,"ms"]})]}),c.size>0&&o.jsxs("div",{style:{marginBottom:"8px"},children:[o.jsx("strong",{children:"다른 플레이어:"}),o.jsx("div",{style:{marginTop:"6px",maxHeight:"80px",overflowY:"auto",fontSize:"11px"},children:Array.from(c.entries()).map(([S,w])=>o.jsxs("div",{style:{display:"flex",alignItems:"center",marginBottom:"4px",padding:"3px",background:"rgba(255, 255, 255, 0.05)",borderRadius:"3px"},children:[o.jsx("div",{style:{width:"10px",height:"10px",backgroundColor:w.color,borderRadius:"50%",marginRight:"6px",border:"1px solid rgba(255, 255, 255, 0.3)"}}),o.jsxs("span",{style:{flex:1},children:[w.name,o.jsxs("span",{style:{opacity:.7,marginLeft:"8px"},children:["(",w.position[0].toFixed(1),",",w.position[1].toFixed(1),",",w.position[2].toFixed(1),")"]}),w.animation?o.jsx("span",{style:{opacity:.7,marginLeft:"8px"},children:w.animation}):null]})]},S))})]}),p&&o.jsx("div",{style:{color:"#ff6b6b",marginBottom:"15px",padding:"8px",background:"rgba(255, 107, 107, 0.1)",borderRadius:"5px",fontSize:"14px"},children:p}),n?o.jsxs("div",{style:{marginBottom:"8px"},children:[o.jsx("strong",{children:"채팅:"}),o.jsxs("div",{style:{display:"flex",gap:"6px",marginTop:"6px"},children:[o.jsx("input",{value:b,onChange:S=>R(S.target.value),placeholder:"Enter로 전송",style:{flex:1,padding:"6px",borderRadius:"4px",border:"1px solid rgba(255, 255, 255, 0.2)",background:"rgba(255, 255, 255, 0.05)",color:"white",fontSize:"12px"},onKeyDown:S=>{S.key==="Enter"&&(S.preventDefault(),M())}}),o.jsx("button",{onClick:M,style:{padding:"6px 8px",borderRadius:"4px",border:"none",background:"#4CAF50",color:"white",fontSize:"12px",cursor:"pointer"},disabled:!b.trim(),children:"전송"})]})]}):null,o.jsx("button",{onClick:t,style:{width:"100%",padding:"8px",borderRadius:"4px",border:"none",background:"#ff6b6b",color:"white",fontSize:"12px",cursor:"pointer",transition:"background-color 0.2s"},onMouseEnter:S=>{S.currentTarget.style.backgroundColor="#ff5252"},onMouseLeave:S=>{S.currentTarget.style.backgroundColor="#ff6b6b"},children:"연결 끊기"})]})}const pt=6,ft=1e-4;function gt({playerRef:l,onChange:e}){const t=i.useRef({x:0,y:0,z:0}),n=i.useRef(0);return be.useFrame(()=>{if(n.current++,n.current%pt!==0)return;const s=l.current;if(!s)return;const r=s.translation(),c=t.current,a=r.x-c.x,p=r.y-c.y,u=r.z-c.z;a*a+p*p+u*u<ft||(c.x=r.x,c.y=r.y,c.z=r.z,e(r.x,r.y,r.z))}),null}const mt=i.memo(function({players:e,characterUrl:t,vehicleUrl:n,airplaneUrl:s,playerRef:r,config:c,localPlayerColor:a,proximityRange:p,speechByPlayerId:u,localSpeechText:y}){i.useEffect(()=>{window.CHARACTER_URL=t},[t]);const[C,b]=i.useState([0,0,0]),R=i.useMemo(()=>new E.Vector3,[]),M=i.useMemo(()=>(w,d,k)=>{R.set(w,d,k),b([w,d,k])},[R]),S=i.useMemo(()=>{const w=p;if(!w||w<=0)return e;const[d,k,h]=C,x=new Map;return e.forEach((m,f)=>{const[T,D,O]=m.position,B=T-d,v=D-k,z=O-h;B*B+v*v+z*z<=w*w&&x.set(f,m)}),x},[e,p,C]);return o.jsx(ze.WorldContainer,{urls:{characterUrl:t,vehicleUrl:n,airplaneUrl:s},children:o.jsxs(be.Canvas,{shadows:!0,dpr:[1,1.5],camera:{position:[0,10,20],fov:75,near:.1,far:1e3},style:{width:"100vw",height:"100vh"},children:[o.jsx(H.Environment,{background:!0,preset:"sunset",backgroundBlurriness:1}),o.jsx("directionalLight",{castShadow:!0,"shadow-normalBias":.06,position:[20,30,10],intensity:.5,"shadow-mapSize":[1024,1024],"shadow-camera-near":1,"shadow-camera-far":120,"shadow-camera-top":90,"shadow-camera-right":90,"shadow-camera-bottom":-90,"shadow-camera-left":-90}),o.jsx(i.Suspense,{fallback:null,children:o.jsx(ze.GaesupWorldContent,{children:o.jsxs(xe.Physics,{children:[o.jsx(gt,{playerRef:r,onChange:M}),o.jsx(ve.ControllerWrapper,{rigidBodyRef:r,rotation:xe.euler({x:0,y:Math.PI,z:0}),parts:[],...a?{baseColor:a}:{}}),y?o.jsx(Ue.SpeechBalloon,{text:y,position:R}):null,Array.from(S.entries()).map(([w,d])=>o.jsx(Ve,{playerId:w,state:d,characterUrl:t,config:c,...(()=>{const k=u?.get(w);return k?{speechText:k}:{}})()},w)),o.jsx(H.Grid,{renderOrder:-1,position:[0,.01,0],infiniteGrid:!0,cellSize:2,cellThickness:1,cellColor:"#1d1d1d",sectionSize:5,sectionThickness:0,fadeDistance:1e3}),o.jsx(xe.RigidBody,{type:"fixed",children:o.jsxs("mesh",{receiveShadow:!0,position:[0,-1,0],children:[o.jsx("boxGeometry",{args:[1e3,2,1e3]}),o.jsx("meshStandardMaterial",{color:"#3d3d3d"})]})}),o.jsx(ve.Clicker,{}),o.jsx(ve.GroundClicker,{})]})})})]})})}),yt={updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4,websocket:{url:"ws://localhost:8090",reconnectAttempts:5,reconnectDelay:1e3,pingInterval:3e4},tracking:{updateRate:20,velocityThreshold:.5,sendRateLimit:50,interpolationSpeed:.15},rendering:{nameTagHeight:3.5,nameTagSize:.5,characterScale:1}},De={updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4},xt={high:{updateFrequency:60,maxConnections:200,messageQueueSize:2e3,enableBatching:!0,batchSize:20,compressionLevel:3,connectionPoolSize:100,bandwidth:2e3,signalStrength:2},balanced:{updateFrequency:30,maxConnections:100,messageQueueSize:1e3,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,bandwidth:1e3,signalStrength:1},low:{updateFrequency:15,maxConnections:50,messageQueueSize:500,enableBatching:!1,batchSize:5,compressionLevel:0,connectionPoolSize:25,bandwidth:500,signalStrength:.5}},bt=l=>{const e=[];return(l.updateFrequency<=0||l.updateFrequency>120)&&e.push("updateFrequency must be between 1 and 120"),l.maxConnections<=0&&e.push("maxConnections must be greater than 0"),l.messageQueueSize<=0&&e.push("messageQueueSize must be greater than 0"),l.maxDistance<=0&&e.push("maxDistance must be greater than 0"),l.signalStrength<=0&&e.push("signalStrength must be greater than 0"),l.bandwidth<=0&&e.push("bandwidth must be greater than 0"),l.proximityRange<=0&&e.push("proximityRange must be greater than 0"),l.batchSize<=0&&e.push("batchSize must be greater than 0"),(l.compressionLevel<0||l.compressionLevel>9)&&e.push("compressionLevel must be between 0 and 9"),l.connectionPoolSize<0&&e.push("connectionPoolSize must be non-negative"),l.reliableRetryCount<0&&e.push("reliableRetryCount must be non-negative"),l.reliableTimeout<=0&&e.push("reliableTimeout must be greater than 0"),l.maxGroupSize<=0&&e.push("maxGroupSize must be greater than 0"),l.debugUpdateInterval<=0&&e.push("debugUpdateInterval must be greater than 0"),l.maxLogEntries<=0&&e.push("maxLogEntries must be greater than 0"),l.maxMessagesPerSecond<=0&&e.push("maxMessagesPerSecond must be greater than 0"),l.messageGCInterval<=0&&e.push("messageGCInterval must be greater than 0"),l.connectionTimeout<=0&&e.push("connectionTimeout must be greater than 0"),l.inactiveNodeCleanup<=0&&e.push("inactiveNodeCleanup must be greater than 0"),{isValid:e.length===0,errors:e}},St=Be.create((l,e)=>({config:De,updateConfig:t=>l(n=>({config:{...n.config,...t}})),updatePerformanceConfig:t=>l(n=>({config:{...n.config,...t}})),updateCommunicationConfig:t=>l(n=>({config:{...n.config,...t}})),updateOptimizationConfig:t=>l(n=>({config:{...n.config,...t}})),updateDebugConfig:t=>l(n=>({config:{...n.config,...t}})),resetConfig:()=>l({config:{...De}}),resetToProfile:t=>l(n=>({config:{...n.config,...xt[t]}})),validateConfig:()=>bt(e().config)})),Ee={snapshot:null,connectedNodes:new Map,activeGroups:new Map,recentMessages:[],isConnected:!1,connectionStatus:"disconnected",lastError:null,lastUpdate:0},Se=Be.create((l,e)=>({state:{...Ee},updateSnapshot:t=>l(n=>({state:{...n.state,snapshot:{...t},lastUpdate:Date.now()}})),updateConnectedNodes:t=>l(n=>{const s=new Map;return t.forEach(r=>{s.set(r.id,{...r})}),{state:{...n.state,connectedNodes:s,lastUpdate:Date.now()}}}),updateActiveGroups:t=>l(n=>{const s=new Map;return t.forEach(r=>{s.set(r.id,{...r,members:new Set(r.members)})}),{state:{...n.state,activeGroups:s,lastUpdate:Date.now()}}}),addRecentMessage:t=>l(n=>{const s=[...n.state.recentMessages,{...t}];return s.length>100&&s.shift(),{state:{...n.state,recentMessages:s,lastUpdate:Date.now()}}}),setConnectionStatus:(t,n)=>l(s=>({state:{...s.state,connectionStatus:t,isConnected:t==="connected",lastError:n||null,lastUpdate:Date.now()}})),clearRecentMessages:()=>l(t=>({state:{...t.state,recentMessages:[],lastUpdate:Date.now()}})),getNodeById:t=>{const{state:n}=e();return n.connectedNodes.get(t)||null},getGroupById:t=>{const{state:n}=e();return n.activeGroups.get(t)||null},getNodesByGroup:t=>{const{state:n}=e(),s=n.activeGroups.get(t);if(!s)return[];const r=[];return s.members.forEach(c=>{const a=n.connectedNodes.get(c);a&&r.push(a)}),r},getMessagesForNode:t=>{const{state:n}=e();return n.recentMessages.filter(s=>s.from===t||s.to===t)},resetState:()=>l({state:{...Ee,connectedNodes:new Map,activeGroups:new Map,recentMessages:[]}})})),wt=()=>{const{connectionStatus:l,isConnected:e,lastError:t}=Se(n=>n.state);return{status:l,isConnected:e,lastError:t,isConnecting:l==="connecting",hasError:l==="error"}},vt=l=>{const e=Se(t=>t.state.recentMessages);return l&&l>0?e.slice(-l):e},Ct=()=>{const l=Se(e=>e.state.connectedNodes);return Array.from(l.values())},Mt=()=>{const l=Se(e=>e.state.activeGroups);return Array.from(l.values())};var kt=Object.defineProperty,Pt=Object.getOwnPropertyDescriptor,je=(l,e,t,n)=>{for(var s=n>1?void 0:n?Pt(e,t):e,r=l.length-1,c;r>=0;r--)(c=l[r])&&(s=(n?c(e,t,s):c(s))||s);return n&&s&&kt(e,t,s),s};exports.NetworkBridge=class extends pe.CoreBridge{constructor(){super(),this.setupEngineSubscriptions()}ensureMainEngine(e){this.getEngine("main")||this.register("main",e??this.createDefaultConfig())}buildEngine(e,t){try{const n=new _e(t??this.createDefaultConfig());return n.start(),{system:n,dispose:()=>n.dispose()}}catch(n){return console.error("[NetworkBridge] Failed to build engine:",n),null}}executeCommand(e,t,n){const{system:s}=e;s.executeCommand(t)}createSnapshot(e,t){const{system:n}=e;return n.createSnapshot()}updateSystem(e,t){this.getEngine(e)&&this.notifyListeners(e)}createDefaultConfig(){return{updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4}}setupEngineSubscriptions(){this.on("snapshot",e=>{})}getNetworkStats(e="main"){const t=this.getEngine(e);return t?t.system.getDebugInfo()?.networkStats??null:null}getSystemState(e="main"){const t=this.getEngine(e);return t?t.system.getState():null}};je([pe.ValidateCommand()],exports.NetworkBridge.prototype,"executeCommand",1);je([pe.LogSnapshot(),pe.CacheSnapshot(16)],exports.NetworkBridge.prototype,"createSnapshot",1);exports.NetworkBridge=je([pe.DomainBridge("networks"),pe.EnableMetrics()],exports.NetworkBridge);const $e=Xe.WORLD_SNAPSHOT_DOMAINS;function We(l){const e=new Map;for(const t of l())!t||typeof t.key!="string"||e.set(t.key,t);return e}function Je(l,e){const t=We(l),n=e.domains??$e,s={};for(const c of n){const a=t.get(c);if(a)try{s[c]=a.serialize()}catch{s[c]=null}}const r=e.savedAt??Date.now();return{kind:"world",worldId:e.worldId??e.hostId,version:e.version??1,hostId:e.hostId,...e.hostName?{hostName:e.hostName}:{},savedAt:r,capturedAt:r,domains:s}}function ke(l,e,t={}){const n=We(l),s=t.allowedDomains?new Set(t.allowedDomains):null,r=[],c=[];for(const[a,p]of Object.entries(e.domains??{})){if(s&&!s.has(a)){c.push(a);continue}if(t.filter&&!t.filter(a,p)){c.push(a);continue}const u=n.get(a);if(!u){c.push(a);continue}try{u.hydrate(p),r.push(a)}catch{c.push(a)}}return{applied:r,skipped:c}}function Rt(l){return()=>l.getBindings()}class Tt{listeners=new Set;latest=null;publish(e){this.latest=e,this.emit({type:"snapshot",snapshot:e})}leave(e){this.emit({type:"leave",hostId:e})}subscribe(e){if(this.listeners.add(e),this.latest)try{e({type:"snapshot",snapshot:this.latest})}catch{}return()=>{this.listeners.delete(e)}}close(){this.listeners.clear(),this.latest=null}emit(e){for(const t of this.listeners)try{t(e)}catch{}}}function Nt(){return new Tt}const Pe=1,Re="VisitSnapshot",Te="VisitLeave";function jt(l){try{const e=JSON.parse(l);return!e||typeof e!="object"||e.type!==Re&&e.type!==Te||typeof e.v!="number"||e.v!==Pe?null:e}catch{return null}}function zt(l){const e=new Set;let t=l.onMessage(s=>{const r=jt(s);r&&(r.type===Re?n({type:"snapshot",snapshot:r.snapshot}):r.type===Te&&n({type:"leave",hostId:r.hostId}))});function n(s){for(const r of e)try{r(s)}catch{}}return{publish(s){const r={type:Re,v:Pe,snapshot:s};try{l.send(JSON.stringify(r))}catch{}},leave(s){const r={type:Te,v:Pe,hostId:s};try{l.send(JSON.stringify(r))}catch{}},subscribe(s){return e.add(s),()=>{e.delete(s)}},close(){if(t){try{t()}catch{}t=null}e.clear()}}}function It(l){const{hostId:e,hostName:t,channel:n,bindings:s,hostMode:r=!0,autoApply:c=!1,allowedDomains:a}=l,[p,u]=i.useState(null),[y,C]=i.useState(null),b=i.useRef(s);b.current=s;const R=i.useRef(a);R.current=a;const M=i.useRef(c);M.current=c,i.useEffect(()=>{const h=n.subscribe(x=>{if(x.type==="snapshot"){if(x.snapshot.hostId===e)return;u(x.snapshot),M.current&&ke(b.current,x.snapshot,{...R.current?{allowedDomains:R.current}:{}})}else x.type==="leave"&&u(m=>m&&m.hostId===x.hostId?null:m)});return()=>{h()}},[n,e]);const S=i.useCallback(()=>{const h=Je(b.current,{hostId:e,...t?{hostName:t}:{}});return r&&n.publish(h),C(h),h},[n,e,t,r]),w=i.useCallback(()=>{const h=p;return h?ke(b.current,h,{...R.current?{allowedDomains:R.current}:{}}).applied.length>0:!1},[p]),d=i.useCallback(()=>{u(null)},[]),k=i.useCallback(()=>{n.leave(e)},[n,e]);return i.useMemo(()=>({remoteSnapshot:p,lastPublished:y,publishNow:S,acceptRemote:w,dismissRemote:d,announceLeave:k}),[p,y,S,w,d,k])}exports.MockNetworkAdapter=Ge.MockNetworkAdapter;exports.createNetworkEnvelope=Ge.createNetworkEnvelope;exports.createCommandAcceptedResult=le.createCommandAcceptedResult;exports.createCommandAuthorityRouter=le.createCommandAuthorityRouter;exports.createCommandRejectedResult=le.createCommandRejectedResult;exports.createGameCommand=le.createGameCommand;exports.createServerEvent=le.createServerEvent;exports.createSnapshotAck=le.createSnapshotAck;exports.createStateDelta=le.createStateDelta;exports.ConnectionForm=dt;exports.ConnectionPool=Fe;exports.DEFAULT_VISIT_DOMAINS=$e;exports.MessageQueue=he;exports.MultiplayerCanvas=mt;exports.NPCNetworkManager=Oe;exports.NPCNetworkVisualizer=ut;exports.NetworkDebugPanel=at;exports.NetworkSystem=_e;exports.PlayerInfoOverlay=ht;exports.PlayerNetworkManager=Ne;exports.PlayerPositionTracker=Qe;exports.RemotePlayer=Ve;exports.applyVisitSnapshot=ke;exports.createLocalVisitChannel=Nt;exports.createWebSocketVisitChannel=zt;exports.defaultMultiplayerConfig=yt;exports.serializeVisit=Je;exports.useMultiplayer=rt;exports.useNPCConnection=tt;exports.useNetworkBridge=ue;exports.useNetworkConfigStore=St;exports.useNetworkConnection=wt;exports.useNetworkGroup=st;exports.useNetworkGroups=Mt;exports.useNetworkMessage=nt;exports.useNetworkNodes=Ct;exports.useNetworkStateStore=Se;exports.useNetworkStats=qe;exports.usePlayerNetwork=ot;exports.useRecentMessages=vt;exports.useVisitRoom=It;exports.visitProviderFromSaveSystem=Rt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react"),be=require("@react-three/fiber"),Me=require("./gaesupStore-2zKBYTYo.cjs"),He=require("three"),Ge=require("./types-DgS5FYTs.cjs"),le=require("./authority-BOPCXUrV.cjs"),o=require("react/jsx-runtime"),H=require("@react-three/drei"),xe=require("@react-three/rapier"),Ye=require("three-stdlib"),Ke=require("./sfe-CpgzdMyB.cjs"),Ue=require("./index-BhSman4a.cjs");require("reflect-metadata");const ze=require("./index-syAx2qzT.cjs"),ve=require("./index-Cpso39Zs.cjs"),Be=require("zustand"),pe=require("./index-CJj-Z7Jr.cjs"),Xe=require("./snapshot-DRqZrbCu.cjs");function Ze(l){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const t in l)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(l,t);Object.defineProperty(e,t,n.get?n:{enumerable:!0,get:()=>l[t]})}}return e.default=l,Object.freeze(e)}const E=Ze(He);class Fe{availableConnections=[];activeConnections=new Map;connectionIdCounter=1;maxPoolSize;defaultOptions;constructor(e=50,t){this.maxPoolSize=e,this.defaultOptions={timeout:3e4,retries:3,bandwidth:1e3,encryption:!1,...t}}createConnection(e,t,n){const s={...this.defaultOptions,...n};return{id:`conn_${this.connectionIdCounter++}`,nodeA:e,nodeB:t,strength:1,latency:Math.random()*50+10,bandwidth:s.bandwidth,status:"establishing",lastActivity:Date.now()}}getConnection(e,t,n){const s={...this.defaultOptions,...n},r=this.availableConnections.pop();if(r)return r.nodeA=e,r.nodeB=t,r.status="establishing",r.strength=1,r.latency=0,r.bandwidth=s.bandwidth,r.lastActivity=Date.now(),this.activeConnections.set(r.id,r),r;const c=this.createConnection(e,t,n);return this.activeConnections.set(c.id,c),c}releaseConnection(e){const t=this.activeConnections.get(e);return t?(this.activeConnections.delete(e),this.resetConnection(t),this.availableConnections.length<this.maxPoolSize&&this.availableConnections.push(t),!0):!1}resetConnection(e){e.nodeA="",e.nodeB="",e.status="disconnected",e.strength=0,e.latency=0,e.lastActivity=0}getActiveConnection(e){return this.activeConnections.get(e)||null}findActiveConnection(e,t){for(const n of this.activeConnections.values())if(n.nodeA===e&&n.nodeB===t||n.nodeA===t&&n.nodeB===e)return n;return null}updateConnectionStatus(e,t){const n=this.activeConnections.get(e);return n?(n.status=t,n.lastActivity=Date.now(),!0):!1}updateConnectionMetrics(e,t){const n=this.activeConnections.get(e);return n?(t.latency!==void 0&&(n.latency=t.latency),t.bandwidth!==void 0&&(n.bandwidth=t.bandwidth),t.strength!==void 0&&(n.strength=t.strength),n.lastActivity=Date.now(),!0):!1}cleanupInactiveConnections(e=3e5){const t=Date.now();let n=0;const s=[];for(const[r,c]of this.activeConnections.entries())t-c.lastActivity>e&&s.push(r);for(const r of s)this.releaseConnection(r)&&n++;return n}getPoolStats(){const e=this.availableConnections.length,t=this.activeConnections.size,n=e+t,s=n>0?t/n:0;return{available:e,active:t,total:n,maxSize:this.maxPoolSize,utilizationRate:s}}clear(){this.activeConnections.clear(),this.availableConnections=[],this.connectionIdCounter=1}disconnectNode(e){let t=0;const n=[];for(const[s,r]of this.activeConnections.entries())(r.nodeA===e||r.nodeB===e)&&n.push(s);return n.forEach(s=>{this.releaseConnection(s),t++}),t}updatePoolSettings(e,t){for(this.maxPoolSize=Math.max(0,e),t&&(this.defaultOptions={...this.defaultOptions,...t});this.availableConnections.length>this.maxPoolSize;)this.availableConnections.pop()}}class he{queues=new Map;maxSize;batchSize;enableBatching;totalSize=0;static prioritiesLowToHigh=["low","normal","high","critical"];static prioritiesHighToLow=["critical","high","normal","low"];constructor(e=1e3,t=10,n=!0){this.maxSize=Math.max(1,e),this.batchSize=t,this.enableBatching=n}getOrCreateQueue(e){const t=this.queues.get(e);if(t)return t;const n={items:[],head:0};return this.queues.set(e,n),n}getQueueSizeInternal(e){return e.items.length-e.head}compactQueueIfNeeded(e){if(e.head!==0){if(e.head>=e.items.length){e.items=[],e.head=0;return}e.head>64&&e.head*2>=e.items.length&&(e.items=e.items.slice(e.head),e.head=0)}}shiftOne(e){if(this.getQueueSizeInternal(e)<=0)return null;const t=e.items[e.head]??null;return e.head+=1,this.totalSize=Math.max(0,this.totalSize-1),this.compactQueueIfNeeded(e),t}enqueue(e){const t=e.priority;for(;this.totalSize>=this.maxSize;)if(!this.evictOne(t))return!1;return this.getOrCreateQueue(t).items.push(e),this.totalSize+=1,!0}evictOne(e){const t=he.prioritiesLowToHigh,n=t.indexOf(e);for(let r=0;r<n;r++){const c=t[r];if(!c)continue;const a=this.queues.get(c);if(a&&this.shiftOne(a))return!0}const s=this.queues.get(e);return!!(s&&this.shiftOne(s))}dequeue(){for(const e of he.prioritiesHighToLow){const t=this.queues.get(e);if(!t)continue;const n=this.shiftOne(t);if(n)return n}return null}dequeueBatch(){if(!this.enableBatching){const t=this.dequeue();return t?[t]:[]}const e=[];for(const t of he.prioritiesHighToLow){if(e.length>=this.batchSize)break;const n=this.queues.get(t);if(!n)continue;const s=this.batchSize-e.length,r=this.getQueueSizeInternal(n),c=Math.min(s,r);for(let a=0;a<c;a++){const p=this.shiftOne(n);if(!p)break;e.push(p)}}return e}getQueueSize(e){const t=this.queues.get(e);return t?this.getQueueSizeInternal(t):0}getTotalSize(){return this.totalSize}clear(){this.queues.clear(),this.totalSize=0}findMessage(e){for(const t of this.queues.values())for(let n=t.head;n<t.items.length;n++){const s=t.items[n];if(s&&s.id===e)return s}return null}removeMessage(e){for(const t of this.queues.values())for(let n=t.head;n<t.items.length;n++){const s=t.items[n];if(!(!s||s.id!==e))return n===t.head?(this.shiftOne(t),!0):(t.items.splice(n,1),this.totalSize=Math.max(0,this.totalSize-1),this.compactQueueIfNeeded(t),!0)}return!1}updateBatchSettings(e,t){this.batchSize=Math.max(1,e),this.enableBatching=t}updateMaxSize(e){for(this.maxSize=Math.max(1,e);this.totalSize>this.maxSize&&this.evictOne("critical"););}getStats(){const e={};for(const[t,n]of this.queues.entries())e[t]=this.getQueueSizeInternal(n);return{totalMessages:this.getTotalSize(),queueSizes:e,maxSize:this.maxSize,batchSize:this.batchSize,enableBatching:this.enableBatching}}}class Oe{nodes=new Map;groups=new Map;eventCallbacks=new Map;performanceMetrics;proximityRange;maxDistance;groupIdCounter=1;maxMessageQueueSize;gridCellSize;grid=new Map;nodeCellKey=new Map;scratchNearbyNodeIds=new Set;scratchDisconnectIds=[];scratchCenter=new E.Vector3;constructor(e=50,t=100,n=200){this.proximityRange=e,this.maxDistance=t,this.maxMessageQueueSize=n,this.gridCellSize=Math.max(1,e),this.performanceMetrics={messagesProcessed:0,averageLatency:0,bandwidth:0,connectionCount:0,errorRate:0,lastUpdate:Date.now()}}registerNode(e,t,n){const s=`node_${e}`;if(this.nodes.has(s))throw new Error(`Node ${s} is already registered`);const r={id:s,npcId:e,position:t.clone(),connections:new Set,messageQueue:[],lastUpdate:Date.now(),status:"active",communicationRange:n?.communicationRange||this.proximityRange,signalStrength:n?.signalStrength||1};return this.nodes.set(s,r),this.addToGrid(s,r.position),this.emitEvent({type:"nodeConnected",nodeId:s,data:{npcId:e,position:t},timestamp:Date.now()}),r}unregisterNode(e){const t=`node_${e}`;return this.nodes.get(t)?(this.disconnectAllConnections(t),this.leaveAllGroups(t),this.nodes.delete(t),this.removeFromGrid(t),this.emitEvent({type:"nodeDisconnected",nodeId:t,data:{npcId:e},timestamp:Date.now()}),!0):!1}updateNodePosition(e,t){const n=`node_${e}`,s=this.nodes.get(n);return s?(s.position.copy(t),s.lastUpdate=Date.now(),this.updateGridPosition(n,s.position),this.updateProximityConnections(n),!0):!1}connectNodes(e,t){const n=`node_${e}`,s=`node_${t}`,r=this.nodes.get(n),c=this.nodes.get(s);if(!r||!c)return!1;const a=this.maxDistance*this.maxDistance;return r.position.distanceToSquared(c.position)>a?!1:(r.connections.add(s),c.connections.add(n),this.performanceMetrics.connectionCount=this.getTotalConnections(),!0)}disconnectNodes(e,t){const n=`node_${e}`,s=`node_${t}`,r=this.nodes.get(n),c=this.nodes.get(s);return!r||!c?!1:(r.connections.delete(s),c.connections.delete(n),this.performanceMetrics.connectionCount=this.getTotalConnections(),!0)}disconnectAllConnections(e){const t=this.nodes.get(e);if(t){for(const n of t.connections){const s=this.nodes.get(n);s&&s.connections.delete(e)}t.connections.clear()}}updateProximityConnections(e){const t=this.nodes.get(e);if(!t)return;const n=(c,a)=>{const p=Math.min(c.communicationRange,a.communicationRange);return c.position.distanceToSquared(a.position)<=p*p},s=this.scratchDisconnectIds;s.length=0;for(const c of t.connections){const a=this.nodes.get(c);if(!a){s.push(c);continue}n(t,a)||s.push(c)}for(const c of s){t.connections.delete(c);const a=this.nodes.get(c);a&&a.connections.delete(e)}const r=this.getNearbyNodeIds(t,this.scratchNearbyNodeIds);for(const c of r){if(e===c||t.connections.has(c))continue;const a=this.nodes.get(c);a&&n(t,a)&&(t.connections.add(c),a.connections.add(e))}}resolveNodeId(e){return e.startsWith("node_")?e:`node_${e}`}getCellKey(e){const t=this.gridCellSize,n=Math.floor(e.x/t),s=Math.floor(e.z/t);return`${n},${s}`}addToGrid(e,t){const n=this.getCellKey(t),s=this.grid.get(n)??new Set;s.add(e),this.grid.set(n,s),this.nodeCellKey.set(e,n)}removeFromGrid(e){const t=this.nodeCellKey.get(e);if(!t)return;const n=this.grid.get(t);n&&(n.delete(e),n.size===0&&this.grid.delete(t)),this.nodeCellKey.delete(e)}updateGridPosition(e,t){const n=this.nodeCellKey.get(e),s=this.getCellKey(t);if(n===s)return;this.removeFromGrid(e);const r=this.grid.get(s)??new Set;r.add(e),this.grid.set(s,r),this.nodeCellKey.set(e,s)}collectNearbyNodeIdsByPosition(e,t,n){n.clear();const s=this.gridCellSize,r=Math.max(1,Math.ceil(Math.max(1,t)/s)),c=Math.floor(e.x/s),a=Math.floor(e.z/s);for(let p=-r;p<=r;p++)for(let u=-r;u<=r;u++){const y=`${c+p},${a+u}`,C=this.grid.get(y);C&&C.forEach(b=>n.add(b))}}getNearbyNodeIds(e,t){const n=t??new Set;return this.collectNearbyNodeIdsByPosition(e.position,e.communicationRange,n),n}enqueueMessage(e,t){e.messageQueue.length>=this.maxMessageQueueSize&&e.messageQueue.shift(),e.messageQueue.push(t)}sendMessage(e){return this.nodes.get(this.resolveNodeId(e.from))?e.to==="broadcast"?this.broadcastMessage(e):e.to==="group"&&e.groupId?this.sendGroupMessage(e):this.sendDirectMessage(e):!1}sendDirectMessage(e){const t=e.to.startsWith("node_")?e.to:`node_${e.to}`,n=this.nodes.get(t);if(!n)return!1;this.enqueueMessage(n,e);const s=Date.now();return this.performanceMetrics.messagesProcessed++,this.performanceMetrics.lastUpdate=s,this.emitEvent({type:"messageReceived",nodeId:t,data:e,timestamp:s}),!0}broadcastMessage(e){let t=0;const n=this.resolveNodeId(e.from);for(const r of this.nodes.values()){if(r.id===n)continue;const c={...e,to:r.id};this.enqueueMessage(r,c),t++}const s=Date.now();return this.performanceMetrics.messagesProcessed+=t,this.performanceMetrics.lastUpdate=s,t>0}sendGroupMessage(e){if(!e.groupId)return!1;const t=this.groups.get(e.groupId);if(!t)return!1;let n=0;const s=this.resolveNodeId(e.from);for(const c of t.members){if(c===s)continue;const a=this.nodes.get(c);if(a){const p={...e,to:c};this.enqueueMessage(a,p),n++}}const r=Date.now();return this.performanceMetrics.messagesProcessed+=n,this.performanceMetrics.lastUpdate=r,n>0}getMessages(e){const t=`node_${e}`,n=this.nodes.get(t);if(!n)return[];const s=[...n.messageQueue];return n.messageQueue=[],s}createGroup(e,t){const n=`group_${this.groupIdCounter++}`,s={id:n,type:e,members:new Set,maxMembers:t?.maxMembers||(e==="party"?8:e==="guild"?100:20),range:t?.range||(e==="proximity"?30:1e3),persistent:t?.persistent!==void 0?t.persistent:e==="guild",createdAt:Date.now(),lastActivity:Date.now()};return this.groups.set(n,s),s}joinGroup(e,t){const n=`node_${e}`,s=this.nodes.get(n),r=this.groups.get(t);return!s||!r||r.members.size>=r.maxMembers?!1:(r.members.add(n),r.lastActivity=Date.now(),this.emitEvent({type:"groupJoined",nodeId:n,data:{groupId:t},timestamp:Date.now()}),!0)}leaveGroup(e,t){const n=`node_${e}`,s=this.groups.get(t);return!s||!s.members.has(n)?!1:(s.members.delete(n),s.lastActivity=Date.now(),!s.persistent&&s.members.size===0&&this.groups.delete(t),this.emitEvent({type:"groupLeft",nodeId:n,data:{groupId:t},timestamp:Date.now()}),!0)}leaveAllGroups(e){for(const[t,n]of this.groups.entries())n.members.has(e)&&(n.members.delete(e),!n.persistent&&n.members.size===0&&this.groups.delete(t))}updateProximityGroups(){const e=this.scratchCenter,t=this.scratchNearbyNodeIds;for(const n of this.groups.values()){if(n.type!=="proximity"||n.members.size===0||n.range<=0)continue;let s=0,r=0,c=0,a=0;for(const u of n.members){const y=this.nodes.get(u);y&&(s+=y.position.x,r+=y.position.y,c+=y.position.z,a+=1)}if(a===0)continue;e.set(s/a,r/a,c/a),this.collectNearbyNodeIdsByPosition(e,n.range,t);const p=n.range*n.range;for(const u of t){if(n.members.size>=n.maxMembers)break;if(n.members.has(u))continue;const y=this.nodes.get(u);if(!y)continue;const C=y.position.x-e.x,b=y.position.y-e.y,R=y.position.z-e.z;C*C+b*b+R*R<=p&&n.members.add(u)}}}addEventListener(e,t){this.eventCallbacks.has(e)||this.eventCallbacks.set(e,[]),this.eventCallbacks.get(e).push(t)}removeEventListener(e,t){const n=this.eventCallbacks.get(e);if(n){const s=n.indexOf(t);s!==-1&&n.splice(s,1)}}emitEvent(e){const t=this.eventCallbacks.get(e.type);t&&t.forEach(n=>{try{n(e)}catch(s){console.error("Error in event callback:",s)}})}getTotalConnections(){let e=0;for(const t of this.nodes.values())e+=t.connections.size;return e/2}getPerformanceMetrics(){return{...this.performanceMetrics}}getNode(e){const t=`node_${e}`;return this.nodes.get(t)||null}getAllNodes(){return Array.from(this.nodes.values())}forEachNode(e){for(const t of this.nodes.values())e(t)}getGroup(e){return this.groups.get(e)||null}getAllGroups(){return Array.from(this.groups.values())}forEachGroup(e){for(const t of this.groups.values())e(t)}clear(){this.nodes.clear(),this.groups.clear(),this.eventCallbacks.clear(),this.grid.clear(),this.nodeCellKey.clear(),this.performanceMetrics={messagesProcessed:0,averageLatency:0,bandwidth:0,connectionCount:0,errorRate:0,lastUpdate:Date.now()},this.groupIdCounter=1}updateSettings(e,t){e!==void 0&&(this.proximityRange=Math.max(0,e)),t!==void 0&&(this.maxDistance=Math.max(0,t))}getNetworkStats(){const e=this.nodes.size,t=this.getTotalConnections(),n=this.groups.size,s=e>0?t/e:0;let r=0;for(const c of this.nodes.values())r+=c.messageQueue.length;return{nodeCount:e,connectionCount:t,groupCount:n,averageConnections:s,totalMessages:r}}}class _e{state;npcManager;messageQueue;connectionPool;config;lastCleanupTime=0;lastStatsUpdateAt=0;updateTimer;scratchNodeIds=new Set;scratchGroupIds=new Set;scratchRemoveIds=[];messageQueueSig=new Map;constructor(e){this.config={...e},this.npcManager=new Oe(e.proximityRange,e.maxDistance),this.messageQueue=new he(e.messageQueueSize,e.batchSize,e.enableBatching),this.connectionPool=new Fe(e.connectionPoolSize),this.state={nodes:new Map,connections:new Map,groups:new Map,messageQueues:new Map,stats:{totalNodes:0,activeConnections:0,messagesPerSecond:0,averageLatency:0,bandwidth:0,lastUpdate:Date.now()},isRunning:!1,lastUpdate:Date.now()}}start(){this.state.isRunning||(this.state.isRunning=!0,this.lastCleanupTime=Date.now(),this.startUpdateLoop())}stop(){this.state.isRunning&&(this.state.isRunning=!1,this.updateTimer&&(clearTimeout(this.updateTimer),this.updateTimer=void 0))}startUpdateLoop(){this.updateTimer&&clearTimeout(this.updateTimer);const e=Math.max(1,this.config.updateFrequency),t=Math.max(1,Math.floor(1e3/e));let n=Date.now()+t;const s=()=>{if(!this.state.isRunning)return;this.update();const r=Date.now();n+=t,n<r&&(n=r+t);const c=Math.max(0,n-Date.now());this.updateTimer=setTimeout(s,c)};this.updateTimer=setTimeout(s,t)}update(){if(!this.state.isRunning)return;const e=Date.now();this.processMessageBatch(),this.npcManager.updateProximityGroups(),e-this.lastCleanupTime>=this.config.connectionTimeout&&(this.connectionPool.cleanupInactiveConnections(this.config.connectionTimeout),this.lastCleanupTime=e),this.updateStatistics(e),this.syncState(),this.state.lastUpdate=e}processMessageBatch(){const e=this.messageQueue.dequeueBatch();for(const t of e)try{this.npcManager.sendMessage(t)}catch(n){console.error("Error processing message:",n)}}updateStatistics(e){const t=Math.max(0,this.config.debugUpdateInterval??250);if(t>0&&e-this.lastStatsUpdateAt<t)return;this.lastStatsUpdateAt=e;const n=this.npcManager.getNetworkStats(),s=this.npcManager.getPerformanceMetrics();this.state.stats={totalNodes:n.nodeCount,activeConnections:n.connectionCount,messagesPerSecond:this.calculateMessagesPerSecond(s),averageLatency:s.averageLatency,bandwidth:s.bandwidth,lastUpdate:e}}calculateMessagesPerSecond(e){const t=(Date.now()-e.lastUpdate)/1e3,n=Math.max(.001,t);return e.messagesProcessed/n}syncState(){const e=this.scratchNodeIds;e.clear(),this.npcManager.forEachNode(s=>{e.add(s.id),this.state.nodes.set(s.id,s)});const t=this.scratchRemoveIds;t.length=0;for(const s of this.state.nodes.keys())e.has(s)||t.push(s);for(const s of t)this.state.nodes.delete(s);const n=this.scratchGroupIds;n.clear(),this.npcManager.forEachGroup(s=>{n.add(s.id),this.state.groups.set(s.id,s)}),t.length=0;for(const s of this.state.groups.keys())n.has(s)||t.push(s);for(const s of t)this.state.groups.delete(s);for(const s of e){const r=this.state.nodes.get(s);if(!r||r.messageQueue.length===0){this.state.messageQueues.delete(s),this.messageQueueSig.delete(s);continue}const c=r.messageQueue,a=c[c.length-1]?.id??null,p=this.messageQueueSig.get(s);p&&p.len===c.length&&p.tailId===a||(p?(p.len=c.length,p.tailId=a):this.messageQueueSig.set(s,{len:c.length,tailId:a}),this.state.messageQueues.set(s,c.slice()))}t.length=0;for(const s of this.state.messageQueues.keys())e.has(s)||t.push(s);for(const s of t)this.state.messageQueues.delete(s),this.messageQueueSig.delete(s)}executeCommand(e){try{switch(e.type){case"registerNPC":return this.registerNPC(e.npcId,e.position,e.options),!0;case"unregisterNPC":return this.unregisterNPC(e.npcId);case"updateNPCPosition":return this.updateNPCPosition(e.npcId,e.position);case"connect":return this.npcManager.connectNodes(e.npcId,e.targetId);case"disconnect":return e.targetId?this.npcManager.disconnectNodes(e.npcId,e.targetId):this.npcManager.unregisterNode(e.npcId);case"sendMessage":return this.messageQueue.enqueue(e.message),!0;case"broadcast":const t={...e.message,to:"broadcast"};return this.messageQueue.enqueue(t),!0;case"joinGroup":return this.npcManager.joinGroup(e.npcId,e.groupId);case"leaveGroup":return this.npcManager.leaveGroup(e.npcId,e.groupId);case"createGroup":return!!this.npcManager.createGroup(e.group.type,{maxMembers:e.group.maxMembers,range:e.group.range,persistent:e.group.persistent});case"updateSettings":return this.updateConfig(e.settings),!0;case"updateConfig":return this.updateConfig(e.data.config),!0;case"startMonitoring":return!0;case"stopMonitoring":return!0;default:return console.warn("Unknown network command:",e),!1}}catch(t){return console.error("Error executing network command:",t),!1}}createSnapshot(){return{nodeCount:this.state.stats.totalNodes,connectionCount:this.state.stats.activeConnections,activeGroups:this.state.groups.size,messagesPerSecond:this.state.stats.messagesPerSecond,averageLatency:this.state.stats.averageLatency,lastUpdate:this.state.lastUpdate}}updateConfig(e){this.config={...this.config,...e},(e.messageQueueSize||e.batchSize||e.enableBatching)&&(this.messageQueue.updateBatchSettings(this.config.batchSize,this.config.enableBatching),this.messageQueue.updateMaxSize(this.config.messageQueueSize)),e.connectionPoolSize&&this.connectionPool.updatePoolSettings(this.config.connectionPoolSize),(e.proximityRange||e.maxDistance)&&this.npcManager.updateSettings(this.config.proximityRange,this.config.maxDistance),e.updateFrequency&&this.state.isRunning&&this.startUpdateLoop()}registerNPC(e,t,n){return this.npcManager.registerNode(e,t,n)}unregisterNPC(e){return this.npcManager.unregisterNode(e)}updateNPCPosition(e,t){return this.npcManager.updateNodePosition(e,t)}getMessages(e){return this.npcManager.getMessages(e)}getState(){return{...this.state}}getConfig(){return{...this.config}}dispose(){this.stop(),this.npcManager.clear(),this.messageQueue.clear(),this.connectionPool.clear(),this.state.nodes.clear(),this.state.connections.clear(),this.state.groups.clear(),this.state.messageQueues.clear()}addEventListener(e,t){this.npcManager.addEventListener(e,t)}removeEventListener(e,t){this.npcManager.removeEventListener(e,t)}getDebugInfo(){return{isRunning:this.state.isRunning,config:this.config,stats:this.state.stats,networkStats:this.npcManager.getNetworkStats(),performanceMetrics:this.npcManager.getPerformanceMetrics(),poolStats:this.connectionPool.getPoolStats(),messageQueueStats:this.messageQueue.getStats()}}}const et=l=>typeof l!="object"||l===null?!1:"text"in l&&typeof l.text=="function";class Ne{ws=null;url;roomId;playerName;playerColor;players=new Map;localPlayerId=null;isConnected=!1;isConnecting=!1;logLevel;logToConsole;reconnectAttemptsMax;reconnectDelayMs;reconnectAttemptsUsed=0;reconnectTimer=null;shouldReconnect=!1;pingIntervalMs;pingTimer=null;lastPingSentAt=0;updateRateLimitMs;lastUpdateSentAt=0;pendingUpdate=null;updateFlushTimer=null;offlineQueueSize;pendingChats=[];enableAck;reliableTimeoutMs;reliableRetryCount;ackIdCounter=1;pendingAcks=new Map;onConnect;onDisconnect;onWelcome;onPlayerJoin;onPlayerUpdate;onPlayerLeave;onChat;onPing;onReliableFailed;onError;constructor(e){this.url=e.url,this.roomId=e.roomId,this.playerName=e.playerName,this.playerColor=e.playerColor,this.reconnectAttemptsMax=Math.max(0,Math.floor(e.reconnectAttempts??0)),this.reconnectDelayMs=Math.max(0,Math.floor(e.reconnectDelay??1e3)),this.pingIntervalMs=Math.max(0,Math.floor(e.pingInterval??0)),this.updateRateLimitMs=Math.max(0,Math.floor(e.sendRateLimit??0)),this.offlineQueueSize=Math.max(0,Math.floor(e.offlineQueueSize??50)),this.enableAck=!!e.enableAck,this.reliableTimeoutMs=Math.max(0,Math.floor(e.reliableTimeout??5e3)),this.reliableRetryCount=Math.max(0,Math.floor(e.reliableRetryCount??0)),this.logLevel=e.logLevel??"none",this.logToConsole=e.logToConsole??!1,e.onConnect&&(this.onConnect=e.onConnect),e.onDisconnect&&(this.onDisconnect=e.onDisconnect),e.onWelcome&&(this.onWelcome=e.onWelcome),e.onPlayerJoin&&(this.onPlayerJoin=e.onPlayerJoin),e.onPlayerUpdate&&(this.onPlayerUpdate=e.onPlayerUpdate),e.onPlayerLeave&&(this.onPlayerLeave=e.onPlayerLeave),e.onChat&&(this.onChat=e.onChat),e.onPing&&(this.onPing=e.onPing),e.onReliableFailed&&(this.onReliableFailed=e.onReliableFailed),e.onError&&(this.onError=e.onError)}shouldLog(e){if(!this.logToConsole)return!1;const t={none:0,error:1,warn:2,info:3,debug:4};return t[e]<=t[this.logLevel]}debug(e,...t){this.shouldLog("debug")&&console.log(e,...t)}info(e,...t){this.shouldLog("info")&&console.info(e,...t)}warn(e,...t){this.shouldLog("warn")&&console.warn(e,...t)}error(e,...t){this.shouldLog("error")&&console.error(e,...t)}getConnectionStatus(){return this.isConnected}connect(){if(this.ws&&this.ws.readyState===WebSocket.OPEN){this.warn("[PlayerNetworkManager] Already connected");return}if(this.ws&&this.ws.readyState===WebSocket.CONNECTING){this.warn("[PlayerNetworkManager] Already connecting");return}if(this.isConnecting){this.warn("[PlayerNetworkManager] Already connecting");return}this.shouldReconnect=this.reconnectAttemptsMax>0,this.clearReconnectTimer(),this.isConnecting=!0,this.info("[PlayerNetworkManager] Connecting WebSocket",this.url);let e;try{e=new WebSocket(this.url)}catch{this.isConnecting=!1,this.isConnected=!1,this.onError?.("WebSocket 연결 실패");return}this.ws=e,e.onopen=()=>{this.info("[PlayerNetworkManager] WebSocket connected"),this.isConnected=!0,this.isConnecting=!1,this.reconnectAttemptsUsed=0,this.startPingLoop(),e.send(JSON.stringify({type:"Join",room_id:this.roomId,name:this.playerName,color:this.playerColor})),this.flushOfflineQueue(),this.resumePendingAcks(),this.onConnect&&this.onConnect()},e.onmessage=t=>{const n=r=>{try{const c=JSON.parse(r);this.handleServerMessage(c)}catch{this.onError?.("서버 메시지 파싱 실패")}},s=t.data;if(typeof s=="string"){n(s);return}if(et(s)){s.text().then(r=>n(r)).catch(()=>this.onError?.("서버 메시지 수신 실패"));return}if(s instanceof ArrayBuffer)try{const r=new TextDecoder().decode(new Uint8Array(s));n(r)}catch{this.onError?.("서버 메시지 디코딩 실패")}},e.onerror=t=>{this.error("[PlayerNetworkManager] WebSocket error",t),this.isConnected=!1,this.isConnecting=!1,this.onError&&this.onError("WebSocket 연결 에러")},e.onclose=t=>{this.info("[PlayerNetworkManager] WebSocket closed",{code:t.code,reason:t.reason});const n=this.isConnected||this.isConnecting;this.isConnected=!1,this.isConnecting=!1,this.stopPingLoop(),this.pausePendingAcks(),this.players.clear(),this.localPlayerId=null,this.onDisconnect&&this.onDisconnect(),(t.code===1e3||t.code===1001)&&(this.shouldReconnect=!1),n&&this.tryReconnect()}}disconnect(){if(this.shouldReconnect=!1,this.clearReconnectTimer(),this.stopPingLoop(),this.clearUpdateFlushTimer(),this.clearAllPendingAcks(!0),!this.ws){this.players.clear(),this.isConnected=!1,this.isConnecting=!1,this.localPlayerId=null,this.onDisconnect?.();return}const e=this.ws;if(e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null,e.readyState===WebSocket.OPEN)try{e.send(JSON.stringify({type:"Leave"}))}catch{}try{e.close()}catch{}this.ws=null,this.players.clear(),this.isConnected=!1,this.isConnecting=!1,this.localPlayerId=null,this.pendingUpdate=null,this.pendingChats=[],this.onDisconnect?.()}updateLocalPlayer(e){this.pendingUpdate=this.pendingUpdate?{...this.pendingUpdate,...e}:{...e};const t=this.ws;if(!t||t.readyState!==WebSocket.OPEN)return;const n=Date.now();if(this.updateRateLimitMs<=0||n-this.lastUpdateSentAt>=this.updateRateLimitMs){this.lastUpdateSentAt=n;const r=this.pendingUpdate;if(this.pendingUpdate=null,!r)return;t.send(JSON.stringify({type:"Update",state:r}));return}if(this.updateFlushTimer)return;const s=Math.max(0,this.updateRateLimitMs-(n-this.lastUpdateSentAt));this.updateFlushTimer=setTimeout(()=>{this.updateFlushTimer=null;const r=this.pendingUpdate;r&&this.updateLocalPlayer(r)},s)}sendChat(e,t){const n=String(e??"").trim().slice(0,200);if(!n)return;const s=this.ws;if(!s||s.readyState!==WebSocket.OPEN){if(this.offlineQueueSize<=0)return;this.pendingChats.length>=this.offlineQueueSize&&this.pendingChats.shift(),t?.range!==void 0?this.pendingChats.push({text:n,range:t.range}):this.pendingChats.push({text:n});return}const r={type:"Chat",text:n,...t?.range!==void 0?{range:t.range}:{}};if(this.enableAck){this.sendReliable(r);return}s.send(JSON.stringify(r))}handleServerMessage(e){switch(this.debug("[PlayerNetworkManager] Server message",e.type,e),e.type){case"Ack":{typeof e.ackId=="string"&&e.ackId&&this.ackReceived(e.ackId);break}case"Pong":{if(typeof e.ts=="number"&&e.ts>0){const t=Math.max(0,Date.now()-e.ts);this.onPing?.(t)}else if(this.lastPingSentAt>0){const t=Math.max(0,Date.now()-this.lastPingSentAt);this.onPing?.(t)}break}case"Welcome":if(this.localPlayerId=e.client_id,this.onWelcome?.(this.localPlayerId,e.room_state),e.room_state)for(const[t,n]of Object.entries(e.room_state))t!==this.localPlayerId&&(this.players.set(t,n),this.onPlayerJoin&&this.onPlayerJoin(t,n));break;case"PlayerJoined":this.debug("[PlayerNetworkManager] PlayerJoined",e.client_id),e.client_id!==this.localPlayerId&&(this.players.set(e.client_id,e.state),this.onPlayerJoin&&this.onPlayerJoin(e.client_id,e.state));break;case"PlayerLeft":this.debug("[PlayerNetworkManager] PlayerLeft",e.client_id),this.players.delete(e.client_id),this.onPlayerLeave&&this.onPlayerLeave(e.client_id);break;case"PlayerUpdate":this.debug("[PlayerNetworkManager] PlayerUpdate",e.client_id);{const t=this.players.get(e.client_id);if(t){const r={...t,...e.state};this.players.set(e.client_id,r),this.onPlayerUpdate?.(e.client_id,r);break}const n=e.state,s={name:n?.name??"Player",color:n?.color??"#ffffff",position:n?.position??[0,0,0],rotation:n?.rotation??[1,0,0,0],...n??{}};this.players.set(e.client_id,s),this.onPlayerJoin?.(e.client_id,s),this.onPlayerUpdate?.(e.client_id,s)}break;case"Chat":this.onChat?.(e.client_id,e.text,e.timestamp);break}}setCallbacks(e){e.onConnect&&(this.onConnect=e.onConnect),e.onDisconnect&&(this.onDisconnect=e.onDisconnect),e.onWelcome&&(this.onWelcome=e.onWelcome),e.onPlayerJoin&&(this.onPlayerJoin=e.onPlayerJoin),e.onPlayerUpdate&&(this.onPlayerUpdate=e.onPlayerUpdate),e.onPlayerLeave&&(this.onPlayerLeave=e.onPlayerLeave),e.onChat&&(this.onChat=e.onChat),e.onPing&&(this.onPing=e.onPing),e.onReliableFailed&&(this.onReliableFailed=e.onReliableFailed),e.onError&&(this.onError=e.onError)}getPlayers(){return new Map(this.players)}clearReconnectTimer(){this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null)}startPingLoop(){this.pingIntervalMs<=0||(this.stopPingLoop(),this.pingTimer=setInterval(()=>{const e=this.ws;if(!e||e.readyState!==WebSocket.OPEN)return;const t=Date.now();this.lastPingSentAt=t;try{e.send(JSON.stringify({type:"Ping",ts:t}))}catch{}},this.pingIntervalMs))}stopPingLoop(){this.pingTimer&&(clearInterval(this.pingTimer),this.pingTimer=null)}clearUpdateFlushTimer(){this.updateFlushTimer&&(clearTimeout(this.updateFlushTimer),this.updateFlushTimer=null)}flushOfflineQueue(){const e=this.ws;if(!(!e||e.readyState!==WebSocket.OPEN)){if(this.pendingChats.length>0){const t=this.pendingChats;this.pendingChats=[];for(const n of t)try{const s={type:"Chat",text:n.text,...n.range!==void 0?{range:n.range}:{}};this.enableAck?this.sendReliable(s):e.send(JSON.stringify(s))}catch{this.offlineQueueSize>0&&(this.pendingChats=t.slice(t.indexOf(n)));break}}if(this.pendingUpdate){const t=this.pendingUpdate;this.pendingUpdate=null,this.updateLocalPlayer(t)}}}tryReconnect(){if(!this.shouldReconnect||this.reconnectAttemptsMax<=0||this.reconnectAttemptsUsed>=this.reconnectAttemptsMax||this.isConnecting)return;const e=this.reconnectAttemptsUsed+1,t=this.reconnectDelayMs||0,n=Math.min(3e4,Math.floor(t*Math.pow(2,this.reconnectAttemptsUsed)));this.reconnectAttemptsUsed=e,this.warn("[PlayerNetworkManager] Reconnecting...",{attempt:e,delay:n}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.shouldReconnect&&this.connect()},n)}nextAckId(){const e=this.ackIdCounter++;return`ack_${Date.now()}_${e}`}sendReliable(e){const t=this.ws;if(!t||t.readyState!==WebSocket.OPEN)return;const n=this.nextAckId(),s=String(e.type??"Unknown"),r=JSON.stringify({...e,ackId:n});try{t.send(r)}catch{return}this.trackPendingAck({ackId:n,raw:r,messageType:s})}trackPendingAck(e){this.enableAck&&(this.stopAckTimer(e.ackId),this.pendingAcks.set(e.ackId,{raw:e.raw,messageType:e.messageType,retriesLeft:this.reliableRetryCount,timer:null}),this.scheduleAckTimeout(e.ackId))}scheduleAckTimeout(e){if(!this.enableAck)return;const t=this.pendingAcks.get(e);t&&(this.reliableTimeoutMs<=0||(t.timer=setTimeout(()=>{const n=this.pendingAcks.get(e);if(!n)return;const s=this.ws;if(!s||s.readyState!==WebSocket.OPEN){n.timer=null;return}if(n.retriesLeft<=0){this.pendingAcks.delete(e),this.onReliableFailed?.({ackId:e,messageType:n.messageType});return}n.retriesLeft-=1;try{s.send(n.raw)}catch{n.timer=null;return}this.scheduleAckTimeout(e)},this.reliableTimeoutMs)))}stopAckTimer(e){const t=this.pendingAcks.get(e);!t||!t.timer||(clearTimeout(t.timer),t.timer=null)}ackReceived(e){this.pendingAcks.get(e)&&(this.stopAckTimer(e),this.pendingAcks.delete(e))}pausePendingAcks(){for(const[e,t]of this.pendingAcks.entries())t.timer&&(clearTimeout(t.timer),t.timer=null),this.enableAck||this.pendingAcks.delete(e)}resumePendingAcks(){if(!this.enableAck)return;const e=this.ws;if(!(!e||e.readyState!==WebSocket.OPEN))for(const[t,n]of this.pendingAcks.entries()){try{e.send(n.raw)}catch{continue}this.scheduleAckTimeout(t)}}clearAllPendingAcks(e){for(const[t,n]of this.pendingAcks.entries())n.timer&&clearTimeout(n.timer),n.timer=null,e&&this.pendingAcks.delete(t);e&&this.pendingAcks.clear()}}class Qe{lastPosition=new E.Vector3;lastRotation=new E.Quaternion;lastAnimation="idle";velocity=new E.Vector3;lastUpdateTime=0;config;tempPos=new E.Vector3;tempRot=new E.Quaternion;tempSendRot=new E.Quaternion;tempEuler=new E.Euler;baseYaw=null;scratchUpdate={name:"",color:"",position:[0,0,0],rotation:[1,0,0,0],animation:"idle",velocity:[0,0,0]};constructor(e){this.config=e}trackPosition(e,t,n,s,r){if(!e.current)return null;const c=Date.now();if(c-this.lastUpdateTime<this.config.sendRateLimit)return null;const a=e.current.translation(),p=e.current.rotation();this.tempPos.set(a.x,a.y,a.z),this.tempRot.set(p.x,p.y,p.z,p.w);const u=e.current.linvel();if(u)this.velocity.set(u.x,u.y,u.z);else{const T=(c-this.lastUpdateTime)/1e3;T>0&&this.velocity.set((a.x-this.lastPosition.x)/T,(a.y-this.lastPosition.y)/T,(a.z-this.lastPosition.z)/T)}const y=this.velocity.length(),C=typeof r=="string"?r.trim():"",b=this.config.velocityThreshold,R=this.config.velocityThreshold*.6,M=this.lastAnimation==="run"?y<R?"idle":"run":y>b?"run":"idle",S=C.length>0?C:M;this.tempSendRot.copy(this.tempRot);const w=this.velocity.x,d=this.velocity.z;if(Math.hypot(w,d)>.05){this.baseYaw===null&&(this.tempEuler.setFromQuaternion(this.tempRot,"YXZ"),this.baseYaw=this.tempEuler.y+Math.PI);const T=Math.atan2(w,d)+(this.baseYaw??0);this.tempEuler.set(0,T,0,"YXZ"),this.tempSendRot.setFromEuler(this.tempEuler)}const h=!this.lastPosition.equals(this.tempPos),x=!this.lastRotation.equals(this.tempSendRot),m=this.lastAnimation!==S;if(!h&&!x&&!m)return null;const f=this.scratchUpdate;return f.name=t,f.color=n,f.position[0]=a.x,f.position[1]=a.y,f.position[2]=a.z,f.rotation[0]=this.tempSendRot.w,f.rotation[1]=this.tempSendRot.x,f.rotation[2]=this.tempSendRot.y,f.rotation[3]=this.tempSendRot.z,f.animation=S,f.velocity[0]=this.velocity.x,f.velocity[1]=this.velocity.y,f.velocity[2]=this.velocity.z,f.modelUrl=s,this.lastPosition.copy(this.tempPos),this.lastRotation.copy(this.tempSendRot),this.lastAnimation=S,this.lastUpdateTime=c,f}updateConfig(e){this.config={...this.config,...e}}reset(){this.lastPosition.set(0,0,0),this.lastRotation.set(0,0,0,1),this.lastAnimation="idle",this.velocity.set(0,0,0),this.lastUpdateTime=0,this.baseYaw=null}}function ue(l={}){const{systemId:e="main",config:t,enableAutoUpdate:n=!0}=l,s=i.useRef(null),[r,c]=i.useState(null),[a,p]=i.useState(!1);i.useEffect(()=>{s.current||(s.current=Me.BridgeFactory.getOrCreate("networks"));const M=s.current;return M?(e==="main"?M.ensureMainEngine():M.getEngine(e)||M.register(e),t&&Object.keys(t).length>0&&M.execute(e,{type:"updateConfig",data:{config:t}}),c(M),p(!0),()=>{}):(c(null),p(!1),()=>{})},[e,t]),be.useFrame((M,S)=>{n&&s.current&&a&&s.current.updateSystem(e,S)});const u=i.useCallback(M=>{s.current&&a&&s.current.execute(e,M)},[e,a]),y=i.useCallback(()=>s.current&&a?s.current.snapshot(e):null,[e,a]),C=i.useCallback(()=>s.current&&a?s.current.getNetworkStats(e):null,[e,a]),b=i.useCallback(()=>s.current&&a?s.current.getSystemState(e):null,[e,a]),R=i.useCallback(M=>{s.current&&a&&s.current.updateSystem(e,M)},[e,a]);return{bridge:r,executeCommand:u,getSnapshot:y,getNetworkStats:C,getSystemState:b,updateSystem:R,isReady:a}}function tt(l){const{npcId:e,initialOptions:t,...n}=l,{executeCommand:s,getSnapshot:r,isReady:c}=ue(n),a=i.useRef(!1),p=i.useRef(null),u=i.useRef(new Set);i.useEffect(()=>(c&&t&&!a.current&&y(t),()=>{a.current&&C()}),[c,t]);const y=i.useCallback(d=>{!c||a.current||(s({type:"registerNPC",npcId:e,position:d.position,...d.connectionRange!==void 0?{options:{communicationRange:d.connectionRange}}:{}}),a.current=!0,p.current=d.position.clone(),d.autoConnect)},[c,s,e]),C=i.useCallback(()=>{!c||!a.current||(s({type:"unregisterNPC",npcId:e}),a.current=!1,p.current=null,u.current.clear())},[c,s,e]),b=i.useCallback(d=>{!c||!a.current||(s({type:"updateNPCPosition",npcId:e,position:d}),p.current=d.clone())},[c,s,e]),R=i.useCallback((d,k)=>{!c||!a.current||(s({type:"connect",npcId:e,targetId:d}),u.current.add(d))},[c,s,e]),M=i.useCallback(d=>{!c||!a.current||(s({type:"disconnect",npcId:e,targetId:d}),u.current.delete(d))},[c,s,e]),S=i.useCallback(()=>Array.from(u.current),[]),w=i.useCallback(()=>p.current?p.current.clone():null,[]);return{registerNPC:y,unregisterNPC:C,updatePosition:b,connectTo:R,disconnectFrom:M,isRegistered:a.current,getConnections:S,getPosition:w,executeCommand:s,getSnapshot:r,isReady:c}}function nt(l){const{senderId:e,onMessageSent:t,...n}=l,{executeCommand:s,isReady:r}=ue(n),c=500,[a,p]=i.useState([]),[u,y]=i.useState([]),[C,b]=i.useState([]),R=i.useRef(0),M=i.useCallback((x,m,f="chat",T)=>{if(!r)return"";const D=`${e}-${++R.current}-${Date.now()}`,O=Date.now(),B={id:D,from:e,to:x,type:f==="action"||f==="state"||f==="system"?f:"chat",payload:m,priority:T?.priority??"normal",timestamp:O,reliability:T?.reliable?"reliable":"unreliable",...T?.retries!==void 0?{retryCount:T.retries}:{}};return s({type:"sendMessage",message:B}),y(v=>{const z=[...v,B];return z.length>c?z.slice(-c):z}),t?.(B),D},[r,s,e,t]),S=i.useCallback((x,m="chat",f)=>{if(!r)return"";const T=`${e}-broadcast-${++R.current}-${Date.now()}`,D=Date.now(),O={id:T,from:e,type:m==="action"||m==="state"||m==="system"?m:"chat",payload:x,priority:f?.priority??"normal",timestamp:D,reliability:f?.reliable?"reliable":"unreliable",...f?.groupId?{groupId:f.groupId}:{},...f?.retries!==void 0?{retryCount:f.retries}:{}};s({type:"broadcast",message:O});const B={...O,to:"broadcast"};return y(v=>{const z=[...v,B];return z.length>c?z.slice(-c):z}),t?.(B),T},[r,s,e,t]),w=i.useCallback(()=>{p([]),y([]),b([])},[]),d=i.useCallback(x=>x?[...a,...u].filter(m=>m.from===x||m.to===x||m.from===e&&m.to===x||m.to===e&&m.from===x).sort((m,f)=>m.timestamp-f.timestamp):[...a,...u].sort((m,f)=>m.timestamp-f.timestamp),[a,u,e]),k=i.useCallback(x=>[...a,...u].find(m=>m.id===x)||null,[a,u]),h=i.useCallback(()=>({totalSent:u.length,totalReceived:a.length,totalPending:C.length,averageLatency:0}),[u,a,C]);return{sendMessage:M,broadcastMessage:S,receivedMessages:a,sentMessages:u,pendingMessages:C,clearMessages:w,getMessageHistory:d,getMessageById:k,getMessageStats:h,isReady:r}}function st(l){const{npcId:e,onGroupJoined:t,onGroupLeft:n,onGroupMessage:s,onGroupMemberJoined:r,onGroupMemberLeft:c,...a}=l,{executeCommand:p,getSystemState:u,isReady:y}=ue(a),[C,b]=i.useState([]),[R,M]=i.useState([]),[S,w]=i.useState([]),[d,k]=i.useState(new Map),h=i.useRef(0),x=i.useRef(new Map),m=i.useRef(new Set),f=i.useRef([]);f.current=C;const T=i.useRef(new Set),D=i.useRef(""),O=i.useRef(null),B=2e3,v=500;i.useEffect(()=>{if(!y)return;const L=`node_${e}`,_=setInterval(()=>{const U=u();if(!U)return;const Z=Array.from(U.groups.values()),ne=Z.map(q=>`${q.id}:${q.members.size}:${q.lastActivity}`).join("|");if(ne!==D.current){D.current=ne,w(Z);const q=Z.filter(g=>g.members.has(L)).map(g=>g.id);T.current.clear();for(const g of q)T.current.add(g);const se=f.current,I=q.filter(g=>!se.includes(g)),P=se.filter(g=>!q.includes(g));if((I.length>0||P.length>0)&&(b(q),M(q),O.current=null,I.forEach(g=>{const A=Z.find(Q=>Q.id===g);A&&t?.(g,A)}),P.forEach(g=>n?.(g)),P.length>0)){for(const g of P)x.current.delete(g);k(g=>{const A=new Map(g);for(const Q of P)A.delete(Q);return A})}for(const g of Z){const A=new Set(Array.from(g.members).map(j=>j.startsWith("node_")?j.slice(5):j)),Q=x.current.get(g.id);if(Q){for(const j of A)Q.has(j)||r?.(j,g.id);for(const j of Q)A.has(j)||c?.(j,g.id)}x.current.set(g.id,A)}}const ee=U.messageQueues.get(L)??[];if(ee.length===0)return;const fe=ee[ee.length-1]?.id??null,ie=O.current;if(ie&&ie===fe)return;let ae=0;if(ie){for(let q=ee.length-1;q>=0;q--)if(ee[q]?.id===ie){ae=q+1;break}}O.current=fe,!(ae>=ee.length)&&T.current.size!==0&&k(q=>{const se=new Map(q),I=new Set;for(let P=ae;P<ee.length;P++){const g=ee[P];if(!g||g.to!=="group"||!g.groupId||!T.current.has(g.groupId)||m.current.has(g.id))continue;if(m.current.size>=B){const j=Array.from(m.current);m.current=new Set(j.slice(j.length-Math.floor(B/2)))}m.current.add(g.id);const A=se.get(g.groupId),Q=I.has(g.groupId)?A??[]:A?A.slice():[];I.has(g.groupId)||(I.add(g.groupId),se.set(g.groupId,Q)),Q.push(g),s?.(g,g.groupId)}if(I.size===0)return q;for(const P of I){const g=se.get(P);g&&g.length>v&&se.set(P,g.slice(-v))}return se})},250);return()=>clearInterval(_)},[y,u,e,t,n,s,r,c]);const z=i.useCallback((L,_=[],U)=>{if(!y)return;const Z=Date.now();p({type:"createGroup",group:{type:"party",members:new Set,maxMembers:U?.maxSize??20,range:1e3,persistent:!1,createdAt:Z,lastActivity:Z}})},[y,p,e]),N=i.useCallback(L=>{y&&p({type:"joinGroup",npcId:e,groupId:L})},[y,p,e]),G=i.useCallback(L=>{y&&p({type:"leaveGroup",npcId:e,groupId:L})},[y,p,e]),F=i.useCallback((L,_,U="chat")=>{if(!y||!C.includes(L))return"";const Z=`${e}-group-${++h.current}-${Date.now()}`,ne=Date.now();return p({type:"sendMessage",message:{id:Z,from:e,to:"group",groupId:L,type:U==="action"||U==="state"||U==="system"?U:"chat",payload:_,priority:"normal",timestamp:ne,reliability:"reliable"}}),Z},[y,p,e,C]),V=i.useCallback((L,_)=>{if(!y||!R.includes(L))return;const U={id:`invite-${Date.now()}`,from:e,to:_,type:"system",payload:{groupId:L,inviterId:e},priority:"normal",timestamp:Date.now(),reliability:"reliable"};p({type:"sendMessage",message:U})},[y,p,e,R]),Y=i.useCallback((L,_)=>{!y||!R.includes(L)||p({type:"leaveGroup",npcId:_,groupId:L})},[y,p,R]),$=i.useCallback(L=>S.find(_=>_.id===L)||null,[S]),K=i.useCallback(L=>{const _=$(L);return _?Array.from(_.members).map(U=>U.startsWith("node_")?U.slice(5):U):[]},[$]),X=i.useCallback(L=>d.get(L)||[],[d]);return{createGroup:z,joinGroup:N,leaveGroup:G,sendGroupMessage:F,inviteToGroup:V,kickFromGroup:Y,joinedGroups:C,ownedGroups:R,availableGroups:S,getGroupInfo:$,getGroupMembers:K,getGroupMessages:X,isReady:y}}function qe(l={}){const{updateInterval:e=1e3,enableRealTime:t=!0,trackHistory:n=!1,historyLength:s=100,...r}=l,{getSnapshot:c,getNetworkStats:a,getSystemState:p,isReady:u}=ue(r),[y,C]=i.useState(null),[b,R]=i.useState([]),[M,S]=i.useState(!1),[w,d]=i.useState(0),k=i.useCallback(()=>{if(!u)return null;const f=c(),T=a(),D=p();if(!f||!T)return null;const O=f.nodeCount,B=f.connectionCount,v=T.totalMessages??0,z=B,N=0,G=(B>0,100),F=f.messagesPerSecond,V={updateTime:0,messageProcessingTime:0,connectionProcessingTime:0},Y=D?Array.from(D.groups.values()):[],$=D?D.groups.size:f.activeGroups,K=$,X=$>0?Y.reduce((L,_)=>L+_.members.size,0)/$:0;return{totalNodes:O,totalConnections:B,totalMessages:v,averageLatency:f.averageLatency,messagesPerSecond:F,activeConnections:z,failedConnections:N,connectionSuccessRate:G,sentMessages:v,receivedMessages:v,failedMessages:0,messageSuccessRate:100,updateTime:V.updateTime,messageProcessingTime:V.messageProcessingTime,connectionProcessingTime:V.connectionProcessingTime,totalGroups:$,activeGroups:K,averageGroupSize:X}},[u,c,a,p,e]),h=i.useCallback(()=>{S(!0);const f=k();f&&(C(f),d(Date.now()),n&&R(T=>{const D=[...T,f];return D.length>s?D.slice(-s):D})),S(!1)},[k,n,s]);i.useEffect(()=>{if(!t||!u)return;const f=setInterval(()=>{h()},e);return()=>clearInterval(f)},[t,u,h,e]),i.useEffect(()=>{u&&h()},[u,h]);const x=i.useCallback(f=>b.length===0?0:b.reduce((D,O)=>D+O[f],0)/b.length,[b]),m=i.useCallback(f=>b.length===0?0:Math.max(...b.map(T=>T[f])),[b]);return{stats:y,statsHistory:n?b:[],refreshStats:h,getHistoricalAverage:x,getPeakValue:m,isLoading:M,lastUpdate:w,isReady:u}}function ot(l){const[e,t]=i.useState(!1),[n,s]=i.useState(new Map),[r,c]=i.useState(),a=i.useRef(null),p=i.useCallback(C=>{const b={...l,...C};a.current&&a.current.disconnect();const R=new Ne({url:b.url,roomId:b.roomId,playerName:b.playerName,playerColor:b.playerColor,onConnect:()=>{t(!0),c(void 0)},onDisconnect:()=>{t(!1),s(new Map)},onPlayerJoin:(M,S)=>{s(w=>{const d=new Map(w);return d.set(M,S),d})},onPlayerUpdate:(M,S)=>{s(w=>{const d=new Map(w);return d.set(M,S),d})},onPlayerLeave:M=>{s(S=>{const w=new Map(S);return w.delete(M),w})},onError:M=>{c(M)}});a.current=R,R.connect()},[l]),u=i.useCallback(()=>{a.current?.disconnect(),t(!1),s(new Map)},[]),y=i.useCallback(C=>{a.current?.updateLocalPlayer(C)},[]);return i.useEffect(()=>()=>{a.current?.disconnect(),a.current=null},[]),{isConnected:e,players:n,error:r,connect:p,disconnect:u,updateLocalPlayer:y}}function rt(l){const{config:e,characterUrl:t,rigidBodyRef:n}=l,s=Me.useGaesupStore(v=>v.mode?.type??"character"),r=Me.useGaesupStore(v=>v.animationState),[c,a]=i.useState({isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,roomId:null,error:null,ping:0,lastUpdate:0}),p=i.useRef(null),u=i.useRef(null),y=i.useRef(null),C=i.useRef(null),b=i.useRef(e),R=i.useRef(c),M=i.useRef(s),S=i.useRef(r);i.useEffect(()=>{R.current=c},[c]),i.useEffect(()=>{M.current=s},[s]),i.useEffect(()=>{S.current=r},[r]);const[w,d]=i.useState(()=>new Map),k=i.useRef(new Map);i.useEffect(()=>{k.current=w},[w]),i.useEffect(()=>{n&&(C.current=n)},[n]),i.useEffect(()=>{const v={updateRate:e.tracking.updateRate,velocityThreshold:e.tracking.velocityThreshold,sendRateLimit:e.tracking.sendRateLimit};y.current=new Qe(v)},[e.tracking]);const h=i.useCallback(v=>{u.current&&u.current.disconnect(),p.current={playerName:v.playerName,playerColor:v.playerColor},a(N=>({...N,connectionStatus:"connecting",error:null,roomId:v.roomId}));const z=new Ne({url:e.websocket.url,roomId:v.roomId,playerName:v.playerName,playerColor:v.playerColor,reconnectAttempts:e.websocket.reconnectAttempts,reconnectDelay:e.websocket.reconnectDelay,pingInterval:e.websocket.pingInterval,sendRateLimit:e.tracking.sendRateLimit,enableAck:e.enableAck,reliableTimeout:e.reliableTimeout,reliableRetryCount:e.reliableRetryCount,logLevel:e.logLevel,logToConsole:e.logToConsole,onConnect:()=>{a(N=>({...N,isConnected:!0,connectionStatus:"connected",error:null,lastUpdate:Date.now()}))},onWelcome:N=>{a(G=>({...G,localPlayerId:N,lastUpdate:Date.now()}))},onDisconnect:()=>{a(N=>({...N,isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,lastUpdate:Date.now()}))},onPlayerJoin:(N,G)=>{a(F=>{const V=new Map(F.players);return V.set(N,G),{...F,players:V,lastUpdate:Date.now()}})},onPlayerUpdate:(N,G)=>{a(F=>{const V=new Map(F.players);return V.set(N,G),{...F,players:V,lastUpdate:Date.now()}})},onPlayerLeave:N=>{a(G=>{const F=new Map(G.players);return F.delete(N),{...G,players:F,lastUpdate:Date.now()}})},onChat:(N,G,F)=>{d(Y=>{const $=new Map(Y);return $.set(N,{text:G,expiresAt:Date.now()+2500}),$})},onPing:N=>{a(G=>({...G,ping:N,lastUpdate:Date.now()}))},onError:N=>{a(G=>({...G,connectionStatus:"error",error:N,lastUpdate:Date.now()}))}});u.current=z,z.connect()},[e.websocket.url,e.websocket.reconnectAttempts,e.websocket.reconnectDelay,e.websocket.pingInterval,e.tracking.sendRateLimit,e.logLevel,e.logToConsole]),x=i.useCallback(()=>{u.current?.disconnect(),y.current?.reset(),C.current=null,d(new Map),a(v=>({...v,isConnected:!1,connectionStatus:"disconnected",players:new Map,localPlayerId:null,roomId:null,error:null}))},[]),m=i.useCallback(v=>{C.current=v},[]),f=i.useCallback(()=>{C.current=null,y.current?.reset()},[]),T=i.useCallback(v=>{b.current={...b.current,...v},v.tracking&&y.current&&y.current.updateConfig(v.tracking)},[]),D=i.useCallback((v,z)=>{const N=u.current;if(!N)return;const G=z?.range??b.current.proximityRange;N.sendChat(v,{range:G});const F=c.localPlayerId;if(!F)return;const V=z?.ttlMs??2500,Y=String(v??"").trim().slice(0,200);Y&&d($=>{const K=new Map($);return K.set(F,{text:Y,expiresAt:Date.now()+V}),K})},[c.localPlayerId]);i.useEffect(()=>{if(!c.isConnected)return;const v=Math.max(15,Math.floor(1e3/Math.max(1,b.current.tracking.updateRate))),z=window.setInterval(()=>{if(!R.current.isConnected||!u.current||!y.current||!C.current?.current||!p.current)return;const{playerName:G,playerColor:F}=p.current,V=M.current,Y=S.current?.[V]?.current??"idle",$=y.current.trackPosition(C.current,G,F,t,Y);if($){const{modelUrl:K,...X}=$;u.current.updateLocalPlayer(K?{...X,modelUrl:K}:X)}if(k.current.size>0){const K=Date.now(),X=[];if(k.current.forEach((L,_)=>{L.expiresAt<=K&&X.push(_)}),X.length>0){const L=new Map(k.current);for(const _ of X)L.delete(_);d(L)}}},v);return()=>window.clearInterval(z)},[c.isConnected,t]),i.useEffect(()=>()=>{u.current?.disconnect()},[]);const O=i.useMemo(()=>{const v=new Map;return w.forEach((z,N)=>{v.set(N,z.text)}),v},[w]),B=c.localPlayerId?w.get(c.localPlayerId)?.text??null:null;return{...c,connect:h,disconnect:x,startTracking:m,stopTracking:f,updateConfig:T,sendChat:D,speechByPlayerId:O,localSpeechText:B}}function it(l,e){const t=[];for(const n of l.values())for(const s of n)t.length>=e&&t.shift(),t.push(s);return t}const at=({systemId:l="main",className:e,style:t,onClose:n})=>{const{getSnapshot:s,getSystemState:r,isReady:c}=ue({systemId:l}),{stats:a,refreshStats:p}=qe({systemId:l,enableRealTime:!0}),[u,y]=i.useState({snapshot:null,system:null,messages:[],isExpanded:!0,activeTab:"overview"});i.useEffect(()=>{if(!c)return;const d=setInterval(()=>{const k=s(),h=r();if(!k&&!h)return;const x=h?it(h.messageQueues,50):[];y(m=>({...m,snapshot:k??m.snapshot,system:h??m.system,messages:x}))},500);return()=>clearInterval(d)},[c,s,r]);const C=()=>{if(!u.snapshot)return o.jsx("div",{children:"No data available"});const{snapshot:d}=u,k=u.system?.groups.size??d.activeGroups;return o.jsxs("div",{style:{padding:"10px"},children:[o.jsx("h4",{children:"Network Overview"}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"10px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"Total Nodes:"})," ",d.nodeCount]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Total Connections:"})," ",d.connectionCount]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Total Groups:"})," ",k]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Recent Messages:"})," ",u.messages.length]})]}),a&&o.jsxs("div",{style:{marginTop:"15px"},children:[o.jsx("h5",{children:"Performance Metrics"}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"10px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"Messages/sec:"})," ",a.messagesPerSecond.toFixed(2)]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Avg Latency:"})," ",a.averageLatency.toFixed(2),"ms"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Connection Success:"})," ",a.connectionSuccessRate.toFixed(1),"%"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Update Time:"})," ",a.updateTime.toFixed(2),"ms"]})]})]})]})},b=()=>{const d=u.system;if(!d)return o.jsx("div",{children:"No data available"});const k=Array.from(d.nodes.values());return o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Network Nodes (",k.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:k.map(h=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",h.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Position:"})," (",h.position.x.toFixed(1),", ",h.position.y.toFixed(1),", ",h.position.z.toFixed(1),")"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Connections:"})," ",h.connections.size]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Groups:"})," ",Array.from(d.groups.values()).filter(x=>x.members.has(h.id)).map(x=>x.id).join(", ")||"None"]})]},h.id))})]})},R=()=>{const d=u.system;if(!d)return o.jsx("div",{children:"No data available"});const k=Array.from(d.connections.values());return o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Network Connections (",k.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:k.map(h=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",h.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"From:"})," ",h.nodeA," → ",o.jsx("strong",{children:"To:"})," ",h.nodeB]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Status:"})," ",h.status]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Latency:"})," ",h.latency.toFixed(1),"ms"]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Last Activity:"})," ",new Date(h.lastActivity).toLocaleTimeString()]})]},h.id))})]})},M=()=>o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("h4",{children:["Recent Messages (",u.messages.length,")"]}),o.jsx("div",{style:{maxHeight:"300px",overflowY:"auto"},children:u.messages.slice().reverse().map((d,k)=>o.jsxs("div",{style:{border:"1px solid #ccc",margin:"5px 0",padding:"8px",borderRadius:"4px",backgroundColor:d.type==="system"?"#f0f8ff":"#ffffff"},children:[o.jsxs("div",{children:[o.jsx("strong",{children:"ID:"})," ",d.id]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Type:"})," ",d.type]}),o.jsxs("div",{children:[o.jsx("strong",{children:"From:"})," ",d.from," → ",o.jsx("strong",{children:"To:"})," ",d.to==="group"?`group:${d.groupId??"unknown"}`:d.to]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Time:"})," ",new Date(d.timestamp).toLocaleTimeString()]}),o.jsxs("div",{children:[o.jsx("strong",{children:"Payload:"})," ",JSON.stringify(d.payload)]})]},`${d.id}-${k}`))})]}),S=()=>a?o.jsxs("div",{style:{padding:"10px"},children:[o.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"10px"},children:[o.jsx("h4",{children:"Network Statistics"}),o.jsx("button",{onClick:p,children:"Refresh"})]}),o.jsxs("div",{style:{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"15px"},children:[o.jsxs("div",{children:[o.jsx("h5",{children:"Basic Stats"}),o.jsxs("div",{children:["Total Nodes: ",a.totalNodes]}),o.jsxs("div",{children:["Total Connections: ",a.totalConnections]}),o.jsxs("div",{children:["Total Messages: ",a.totalMessages]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Performance"}),o.jsxs("div",{children:["Messages/sec: ",a.messagesPerSecond.toFixed(2)]}),o.jsxs("div",{children:["Avg Latency: ",a.averageLatency.toFixed(2),"ms"]}),o.jsxs("div",{children:["Update Time: ",a.updateTime.toFixed(2),"ms"]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Connection Stats"}),o.jsxs("div",{children:["Active: ",a.activeConnections]}),o.jsxs("div",{children:["Failed: ",a.failedConnections]}),o.jsxs("div",{children:["Success Rate: ",a.connectionSuccessRate.toFixed(1),"%"]})]}),o.jsxs("div",{children:[o.jsx("h5",{children:"Group Stats"}),o.jsxs("div",{children:["Total Groups: ",a.totalGroups]}),o.jsxs("div",{children:["Active Groups: ",a.activeGroups]}),o.jsxs("div",{children:["Avg Group Size: ",a.averageGroupSize.toFixed(1)]})]})]})]}):o.jsx("div",{children:"Loading stats..."}),w=()=>{switch(u.activeTab){case"overview":return C();case"nodes":return b();case"connections":return R();case"messages":return M();case"stats":return S();default:return C()}};return u.isExpanded?o.jsxs("div",{className:e,style:{position:"fixed",top:"10px",right:"10px",width:"600px",height:"500px",backgroundColor:"white",border:"1px solid #ccc",borderRadius:"8px",boxShadow:"0 4px 8px rgba(0,0,0,0.1)",zIndex:1e3,display:"flex",flexDirection:"column",...t},children:[o.jsxs("div",{style:{padding:"10px",borderBottom:"1px solid #ccc",display:"flex",justifyContent:"space-between",alignItems:"center"},children:[o.jsx("h3",{style:{margin:0},children:"Network Debug Panel"}),o.jsxs("div",{children:[o.jsx("button",{onClick:()=>y(d=>({...d,isExpanded:!1})),children:"−"}),n&&o.jsx("button",{onClick:n,style:{marginLeft:"5px"},children:"×"})]})]}),o.jsx("div",{style:{display:"flex",borderBottom:"1px solid #ccc",backgroundColor:"#f9f9f9"},children:["overview","nodes","connections","messages","stats"].map(d=>o.jsx("button",{style:{flex:1,padding:"8px 12px",border:"none",backgroundColor:u.activeTab===d?"white":"transparent",borderBottom:u.activeTab===d?"2px solid #007acc":"none",cursor:"pointer"},onClick:()=>y(k=>({...k,activeTab:d})),children:d.charAt(0).toUpperCase()+d.slice(1)},d))}),o.jsx("div",{style:{flex:1,overflow:"auto"},children:w()}),o.jsxs("div",{style:{padding:"5px 10px",borderTop:"1px solid #ccc",backgroundColor:"#f9f9f9",fontSize:"12px",color:"#666"},children:["Status: ",c?"Connected":"Disconnected"," | System: ",l," | Last Update: ",new Date().toLocaleTimeString()]})]}):o.jsx("div",{className:e,style:{position:"fixed",top:"10px",right:"10px",backgroundColor:"#f0f0f0",border:"1px solid #ccc",borderRadius:"4px",padding:"5px 10px",cursor:"pointer",zIndex:1e3,...t},onClick:()=>y(d=>({...d,isExpanded:!0})),children:"Network Debug"})},Ie=["#ff6b6b","#4ecdc4","#45b7d1","#96ceb4","#feca57","#ff9ff3","#54a0ff","#5f27cd","#00d2d3","#ff9f43"],Ce="#cccccc",Ae="#4a90e2",ct={active:"#00ff00",establishing:"#ffff00",unstable:"#ff9f43",disconnected:"#cccccc"},lt=l=>ct[l]??"#666666",ut=({systemId:l="main",showLabels:e=!0,showConnectionLines:t=!0,showGroups:n=!0,nodeSize:s=.5,connectionWidth:r=.05,updateInterval:c=100,maxRenderDistance:a=100})=>{const{getSystemState:p,isReady:u}=ue({systemId:l}),y=i.useRef(null),C=i.useRef(0),[b,R]=i.useState({nodes:[],connections:[],groups:new Map});be.useFrame(()=>{const h=Date.now();if(!u||h-C.current<c)return;const x=p();if(!x)return;const m=new Map;x.groups.forEach((f,T)=>{m.set(T,Array.from(f.members))}),R({nodes:Array.from(x.nodes.values()),connections:Array.from(x.connections.values()),groups:m}),C.current=h});const M=i.useMemo(()=>{const h=new Map;let x=0;return b.groups.forEach((m,f)=>{h.set(f,Ie[x%Ie.length]??Ce),x++}),h},[b.groups]),S=i.useMemo(()=>{const h=new Map;return b.groups.forEach((x,m)=>{for(const f of x){const T=h.get(f);T?T.push(m):h.set(f,[m])}}),h},[b.groups]),w=i.useMemo(()=>{const h=new Map;for(const x of b.nodes)h.set(x.id,x);return h},[b.nodes]),d=i.useMemo(()=>{const h=[];return b.groups.forEach((x,m)=>{const f=[];for(const v of x){const z=w.get(v);z&&f.push(z)}if(f.length<2)return;let T=0,D=0,O=0;for(const v of f)T+=v.position.x,D+=v.position.y,O+=v.position.z;T/=f.length,D/=f.length,O/=f.length;let B=0;for(const v of f){const z=v.position.x-T,N=v.position.y-D,G=v.position.z-O,F=z*z+N*N+G*G;F>B&&(B=F)}h.push({groupId:m,center:[T,D,O],radius:Math.sqrt(B)+1})}),h},[b.groups,w]);if(!u)return o.jsx(H.Text,{position:[0,0,0],fontSize:1,color:"#ff0000",anchorX:"center",anchorY:"middle",children:"Network not ready"});const k=h=>{if(!n)return Ae;const m=S.get(h)?.[0];return m?M.get(m)??Ce:Ae};return o.jsxs("group",{ref:y,children:[b.nodes.map(h=>{const x=k(h.id),m=S.get(h.id);return o.jsxs("group",{position:[h.position.x,h.position.y,h.position.z],children:[o.jsx(H.Sphere,{args:[s],position:[0,0,0],children:o.jsx("meshBasicMaterial",{color:x})}),h.connections.size>0&&o.jsx(H.Sphere,{args:[s*.3],position:[0,s+.2,0],children:o.jsx("meshBasicMaterial",{color:"#ffffff"})}),e&&o.jsx(H.Text,{position:[0,s+.5,0],fontSize:.3,color:"#ffffff",anchorX:"center",anchorY:"middle",children:h.id}),n&&m&&m.length>0&&o.jsx(H.Text,{position:[0,s+.8,0],fontSize:.2,color:x,anchorX:"center",anchorY:"middle",children:m.join(", ")})]},h.id)}),t&&b.connections.map(h=>{const x=w.get(h.nodeA),m=w.get(h.nodeB);return!x||!m?null:o.jsx(H.Line,{points:[[x.position.x,x.position.y,x.position.z],[m.position.x,m.position.y,m.position.z]],color:lt(h.status),lineWidth:r,transparent:!0,opacity:h.status==="active"?.8:.4},h.id)}),n&&d.map(({groupId:h,center:x,radius:m})=>{const f=M.get(h)??Ce;return o.jsxs("group",{children:[o.jsxs("mesh",{position:x,children:[o.jsx("ringGeometry",{args:[m-.1,m+.1,32]}),o.jsx("meshBasicMaterial",{color:f,transparent:!0,opacity:.3})]}),o.jsxs(H.Text,{position:[x[0],x[1]+m+.5,x[2]],fontSize:.4,color:f,anchorX:"center",anchorY:"middle",children:["Group: ",h]})]},`group-${h}`)}),o.jsxs("group",{position:[-10,10,0],children:[o.jsx(H.Text,{position:[0,2,0],fontSize:.5,color:"#ffffff",anchorX:"left",anchorY:"middle",children:"Network Visualization"}),o.jsxs(H.Text,{position:[0,1,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Nodes: ",b.nodes.length]}),o.jsxs(H.Text,{position:[0,.5,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Connections: ",b.connections.length]}),o.jsxs(H.Text,{position:[0,0,0],fontSize:.3,color:"#ffffff",anchorX:"left",anchorY:"middle",children:["Groups: ",b.groups.size]})]})]})};function Le(l){return"color"in l&&l.color instanceof E.Color}const Ve=i.memo(function({state:e,characterUrl:t,config:n,speechText:s}){const r=i.useRef(null),c=i.useRef(null),a=i.useRef(null);a.current||(a.current=[e.position[0],e.position[1],e.position[2]]);const p=i.useRef(new E.Vector3),u=i.useRef(new E.Quaternion),y=i.useRef(new E.Vector3),C=i.useRef(performance.now()),b=i.useRef(new E.Vector3),R=i.useRef(new E.Quaternion),M=i.useRef(new E.Vector3),S=i.useRef(new E.Vector3),w=i.useRef(new E.Vector3),d=i.useRef(new E.Quaternion),k=i.useRef(!1),h=i.useRef(new E.Vector3),x=i.useRef(new E.Vector3),m=i.useRef(new E.Vector3),f=i.useRef(new E.Vector3),T=i.useRef(new E.Vector3),D=i.useRef(new E.Vector3),O=i.useRef({x:0,y:0,z:0}),B=i.useRef({x:0,y:0,z:0,w:1}),v=i.useRef(0),z=i.useRef(0),N=t||e.modelUrl||"";if(!N)return null;const G=I=>{if(typeof I!="string")return null;const P=I.trim();if(!P)return null;const g=P.startsWith("#")?P:`#${P}`;return/^#[0-9a-fA-F]{3}$/.test(g)||/^#[0-9a-fA-F]{6}$/.test(g)?g:null},F=i.useMemo(()=>G(e.color),[e.color]),V=n?.tracking?.interpolationSpeed||.15,Y=n?.rendering?.characterScale||1,$=n?.rendering?.nameTagHeight||3.5,K=n?.rendering?.nameTagSize||.5,{scene:X,animations:L}=H.useGLTF(N),_=i.useMemo(()=>Ye.SkeletonUtils.clone(X),[X]),{actions:U,ref:Z}=H.useAnimations(L,c),ne=i.useRef([]),ee=i.useRef(null),fe=i.useRef(null),ie=i.useRef(performance.now()),ae=i.useRef(new E.Vector3);i.useEffect(()=>{for(const P of ne.current)try{P.dispose()}catch{}if(ne.current=[],!F)return;const I=P=>{if(!Le(P))return P;const g=P.clone();return Le(g)?(g.color.set(F),ne.current.push(g),g):P};return _.traverse(P=>{(P instanceof E.Mesh||P instanceof E.SkinnedMesh)&&P.material&&(Array.isArray(P.material)?P.material=P.material.map(g=>I(g)):P.material=I(P.material))}),()=>{for(const P of ne.current)try{P.dispose()}catch{}ne.current=[]}},[_,F]);const q=I=>{if(!U)return null;const P=U[I];if(P)return P;const g=I.toLowerCase(),A=Object.keys(U),Q=A.find(j=>j.toLowerCase().includes(g));if(Q)return U[Q]??null;if(g==="run"){const j=A.find(W=>W.toLowerCase().includes("walk"))??A[0];return j?U[j]??null:null}if(g==="idle"){const j=A.find(W=>W.toLowerCase().includes("idle"))??A[0];return j?U[j]??null:null}return A[0]?U[A[0]]??null:null},se=(I,P,g,A,Q,j,W)=>{const oe=Math.max(1e-4,A),ce=Math.max(0,j),J=2/oe,te=J*ce,we=1/(1+te+.48*te*te+.235*te*te*te);m.current.copy(P),h.current.copy(I).sub(P);const ge=Q*oe,re=h.current.length();re>ge&&re>0&&h.current.multiplyScalar(ge/re),f.current.copy(I).sub(h.current),x.current.copy(g).addScaledVector(h.current,J).multiplyScalar(ce),g.addScaledVector(x.current,-J).multiplyScalar(we),W.copy(h.current).add(x.current).multiplyScalar(we).add(f.current),T.current.copy(m.current).sub(I),D.current.copy(W).sub(m.current),T.current.dot(D.current)>0&&(W.copy(m.current),g.set(0,0,0))};return i.useEffect(()=>{if(!U)return;const I=n?.tracking?.velocityThreshold??.5,P=I,g=I*.6,A=180,Q=e.velocity?Math.hypot(e.velocity[0],e.velocity[1],e.velocity[2]):y.current.length(),j=e.animation?.trim(),W=(ee.current??"idle")==="run"?Q<g?"idle":"run":Q>P?"run":"idle",oe=(j&&j.length>0?j:W)||"idle";if(ee.current===oe)return;const ce=performance.now();if(ce-ie.current<A)return;const J=q(oe);if(!J)return;const te=fe.current;return J.enabled=!0,J.setEffectiveTimeScale(1),J.setEffectiveWeight(1),J.reset().play(),te&&te!==J?J.crossFadeFrom(te,.18,!0):J.fadeIn(.18),ee.current=oe,fe.current=J,ie.current=ce,()=>{}},[U,e.animation,e.velocity,n?.tracking?.velocityThreshold]),i.useEffect(()=>{if(C.current=performance.now(),p.current.set(e.position[0],e.position[1],e.position[2]),ae.current.set(e.position[0],e.position[1],e.position[2]),!k.current&&r.current){const A=p.current;k.current=!0,S.current.copy(A),w.current.set(0,0,0),d.current.copy(u.current);const Q=r.current,j=O.current;j.x=A.x,j.y=A.y,j.z=A.z,Q.setNextKinematicTranslation(j);const W=B.current;W.x=u.current.x,W.y=u.current.y,W.z=u.current.z,W.w=u.current.w,Q.setNextKinematicRotation(W)}const I=e.rotation,g=Math.abs(I[0])<1e-6&&Math.abs(I[1])<1e-6&&Math.abs(I[2])<1e-6&&Math.abs(I[3]-1)<1e-6?[1,0,0,0]:I;u.current.set(g[1],g[2],g[3],g[0]),e.velocity&&y.current.set(e.velocity[0],e.velocity[1],e.velocity[2])},[e.position,e.rotation,e.velocity]),be.useFrame((I,P)=>{if(!r.current||!c.current)return;const g=z.current;if(g>0){if(v.current+=Math.max(0,P),v.current<g)return;v.current=0}else v.current=0;const A=k.current?S.current:p.current,Q=I.camera.position.distanceTo(A),j=k.current?Ke.weightFromDistance(Q,25,140,4):1;z.current=j>=.7?0:j>=.4?1/30:j>=.2?1/15:1/8;const W=(performance.now()-C.current)/1e3,oe=Math.max(0,Math.min(.12,W));if(M.current.copy(p.current).addScaledVector(y.current,oe),!k.current){const ye=r.current.translation(),de=r.current.rotation();k.current=!0,S.current.set(ye.x,ye.y,ye.z),w.current.set(0,0,0),d.current.set(de.x,de.y,de.z,de.w)}const ce=Math.max(.01,Math.min(.9,V)),J=Math.max(.03,Math.min(.22,.03+(1-ce)*.19)),te=120;if(S.current.distanceTo(M.current)>10||P>.25)S.current.copy(M.current),w.current.set(0,0,0),d.current.copy(u.current);else{se(S.current,M.current,w.current,J,te,P,b.current),S.current.copy(b.current);const ye=Math.max(.025,J*.7),de=1-Math.exp(-Math.max(0,P)/ye);R.current.copy(d.current).slerp(u.current,de),d.current.copy(R.current)}ae.current.copy(S.current);const ge=r.current,re=O.current;re.x=S.current.x,re.y=S.current.y,re.z=S.current.z,ge.setNextKinematicTranslation(re);const me=B.current;me.x=d.current.x,me.y=d.current.y,me.z=d.current.z,me.w=d.current.w,ge.setNextKinematicRotation(me)}),o.jsxs("group",{children:[o.jsxs(xe.RigidBody,{ref:r,type:"kinematicPosition",position:a.current??void 0,colliders:!1,children:[o.jsx(xe.CapsuleCollider,{args:[.5,.5],position:[0,1.5,0]}),o.jsx("group",{ref:c,children:o.jsx("group",{ref:Z,scale:[Y,Y,Y],children:o.jsx("primitive",{object:_})})}),o.jsx(H.Text,{position:[0,$,0],fontSize:K,color:"white",anchorX:"center",anchorY:"middle",outlineWidth:.05,outlineColor:"black",children:e.name})]}),s?o.jsx(Ue.SpeechBalloon,{text:s,position:ae.current}):null]})});function dt({onConnect:l,error:e,isConnecting:t}){const[n,s]=i.useState(""),[r,c]=i.useState("room1"),[a]=i.useState(()=>`#${Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")}`),p=u=>{u.preventDefault(),n.trim()&&l({roomId:r,playerName:n.trim(),playerColor:a})};return o.jsx("div",{style:{width:"100vw",height:"100vh",display:"flex",alignItems:"center",justifyContent:"center",background:"#1a1a1a"},children:o.jsxs("form",{onSubmit:p,style:{background:"rgba(0, 0, 0, 0.8)",padding:"40px",borderRadius:"10px",color:"white",minWidth:"300px"},children:[o.jsx("h2",{style:{marginBottom:"20px",textAlign:"center"},children:"네트워크 멀티플레이어"}),o.jsxs("div",{style:{marginBottom:"15px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"플레이어 이름"}),o.jsx("input",{type:"text",placeholder:"이름을 입력하세요",value:n,onChange:u=>s(u.target.value),disabled:t,style:{width:"100%",padding:"10px",borderRadius:"5px",border:"1px solid #ccc",background:"#333",color:"white",fontSize:"14px"}})]}),o.jsxs("div",{style:{marginBottom:"20px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"방 코드"}),o.jsx("input",{type:"text",placeholder:"방 코드",value:r,onChange:u=>c(u.target.value),disabled:t,style:{width:"100%",padding:"10px",borderRadius:"5px",border:"1px solid #ccc",background:"#333",color:"white",fontSize:"14px"}})]}),o.jsxs("div",{style:{marginBottom:"20px"},children:[o.jsx("label",{style:{display:"block",marginBottom:"5px"},children:"플레이어 색상"}),o.jsx("div",{style:{width:"30px",height:"30px",backgroundColor:a,borderRadius:"50%",border:"2px solid #ccc"}})]}),o.jsx("button",{type:"submit",disabled:!n.trim()||t,style:{width:"100%",padding:"12px",borderRadius:"5px",border:"none",background:!n.trim()||t?"#666":"#4CAF50",color:"white",fontSize:"16px",cursor:!n.trim()||t?"not-allowed":"pointer",transition:"background-color 0.2s"},children:t?"연결 중...":"연결하기"}),e&&o.jsx("div",{style:{color:"#ff6b6b",marginTop:"15px",padding:"10px",background:"rgba(255, 107, 107, 0.1)",borderRadius:"5px",fontSize:"14px"},children:e})]})})}function ht({state:l,playerName:e,onDisconnect:t,onSendChat:n}){const{isConnected:s,connectionStatus:r,players:c,roomId:a,error:p,ping:u,localPlayerId:y,lastUpdate:C}=l,[b,R]=i.useState("");if(!s)return null;const M=i.useCallback(()=>{if(!n)return;const S=b.trim();S&&(n(S),R(""))},[n,b]);return o.jsxs("div",{style:{position:"fixed",top:10,left:10,background:"rgba(0, 0, 0, 0.8)",padding:"8px",borderRadius:"6px",color:"white",minWidth:"160px",backdropFilter:"blur(5px)",border:"1px solid rgba(255, 255, 255, 0.08)",lineHeight:1.2},children:[o.jsx("h3",{style:{marginTop:0,marginBottom:"6px",fontSize:"12px",borderBottom:"1px solid rgba(255, 255, 255, 0.2)",paddingBottom:"6px"},children:"네트워크 정보"}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"상태:"}),o.jsx("span",{style:{marginLeft:"8px",color:r==="connected"?"#4CAF50":"#ff6b6b"},children:r==="connected"?"연결됨":r==="connecting"?"연결 중":r==="error"?"오류":"연결 끊김"})]}),e&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"플레이어:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:e})]}),a&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"방:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:a})]}),y&&o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"내 ID:"})," ",o.jsx("span",{style:{marginLeft:"8px"},children:y})]}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"최근 업데이트:"}),o.jsx("span",{style:{marginLeft:"8px"},children:C?`${Math.max(0,Date.now()-C)}ms 전`:"-"})]}),o.jsxs("div",{style:{marginBottom:"6px",fontSize:"12px"},children:[o.jsx("strong",{children:"접속자:"}),o.jsxs("span",{style:{marginLeft:"8px"},children:[c.size+(s?1:0),"명"]})]}),u>0&&o.jsxs("div",{style:{marginBottom:"8px",fontSize:"12px"},children:[o.jsx("strong",{children:"핑:"}),o.jsxs("span",{style:{marginLeft:"8px",color:u<50?"#4CAF50":u<100?"#FFA726":"#ff6b6b"},children:[u,"ms"]})]}),c.size>0&&o.jsxs("div",{style:{marginBottom:"8px"},children:[o.jsx("strong",{children:"다른 플레이어:"}),o.jsx("div",{style:{marginTop:"6px",maxHeight:"80px",overflowY:"auto",fontSize:"11px"},children:Array.from(c.entries()).map(([S,w])=>o.jsxs("div",{style:{display:"flex",alignItems:"center",marginBottom:"4px",padding:"3px",background:"rgba(255, 255, 255, 0.05)",borderRadius:"3px"},children:[o.jsx("div",{style:{width:"10px",height:"10px",backgroundColor:w.color,borderRadius:"50%",marginRight:"6px",border:"1px solid rgba(255, 255, 255, 0.3)"}}),o.jsxs("span",{style:{flex:1},children:[w.name,o.jsxs("span",{style:{opacity:.7,marginLeft:"8px"},children:["(",w.position[0].toFixed(1),",",w.position[1].toFixed(1),",",w.position[2].toFixed(1),")"]}),w.animation?o.jsx("span",{style:{opacity:.7,marginLeft:"8px"},children:w.animation}):null]})]},S))})]}),p&&o.jsx("div",{style:{color:"#ff6b6b",marginBottom:"15px",padding:"8px",background:"rgba(255, 107, 107, 0.1)",borderRadius:"5px",fontSize:"14px"},children:p}),n?o.jsxs("div",{style:{marginBottom:"8px"},children:[o.jsx("strong",{children:"채팅:"}),o.jsxs("div",{style:{display:"flex",gap:"6px",marginTop:"6px"},children:[o.jsx("input",{value:b,onChange:S=>R(S.target.value),placeholder:"Enter로 전송",style:{flex:1,padding:"6px",borderRadius:"4px",border:"1px solid rgba(255, 255, 255, 0.2)",background:"rgba(255, 255, 255, 0.05)",color:"white",fontSize:"12px"},onKeyDown:S=>{S.key==="Enter"&&(S.preventDefault(),M())}}),o.jsx("button",{onClick:M,style:{padding:"6px 8px",borderRadius:"4px",border:"none",background:"#4CAF50",color:"white",fontSize:"12px",cursor:"pointer"},disabled:!b.trim(),children:"전송"})]})]}):null,o.jsx("button",{onClick:t,style:{width:"100%",padding:"8px",borderRadius:"4px",border:"none",background:"#ff6b6b",color:"white",fontSize:"12px",cursor:"pointer",transition:"background-color 0.2s"},onMouseEnter:S=>{S.currentTarget.style.backgroundColor="#ff5252"},onMouseLeave:S=>{S.currentTarget.style.backgroundColor="#ff6b6b"},children:"연결 끊기"})]})}const pt=6,ft=1e-4;function gt({playerRef:l,onChange:e}){const t=i.useRef({x:0,y:0,z:0}),n=i.useRef(0);return be.useFrame(()=>{if(n.current++,n.current%pt!==0)return;const s=l.current;if(!s)return;const r=s.translation(),c=t.current,a=r.x-c.x,p=r.y-c.y,u=r.z-c.z;a*a+p*p+u*u<ft||(c.x=r.x,c.y=r.y,c.z=r.z,e(r.x,r.y,r.z))}),null}const mt=i.memo(function({players:e,characterUrl:t,vehicleUrl:n,airplaneUrl:s,playerRef:r,config:c,localPlayerColor:a,proximityRange:p,speechByPlayerId:u,localSpeechText:y}){i.useEffect(()=>{window.CHARACTER_URL=t},[t]);const[C,b]=i.useState([0,0,0]),R=i.useMemo(()=>new E.Vector3,[]),M=i.useMemo(()=>(w,d,k)=>{R.set(w,d,k),b([w,d,k])},[R]),S=i.useMemo(()=>{const w=p;if(!w||w<=0)return e;const[d,k,h]=C,x=new Map;return e.forEach((m,f)=>{const[T,D,O]=m.position,B=T-d,v=D-k,z=O-h;B*B+v*v+z*z<=w*w&&x.set(f,m)}),x},[e,p,C]);return o.jsx(ze.WorldContainer,{urls:{characterUrl:t,vehicleUrl:n,airplaneUrl:s},children:o.jsxs(be.Canvas,{shadows:!0,dpr:[1,1.5],camera:{position:[0,10,20],fov:75,near:.1,far:1e3},style:{width:"100vw",height:"100vh"},children:[o.jsx(H.Environment,{background:!0,preset:"sunset",backgroundBlurriness:1}),o.jsx("directionalLight",{castShadow:!0,"shadow-normalBias":.06,position:[20,30,10],intensity:.5,"shadow-mapSize":[1024,1024],"shadow-camera-near":1,"shadow-camera-far":120,"shadow-camera-top":90,"shadow-camera-right":90,"shadow-camera-bottom":-90,"shadow-camera-left":-90}),o.jsx(i.Suspense,{fallback:null,children:o.jsx(ze.GaesupWorldContent,{children:o.jsxs(xe.Physics,{children:[o.jsx(gt,{playerRef:r,onChange:M}),o.jsx(ve.ControllerWrapper,{rigidBodyRef:r,rotation:xe.euler({x:0,y:Math.PI,z:0}),parts:[],...a?{baseColor:a}:{}}),y?o.jsx(Ue.SpeechBalloon,{text:y,position:R}):null,Array.from(S.entries()).map(([w,d])=>o.jsx(Ve,{playerId:w,state:d,characterUrl:t,config:c,...(()=>{const k=u?.get(w);return k?{speechText:k}:{}})()},w)),o.jsx(H.Grid,{renderOrder:-1,position:[0,.01,0],infiniteGrid:!0,cellSize:2,cellThickness:1,cellColor:"#1d1d1d",sectionSize:5,sectionThickness:0,fadeDistance:1e3}),o.jsx(xe.RigidBody,{type:"fixed",children:o.jsxs("mesh",{receiveShadow:!0,position:[0,-1,0],children:[o.jsx("boxGeometry",{args:[1e3,2,1e3]}),o.jsx("meshStandardMaterial",{color:"#3d3d3d"})]})}),o.jsx(ve.Clicker,{}),o.jsx(ve.GroundClicker,{})]})})})]})})}),yt={updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4,websocket:{url:"ws://localhost:8090",reconnectAttempts:5,reconnectDelay:1e3,pingInterval:3e4},tracking:{updateRate:20,velocityThreshold:.5,sendRateLimit:50,interpolationSpeed:.15},rendering:{nameTagHeight:3.5,nameTagSize:.5,characterScale:1}},De={updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4},xt={high:{updateFrequency:60,maxConnections:200,messageQueueSize:2e3,enableBatching:!0,batchSize:20,compressionLevel:3,connectionPoolSize:100,bandwidth:2e3,signalStrength:2},balanced:{updateFrequency:30,maxConnections:100,messageQueueSize:1e3,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,bandwidth:1e3,signalStrength:1},low:{updateFrequency:15,maxConnections:50,messageQueueSize:500,enableBatching:!1,batchSize:5,compressionLevel:0,connectionPoolSize:25,bandwidth:500,signalStrength:.5}},bt=l=>{const e=[];return(l.updateFrequency<=0||l.updateFrequency>120)&&e.push("updateFrequency must be between 1 and 120"),l.maxConnections<=0&&e.push("maxConnections must be greater than 0"),l.messageQueueSize<=0&&e.push("messageQueueSize must be greater than 0"),l.maxDistance<=0&&e.push("maxDistance must be greater than 0"),l.signalStrength<=0&&e.push("signalStrength must be greater than 0"),l.bandwidth<=0&&e.push("bandwidth must be greater than 0"),l.proximityRange<=0&&e.push("proximityRange must be greater than 0"),l.batchSize<=0&&e.push("batchSize must be greater than 0"),(l.compressionLevel<0||l.compressionLevel>9)&&e.push("compressionLevel must be between 0 and 9"),l.connectionPoolSize<0&&e.push("connectionPoolSize must be non-negative"),l.reliableRetryCount<0&&e.push("reliableRetryCount must be non-negative"),l.reliableTimeout<=0&&e.push("reliableTimeout must be greater than 0"),l.maxGroupSize<=0&&e.push("maxGroupSize must be greater than 0"),l.debugUpdateInterval<=0&&e.push("debugUpdateInterval must be greater than 0"),l.maxLogEntries<=0&&e.push("maxLogEntries must be greater than 0"),l.maxMessagesPerSecond<=0&&e.push("maxMessagesPerSecond must be greater than 0"),l.messageGCInterval<=0&&e.push("messageGCInterval must be greater than 0"),l.connectionTimeout<=0&&e.push("connectionTimeout must be greater than 0"),l.inactiveNodeCleanup<=0&&e.push("inactiveNodeCleanup must be greater than 0"),{isValid:e.length===0,errors:e}},St=Be.create((l,e)=>({config:De,updateConfig:t=>l(n=>({config:{...n.config,...t}})),updatePerformanceConfig:t=>l(n=>({config:{...n.config,...t}})),updateCommunicationConfig:t=>l(n=>({config:{...n.config,...t}})),updateOptimizationConfig:t=>l(n=>({config:{...n.config,...t}})),updateDebugConfig:t=>l(n=>({config:{...n.config,...t}})),resetConfig:()=>l({config:{...De}}),resetToProfile:t=>l(n=>({config:{...n.config,...xt[t]}})),validateConfig:()=>bt(e().config)})),Ee={snapshot:null,connectedNodes:new Map,activeGroups:new Map,recentMessages:[],isConnected:!1,connectionStatus:"disconnected",lastError:null,lastUpdate:0},Se=Be.create((l,e)=>({state:{...Ee},updateSnapshot:t=>l(n=>({state:{...n.state,snapshot:{...t},lastUpdate:Date.now()}})),updateConnectedNodes:t=>l(n=>{const s=new Map;return t.forEach(r=>{s.set(r.id,{...r})}),{state:{...n.state,connectedNodes:s,lastUpdate:Date.now()}}}),updateActiveGroups:t=>l(n=>{const s=new Map;return t.forEach(r=>{s.set(r.id,{...r,members:new Set(r.members)})}),{state:{...n.state,activeGroups:s,lastUpdate:Date.now()}}}),addRecentMessage:t=>l(n=>{const s=[...n.state.recentMessages,{...t}];return s.length>100&&s.shift(),{state:{...n.state,recentMessages:s,lastUpdate:Date.now()}}}),setConnectionStatus:(t,n)=>l(s=>({state:{...s.state,connectionStatus:t,isConnected:t==="connected",lastError:n||null,lastUpdate:Date.now()}})),clearRecentMessages:()=>l(t=>({state:{...t.state,recentMessages:[],lastUpdate:Date.now()}})),getNodeById:t=>{const{state:n}=e();return n.connectedNodes.get(t)||null},getGroupById:t=>{const{state:n}=e();return n.activeGroups.get(t)||null},getNodesByGroup:t=>{const{state:n}=e(),s=n.activeGroups.get(t);if(!s)return[];const r=[];return s.members.forEach(c=>{const a=n.connectedNodes.get(c);a&&r.push(a)}),r},getMessagesForNode:t=>{const{state:n}=e();return n.recentMessages.filter(s=>s.from===t||s.to===t)},resetState:()=>l({state:{...Ee,connectedNodes:new Map,activeGroups:new Map,recentMessages:[]}})})),wt=()=>{const{connectionStatus:l,isConnected:e,lastError:t}=Se(n=>n.state);return{status:l,isConnected:e,lastError:t,isConnecting:l==="connecting",hasError:l==="error"}},vt=l=>{const e=Se(t=>t.state.recentMessages);return l&&l>0?e.slice(-l):e},Ct=()=>{const l=Se(e=>e.state.connectedNodes);return Array.from(l.values())},Mt=()=>{const l=Se(e=>e.state.activeGroups);return Array.from(l.values())};var kt=Object.defineProperty,Pt=Object.getOwnPropertyDescriptor,je=(l,e,t,n)=>{for(var s=n>1?void 0:n?Pt(e,t):e,r=l.length-1,c;r>=0;r--)(c=l[r])&&(s=(n?c(e,t,s):c(s))||s);return n&&s&&kt(e,t,s),s};exports.NetworkBridge=class extends pe.CoreBridge{constructor(){super(),this.setupEngineSubscriptions()}ensureMainEngine(e){this.getEngine("main")||this.register("main",e??this.createDefaultConfig())}buildEngine(e,t){try{const n=new _e(t??this.createDefaultConfig());return n.start(),{system:n,dispose:()=>n.dispose()}}catch(n){return console.error("[NetworkBridge] Failed to build engine:",n),null}}executeCommand(e,t,n){const{system:s}=e;s.executeCommand(t)}createSnapshot(e,t){const{system:n}=e;return n.createSnapshot()}updateSystem(e,t){this.getEngine(e)&&this.notifyListeners(e)}createDefaultConfig(){return{updateFrequency:30,maxConnections:100,messageQueueSize:1e3,maxDistance:100,signalStrength:1,bandwidth:1e3,proximityRange:10,enableBatching:!0,batchSize:10,compressionLevel:1,connectionPoolSize:50,enableChatMessages:!0,enableActionMessages:!0,enableStateMessages:!0,enableSystemMessages:!0,reliableRetryCount:3,reliableTimeout:5e3,enableAck:!0,maxGroupSize:20,autoJoinProximity:!0,groupMessagePriority:"normal",enableDebugPanel:!1,enableVisualizer:!1,showConnectionLines:!1,showMessageFlow:!1,debugUpdateInterval:500,logLevel:"warn",logToConsole:!0,logToFile:!1,maxLogEntries:1e3,enableEncryption:!1,enableRateLimit:!0,maxMessagesPerSecond:100,messageGCInterval:3e4,connectionTimeout:3e4,inactiveNodeCleanup:6e4}}setupEngineSubscriptions(){this.on("snapshot",e=>{})}getNetworkStats(e="main"){const t=this.getEngine(e);return t?t.system.getDebugInfo()?.networkStats??null:null}getSystemState(e="main"){const t=this.getEngine(e);return t?t.system.getState():null}};je([pe.ValidateCommand()],exports.NetworkBridge.prototype,"executeCommand",1);je([pe.LogSnapshot(),pe.CacheSnapshot(16)],exports.NetworkBridge.prototype,"createSnapshot",1);exports.NetworkBridge=je([pe.DomainBridge("networks"),pe.EnableMetrics()],exports.NetworkBridge);const $e=Xe.WORLD_SNAPSHOT_DOMAINS;function We(l){const e=new Map;for(const t of l())!t||typeof t.key!="string"||e.set(t.key,t);return e}function Je(l,e){const t=We(l),n=e.domains??$e,s={};for(const c of n){const a=t.get(c);if(a)try{s[c]=a.serialize()}catch{s[c]=null}}const r=e.savedAt??Date.now();return{kind:"world",worldId:e.worldId??e.hostId,version:e.version??1,hostId:e.hostId,...e.hostName?{hostName:e.hostName}:{},savedAt:r,capturedAt:r,domains:s}}function ke(l,e,t={}){const n=We(l),s=t.allowedDomains?new Set(t.allowedDomains):null,r=[],c=[];for(const[a,p]of Object.entries(e.domains??{})){if(s&&!s.has(a)){c.push(a);continue}if(t.filter&&!t.filter(a,p)){c.push(a);continue}const u=n.get(a);if(!u){c.push(a);continue}try{u.hydrate(p),r.push(a)}catch{c.push(a)}}return{applied:r,skipped:c}}function Rt(l){return()=>l.getBindings()}class Tt{listeners=new Set;latest=null;publish(e){this.latest=e,this.emit({type:"snapshot",snapshot:e})}leave(e){this.emit({type:"leave",hostId:e})}subscribe(e){if(this.listeners.add(e),this.latest)try{e({type:"snapshot",snapshot:this.latest})}catch{}return()=>{this.listeners.delete(e)}}close(){this.listeners.clear(),this.latest=null}emit(e){for(const t of this.listeners)try{t(e)}catch{}}}function Nt(){return new Tt}const Pe=1,Re="VisitSnapshot",Te="VisitLeave";function jt(l){try{const e=JSON.parse(l);return!e||typeof e!="object"||e.type!==Re&&e.type!==Te||typeof e.v!="number"||e.v!==Pe?null:e}catch{return null}}function zt(l){const e=new Set;let t=l.onMessage(s=>{const r=jt(s);r&&(r.type===Re?n({type:"snapshot",snapshot:r.snapshot}):r.type===Te&&n({type:"leave",hostId:r.hostId}))});function n(s){for(const r of e)try{r(s)}catch{}}return{publish(s){const r={type:Re,v:Pe,snapshot:s};try{l.send(JSON.stringify(r))}catch{}},leave(s){const r={type:Te,v:Pe,hostId:s};try{l.send(JSON.stringify(r))}catch{}},subscribe(s){return e.add(s),()=>{e.delete(s)}},close(){if(t){try{t()}catch{}t=null}e.clear()}}}function It(l){const{hostId:e,hostName:t,channel:n,bindings:s,hostMode:r=!0,autoApply:c=!1,allowedDomains:a}=l,[p,u]=i.useState(null),[y,C]=i.useState(null),b=i.useRef(s);b.current=s;const R=i.useRef(a);R.current=a;const M=i.useRef(c);M.current=c,i.useEffect(()=>{const h=n.subscribe(x=>{if(x.type==="snapshot"){if(x.snapshot.hostId===e)return;u(x.snapshot),M.current&&ke(b.current,x.snapshot,{...R.current?{allowedDomains:R.current}:{}})}else x.type==="leave"&&u(m=>m&&m.hostId===x.hostId?null:m)});return()=>{h()}},[n,e]);const S=i.useCallback(()=>{const h=Je(b.current,{hostId:e,...t?{hostName:t}:{}});return r&&n.publish(h),C(h),h},[n,e,t,r]),w=i.useCallback(()=>{const h=p;return h?ke(b.current,h,{...R.current?{allowedDomains:R.current}:{}}).applied.length>0:!1},[p]),d=i.useCallback(()=>{u(null)},[]),k=i.useCallback(()=>{n.leave(e)},[n,e]);return i.useMemo(()=>({remoteSnapshot:p,lastPublished:y,publishNow:S,acceptRemote:w,dismissRemote:d,announceLeave:k}),[p,y,S,w,d,k])}exports.MockNetworkAdapter=Ge.MockNetworkAdapter;exports.createNetworkEnvelope=Ge.createNetworkEnvelope;exports.createCommandAcceptedResult=le.createCommandAcceptedResult;exports.createCommandAuthorityRouter=le.createCommandAuthorityRouter;exports.createCommandRejectedResult=le.createCommandRejectedResult;exports.createGameCommand=le.createGameCommand;exports.createServerEvent=le.createServerEvent;exports.createSnapshotAck=le.createSnapshotAck;exports.createStateDelta=le.createStateDelta;exports.ConnectionForm=dt;exports.ConnectionPool=Fe;exports.DEFAULT_VISIT_DOMAINS=$e;exports.MessageQueue=he;exports.MultiplayerCanvas=mt;exports.NPCNetworkManager=Oe;exports.NPCNetworkVisualizer=ut;exports.NetworkDebugPanel=at;exports.NetworkSystem=_e;exports.PlayerInfoOverlay=ht;exports.PlayerNetworkManager=Ne;exports.PlayerPositionTracker=Qe;exports.RemotePlayer=Ve;exports.applyVisitSnapshot=ke;exports.createLocalVisitChannel=Nt;exports.createWebSocketVisitChannel=zt;exports.defaultMultiplayerConfig=yt;exports.serializeVisit=Je;exports.useMultiplayer=rt;exports.useNPCConnection=tt;exports.useNetworkBridge=ue;exports.useNetworkConfigStore=St;exports.useNetworkConnection=wt;exports.useNetworkGroup=st;exports.useNetworkGroups=Mt;exports.useNetworkMessage=nt;exports.useNetworkNodes=Ct;exports.useNetworkStateStore=Se;exports.useNetworkStats=qe;exports.usePlayerNetwork=ot;exports.useRecentMessages=vt;exports.useVisitRoom=It;exports.visitProviderFromSaveSystem=Rt;
package/dist/network.js CHANGED
@@ -11,8 +11,8 @@ import { SkeletonUtils as tt } from "three-stdlib";
11
11
  import { w as nt } from "./sfe-CRsG1dTW.js";
12
12
  import { S as Oe } from "./index-CUYKx17r.js";
13
13
  import "reflect-metadata";
14
- import { W as st, G as ot } from "./index-Drmv86ws.js";
15
- import { C as rt, a as it, G as at } from "./index-HxpKt5rO.js";
14
+ import { W as st, G as ot } from "./index-3WAK67Ha.js";
15
+ import { C as rt, a as it, G as at } from "./index-DXZjZF_s.js";
16
16
  import { create as _e } from "zustand";
17
17
  import { $ as ct, a0 as lt, a1 as ut, a2 as dt, a3 as ht, a8 as pt } from "./index-C5agFfBe.js";
18
18
  import { W as gt } from "./snapshot-OExk53wq.js";