mudlet-map-renderer 0.12.0-konva → 0.13.0-konva
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/Renderer.d.ts +5 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +254 -255
- package/dist/index.mjs.map +1 -1
- package/package.json +40 -40
package/dist/Renderer.d.ts
CHANGED
|
@@ -213,8 +213,12 @@ export declare class Renderer {
|
|
|
213
213
|
* Note: This is more expensive than refreshCurrentRoomOverlay() but ensures everything is updated.
|
|
214
214
|
*/
|
|
215
215
|
refresh(): void;
|
|
216
|
+
/**
|
|
217
|
+
* Updates the player position marker without centering the view.
|
|
218
|
+
* Use this when you want to show where the player is without moving the viewport.
|
|
219
|
+
*/
|
|
220
|
+
updatePositionMarker(roomId: number): void;
|
|
216
221
|
setPosition(roomId: number): void;
|
|
217
|
-
centerOn(roomId: number): void;
|
|
218
222
|
renderPath(locations: number[], color?: string): import('konva/lib/shapes/Line').Line<{
|
|
219
223
|
points: number[];
|
|
220
224
|
stroke: string;
|
|
@@ -226,7 +230,6 @@ export declare class Renderer {
|
|
|
226
230
|
private refreshHighlights;
|
|
227
231
|
private createHighlightShape;
|
|
228
232
|
private centerOnRoom;
|
|
229
|
-
private centerOnRoomView;
|
|
230
233
|
private renderRooms;
|
|
231
234
|
private scheduleRoomCulling;
|
|
232
235
|
private updateRoomCulling;
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const R=require("konva"),H=["north","south","east","west","northeast","northwest","southeast","southwest"],j={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},nt={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},ot=["north","south","east","west","northeast","northwest","southeast","southwest"],pt={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function xt(C){return C?Object.prototype.hasOwnProperty.call(nt,C):!1}function F(C,t,e,s=1){if(!xt(e))return{x:C,y:t};const o=nt[e];return{x:C+o.x*s,y:t+o.y*s}}function wt(C,t,e,s=1){if(!xt(e))return{x:C,y:t};const o=nt[e],n=Math.atan2(o.y,o.x);return{x:C+Math.cos(n)*s,y:t+Math.sin(n)*s}}const q={OPEN_DOOR:"rgb(10, 155, 10)",CLOSED_DOOR:"rgb(226, 205, 59)",LOCKED_DOOR:"rgb(155, 10, 10)",ONE_WAY_FILL:"rgb(155, 10, 10)"},bt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},Rt=["up","down","in","out"];function vt(C){switch(C){case 1:return q.OPEN_DOOR;case 2:return q.CLOSED_DOOR;default:return q.LOCKED_DOOR}}class Et{constructor(t,e){this.mapReader=t,this.mapRenderer=e}getRoomEdgePoint(t,e,s,o){return d.roomShape==="circle"?wt(t,e,s,o):F(t,e,s,o)}render(t,e){return this.renderWithColor(t,d.lineColor,e)}renderWithColor(t,e,s){return t.aDir&&t.bDir&&H.includes(t.aDir)&&H.includes(t.bDir)?this.renderTwoWayExit(t,e,s):this.renderOneWayExit(t,e)}renderTwoWayExit(t,e,s){const o=this.mapReader.getRoom(t.a),n=this.mapReader.getRoom(t.b);if(!o||!n||!t.aDir||!t.bDir||!H.includes(t.aDir)||!H.includes(t.bDir)||o.customLines[j[t.aDir]]&&n.customLines[j[t.bDir]]||o.z!==n.z&&(s!==n.z&&o.customLines[j[t.aDir]]||s!==o.z&&n.customLines[j[t.bDir]]))return;const i=new R.Group,r=[];if(r.push(...Object.values(this.getRoomEdgePoint(o.x,o.y,t.aDir,d.roomSize/2))),r.push(...Object.values(this.getRoomEdgePoint(n.x,n.y,t.bDir,d.roomSize/2))),o.doors[j[t.aDir]]||n.doors[j[t.bDir]]){const c=this.renderDoor(r,o.doors[j[t.aDir]]??n.doors[j[t.bDir]]);i.add(c)}const a=new R.Line({points:r,stroke:e,strokeWidth:d.lineWidth,perfectDrawEnabled:!1});return i.add(a),i}renderOneWayExit(t,e){const s=t.aDir?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),o=t.aDir?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),n=t.aDir?t.aDir:t.bDir;if(!n||!s||!o||!H.includes(n)||s.customLines[j[n]||n])return;if(s.area!=o.area&&n){const u=this.mapReader.getColorValue(o.env);return this.renderAreaExit(s,n,u)}let i={x:o.x,y:o.y};(o.area!==s.area||o.z!==s.z)&&(i=F(s.x,s.y,n,d.roomSize/2));const r=F(s.x,s.y,n,.3),a=r.x-(r.x-i.x)/2,c=r.y-(r.y-i.y)/2,l=new R.Group,h=[];h.push(...Object.values(this.getRoomEdgePoint(s.x,s.y,n,d.roomSize/2))),h.push(i.x,i.y);const g=new R.Line({points:h,stroke:e,strokeWidth:d.lineWidth,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1});l.add(g);const f=new R.Arrow({points:[h[0],h[1],a,c],pointerLength:.5,pointerWidth:.35,strokeWidth:d.lineWidth*1.4,stroke:e,fill:q.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return l.add(f),l}renderAreaExit(t,e,s){const o=this.getRoomEdgePoint(t.x,t.y,e,d.roomSize/2),n=F(t.x,t.y,e,d.roomSize*1.5),i=s??this.mapReader.getColorValue(t.env);return new R.Arrow({points:[o.x,o.y,n.x,n.y],pointerLength:.3,pointerWidth:.3,strokeWidth:d.lineWidth*1.4,stroke:i,fill:i})}renderSpecialExits(t,e){return Object.entries(t.customLines).map(([s,o])=>{const n=[t.x,t.y];o.points.reduce((l,h)=>(l.push(h.x,-h.y),l),n);const i=o.attributes.arrow?R.Arrow:R.Line,r=e??`rgb(${o.attributes.color.r}, ${o.attributes.color.g}, ${o.attributes.color.b})`,a=new i({points:n,strokeWidth:d.lineWidth,stroke:r,fill:e??`rgb(${o.attributes.color.r}, ${o.attributes.color.g} , ${o.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1});let c=o.attributes.style;return c==="dot line"?(a.dash([.05,.05]),a.dashOffset(.1)):c==="dash line"?a.dash([.4,.2]):c==="solid line"||c!==void 0&&console.log("Brak opisu stylu: "+c),a})}renderStubs(t,e=d.lineColor){return t.stubs.map(s=>{const o=bt[s],n=this.getRoomEdgePoint(t.x,t.y,o,d.roomSize/2),i=F(t.x,t.y,o,d.roomSize/2+.5),r=[n.x,n.y,i.x,i.y];return new R.Line({points:r,stroke:e,strokeWidth:d.lineWidth})})}renderInnerExits(t){return Rt.map(e=>{if(t.exits[e]){const s=new R.Group,o=new R.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.mapReader.getSymbolColor(t.env,.6),stroke:this.mapReader.getSymbolColor(t.env),strokeWidth:d.lineWidth,radius:d.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1});s.add(o);let n=t.doors[e];if(n!==void 0)switch(n){case 1:o.stroke(q.OPEN_DOOR);break;case 2:o.stroke(q.CLOSED_DOOR);break;default:o.stroke(q.LOCKED_DOOR)}switch(e){case"up":o.position(F(t.x,t.y,"south",d.roomSize/4));break;case"down":o.rotation(180),o.position(F(t.x,t.y,"north",d.roomSize/4));break;case"in":const i=o.clone();i.rotation(-90),i.position(F(t.x,t.y,"east",d.roomSize/4)),s.add(i),o.rotation(90),o.position(F(t.x,t.y,"west",d.roomSize/4));break;case"out":const r=o.clone();r.rotation(90),r.position(F(t.x,t.y,"east",d.roomSize/4)),s.add(r),o.rotation(-90),o.position(F(t.x,t.y,"west",d.roomSize/4));break}return s}}).filter(e=>e!==void 0)}renderDoor(t,e){const s={x:t[0]+(t[2]-t[0])/2,y:t[1]+(t[3]-t[1])/2};return new R.Rect({x:s.x-d.roomSize/4,y:s.y-d.roomSize/4,width:d.roomSize/2,height:d.roomSize/2,stroke:vt(e),strokeWidth:d.lineWidth})}}class yt{constructor(t,e){this.rooms=[],this.labels=[],this.rooms=t,this.bounds=this.createBounds(),this.labels=e}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){return this.rooms.reduce((t,e)=>({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY})}}class it{constructor(t){this.planes={},this.exits=new Map,this.version=0,this.area=t,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(t){return this.planes[t]}getPlanes(){return Object.values(this.planes)}getRooms(){return this.area.rooms}getLinkExits(t){return Array.from(this.exits.values()).filter(e=>e.zIndex.includes(t))}createPlanes(){const t=this.area.rooms.reduce((e,s)=>(e[s.z]||(e[s.z]=[]),e[s.z].push(s),e),{});return Object.entries(t).reduce((e,[s,o])=>(e[+s]=new yt(o,this.area.labels.filter(n=>n.Z===+s)),e),{})}createExits(){this.area.rooms.forEach(t=>{Object.entries(t.specialExits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e)),Object.entries(t.exits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e))})}createHalfExit(t,e,s,o){if(t===e)return;const n=Math.min(t,e),i=Math.max(t,e),r=`${n}-${i}`;let a=this.exits.get(r);a||(a={a:n,b:i,zIndex:[s]}),n==t?a.aDir=o:a.bDir=o,a.zIndex.push(s),this.exits.set(r,a)}}class at extends yt{constructor(t,e){super(t.getRooms(),t.getLabels()),this.basePlane=t,this.visitedRooms=e}getRooms(){return this.basePlane.getRooms().filter(t=>this.visitedRooms.has(t.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const t=this.getRooms();return t.length?t.reduce((e,s)=>({minX:Math.min(e.minX,s.x),maxX:Math.max(e.maxX,s.x),minY:Math.min(e.minY,s.y),maxY:Math.max(e.maxY,s.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class Q extends it{constructor(t,e){super(t),this.planeCache=new WeakMap,this.visitedRooms=e instanceof Set?e:new Set(e??[]),this.areaRoomIds=new Set(t.rooms.map(s=>s.id))}getPlane(t){const e=super.getPlane(t);if(!e)return e;let s=this.planeCache.get(e);return s||(s=new at(e,this.visitedRooms),this.planeCache.set(e,s)),s}getPlanes(){return super.getPlanes().map(t=>{let e=this.planeCache.get(t);return e||(e=new at(t,this.visitedRooms),this.planeCache.set(t,e)),e})}getLinkExits(t){return super.getLinkExits(t).filter(e=>this.visitedRooms.has(e.a)||this.visitedRooms.has(e.b))}getVisitedRoomCount(){return super.getRooms().reduce((t,e)=>t+(this.visitedRooms.has(e.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(t){return this.areaRoomIds.has(t)&&this.visitedRooms.has(t)}getVisitedRoomIds(){return super.getRooms().filter(t=>this.visitedRooms.has(t.id)).map(t=>t.id)}addVisitedRoom(t){const e=this.visitedRooms.has(t);this.visitedRooms.add(t);const s=!e&&this.areaRoomIds.has(t);return s&&this.markDirty(),s}addVisitedRooms(t){let e=0;for(const s of t){const o=this.visitedRooms.has(s);this.visitedRooms.add(s),!o&&this.areaRoomIds.has(s)&&e++}return e>0&&this.markDirty(),e}}class Ct{constructor(t,e){this.paths=[],this.mapReader=t,this.overlayLayer=e}renderPath(t,e,s,o="#66E64D"){if(e===void 0||s===void 0)return;const n=t.map(h=>this.mapReader.getRoom(h)).filter(h=>h!==void 0),i=[];let r=null;const a=()=>{r&&(r.length<4&&i.pop(),r=null)},c=()=>(r||(r=[],i.push(r)),r);n.forEach((h,g)=>{if(!this.isRoomVisible(h,e,s))return;const f=g>0?n[g-1]:void 0,u=g<n.length-1?n[g+1]:void 0;if(this.isRoomVisible(f,e,s))c();else{a();const x=c();if(f){const y=this.getDirectionTowards(h,f);if(y){const I=F(h.x,h.y,y,d.roomSize);x.push(I.x,I.y)}}}if(r?.push(h.x,h.y),!this.isRoomVisible(u,e,s)&&u){const x=this.getDirectionTowards(h,u);if(x){const y=F(h.x,h.y,x,d.roomSize);r?.push(y.x,y.y)}a()}}),a();const l=i.filter(h=>h.length>=4).map(h=>new R.Line({points:h,stroke:o,strokeWidth:d.lineWidth*4}));return l.forEach(h=>{this.overlayLayer.add(h),this.paths.push(h)}),l[0]}clearPaths(){this.paths.forEach(t=>{t.destroy()}),this.paths=[]}isRoomVisible(t,e,s){return t?t.area===e&&t.z===s:!1}getDirectionTowards(t,e){for(const s of ot)if(t.exits[s]===e.id)return s;for(const s of ot)if(e.exits[s]===t.id)return pt[s]}}const St=.6,K=75,kt=.025,It="rgb(225, 255, 225)",_="rgb(120, 72, 0)";function ht(C,t){const e=parseInt(C.slice(1,3),16),s=parseInt(C.slice(3,5),16),o=parseInt(C.slice(5,7),16);return`rgba(${e}, ${s}, ${o}, ${t})`}const B=class B{};B.roomSize=St,B.lineWidth=kt,B.lineColor=It,B.instantMapMove=!1,B.highlightCurrentRoom=!0,B.cullingEnabled=!0,B.cullingMode="indexed",B.cullingBounds=null,B.labelRenderMode="image",B.roomShape="rectangle",B.playerMarker={strokeColor:"#00e5b2",strokeAlpha:1,fillColor:"#00e5b2",fillAlpha:0,strokeWidth:.1,sizeFactor:1.7,dash:[.05,.05],dashEnabled:!0};let d=B;class Mt{constructor(t,e){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.standaloneExitNodes=[],this.spatialBucketSize=5,this.roomSpatialIndex=new Map,this.exitSpatialIndex=new Map,this.visibleRooms=new Set,this.visibleStandaloneExitNodes=new Set,this.cullingScheduled=!1,this.stage=new R.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),window.addEventListener("resize",()=>{this.onResize(t)}),t.addEventListener("resize",()=>{this.onResize(t)}),this.linkLayer=new R.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new R.Layer,this.stage.add(this.roomLayer),this.positionLayer=new R.Layer({listening:!1}),this.stage.add(this.positionLayer),this.overlayLayer=new R.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.mapReader=e,this.exitRenderer=new Et(e,this),this.pathRenderer=new Ct(e,this.overlayLayer),this.initScaling(1.1),this.stage.on("dragmove",()=>this.scheduleRoomCulling()),this.stage.on("dragend",()=>this.scheduleRoomCulling())}onResize(t){this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(t){R.hitOnDragEnabled=!0;let e,s=!1,o=!1;this.stage.on("touchstart",n=>{const i=n.evt.touches;i&&i.length>1?(o=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(o=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",n=>{e=void 0;const i=n.evt.touches;(!i||i.length<=1)&&(o=!1,this.stage.draggable(!0))}),this.stage.on("wheel",n=>{n.evt.preventDefault();const i=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;const a={x:(r.x-this.stage.x())/i,y:(r.y-this.stage.y())/i};let c=n.evt.deltaY>0?-1:1;n.evt.ctrlKey&&(c=-c);const l=c>0?this.currentZoom*t:this.currentZoom/t,h=l*K,g=this.setZoom(l),f={x:r.x-a.x*h,y:r.y-a.y*h};this.stage.position(f),this.scheduleRoomCulling(),g&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",n=>{const i=n.evt.touches,r=i?.[0],a=i?.[1];if(a||o&&(o=!1,this.stage.draggable(!0)),r&&!a&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!r||!a){e=void 0;return}n.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),o||(o=!0,this.stage.draggable(!1));const c=this.stage.container().getBoundingClientRect(),l={x:r.clientX-c.left,y:r.clientY-c.top},h={x:a.clientX-c.left,y:a.clientY-c.top},g=Math.hypot(l.x-h.x,l.y-h.y);if(e===void 0){e=g;return}if(e===0)return;const f=this.stage.scaleX(),u=this.stage.x(),p=this.stage.y(),m={x:this.stage.width()/2,y:this.stage.height()/2},x={x:(m.x-u)/f,y:(m.y-p)/f},y=this.currentZoom*(g/e),I=this.setZoom(y),A=this.stage.scaleX(),O={x:m.x-x.x*A,y:m.y-x.y*A};this.stage.position(O),this.stage.batchDraw(),this.scheduleRoomCulling(),e=g,I&&this.emitZoomChangeEvent()})}drawArea(t,e){const s=this.mapReader.getArea(t);if(!s)return;const o=s.getPlane(e);o&&(this.currentArea=t,this.currentAreaInstance=s,this.currentZIndex=e,this.currentAreaVersion=s.getVersion(),this.clearCurrentRoomOverlay(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.standaloneExitBoundsRoomSize=void 0,this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:K*this.currentZoom,y:K*this.currentZoom}),this.renderLabels(o.getLabels()),this.renderExits(s.getLinkExits(e)),this.renderRooms(o.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}computeSpatialBucketSize(){return Math.max(d.roomSize*10,5)}getBucketKey(t,e){return`${t},${e}`}forEachBucket(t,e,s,o,n){const i=this.spatialBucketSize,r=Math.min(t,s),a=Math.max(t,s),c=Math.min(e,o),l=Math.max(e,o),h=Math.floor(r/i),g=Math.floor(a/i),f=Math.floor(c/i),u=Math.floor(l/i);for(let p=h;p<=g;p++)for(let m=f;m<=u;m++)n(this.getBucketKey(p,m))}addRoomToSpatialIndex(t){const e=d.roomSize/2,s=t.room.x-e,o=t.room.x+e,n=t.room.y-e,i=t.room.y+e;this.forEachBucket(s,n,o,i,r=>{let a=this.roomSpatialIndex.get(r);a||(a=new Set,this.roomSpatialIndex.set(r,a)),a.add(t)})}addStandaloneExitToSpatialIndex(t){const{bounds:e}=t,s=e.x,o=e.x+e.width,n=e.y,i=e.y+e.height;this.forEachBucket(s,n,o,i,r=>{let a=this.exitSpatialIndex.get(r);a||(a=new Set,this.exitSpatialIndex.set(r,a)),a.add(t)})}collectRoomCandidates(t,e,s,o){const n=new Set;return this.forEachBucket(t,e,s,o,i=>{this.roomSpatialIndex.get(i)?.forEach(a=>n.add(a))}),n}collectStandaloneExitCandidates(t,e,s,o){const n=new Set;return this.forEachBucket(t,e,s,o,i=>{this.exitSpatialIndex.get(i)?.forEach(a=>n.add(a))}),n}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==d.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(t=>{t.bounds=t.node.getClientRect({relativeTo:this.linkLayer}),this.addStandaloneExitToSpatialIndex(t)}),this.standaloneExitBoundsRoomSize=d.roomSize)}emitRoomContextEvent(t,e,s){const o=this.stage.container(),n=o.getBoundingClientRect(),i={roomId:t,position:{x:e-n.left,y:s-n.top}},r=new CustomEvent("roomcontextmenu",{detail:i});o.dispatchEvent(r)}emitZoomChangeEvent(){const t=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(t)}setZoom(t){return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:K*t,y:K*t}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}setCullingMode(t){d.cullingMode=t,d.cullingEnabled=t!=="none",this.scheduleRoomCulling()}getCullingMode(){return d.cullingMode}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}refreshCurrentRoomOverlay(){if(this.currentRoomId!==void 0){const t=this.mapReader.getRoom(this.currentRoomId);t&&this.updateCurrentRoomOverlay(t)}}refresh(){this.currentRoomId!==void 0&&this.currentArea!==void 0&&this.currentZIndex!==void 0&&(this.drawArea(this.currentArea,this.currentZIndex),this.setPosition(this.currentRoomId))}setPosition(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),o=s?.getVersion();let n=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||o!==void 0&&this.currentAreaVersion!==o||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.centerOnRoom(e,n),this.updateCurrentRoomOverlay(e);const i=ht(d.playerMarker.strokeColor,d.playerMarker.strokeAlpha),r=ht(d.playerMarker.fillColor,d.playerMarker.fillAlpha),a=d.roomSize/2*d.playerMarker.sizeFactor;this.positionRender?(this.positionRender.radius(a),this.positionRender.stroke(i),this.positionRender.fill(r),this.positionRender.strokeWidth(d.playerMarker.strokeWidth),this.positionRender.dash(d.playerMarker.dash??[]),this.positionRender.dashEnabled(d.playerMarker.dashEnabled)):(this.positionRender=new R.Circle({x:e.x,y:e.y,radius:a,stroke:i,fill:r,strokeWidth:d.playerMarker.strokeWidth,dash:d.playerMarker.dash,dashEnabled:d.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender))}centerOn(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),o=s?.getVersion();let n=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||o!==void 0&&this.currentAreaVersion!==o||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.centerOnRoomView(e,n)}renderPath(t,e){return this.pathRenderer.renderPath(t,this.currentArea,this.currentZIndex,e)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(t,e){const s=this.mapReader.getRoom(t);if(!s)return;const o=this.highlights.get(t);o?.shape&&(o.shape.destroy(),delete o.shape);const n={color:e,area:s.area,z:s.z};if(this.highlights.set(t,n),s.area===this.currentArea&&s.z===this.currentZIndex){const i=this.createHighlightShape(s,e);return this.overlayLayer.add(i),n.shape=i,this.overlayLayer.batchDraw(),i}return n.shape}clearHighlights(){this.highlights.forEach(({shape:t})=>t?.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,e)=>{if(t.shape?.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(e);if(!s)return;const o=this.createHighlightShape(s,t.color);this.overlayLayer.add(o),t.shape=o}),this.overlayLayer.batchDraw()}createHighlightShape(t,e){return d.roomShape==="circle"?new R.Circle({x:t.x,y:t.y,radius:d.roomSize/2*1.5,stroke:e,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1}):new R.Rect({x:t.x-d.roomSize/2*1.5,y:t.y-d.roomSize/2*1.5,width:d.roomSize*1.5,height:d.roomSize*1.5,stroke:e,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1})}centerOnRoom(t,e=!1){this.currentRoomId=t.id;const s={x:t.x,y:t.y};this.positionRender?.position(t);const n=this.stage.getAbsoluteTransform().point(s),i={x:this.stage.width()/2,y:this.stage.height()/2},r=i.x-n.x,a=i.y-n.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||d.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new R.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+a,duration:.2,easing:R.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}centerOnRoomView(t,e=!1){const s={x:t.x,y:t.y},n=this.stage.getAbsoluteTransform().point(s),i={x:this.stage.width()/2,y:this.stage.height()/2},r=i.x-n.x,a=i.y-n.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||d.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new R.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+a,duration:.2,easing:R.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(t){t.forEach(e=>{const s=new R.Group({x:e.x-d.roomSize/2,y:e.y-d.roomSize/2}),o=this.mapReader.getColorValue(e.env),n=d.lineColor,r=d.roomShape==="circle"?new R.Circle({x:d.roomSize/2,y:d.roomSize/2,radius:d.roomSize/2,fill:o,strokeWidth:d.lineWidth,stroke:n,perfectDrawEnabled:!1}):new R.Rect({x:0,y:0,width:d.roomSize,height:d.roomSize,fill:o,strokeWidth:d.lineWidth,stroke:n,perfectDrawEnabled:!1}),a=(m,x)=>this.emitRoomContextEvent(e.id,m,x);s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer"}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto"}),s.on("contextmenu",m=>{m.evt.preventDefault();const x=m.evt;a(x.clientX,x.clientY)});let c,l,h;const g=()=>{h!==void 0&&(this.stage.draggable(h),h=void 0)},f=()=>{c!==void 0&&(window.clearTimeout(c),c=void 0),l=void 0,g()};s.on("touchstart",m=>{if(f(),m.evt.touches&&m.evt.touches.length>1)return;const x=m.evt.touches?.[0];x&&(l={clientX:x.clientX,clientY:x.clientY},h=this.stage.draggable(),this.stage.draggable(!1),c=window.setTimeout(()=>{l&&a(l.clientX,l.clientY),f()},500))}),s.on("touchend",f),s.on("touchmove",m=>{if(!l)return;const x=m.evt.touches?.[0];if(!x){f();return}const y=x.clientX-l.clientX,I=x.clientY-l.clientY,A=y*y+I*I,O=10;if(A>O*O){const T=h;f(),T&&this.stage.startDrag()}}),s.on("touchcancel",f),s.add(r),this.renderSymbol(e,s),this.roomLayer.add(s);const u=[];this.exitRenderer.renderSpecialExits(e).forEach(m=>{this.linkLayer.add(m);const x=m.getClientRect({relativeTo:this.linkLayer}),y={node:m,bounds:x};this.standaloneExitNodes.push(y),this.addStandaloneExitToSpatialIndex(y)}),this.exitRenderer.renderStubs(e).forEach(m=>{this.linkLayer.add(m),u.push(m)}),this.exitRenderer.renderInnerExits(e).forEach(m=>{this.roomLayer.add(m)});const p={room:e,group:s,linkNodes:u};this.roomNodes.set(e.id,p),this.addRoomToSpatialIndex(p)})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;const t=this.stage.scaleX();if(!t)return;const e=this.stage.position(),s=d.roomSize/2,o=d.cullingBounds,n=o?o.x:0,i=o?o.x+o.width:this.stage.width(),r=o?o.y:0,a=o?o.y+o.height:this.stage.height(),c=Math.min(n,i),l=Math.max(n,i),h=Math.min(r,a),g=Math.max(r,a),f=(c-e.x)/t,u=(l-e.x)/t,p=(h-e.y)/t,m=(g-e.y)/t;let x=!1,y=!1;const I=d.cullingEnabled?d.cullingMode??"indexed":"none",A=f-s,O=u+s,T=p-s,w=m+s;if(this.refreshStandaloneExitBoundsIfNeeded(),I==="none"){this.roomNodes.forEach(v=>{v.group.visible()||(v.group.visible(!0),x=!0),v.linkNodes.forEach(k=>{k.visible()||(k.visible(!0),y=!0)})}),this.standaloneExitNodes.forEach(v=>{const{node:k}=v;k.visible()||(y=!0,k.visible(!0))}),x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw(),this.visibleRooms=new Set(this.roomNodes.values()),this.visibleStandaloneExitNodes=new Set(this.standaloneExitNodes);return}if(I==="basic"){const v=new Set;this.roomNodes.forEach(M=>{const Y=M.room.x-s,X=M.room.x+s,W=M.room.y-s,V=M.room.y+s,P=X>=f&&Y<=u&&V>=p&&W<=m;M.group.visible()!==P&&(M.group.visible(P),x=!0),M.linkNodes.forEach($=>{$.visible()!==P&&($.visible(P),y=!0)}),P&&v.add(M)});const k=new Set;this.standaloneExitNodes.forEach(M=>{const{node:Y,bounds:X}=M,W=X.x,V=X.x+X.width,P=X.y,$=X.y+X.height,G=V>=f&&W<=u&&$>=p&&P<=m;Y.visible()!==G&&(Y.visible(G),y=!0),G&&k.add(M)}),this.visibleRooms=v,this.visibleStandaloneExitNodes=k,x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw();return}const b=this.collectRoomCandidates(A,T,O,w),S=new Set,D=new Set;b.forEach(v=>{S.add(v);const k=v.room.x-s,M=v.room.x+s,Y=v.room.y-s,X=v.room.y+s,W=M>=f&&k<=u&&X>=p&&Y<=m;v.group.visible()!==W&&(v.group.visible(W),x=!0),v.linkNodes.forEach(V=>{V.visible()!==W&&(V.visible(W),y=!0)}),W&&D.add(v)}),this.visibleRooms.forEach(v=>{S.has(v)||(v.group.visible()&&(v.group.visible(!1),x=!0),v.linkNodes.forEach(k=>{k.visible()&&(k.visible(!1),y=!0)}))}),this.visibleRooms=D;const E=this.collectStandaloneExitCandidates(A,T,O,w),N=new Set,L=new Set;E.forEach(v=>{N.add(v);const{node:k,bounds:M}=v,Y=M.x,X=M.x+M.width,W=M.y,V=M.y+M.height,P=X>=f&&Y<=u&&V>=p&&W<=m;k.visible()!==P&&(k.visible(P),y=!0),P&&L.add(v)}),this.visibleStandaloneExitNodes.forEach(v=>{const{node:k}=v;!N.has(v)&&k.visible()&&(k.visible(!1),y=!0)}),this.visibleStandaloneExitNodes=L,x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.positionLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.positionLayer.batchDraw();return}const e=new Map;e.set(t.id,t);const s=[],o=this.currentAreaInstance instanceof Q?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(a=>a.a===t.id||a.b===t.id).forEach(a=>{const c=d.highlightCurrentRoom?this.exitRenderer.renderWithColor(a,_,this.currentZIndex):this.exitRenderer.render(a,this.currentZIndex);c&&s.push(c)});const n=d.highlightCurrentRoom?_:void 0;this.exitRenderer.renderSpecialExits(t,n).forEach(r=>{s.push(r)}),(d.highlightCurrentRoom?this.exitRenderer.renderStubs(t,_):this.exitRenderer.renderStubs(t)).forEach(r=>{s.push(r)}),[...Object.values(t.exits),...Object.values(t.specialExits)].forEach(r=>{const a=this.mapReader.getRoom(r),c=!o||o.hasVisitedRoom(r);a&&a.area===this.currentArea&&a.z===this.currentZIndex&&c&&e.set(r,a)}),s.forEach(r=>{this.positionLayer.add(r),this.currentRoomOverlay.push(r)}),e.forEach((r,a)=>{const c=a===t.id,l=this.createOverlayRoomGroup(r,{stroke:c&&d.highlightCurrentRoom?_:d.lineColor});this.positionLayer.add(l),this.currentRoomOverlay.push(l),this.exitRenderer.renderInnerExits(r).forEach(h=>{this.positionLayer.add(h),this.currentRoomOverlay.push(h)})}),this.positionRender&&this.positionRender.moveToTop(),this.positionLayer.batchDraw()}createOverlayRoomGroup(t,e){const s=new R.Group({x:t.x-d.roomSize/2,y:t.y-d.roomSize/2,listening:!1}),o=this.mapReader.getColorValue(t.env),n=e.stroke,i=d.roomShape==="circle"?new R.Circle({x:d.roomSize/2,y:d.roomSize/2,radius:d.roomSize/2,fill:o,stroke:n,strokeWidth:d.lineWidth}):new R.Rect({x:0,y:0,width:d.roomSize,height:d.roomSize,fill:o,stroke:n,strokeWidth:d.lineWidth});return s.add(i),this.renderSymbol(t,s),s}renderSymbol(t,e){if(t.roomChar!==void 0){const s=d.roomSize*.75,o=new R.Text({x:0,y:0,text:t.roomChar,fontSize:s,fontStyle:"bold",fill:this.mapReader.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:d.roomSize,height:d.roomSize});e.add(o)}}renderExits(t){t.forEach(e=>{const s=this.exitRenderer.render(e,this.currentZIndex);if(!s)return;this.linkLayer.add(s);const o=s.getClientRect({relativeTo:this.linkLayer}),n={node:s,bounds:o};this.standaloneExitNodes.push(n),this.addStandaloneExitToSpatialIndex(n)}),this.standaloneExitBoundsRoomSize=d.roomSize}renderLabels(t){t.forEach(e=>{if(d.labelRenderMode==="image"){if(!e.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${e.pixMap}`;const o=new R.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:s,listening:!1});this.linkLayer.add(o);return}this.renderLabelAsData(e)})}renderLabelAsData(t){const e=new R.Group({listening:!1}),s=new R.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(t.BgColor?.alpha??0)>0&&!d.transparentLabels?s.fill(this.getLabelColor(t.BgColor)):s.fillEnabled(!1),e.add(s);const o=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),n=Math.max(.1,Math.min(o,Math.max(t.Height*.9,.1))),i=new R.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:n,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});e.add(i),this.linkLayer.add(e)}getLabelColor(t){const e=(t?.alpha??255)/255,s=o=>Math.min(255,Math.max(0,o??0));return`rgba(${s(t?.r)}, ${s(t?.g)}, ${s(t?.b)}, ${e})`}}const ct={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function dt(C){const t=C[0]/255,e=C[1]/255,s=C[2]/255,o=Math.max(t,e,s),n=Math.min(t,e,s);return(o+n)/2}class Dt{constructor(t,e){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(s=>{s.rooms.forEach(n=>{n.y=-n.y,this.rooms[n.id]=n});const o=parseInt(s.areaId);this.areas[o]=new it(s),this.areaSources[o]=s}),this.colors=e.reduce((s,o)=>({...s,[o.envId]:{rgb:o.colors,rgbValue:`rgb(${o.colors.join(",")})`,symbolColor:dt(o.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:dt(o.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(t){return this.areas[t]}getExplorationArea(t){const e=this.areas[t];if(e instanceof Q)return e}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(t){return this.rooms[t]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new Q(e,this.visitedRooms)})}decorateWithExploration(t){return t!==void 0?this.setVisitedRooms(t):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new it(e)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(t){return this.visitedRooms=t instanceof Set?t:new Set(t),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(t){if(this.explorationEnabled){const o=this.getRoom(t);if(o){const n=this.getExplorationArea(o.area);if(n)return n.addVisitedRoom(t)}}const e=this.ensureVisitedRooms(),s=e.has(t);return e.add(t),!s}addVisitedRooms(t){const e=this.ensureVisitedRooms();let s=0;for(const o of t){if(this.explorationEnabled){const i=this.getRoom(o);if(i){const r=this.getExplorationArea(i.area);if(r){r.addVisitedRoom(o)&&s++;continue}}}const n=e.has(o);e.add(o),n||s++}return s}hasVisitedRoom(t){return this.visitedRooms?.has(t)??!1}getColorValue(t){return this.colors[t]?.rgbValue??ct.rgbValue}getSymbolColor(t,e){const s=this.colors[t]?.symbolColor??ct.symbolColor,o=Math.min(Math.max(e??1,0),1),n=s.join(",");return o!=1?`rgba(${n}, ${o})`:`rgba(${n})`}}function Nt(C){return C&&C.__esModule&&Object.prototype.hasOwnProperty.call(C,"default")?C.default:C}var U,lt;function Lt(){if(lt)return U;lt=1;class C{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((e,s)=>e.priority-s.priority)}set(e,s){const o=Number(s);if(isNaN(o))throw new TypeError('"priority" must be a number');return this.keys.has(e)?this.queue.map(n=>(n.key===e&&Object.assign(n,{priority:o}),n)):(this.keys.add(e),this.queue.push({key:e,priority:o})),this.sort(),this.queue.length}next(){const e=this.queue.shift();return this.keys.delete(e.key),e}isEmpty(){return this.queue.length===0}has(e){return this.keys.has(e)}get(e){return this.queue.find(s=>s.key===e)}}return U=C,U}var J,ut;function zt(){if(ut)return J;ut=1;function C(t,e){const s=new Map;for(const[o,n]of t)o!==e&&n instanceof Map?s.set(o,C(n,e)):o!==e&&s.set(o,n);return s}return J=C,J}var tt,ft;function At(){if(ft)return tt;ft=1;function C(e){const s=Number(e);return!(isNaN(s)||s<=0)}function t(e){const s=new Map;return Object.keys(e).forEach(n=>{const i=e[n];if(i!==null&&typeof i=="object"&&!Array.isArray(i))return s.set(n,t(i));if(!C(i))throw new Error(`Could not add node at key "${n}", make sure it's a valid node`,i);return s.set(n,Number(i))}),s}return tt=t,tt}var et,gt;function Xt(){if(gt)return et;gt=1;function C(t){if(!(t instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof t}`);t.forEach((e,s)=>{if(typeof e=="object"&&e instanceof Map){C(e);return}if(typeof e!="number"||e<=0)throw new Error(`Values must be numbers greater than 0. Found value ${e} at ${s}`)})}return et=C,et}var st,mt;function Ot(){if(mt)return st;mt=1;const C=Lt(),t=zt(),e=At(),s=Xt();class o{constructor(i){i instanceof Map?(s(i),this.graph=i):i?this.graph=e(i):this.graph=new Map}addNode(i,r){let a;return r instanceof Map?(s(r),a=r):a=e(r),this.graph.set(i,a),this}addVertex(i,r){return this.addNode(i,r)}removeNode(i){return this.graph=t(this.graph,i),this}path(i,r,a={}){if(!this.graph.size)return a.cost?{path:null,cost:0}:null;const c=new Set,l=new C,h=new Map;let g=[],f=0,u=[];if(a.avoid&&(u=[].concat(a.avoid)),u.includes(i))throw new Error(`Starting node (${i}) cannot be avoided`);if(u.includes(r))throw new Error(`Ending node (${r}) cannot be avoided`);for(l.set(i,0);!l.isEmpty();){const p=l.next();if(p.key===r){f=p.priority;let x=p.key;for(;h.has(x);)g.push(x),x=h.get(x);break}c.add(p.key),(this.graph.get(p.key)||new Map).forEach((x,y)=>{if(c.has(y)||u.includes(y))return null;if(!l.has(y))return h.set(y,p.key),l.set(y,p.priority+x);const I=l.get(y).priority,A=p.priority+x;return A<I?(h.set(y,p.key),l.set(y,A)):null})}return g.length?(a.trim?g.shift():g=g.concat([i]),a.reverse||(g=g.reverse()),a.cost?{path:g,cost:f}:g):a.cost?{path:null,cost:0}:null}shortestPath(...i){return this.path(...i)}}return st=o,st}var Yt=Ot();const Pt=Nt(Yt),Vt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"};class Tt{constructor(t){this.cache=new Map,this.mapReader=t,this.graph=this.buildGraph()}buildGraph(){const t={};return this.mapReader.getRooms().forEach(e=>{const s={},o=new Set((e.exitLocks??[]).map(i=>Vt[i]).filter(i=>!!i)),n=new Set(e.mSpecialExitLocks??[]);Object.entries(e.exits??{}).forEach(([i,r])=>{o.has(i)||this.mapReader.getRoom(r)&&(s[r.toString()]=1)}),Object.values(e.specialExits??{}).forEach(i=>{n.has(i)||this.mapReader.getRoom(i)&&(s[i.toString()]=1)}),t[e.id.toString()]=s}),new Pt(t)}findPath(t,e){const s=`${t}->${e}`;if(this.cache.has(s))return this.cache.get(s);if(t===e){const r=this.mapReader.getRoom(t)?[t]:null;return this.cache.set(s,r),r}if(!this.mapReader.getRoom(t)||!this.mapReader.getRoom(e))return this.cache.set(s,null),null;const o=this.graph.path(t.toString(),e.toString()),n=Array.isArray(o)?o:o?.path,i=n?n.map(r=>Number(r)):null;return this.cache.set(s,i),i}}const Wt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},Z=class Z{};Z.areaWidth=150,Z.areaHeight=80,Z.areaSpacing=50,Z.fontSize=14,Z.connectionLineWidth=2,Z.areaFillColor="#2a2a3e",Z.areaStrokeColor="#4a4a6e",Z.textColor="#e0e0e0",Z.connectionColor="#6a6a8e",Z.highlightColor="#ff9900";let z=Z;class Ft{constructor(t,e){this.areaNodes=new Map,this.connectionGroups=[],this.currentZoom=1,this.domainInfo=new Map,this.domainFilter="all",this.dotsMode=!1,this.stage=new R.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),this.backgroundLayer=new R.Layer({listening:!1}),this.stage.add(this.backgroundLayer),this.connectionLayer=new R.Layer({listening:!1}),this.stage.add(this.connectionLayer),this.areaLayer=new R.Layer,this.stage.add(this.areaLayer),this.mapReader=e,this.initScaling(),this.initResize(t)}initResize(t){new ResizeObserver(()=>{this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.stage.batchDraw()}).observe(t)}initScaling(){this.stage.on("wheel",e=>{e.evt.preventDefault();const s=this.stage.scaleX(),o=this.stage.getPointerPosition();if(!o)return;const n={x:(o.x-this.stage.x())/s,y:(o.y-this.stage.y())/s},r=(e.evt.deltaY>0?-1:1)>0?this.currentZoom*1.1:this.currentZoom/1.1;this.setZoom(r);const a=this.stage.scaleX(),c={x:o.x-n.x*a,y:o.y-n.y*a};this.stage.position(c),this.stage.batchDraw()})}setZoom(t){this.currentZoom=Math.max(.1,Math.min(5,t)),this.stage.scale({x:this.currentZoom,y:this.currentZoom})}getZoom(){return this.currentZoom}setDomainInfo(t){this.domainInfo.clear();for(const[e,s]of Object.entries(t))this.domainInfo.set(Number(e),s)}setDomainFilter(t){this.domainFilter=t}getDomainFilter(){return this.domainFilter}setBackgroundImage(t){this.backgroundConfig={url:t.url,x:t.x,y:t.y,width:t.width,height:t.height,opacity:t.opacity??.3}}clearBackgroundImage(){this.backgroundConfig=void 0,this.backgroundImage=void 0,this.backgroundLayer.destroyChildren(),this.backgroundLayer.batchDraw()}redrawBackground(){this.drawBackground()}setDotsMode(t){this.dotsMode=t}getDotsMode(){return this.dotsMode}redraw(){this.drawBackground(),this.drawConnections(),this.drawAreas(),this.stage.batchDraw()}isAreaInDomain(t){const e=this.domainInfo.get(t);if(!e)return this.domainFilter==="interdomain"||this.domainFilter==="all";switch(this.domainFilter){case"ishtar":return e.isIshtar;case"empire":return e.isEmpire;case"interdomain":return!e.isIshtar&&!e.isEmpire;case"all":return!0}}areAreasInSameDomain(t,e){const s=this.domainInfo.get(t),o=this.domainInfo.get(e);return!s||!o?!1:!!(s.isIshtar&&o.isIshtar||s.isEmpire&&o.isEmpire||!s.isIshtar&&!s.isEmpire&&!o.isIshtar&&!o.isEmpire)}render(){this.analyzeConnections(),this.layoutAreas(),this.drawBackground(),this.drawConnections(),this.drawAreas(),this.centerView(),this.stage.batchDraw()}drawBackground(){if(this.backgroundLayer.destroyChildren(),!this.backgroundConfig)return;const t=new Image;t.crossOrigin="anonymous",t.onload=()=>{this.backgroundImage=new R.Image({x:this.backgroundConfig.x,y:this.backgroundConfig.y,image:t,width:this.backgroundConfig.width,height:this.backgroundConfig.height,opacity:this.backgroundConfig.opacity,listening:!1}),this.backgroundLayer.add(this.backgroundImage),this.backgroundLayer.batchDraw()},t.onerror=()=>{console.error("Failed to load background image:",this.backgroundConfig?.url)},t.src=this.backgroundConfig.url}analyzeConnections(){this.areaNodes.clear(),this.connectionGroups=[];const t=this.mapReader.getRooms(),e=this.mapReader.getAreas(),s=new Map;for(const c of e){const l=c.getAreaId(),h=c.getRooms();if(h.length===0)continue;let g=1/0,f=-1/0,u=1/0,p=-1/0,m=0;for(const I of h)I.z===0&&(m++,g=Math.min(g,I.x),f=Math.max(f,I.x),u=Math.min(u,I.y),p=Math.max(p,I.y));if(m===0)for(const I of h)g=Math.min(g,I.x),f=Math.max(f,I.x),u=Math.min(u,I.y),p=Math.max(p,I.y);const x=(g+f)/2,y=(u+p)/2;s.set(l,{minX:g,maxX:f,minY:u,maxY:p,centerX:x,centerY:y,roomCount:h.length})}let o=1;for(const c of s.values()){const l=c.maxX-c.minX,h=c.maxY-c.minY;o=Math.max(o,l,h)}const n=200,i=100,r=n/o;for(const c of e){const l=c.getAreaId(),h=s.get(l);if(!h||!this.isAreaInDomain(l))continue;const g=h.maxX-h.minX,f=h.maxY-h.minY;let u=Math.max(i,g*r),p=Math.max(i,f*r);const m=u/p;m>3?p=u/3:m<1/3&&(u=p/3),this.areaNodes.set(l,{areaId:l,name:c.getAreaName(),x:0,y:0,width:u,height:p,connections:[],roomCount:h.roomCount,realCenterX:h.centerX,realCenterY:h.centerY})}const a=new Map;for(const c of t){const l=c.area;if(!this.areaNodes.has(l))continue;const h=this.getLockedDirections(c),g=new Set(c.mSpecialExitLocks??[]);for(const[f,u]of Object.entries(c.exits??{})){if(h.has(f))continue;const p=this.mapReader.getRoom(u);if(!p||p.area===l||!this.areaNodes.has(p.area)||!this.areAreasInSameDomain(l,p.area))continue;const m=this.createConnection(c,p,f);m&&this.addConnection(a,m)}for(const[f,u]of Object.entries(c.specialExits??{})){if(g.has(u))continue;const p=this.mapReader.getRoom(u);if(!p||p.area===l||!this.areaNodes.has(p.area)||!this.areAreasInSameDomain(l,p.area))continue;const m=this.parseDirection(f),x=this.createConnection(c,p,m);x&&this.addConnection(a,x)}}for(const[c,l]of a){const[h,g]=c.split("-").map(Number),f=this.createConnectionGroup(h,g,l);this.connectionGroups.push(f);const u=this.areaNodes.get(h),p=this.areaNodes.get(g);if(u&&u.connections.push(...l),p)for(const m of l)p.connections.push({...m,fromAreaId:m.toAreaId,toAreaId:m.fromAreaId,fromRoomId:m.toRoomId,toRoomId:m.fromRoomId,direction:m.direction?pt[m.direction]:null,fromRoomPosition:m.toRoomPosition,toRoomPosition:m.fromRoomPosition})}}getLockedDirections(t){return new Set((t.exitLocks??[]).map(e=>Wt[e]).filter(e=>!!e))}createConnection(t,e,s){const o=this.toPlanarDirection(s);return{fromAreaId:t.area,toAreaId:e.area,fromRoomId:t.id,toRoomId:e.id,direction:o,fromRoomPosition:{x:t.x,y:t.y},toRoomPosition:{x:e.x,y:e.y}}}addConnection(t,e){const s=e.fromAreaId<e.toAreaId?`${e.fromAreaId}-${e.toAreaId}`:`${e.toAreaId}-${e.fromAreaId}`;t.has(s)||t.set(s,[]),t.get(s).push(e)}createConnectionGroup(t,e,s){const o=new Map;let n=0,i=0;for(const c of s)c.direction&&o.set(c.direction,(o.get(c.direction)??0)+1),n+=c.toRoomPosition.x-c.fromRoomPosition.x,i+=c.toRoomPosition.y-c.fromRoomPosition.y;let r=null,a=0;for(const[c,l]of o)l>a&&(a=l,r=c);return{fromAreaId:t,toAreaId:e,connections:s,primaryDirection:r,averageOffset:{x:n/s.length,y:i/s.length}}}parseDirection(t){const e=t.toLowerCase().trim();return{n:"north",north:"north",s:"south",south:"south",e:"east",east:"east",w:"west",west:"west",ne:"northeast",northeast:"northeast",nw:"northwest",northwest:"northwest",se:"southeast",southeast:"southeast",sw:"southwest",southwest:"southwest",u:"up",up:"up",d:"down",down:"down",i:"in",in:"in",o:"out",out:"out"}[e]??null}toPlanarDirection(t){return t&&ot.includes(t)?t:null}layoutAreas(){if(Array.from(this.areaNodes.values()).length===0)return;const e=this.findConnectedComponents();let s=0;const o=z.areaWidth*3;for(const n of e)if(n.length===1){const i=this.areaNodes.get(n[0]);i&&(i.x=s,i.y=0),s+=z.areaWidth+o}else{const i=this.forceDirectedLayout(n);for(const a of n){const c=this.areaNodes.get(a);c&&isFinite(i.minX)&&isFinite(i.minY)&&(c.x-=i.minX,c.x+=s,c.y-=i.minY)}const r=isFinite(i.maxX-i.minX)?i.maxX-i.minX:z.areaWidth;s+=r+o}}findConnectedComponents(){const t=new Set,e=[];for(const[s]of this.areaNodes){if(t.has(s))continue;const o=[],n=[s];for(;n.length>0;){const i=n.shift();if(t.has(i))continue;t.add(i),o.push(i);const r=this.areaNodes.get(i);if(r)for(const a of r.connections)t.has(a.toAreaId)||n.push(a.toAreaId)}e.push(o)}return e}forceDirectedLayout(t){const e=new Map;for(const w of t){const b=this.areaNodes.get(w);if(!b)continue;const S=new Set(b.connections.map(D=>D.toAreaId));e.set(w,S)}const s=new Set,o=new Set;for(const[w,b]of e)b.size>=3&&s.add(w);for(const[w,b]of e){if(s.has(w)||o.has(w)||b.size>2)continue;const S=[w];o.add(w);const D=Array.from(b);for(const N of D){let L=N,v=w;for(;L&&!o.has(L)&&!s.has(L);){const k=e.get(L);if(!k)break;if(k.size>=3){s.add(L);break}S.push(L),o.add(L);let M=!1;for(const Y of k)if(Y!==v&&!o.has(Y)){v=L,L=Y,M=!0;break}if(!M)break}}let E=!1;for(const N of S){const L=e.get(N);if(L){for(const v of L)if(s.has(v)){E=!0;break}}if(E)break}if(!E&&S.length>0){let N=S[0],L=e.get(S[0])?.size??0;for(const v of S){const k=e.get(v)?.size??0;k>L&&(L=k,N=v)}s.add(N),o.delete(N)}}for(const w of t){const b=e.get(w);(!b||b.size===0)&&s.add(w)}const n=new Map,i=new Map;for(const w of s)n.set(w,w),i.set(w,[]);const r=new Set(s);for(const w of s){const b=e.get(w)??new Set;for(const S of b){if(r.has(S))continue;const D=[];let E=S,N=w;for(;E&&!r.has(E);){D.push(E),n.set(E,w),r.add(E);const L=e.get(E)??new Set;let v;for(const k of L)if(k!==N&&!r.has(k)){v=k;break}N=E,E=v}D.length>0&&i.get(w).push(D)}}const a=new Set,c=[],l=s.values().next().value,h=l!==void 0?l:t[0];if(h!==void 0){const w=this.areaNodes.get(h);w&&(w.x=0,w.y=0,a.add(h),c.push(h))}for(;c.length>0;){const w=c.shift(),b=this.areaNodes.get(w),S=new Map;for(const D of b.connections){const E=D.toAreaId;if(a.has(E)||!s.has(E))continue;const N=this.areaNodes.get(E);if(!N)continue;const L=D.direction??"none";S.has(L)||S.set(L,[]),S.get(L).push({id:E,node:N,conn:D})}for(const[D,E]of S){const N=this.getDirectionOffset(D==="none"?null:D);E.sort((k,M)=>Math.abs(N.x)>Math.abs(N.y)?M.node.realCenterY-k.node.realCenterY:k.node.realCenterX-M.node.realCenterX);const L=z.areaWidth+z.areaSpacing,v=z.areaHeight+z.areaSpacing;E.forEach((k,M)=>{if(k.node.x=b.x+N.x*L,k.node.y=b.y+N.y*v,E.length>1){const Y=(M-(E.length-1)/2)*.5;Math.abs(N.x)>Math.abs(N.y)?k.node.y+=Y*v:k.node.x+=Y*L}a.add(k.id),c.push(k.id)})}}const g=Array.from(s);g.length>1&&this.applyForces(g,80);const f=z.areaWidth+z.areaSpacing+30,u=z.areaHeight+z.areaSpacing+30,p=new Map,m=["east","west","north","south","northeast","northwest","southeast","southwest"];for(const[w,b]of i){const S=this.areaNodes.get(w);if(!S)continue;let D=0;const E=new Map;for(const N of b){let L=w,v=S.x,k=S.y,M=null;for(const Y of N){const X=this.areaNodes.get(Y);if(!X)continue;const W=this.areaNodes.get(L);let V=null;if(W){for(const G of W.connections)if(G.toAreaId===Y){V=G.direction;break}}!V&&L===w?(M=m[D%m.length],D++,V=M):!V&&M&&(V=M);const P=this.getDirectionOffset(V);let $=0;if(L===w&&V){const G=V,rt=E.get(G)??0;E.set(G,rt+1),$=rt}X.x=v+P.x*f,X.y=k+P.y*u,$>0&&(P.x!==0&&P.y===0?X.y+=$*u*1.2:P.y!==0&&P.x===0?X.x+=$*f*1.2:(X.x+=$*f*1.2,X.y-=$*u*1.2)),p.set(Y,{dx:X.x-S.x,dy:X.y-S.y,hubId:w}),L=Y,v=X.x,k=X.y}}}const x=new Map,y=new Map;for(const w of s){const b=this.areaNodes.get(w);if(!b)continue;let S=b.x,D=b.y,E=b.x+b.width,N=b.y+b.height;const L=i.get(w)??[];for(const v of L)for(const k of v){const M=this.areaNodes.get(k);M&&(S=Math.min(S,M.x),D=Math.min(D,M.y),E=Math.max(E,M.x+M.width),N=Math.max(N,M.y+M.height))}x.set(w,{minX:S,minY:D,maxX:E,maxY:N}),y.set(w,{dx:S-b.x,dy:D-b.y})}this.applyClusterForces(g,x,y,60);for(const[w,b]of p){const S=this.areaNodes.get(w),D=this.areaNodes.get(b.hubId);!S||!D||(S.x=D.x+b.dx,S.y=D.y+b.dy)}let I=1/0,A=1/0,O=-1/0,T=-1/0;for(const w of t){const b=this.areaNodes.get(w);I=Math.min(I,b.x),A=Math.min(A,b.y),O=Math.max(O,b.x+b.width),T=Math.max(T,b.y+b.height)}return{minX:I,minY:A,maxX:O,maxY:T}}getDirectionOffset(t){const e={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:.75,y:-.75},northwest:{x:-.75,y:-.75},southeast:{x:.75,y:.75},southwest:{x:-.75,y:.75}};return t&&e[t]?e[t]:{x:1,y:0}}applyClusterForces(t,e,s,o){const r=new Map;for(const a of t)r.set(a,{vx:0,vy:0});for(let a=0;a<o;a++){for(const c of t){const l=this.areaNodes.get(c),h=e.get(c),g=s.get(c);if(!l||!h||!g)continue;const f=h.maxX-h.minX,u=h.maxY-h.minY;h.minX=l.x+g.dx,h.minY=l.y+g.dy,h.maxX=h.minX+f,h.maxY=h.minY+u}for(const c of t){const l=this.areaNodes.get(c),h=r.get(c),g=e.get(c);if(!(!l||!h||!g)){for(const f of t){if(c===f)continue;const u=e.get(f);if(!u)continue;const p=(g.minX+g.maxX)/2,m=(g.minY+g.maxY)/2,x=(u.minX+u.maxX)/2,y=(u.minY+u.maxY)/2,I=p-x,A=m-y,O=(g.maxX-g.minX)/2,T=(g.maxY-g.minY)/2,w=(u.maxX-u.minX)/2,b=(u.maxY-u.minY)/2,S=O+w+50,D=T+b+50,E=S-Math.abs(I),N=D-Math.abs(A);if(E>0&&N>0)if(E<N){const L=E*(I>=0?1:-1)*.5;h.vx+=L}else{const L=N*(A>=0?1:-1)*.5;h.vy+=L}}for(const f of l.connections){const u=this.areaNodes.get(f.toAreaId);if(!u||!t.includes(f.toAreaId))continue;const p=u.x-l.x,m=u.y-l.y,x=Math.sqrt(p*p+m*m)||1,y=z.areaWidth+z.areaSpacing+50,A=(x-y)*.015;h.vx+=p/x*A,h.vy+=m/x*A}}}for(const c of t){const l=this.areaNodes.get(c),h=r.get(c);!l||!h||(l.x+=h.vx,l.y+=h.vy,h.vx*=.8,h.vy*=.8)}}}applyForces(t,e){const n=z.areaWidth+z.areaSpacing,i=z.areaWidth/2+60,r=new Set(t),a=[],c=new Set;for(const h of t){const g=this.areaNodes.get(h);if(g)for(const f of g.connections){if(!r.has(f.toAreaId))continue;const u=Math.min(h,f.toAreaId)+"-"+Math.max(h,f.toAreaId);c.has(u)||(c.add(u),a.push({from:h,to:f.toAreaId}))}}const l=new Map;for(const h of t)l.set(h,{vx:0,vy:0});for(let h=0;h<e;h++){for(const g of t){const f=this.areaNodes.get(g),u=l.get(g);if(!f||!u)continue;const p=f.x+f.width/2,m=f.y+f.height/2;for(const x of t){if(g===x)continue;const y=this.areaNodes.get(x);if(!y)continue;const I=(f.width+y.width)/2+20,A=(f.height+y.height)/2+20,O=f.x+f.width/2,T=f.y+f.height/2,w=y.x+y.width/2,b=y.y+y.height/2,S=O-w,D=T-b,E=I-Math.abs(S),N=A-Math.abs(D);E>0&&N>0&&(E<N?u.vx+=(S>=0?1:-1)*E*.5:u.vy+=(D>=0?1:-1)*N*.5)}for(const x of a){if(x.from===g||x.to===g)continue;const y=this.areaNodes.get(x.from),I=this.areaNodes.get(x.to);if(!y||!I)continue;const A=y.x+y.width/2,O=y.y+y.height/2,T=I.x+I.width/2,w=I.y+I.height/2,b=this.closestPointOnSegment(p,m,A,O,T,w),S=p-b.x,D=m-b.y,E=Math.sqrt(S*S+D*D)||1;if(E<i){const N=(i-E)*.6;u.vx+=S/E*N,u.vy+=D/E*N}}for(const x of f.connections){if(!r.has(x.toAreaId))continue;const y=this.areaNodes.get(x.toAreaId);if(!y)continue;const I=y.x-f.x,A=y.y-f.y,O=Math.sqrt(I*I+A*A)||1,w=(O-n)*.03;u.vx+=I/O*w,u.vy+=A/O*w;const b=this.getDirectionOffset(x.direction),S=f.x+b.x*n,D=f.y+b.y*n,E=l.get(x.toAreaId);E&&(E.vx+=(S-y.x)*.01,E.vy+=(D-y.y)*.01)}}for(const g of t){const f=this.areaNodes.get(g),u=l.get(g);!f||!u||(f.x+=u.vx,f.y+=u.vy,u.vx*=.8,u.vy*=.8)}}}closestPointOnSegment(t,e,s,o,n,i){const r=n-s,a=i-o,c=t-s,l=e-o,h=r*r+a*a;if(h===0)return{x:s,y:o};let g=(c*r+l*a)/h;return g=Math.max(0,Math.min(1,g)),{x:s+g*r,y:o+g*a}}edgesIntersect(t,e,s,o,n,i,r,a){const c=(l,h,g,f,u,p)=>(p-h)*(g-l)>(f-h)*(u-l);return c(t,e,n,i,r,a)!==c(s,o,n,i,r,a)&&c(t,e,s,o,n,i)!==c(t,e,s,o,r,a)}drawConnections(){this.connectionLayer.destroyChildren();for(const t of this.connectionGroups){const e=this.areaNodes.get(t.fromAreaId),s=this.areaNodes.get(t.toAreaId);if(!e||!s||!isFinite(e.x)||!isFinite(e.y)||!isFinite(s.x)||!isFinite(s.y))continue;const o={x:e.x+e.width/2,y:e.y+e.height/2},n={x:s.x+s.width/2,y:s.y+s.height/2};let i,r;if(this.dotsMode?(i=o,r=n):(i=this.getEdgePoint(e,n),r=this.getEdgePoint(s,o)),!isFinite(i.x)||!isFinite(i.y)||!isFinite(r.x)||!isFinite(r.y))continue;const a=this.dotsMode?"#ffffff":z.connectionColor,c=this.dotsMode?1:Math.min(z.connectionLineWidth,1+t.connections.length*.5),l=new R.Line({points:[i.x,i.y,r.x,r.y],stroke:a,strokeWidth:c,lineCap:"round",listening:!1});this.connectionLayer.add(l)}}getEdgePoint(t,e){const s=t.x+t.width/2,o=t.y+t.height/2,n=e.x-s,i=e.y-o,r=t.width/2,a=t.height/2;if(n===0&&i===0)return{x:s,y:o};const c=Math.abs(n),l=Math.abs(i);let h;return c/r>l/a?h=r/c:h=a/l,{x:s+n*h,y:o+i*h}}drawAreas(){this.areaLayer.destroyChildren();for(const[,t]of this.areaNodes){if(!isFinite(t.x)||!isFinite(t.y))continue;const e=t.areaId===this.highlightedArea;if(this.dotsMode){const o=t.x+t.width/2,n=t.y+t.height/2,i=new R.Group({x:o,y:n,draggable:!0}),r=new R.Circle({radius:6,fill:e?z.highlightColor:"#ffffff",stroke:e?z.highlightColor:"#ffffff",strokeWidth:1}),a=new R.Text({text:t.name,fontSize:10,fill:"#ffffff",x:10,y:-5});i.add(r),i.add(a),i.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),i.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",r.fill(z.highlightColor),r.stroke(z.highlightColor),this.areaLayer.batchDraw()}),i.on("mouseleave",()=>{this.stage.container().style.cursor="auto",r.fill(e?z.highlightColor:"#ffffff"),r.stroke(e?z.highlightColor:"#ffffff"),this.areaLayer.batchDraw()}),i.on("dragmove",()=>{t.x=i.x()-t.width/2,t.y=i.y()-t.height/2,this.drawConnections(),this.connectionLayer.batchDraw()}),i.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),i.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(i)}else{const s=new R.Group({x:t.x,y:t.y,draggable:!0}),o=new R.Rect({width:t.width,height:t.height,fill:z.areaFillColor,stroke:e?z.highlightColor:z.areaStrokeColor,strokeWidth:e?3:2,cornerRadius:8}),n=new R.Text({text:t.name,fontSize:z.fontSize,fill:z.textColor,width:t.width-10,height:t.height-20,x:5,y:10,align:"center",verticalAlign:"middle",ellipsis:!0,wrap:"word"}),i=new R.Text({text:`${t.roomCount} rooms`,fontSize:10,fill:z.connectionColor,width:t.width-10,x:5,y:t.height-18,align:"center"});s.add(o),s.add(n),s.add(i),s.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",o.stroke(z.highlightColor),this.areaLayer.batchDraw()}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto",o.stroke(e?z.highlightColor:z.areaStrokeColor),this.areaLayer.batchDraw()}),s.on("dragmove",()=>{t.x=s.x(),t.y=s.y(),this.drawConnections(),this.connectionLayer.batchDraw()}),s.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),s.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(s)}}}centerView(){let t=1/0,e=1/0,s=-1/0,o=-1/0;for(const[,u]of this.areaNodes)t=Math.min(t,u.x),e=Math.min(e,u.y),s=Math.max(s,u.x+u.width),o=Math.max(o,u.y+u.height);if(!isFinite(t))return;const n=s-t,i=o-e,r=t+n/2,a=e+i/2,c=50,l=(this.stage.width()-c*2)/n,h=(this.stage.height()-c*2)/i,g=Math.min(l,h,1.5);this.setZoom(g);const f=this.stage.scaleX();this.stage.position({x:this.stage.width()/2-r*f,y:this.stage.height()/2-a*f})}highlightArea(t){this.highlightedArea=t,this.drawAreas(),this.stage.batchDraw()}centerOnArea(t){const e=this.areaNodes.get(t);if(!e)return;const s=this.stage.scaleX(),o=e.x+e.width/2,n=e.y+e.height/2;this.stage.position({x:this.stage.width()/2-o*s,y:this.stage.height()/2-n*s}),this.stage.batchDraw()}emitAreaClickEvent(t){const e=new CustomEvent("areaclick",{detail:{areaId:t}});this.stage.container().dispatchEvent(e)}getAreaNode(t){return this.areaNodes.get(t)}getConnectionGroups(){return this.connectionGroups}destroy(){this.stage.destroy()}}exports.AreaMapRenderer=Ft;exports.AreaMapSettings=z;exports.ExplorationArea=Q;exports.MapReader=Dt;exports.PathFinder=Tt;exports.Renderer=Mt;exports.Settings=d;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("konva"),H=["north","south","east","west","northeast","northwest","southeast","southwest"],j={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},rt={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:1,y:-1},northwest:{x:-1,y:-1},southeast:{x:1,y:1},southwest:{x:-1,y:1}},it=["north","south","east","west","northeast","northwest","southeast","southwest"],pt={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function xt(k){return k?Object.prototype.hasOwnProperty.call(rt,k):!1}function F(k,t,e,s=1){if(!xt(e))return{x:k,y:t};const o=rt[e];return{x:k+o.x*s,y:t+o.y*s}}function wt(k,t,e,s=1){if(!xt(e))return{x:k,y:t};const o=rt[e],n=Math.atan2(o.y,o.x);return{x:k+Math.cos(n)*s,y:t+Math.sin(n)*s}}const q={OPEN_DOOR:"rgb(10, 155, 10)",CLOSED_DOOR:"rgb(226, 205, 59)",LOCKED_DOOR:"rgb(155, 10, 10)",ONE_WAY_FILL:"rgb(155, 10, 10)"},bt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},Rt=["up","down","in","out"];function vt(k){switch(k){case 1:return q.OPEN_DOOR;case 2:return q.CLOSED_DOOR;default:return q.LOCKED_DOOR}}class Et{constructor(t,e){this.mapReader=t,this.mapRenderer=e}getRoomEdgePoint(t,e,s,o){return d.roomShape==="circle"?wt(t,e,s,o):F(t,e,s,o)}render(t,e){return this.renderWithColor(t,d.lineColor,e)}renderWithColor(t,e,s){return t.aDir&&t.bDir&&H.includes(t.aDir)&&H.includes(t.bDir)?this.renderTwoWayExit(t,e,s):this.renderOneWayExit(t,e)}renderTwoWayExit(t,e,s){const o=this.mapReader.getRoom(t.a),n=this.mapReader.getRoom(t.b);if(!o||!n||!t.aDir||!t.bDir||!H.includes(t.aDir)||!H.includes(t.bDir)||o.customLines[j[t.aDir]]&&n.customLines[j[t.bDir]]||o.z!==n.z&&(s!==n.z&&o.customLines[j[t.aDir]]||s!==o.z&&n.customLines[j[t.bDir]]))return;const i=new v.Group,r=[];if(r.push(...Object.values(this.getRoomEdgePoint(o.x,o.y,t.aDir,d.roomSize/2))),r.push(...Object.values(this.getRoomEdgePoint(n.x,n.y,t.bDir,d.roomSize/2))),o.doors[j[t.aDir]]||n.doors[j[t.bDir]]){const c=this.renderDoor(r,o.doors[j[t.aDir]]??n.doors[j[t.bDir]]);i.add(c)}const a=new v.Line({points:r,stroke:e,strokeWidth:d.lineWidth,perfectDrawEnabled:!1});return i.add(a),i}renderOneWayExit(t,e){const s=t.aDir?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),o=t.aDir?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),n=t.aDir?t.aDir:t.bDir;if(!n||!s||!o||!H.includes(n)||s.customLines[j[n]||n])return;if(s.area!=o.area&&n){const u=this.mapReader.getColorValue(o.env);return this.renderAreaExit(s,n,u)}let i={x:o.x,y:o.y};(o.area!==s.area||o.z!==s.z)&&(i=F(s.x,s.y,n,d.roomSize/2));const r=F(s.x,s.y,n,.3),a=r.x-(r.x-i.x)/2,c=r.y-(r.y-i.y)/2,l=new v.Group,h=[];h.push(...Object.values(this.getRoomEdgePoint(s.x,s.y,n,d.roomSize/2))),h.push(i.x,i.y);const g=new v.Line({points:h,stroke:e,strokeWidth:d.lineWidth,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1});l.add(g);const f=new v.Arrow({points:[h[0],h[1],a,c],pointerLength:.5,pointerWidth:.35,strokeWidth:d.lineWidth*1.4,stroke:e,fill:q.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return l.add(f),l}renderAreaExit(t,e,s){const o=this.getRoomEdgePoint(t.x,t.y,e,d.roomSize/2),n=F(t.x,t.y,e,d.roomSize*1.5),i=s??this.mapReader.getColorValue(t.env);return new v.Arrow({points:[o.x,o.y,n.x,n.y],pointerLength:.3,pointerWidth:.3,strokeWidth:d.lineWidth*1.4,stroke:i,fill:i})}renderSpecialExits(t,e){return Object.entries(t.customLines).map(([s,o])=>{const n=[t.x,t.y];o.points.reduce((l,h)=>(l.push(h.x,-h.y),l),n);const i=o.attributes.arrow?v.Arrow:v.Line,r=e??`rgb(${o.attributes.color.r}, ${o.attributes.color.g}, ${o.attributes.color.b})`,a=new i({points:n,strokeWidth:d.lineWidth,stroke:r,fill:e??`rgb(${o.attributes.color.r}, ${o.attributes.color.g} , ${o.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1});let c=o.attributes.style;return c==="dot line"?(a.dash([.05,.05]),a.dashOffset(.1)):c==="dash line"?a.dash([.4,.2]):c==="solid line"||c!==void 0&&console.log("Brak opisu stylu: "+c),a})}renderStubs(t,e=d.lineColor){return t.stubs.map(s=>{const o=bt[s],n=this.getRoomEdgePoint(t.x,t.y,o,d.roomSize/2),i=F(t.x,t.y,o,d.roomSize/2+.5),r=[n.x,n.y,i.x,i.y];return new v.Line({points:r,stroke:e,strokeWidth:d.lineWidth})})}renderInnerExits(t){return Rt.map(e=>{if(t.exits[e]){const s=new v.Group,o=new v.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.mapReader.getSymbolColor(t.env,.6),stroke:this.mapReader.getSymbolColor(t.env),strokeWidth:d.lineWidth,radius:d.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1});s.add(o);let n=t.doors[e];if(n!==void 0)switch(n){case 1:o.stroke(q.OPEN_DOOR);break;case 2:o.stroke(q.CLOSED_DOOR);break;default:o.stroke(q.LOCKED_DOOR)}switch(e){case"up":o.position(F(t.x,t.y,"south",d.roomSize/4));break;case"down":o.rotation(180),o.position(F(t.x,t.y,"north",d.roomSize/4));break;case"in":const i=o.clone();i.rotation(-90),i.position(F(t.x,t.y,"east",d.roomSize/4)),s.add(i),o.rotation(90),o.position(F(t.x,t.y,"west",d.roomSize/4));break;case"out":const r=o.clone();r.rotation(90),r.position(F(t.x,t.y,"east",d.roomSize/4)),s.add(r),o.rotation(-90),o.position(F(t.x,t.y,"west",d.roomSize/4));break}return s}}).filter(e=>e!==void 0)}renderDoor(t,e){const s={x:t[0]+(t[2]-t[0])/2,y:t[1]+(t[3]-t[1])/2};return new v.Rect({x:s.x-d.roomSize/4,y:s.y-d.roomSize/4,width:d.roomSize/2,height:d.roomSize/2,stroke:vt(e),strokeWidth:d.lineWidth})}}class yt{constructor(t,e){this.rooms=[],this.labels=[],this.rooms=t,this.bounds=this.createBounds(),this.labels=e}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){return this.rooms.reduce((t,e)=>({minX:Math.min(t.minX,e.x),maxX:Math.max(t.maxX,e.x),minY:Math.min(t.minY,e.y),maxY:Math.max(t.maxY,e.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY})}}class nt{constructor(t){this.planes={},this.exits=new Map,this.version=0,this.area=t,this.planes=this.createPlanes(),this.createExits()}getAreaName(){return this.area.areaName}getAreaId(){return parseInt(this.area.areaId)}getVersion(){return this.version}markDirty(){this.version++}getPlane(t){return this.planes[t]}getPlanes(){return Object.values(this.planes)}getRooms(){return this.area.rooms}getLinkExits(t){return Array.from(this.exits.values()).filter(e=>e.zIndex.includes(t))}createPlanes(){const t=this.area.rooms.reduce((e,s)=>(e[s.z]||(e[s.z]=[]),e[s.z].push(s),e),{});return Object.entries(t).reduce((e,[s,o])=>(e[+s]=new yt(o,this.area.labels.filter(n=>n.Z===+s)),e),{})}createExits(){this.area.rooms.forEach(t=>{Object.entries(t.specialExits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e)),Object.entries(t.exits).forEach(([e,s])=>this.createHalfExit(t.id,s,t.z,e))})}createHalfExit(t,e,s,o){if(t===e)return;const n=Math.min(t,e),i=Math.max(t,e),r=`${n}-${i}`;let a=this.exits.get(r);a||(a={a:n,b:i,zIndex:[s]}),n==t?a.aDir=o:a.bDir=o,a.zIndex.push(s),this.exits.set(r,a)}}class ht extends yt{constructor(t,e){super(t.getRooms(),t.getLabels()),this.basePlane=t,this.visitedRooms=e}getRooms(){return this.basePlane.getRooms().filter(t=>this.visitedRooms.has(t.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const t=this.getRooms();return t.length?t.reduce((e,s)=>({minX:Math.min(e.minX,s.x),maxX:Math.max(e.maxX,s.x),minY:Math.min(e.minY,s.y),maxY:Math.max(e.maxY,s.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class U extends nt{constructor(t,e){super(t),this.planeCache=new WeakMap,this.visitedRooms=e instanceof Set?e:new Set(e??[]),this.areaRoomIds=new Set(t.rooms.map(s=>s.id))}getPlane(t){const e=super.getPlane(t);if(!e)return e;let s=this.planeCache.get(e);return s||(s=new ht(e,this.visitedRooms),this.planeCache.set(e,s)),s}getPlanes(){return super.getPlanes().map(t=>{let e=this.planeCache.get(t);return e||(e=new ht(t,this.visitedRooms),this.planeCache.set(t,e)),e})}getLinkExits(t){return super.getLinkExits(t).filter(e=>this.visitedRooms.has(e.a)||this.visitedRooms.has(e.b))}getVisitedRoomCount(){return super.getRooms().reduce((t,e)=>t+(this.visitedRooms.has(e.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(t){return this.areaRoomIds.has(t)&&this.visitedRooms.has(t)}getVisitedRoomIds(){return super.getRooms().filter(t=>this.visitedRooms.has(t.id)).map(t=>t.id)}addVisitedRoom(t){const e=this.visitedRooms.has(t);this.visitedRooms.add(t);const s=!e&&this.areaRoomIds.has(t);return s&&this.markDirty(),s}addVisitedRooms(t){let e=0;for(const s of t){const o=this.visitedRooms.has(s);this.visitedRooms.add(s),!o&&this.areaRoomIds.has(s)&&e++}return e>0&&this.markDirty(),e}}class kt{constructor(t,e){this.paths=[],this.mapReader=t,this.overlayLayer=e}renderPath(t,e,s,o="#66E64D"){if(e===void 0||s===void 0)return;const n=t.map(h=>this.mapReader.getRoom(h)).filter(h=>h!==void 0),i=[];let r=null;const a=()=>{r&&(r.length<4&&i.pop(),r=null)},c=()=>(r||(r=[],i.push(r)),r);n.forEach((h,g)=>{if(!this.isRoomVisible(h,e,s))return;const f=g>0?n[g-1]:void 0,u=g<n.length-1?n[g+1]:void 0;if(this.isRoomVisible(f,e,s))c();else{a();const x=c();if(f){const y=this.getDirectionTowards(h,f);if(y){const I=F(h.x,h.y,y,d.roomSize);x.push(I.x,I.y)}}}if(r?.push(h.x,h.y),!this.isRoomVisible(u,e,s)&&u){const x=this.getDirectionTowards(h,u);if(x){const y=F(h.x,h.y,x,d.roomSize);r?.push(y.x,y.y)}a()}}),a();const l=i.filter(h=>h.length>=4).map(h=>new v.Line({points:h,stroke:o,strokeWidth:d.lineWidth*4}));return l.forEach(h=>{this.overlayLayer.add(h),this.paths.push(h)}),l[0]}clearPaths(){this.paths.forEach(t=>{t.destroy()}),this.paths=[]}isRoomVisible(t,e,s){return t?t.area===e&&t.z===s:!1}getDirectionTowards(t,e){for(const s of it)if(t.exits[s]===e.id)return s;for(const s of it)if(e.exits[s]===t.id)return pt[s]}}const Ct=.6,K=75,St=.025,It="rgb(225, 255, 225)",_="rgb(120, 72, 0)";function Q(k,t){const e=parseInt(k.slice(1,3),16),s=parseInt(k.slice(3,5),16),o=parseInt(k.slice(5,7),16);return`rgba(${e}, ${s}, ${o}, ${t})`}const B=class B{};B.roomSize=Ct,B.lineWidth=St,B.lineColor=It,B.instantMapMove=!1,B.highlightCurrentRoom=!0,B.cullingEnabled=!0,B.cullingMode="indexed",B.cullingBounds=null,B.labelRenderMode="image",B.roomShape="rectangle",B.playerMarker={strokeColor:"#00e5b2",strokeAlpha:1,fillColor:"#00e5b2",fillAlpha:0,strokeWidth:.1,sizeFactor:1.7,dash:[.05,.05],dashEnabled:!0};let d=B;class Mt{constructor(t,e){this.highlights=new Map,this.currentZoom=1,this.currentRoomOverlay=[],this.roomNodes=new Map,this.standaloneExitNodes=[],this.spatialBucketSize=5,this.roomSpatialIndex=new Map,this.exitSpatialIndex=new Map,this.visibleRooms=new Set,this.visibleStandaloneExitNodes=new Set,this.cullingScheduled=!1,this.stage=new v.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),window.addEventListener("resize",()=>{this.onResize(t)}),t.addEventListener("resize",()=>{this.onResize(t)}),this.linkLayer=new v.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new v.Layer,this.stage.add(this.roomLayer),this.positionLayer=new v.Layer({listening:!1}),this.stage.add(this.positionLayer),this.overlayLayer=new v.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.mapReader=e,this.exitRenderer=new Et(e,this),this.pathRenderer=new kt(e,this.overlayLayer),this.initScaling(1.1),this.stage.on("dragmove",()=>this.scheduleRoomCulling()),this.stage.on("dragend",()=>this.scheduleRoomCulling())}onResize(t){this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(t){v.hitOnDragEnabled=!0;let e,s=!1,o=!1;this.stage.on("touchstart",n=>{const i=n.evt.touches;i&&i.length>1?(o=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(o=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",n=>{e=void 0;const i=n.evt.touches;(!i||i.length<=1)&&(o=!1,this.stage.draggable(!0))}),this.stage.on("wheel",n=>{n.evt.preventDefault();const i=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;const a={x:(r.x-this.stage.x())/i,y:(r.y-this.stage.y())/i};let c=n.evt.deltaY>0?-1:1;n.evt.ctrlKey&&(c=-c);const l=c>0?this.currentZoom*t:this.currentZoom/t,h=l*K,g=this.setZoom(l),f={x:r.x-a.x*h,y:r.y-a.y*h};this.stage.position(f),this.scheduleRoomCulling(),g&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",n=>{const i=n.evt.touches,r=i?.[0],a=i?.[1];if(a||o&&(o=!1,this.stage.draggable(!0)),r&&!a&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!r||!a){e=void 0;return}n.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),o||(o=!0,this.stage.draggable(!1));const c=this.stage.container().getBoundingClientRect(),l={x:r.clientX-c.left,y:r.clientY-c.top},h={x:a.clientX-c.left,y:a.clientY-c.top},g=Math.hypot(l.x-h.x,l.y-h.y);if(e===void 0){e=g;return}if(e===0)return;const f=this.stage.scaleX(),u=this.stage.x(),p=this.stage.y(),m={x:this.stage.width()/2,y:this.stage.height()/2},x={x:(m.x-u)/f,y:(m.y-p)/f},y=this.currentZoom*(g/e),I=this.setZoom(y),A=this.stage.scaleX(),Y={x:m.x-x.x*A,y:m.y-x.y*A};this.stage.position(Y),this.stage.batchDraw(),this.scheduleRoomCulling(),e=g,I&&this.emitZoomChangeEvent()})}drawArea(t,e){const s=this.mapReader.getArea(t);if(!s)return;const o=s.getPlane(e);o&&(this.currentArea=t,this.currentAreaInstance=s,this.currentZIndex=e,this.currentAreaVersion=s.getVersion(),this.clearCurrentRoomOverlay(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.standaloneExitBoundsRoomSize=void 0,this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:K*this.currentZoom,y:K*this.currentZoom}),this.renderLabels(o.getLabels()),this.renderExits(s.getLinkExits(e)),this.renderRooms(o.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}computeSpatialBucketSize(){return Math.max(d.roomSize*10,5)}getBucketKey(t,e){return`${t},${e}`}forEachBucket(t,e,s,o,n){const i=this.spatialBucketSize,r=Math.min(t,s),a=Math.max(t,s),c=Math.min(e,o),l=Math.max(e,o),h=Math.floor(r/i),g=Math.floor(a/i),f=Math.floor(c/i),u=Math.floor(l/i);for(let p=h;p<=g;p++)for(let m=f;m<=u;m++)n(this.getBucketKey(p,m))}addRoomToSpatialIndex(t){const e=d.roomSize/2,s=t.room.x-e,o=t.room.x+e,n=t.room.y-e,i=t.room.y+e;this.forEachBucket(s,n,o,i,r=>{let a=this.roomSpatialIndex.get(r);a||(a=new Set,this.roomSpatialIndex.set(r,a)),a.add(t)})}addStandaloneExitToSpatialIndex(t){const{bounds:e}=t,s=e.x,o=e.x+e.width,n=e.y,i=e.y+e.height;this.forEachBucket(s,n,o,i,r=>{let a=this.exitSpatialIndex.get(r);a||(a=new Set,this.exitSpatialIndex.set(r,a)),a.add(t)})}collectRoomCandidates(t,e,s,o){const n=new Set;return this.forEachBucket(t,e,s,o,i=>{this.roomSpatialIndex.get(i)?.forEach(a=>n.add(a))}),n}collectStandaloneExitCandidates(t,e,s,o){const n=new Set;return this.forEachBucket(t,e,s,o,i=>{this.exitSpatialIndex.get(i)?.forEach(a=>n.add(a))}),n}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==d.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(t=>{t.bounds=t.node.getClientRect({relativeTo:this.linkLayer}),this.addStandaloneExitToSpatialIndex(t)}),this.standaloneExitBoundsRoomSize=d.roomSize)}emitRoomContextEvent(t,e,s){const o=this.stage.container(),n=o.getBoundingClientRect(),i={roomId:t,position:{x:e-n.left,y:s-n.top}},r=new CustomEvent("roomcontextmenu",{detail:i});o.dispatchEvent(r)}emitZoomChangeEvent(){const t=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(t)}setZoom(t){return this.currentZoom===t?!1:(this.currentZoom=t,this.stage.scale({x:K*t,y:K*t}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}setCullingMode(t){d.cullingMode=t,d.cullingEnabled=t!=="none",this.scheduleRoomCulling()}getCullingMode(){return d.cullingMode}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}refreshCurrentRoomOverlay(){if(this.currentRoomId!==void 0){const t=this.mapReader.getRoom(this.currentRoomId);t&&this.updateCurrentRoomOverlay(t)}}refresh(){this.currentRoomId!==void 0&&this.currentArea!==void 0&&this.currentZIndex!==void 0&&(this.drawArea(this.currentArea,this.currentZIndex),this.setPosition(this.currentRoomId))}updatePositionMarker(t){const e=this.mapReader.getRoom(t);if(!e)return;if(e.area!==this.currentArea||e.z!==this.currentZIndex){this.positionRender&&(this.positionRender.hide(),this.positionLayer.batchDraw());return}this.currentRoomId=t,this.updateCurrentRoomOverlay(e);const s=Q(d.playerMarker.strokeColor,d.playerMarker.strokeAlpha),o=Q(d.playerMarker.fillColor,d.playerMarker.fillAlpha),n=d.roomSize/2*d.playerMarker.sizeFactor;this.positionRender?(this.positionRender.position({x:e.x,y:e.y}),this.positionRender.radius(n),this.positionRender.stroke(s),this.positionRender.fill(o),this.positionRender.strokeWidth(d.playerMarker.strokeWidth),this.positionRender.dash(d.playerMarker.dash??[]),this.positionRender.dashEnabled(d.playerMarker.dashEnabled),this.positionRender.show()):(this.positionRender=new v.Circle({x:e.x,y:e.y,radius:n,stroke:s,fill:o,strokeWidth:d.playerMarker.strokeWidth,dash:d.playerMarker.dash,dashEnabled:d.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender)),this.positionLayer.batchDraw()}setPosition(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),o=s?.getVersion();let n=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||o!==void 0&&this.currentAreaVersion!==o||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.centerOnRoom(e,n),this.updateCurrentRoomOverlay(e);const i=Q(d.playerMarker.strokeColor,d.playerMarker.strokeAlpha),r=Q(d.playerMarker.fillColor,d.playerMarker.fillAlpha),a=d.roomSize/2*d.playerMarker.sizeFactor;this.positionRender?(this.positionRender.radius(a),this.positionRender.stroke(i),this.positionRender.fill(r),this.positionRender.strokeWidth(d.playerMarker.strokeWidth),this.positionRender.dash(d.playerMarker.dash??[]),this.positionRender.dashEnabled(d.playerMarker.dashEnabled)):(this.positionRender=new v.Circle({x:e.x,y:e.y,radius:a,stroke:i,fill:r,strokeWidth:d.playerMarker.strokeWidth,dash:d.playerMarker.dash,dashEnabled:d.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender))}renderPath(t,e){return this.pathRenderer.renderPath(t,this.currentArea,this.currentZIndex,e)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(t,e){const s=this.mapReader.getRoom(t);if(!s)return;const o=this.highlights.get(t);o?.shape&&(o.shape.destroy(),delete o.shape);const n={color:e,area:s.area,z:s.z};if(this.highlights.set(t,n),s.area===this.currentArea&&s.z===this.currentZIndex){const i=this.createHighlightShape(s,e);return this.overlayLayer.add(i),n.shape=i,this.overlayLayer.batchDraw(),i}return n.shape}clearHighlights(){this.highlights.forEach(({shape:t})=>t?.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,e)=>{if(t.shape?.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(e);if(!s)return;const o=this.createHighlightShape(s,t.color);this.overlayLayer.add(o),t.shape=o}),this.overlayLayer.batchDraw()}createHighlightShape(t,e){return d.roomShape==="circle"?new v.Circle({x:t.x,y:t.y,radius:d.roomSize/2*1.5,stroke:e,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1}):new v.Rect({x:t.x-d.roomSize/2*1.5,y:t.y-d.roomSize/2*1.5,width:d.roomSize*1.5,height:d.roomSize*1.5,stroke:e,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1})}centerOnRoom(t,e=!1){this.currentRoomId=t.id;const s={x:t.x,y:t.y};this.positionRender?.position(t);const n=this.stage.getAbsoluteTransform().point(s),i={x:this.stage.width()/2,y:this.stage.height()/2},r=i.x-n.x,a=i.y-n.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||d.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new v.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+a,duration:.2,easing:v.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(t){t.forEach(e=>{const s=new v.Group({x:e.x-d.roomSize/2,y:e.y-d.roomSize/2}),o=this.mapReader.getColorValue(e.env),n=d.lineColor,r=d.roomShape==="circle"?new v.Circle({x:d.roomSize/2,y:d.roomSize/2,radius:d.roomSize/2,fill:o,strokeWidth:d.lineWidth,stroke:n,perfectDrawEnabled:!1}):new v.Rect({x:0,y:0,width:d.roomSize,height:d.roomSize,fill:o,strokeWidth:d.lineWidth,stroke:n,perfectDrawEnabled:!1}),a=(m,x)=>this.emitRoomContextEvent(e.id,m,x);s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer"}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto"}),s.on("contextmenu",m=>{m.evt.preventDefault();const x=m.evt;a(x.clientX,x.clientY)});let c,l,h;const g=()=>{h!==void 0&&(this.stage.draggable(h),h=void 0)},f=()=>{c!==void 0&&(window.clearTimeout(c),c=void 0),l=void 0,g()};s.on("touchstart",m=>{if(f(),m.evt.touches&&m.evt.touches.length>1)return;const x=m.evt.touches?.[0];x&&(l={clientX:x.clientX,clientY:x.clientY},h=this.stage.draggable(),this.stage.draggable(!1),c=window.setTimeout(()=>{l&&a(l.clientX,l.clientY),f()},500))}),s.on("touchend",f),s.on("touchmove",m=>{if(!l)return;const x=m.evt.touches?.[0];if(!x){f();return}const y=x.clientX-l.clientX,I=x.clientY-l.clientY,A=y*y+I*I,Y=10;if(A>Y*Y){const W=h;f(),W&&this.stage.startDrag()}}),s.on("touchcancel",f),s.add(r),this.renderSymbol(e,s),this.roomLayer.add(s);const u=[];this.exitRenderer.renderSpecialExits(e).forEach(m=>{this.linkLayer.add(m);const x=m.getClientRect({relativeTo:this.linkLayer}),y={node:m,bounds:x};this.standaloneExitNodes.push(y),this.addStandaloneExitToSpatialIndex(y)}),this.exitRenderer.renderStubs(e).forEach(m=>{this.linkLayer.add(m),u.push(m)}),this.exitRenderer.renderInnerExits(e).forEach(m=>{this.roomLayer.add(m)});const p={room:e,group:s,linkNodes:u};this.roomNodes.set(e.id,p),this.addRoomToSpatialIndex(p)})}scheduleRoomCulling(){this.cullingScheduled||(this.cullingScheduled=!0,window.requestAnimationFrame(()=>{this.cullingScheduled=!1,this.updateRoomCulling()}))}updateRoomCulling(){if(this.roomNodes.size===0&&this.standaloneExitNodes.length===0)return;const t=this.stage.scaleX();if(!t)return;const e=this.stage.position(),s=d.roomSize/2,o=d.cullingBounds,n=o?o.x:0,i=o?o.x+o.width:this.stage.width(),r=o?o.y:0,a=o?o.y+o.height:this.stage.height(),c=Math.min(n,i),l=Math.max(n,i),h=Math.min(r,a),g=Math.max(r,a),f=(c-e.x)/t,u=(l-e.x)/t,p=(h-e.y)/t,m=(g-e.y)/t;let x=!1,y=!1;const I=d.cullingEnabled?d.cullingMode??"indexed":"none",A=f-s,Y=u+s,W=p-s,w=m+s;if(this.refreshStandaloneExitBoundsIfNeeded(),I==="none"){this.roomNodes.forEach(R=>{R.group.visible()||(R.group.visible(!0),x=!0),R.linkNodes.forEach(S=>{S.visible()||(S.visible(!0),y=!0)})}),this.standaloneExitNodes.forEach(R=>{const{node:S}=R;S.visible()||(y=!0,S.visible(!0))}),x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw(),this.visibleRooms=new Set(this.roomNodes.values()),this.visibleStandaloneExitNodes=new Set(this.standaloneExitNodes);return}if(I==="basic"){const R=new Set;this.roomNodes.forEach(M=>{const O=M.room.x-s,X=M.room.x+s,T=M.room.y-s,V=M.room.y+s,P=X>=f&&O<=u&&V>=p&&T<=m;M.group.visible()!==P&&(M.group.visible(P),x=!0),M.linkNodes.forEach($=>{$.visible()!==P&&($.visible(P),y=!0)}),P&&R.add(M)});const S=new Set;this.standaloneExitNodes.forEach(M=>{const{node:O,bounds:X}=M,T=X.x,V=X.x+X.width,P=X.y,$=X.y+X.height,G=V>=f&&T<=u&&$>=p&&P<=m;O.visible()!==G&&(O.visible(G),y=!0),G&&S.add(M)}),this.visibleRooms=R,this.visibleStandaloneExitNodes=S,x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw();return}const b=this.collectRoomCandidates(A,W,Y,w),C=new Set,D=new Set;b.forEach(R=>{C.add(R);const S=R.room.x-s,M=R.room.x+s,O=R.room.y-s,X=R.room.y+s,T=M>=f&&S<=u&&X>=p&&O<=m;R.group.visible()!==T&&(R.group.visible(T),x=!0),R.linkNodes.forEach(V=>{V.visible()!==T&&(V.visible(T),y=!0)}),T&&D.add(R)}),this.visibleRooms.forEach(R=>{C.has(R)||(R.group.visible()&&(R.group.visible(!1),x=!0),R.linkNodes.forEach(S=>{S.visible()&&(S.visible(!1),y=!0)}))}),this.visibleRooms=D;const E=this.collectStandaloneExitCandidates(A,W,Y,w),N=new Set,L=new Set;E.forEach(R=>{N.add(R);const{node:S,bounds:M}=R,O=M.x,X=M.x+M.width,T=M.y,V=M.y+M.height,P=X>=f&&O<=u&&V>=p&&T<=m;S.visible()!==P&&(S.visible(P),y=!0),P&&L.add(R)}),this.visibleStandaloneExitNodes.forEach(R=>{const{node:S}=R;!N.has(R)&&S.visible()&&(S.visible(!1),y=!0)}),this.visibleStandaloneExitNodes=L,x&&this.roomLayer.batchDraw(),y&&this.linkLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.positionLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.positionLayer.batchDraw();return}const e=new Map;e.set(t.id,t);const s=[],o=this.currentAreaInstance instanceof U?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(a=>a.a===t.id||a.b===t.id).forEach(a=>{const c=d.highlightCurrentRoom?this.exitRenderer.renderWithColor(a,_,this.currentZIndex):this.exitRenderer.render(a,this.currentZIndex);c&&s.push(c)});const n=d.highlightCurrentRoom?_:void 0;this.exitRenderer.renderSpecialExits(t,n).forEach(r=>{s.push(r)}),(d.highlightCurrentRoom?this.exitRenderer.renderStubs(t,_):this.exitRenderer.renderStubs(t)).forEach(r=>{s.push(r)}),[...Object.values(t.exits),...Object.values(t.specialExits)].forEach(r=>{const a=this.mapReader.getRoom(r),c=!o||o.hasVisitedRoom(r);a&&a.area===this.currentArea&&a.z===this.currentZIndex&&c&&e.set(r,a)}),s.forEach(r=>{this.positionLayer.add(r),this.currentRoomOverlay.push(r)}),e.forEach((r,a)=>{const c=a===t.id,l=this.createOverlayRoomGroup(r,{stroke:c&&d.highlightCurrentRoom?_:d.lineColor});this.positionLayer.add(l),this.currentRoomOverlay.push(l),this.exitRenderer.renderInnerExits(r).forEach(h=>{this.positionLayer.add(h),this.currentRoomOverlay.push(h)})}),this.positionRender&&this.positionRender.moveToTop(),this.positionLayer.batchDraw()}createOverlayRoomGroup(t,e){const s=new v.Group({x:t.x-d.roomSize/2,y:t.y-d.roomSize/2,listening:!1}),o=this.mapReader.getColorValue(t.env),n=e.stroke,i=d.roomShape==="circle"?new v.Circle({x:d.roomSize/2,y:d.roomSize/2,radius:d.roomSize/2,fill:o,stroke:n,strokeWidth:d.lineWidth}):new v.Rect({x:0,y:0,width:d.roomSize,height:d.roomSize,fill:o,stroke:n,strokeWidth:d.lineWidth});return s.add(i),this.renderSymbol(t,s),s}renderSymbol(t,e){if(t.roomChar!==void 0){const s=d.roomSize*.75,o=new v.Text({x:0,y:0,text:t.roomChar,fontSize:s,fontStyle:"bold",fill:this.mapReader.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:d.roomSize,height:d.roomSize});e.add(o)}}renderExits(t){t.forEach(e=>{const s=this.exitRenderer.render(e,this.currentZIndex);if(!s)return;this.linkLayer.add(s);const o=s.getClientRect({relativeTo:this.linkLayer}),n={node:s,bounds:o};this.standaloneExitNodes.push(n),this.addStandaloneExitToSpatialIndex(n)}),this.standaloneExitBoundsRoomSize=d.roomSize}renderLabels(t){t.forEach(e=>{if(d.labelRenderMode==="image"){if(!e.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${e.pixMap}`;const o=new v.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:s,listening:!1});this.linkLayer.add(o);return}this.renderLabelAsData(e)})}renderLabelAsData(t){const e=new v.Group({listening:!1}),s=new v.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(t.BgColor?.alpha??0)>0&&!d.transparentLabels?s.fill(this.getLabelColor(t.BgColor)):s.fillEnabled(!1),e.add(s);const o=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),n=Math.max(.1,Math.min(o,Math.max(t.Height*.9,.1))),i=new v.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:n,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});e.add(i),this.linkLayer.add(e)}getLabelColor(t){const e=(t?.alpha??255)/255,s=o=>Math.min(255,Math.max(0,o??0));return`rgba(${s(t?.r)}, ${s(t?.g)}, ${s(t?.b)}, ${e})`}}const ct={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function dt(k){const t=k[0]/255,e=k[1]/255,s=k[2]/255,o=Math.max(t,e,s),n=Math.min(t,e,s);return(o+n)/2}class Dt{constructor(t,e){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(s=>{s.rooms.forEach(n=>{n.y=-n.y,this.rooms[n.id]=n});const o=parseInt(s.areaId);this.areas[o]=new nt(s),this.areaSources[o]=s}),this.colors=e.reduce((s,o)=>({...s,[o.envId]:{rgb:o.colors,rgbValue:`rgb(${o.colors.join(",")})`,symbolColor:dt(o.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:dt(o.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(t){return this.areas[t]}getExplorationArea(t){const e=this.areas[t];if(e instanceof U)return e}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(t){return this.rooms[t]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new U(e,this.visitedRooms)})}decorateWithExploration(t){return t!==void 0?this.setVisitedRooms(t):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([t,e])=>{const s=parseInt(t,10);this.areas[s]=new nt(e)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(t){return this.visitedRooms=t instanceof Set?t:new Set(t),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(t){if(this.explorationEnabled){const o=this.getRoom(t);if(o){const n=this.getExplorationArea(o.area);if(n)return n.addVisitedRoom(t)}}const e=this.ensureVisitedRooms(),s=e.has(t);return e.add(t),!s}addVisitedRooms(t){const e=this.ensureVisitedRooms();let s=0;for(const o of t){if(this.explorationEnabled){const i=this.getRoom(o);if(i){const r=this.getExplorationArea(i.area);if(r){r.addVisitedRoom(o)&&s++;continue}}}const n=e.has(o);e.add(o),n||s++}return s}hasVisitedRoom(t){return this.visitedRooms?.has(t)??!1}getColorValue(t){return this.colors[t]?.rgbValue??ct.rgbValue}getSymbolColor(t,e){const s=this.colors[t]?.symbolColor??ct.symbolColor,o=Math.min(Math.max(e??1,0),1),n=s.join(",");return o!=1?`rgba(${n}, ${o})`:`rgba(${n})`}}function Nt(k){return k&&k.__esModule&&Object.prototype.hasOwnProperty.call(k,"default")?k.default:k}var J,lt;function Lt(){if(lt)return J;lt=1;class k{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((e,s)=>e.priority-s.priority)}set(e,s){const o=Number(s);if(isNaN(o))throw new TypeError('"priority" must be a number');return this.keys.has(e)?this.queue.map(n=>(n.key===e&&Object.assign(n,{priority:o}),n)):(this.keys.add(e),this.queue.push({key:e,priority:o})),this.sort(),this.queue.length}next(){const e=this.queue.shift();return this.keys.delete(e.key),e}isEmpty(){return this.queue.length===0}has(e){return this.keys.has(e)}get(e){return this.queue.find(s=>s.key===e)}}return J=k,J}var tt,ut;function zt(){if(ut)return tt;ut=1;function k(t,e){const s=new Map;for(const[o,n]of t)o!==e&&n instanceof Map?s.set(o,k(n,e)):o!==e&&s.set(o,n);return s}return tt=k,tt}var et,ft;function At(){if(ft)return et;ft=1;function k(e){const s=Number(e);return!(isNaN(s)||s<=0)}function t(e){const s=new Map;return Object.keys(e).forEach(n=>{const i=e[n];if(i!==null&&typeof i=="object"&&!Array.isArray(i))return s.set(n,t(i));if(!k(i))throw new Error(`Could not add node at key "${n}", make sure it's a valid node`,i);return s.set(n,Number(i))}),s}return et=t,et}var st,gt;function Xt(){if(gt)return st;gt=1;function k(t){if(!(t instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof t}`);t.forEach((e,s)=>{if(typeof e=="object"&&e instanceof Map){k(e);return}if(typeof e!="number"||e<=0)throw new Error(`Values must be numbers greater than 0. Found value ${e} at ${s}`)})}return st=k,st}var ot,mt;function Yt(){if(mt)return ot;mt=1;const k=Lt(),t=zt(),e=At(),s=Xt();class o{constructor(i){i instanceof Map?(s(i),this.graph=i):i?this.graph=e(i):this.graph=new Map}addNode(i,r){let a;return r instanceof Map?(s(r),a=r):a=e(r),this.graph.set(i,a),this}addVertex(i,r){return this.addNode(i,r)}removeNode(i){return this.graph=t(this.graph,i),this}path(i,r,a={}){if(!this.graph.size)return a.cost?{path:null,cost:0}:null;const c=new Set,l=new k,h=new Map;let g=[],f=0,u=[];if(a.avoid&&(u=[].concat(a.avoid)),u.includes(i))throw new Error(`Starting node (${i}) cannot be avoided`);if(u.includes(r))throw new Error(`Ending node (${r}) cannot be avoided`);for(l.set(i,0);!l.isEmpty();){const p=l.next();if(p.key===r){f=p.priority;let x=p.key;for(;h.has(x);)g.push(x),x=h.get(x);break}c.add(p.key),(this.graph.get(p.key)||new Map).forEach((x,y)=>{if(c.has(y)||u.includes(y))return null;if(!l.has(y))return h.set(y,p.key),l.set(y,p.priority+x);const I=l.get(y).priority,A=p.priority+x;return A<I?(h.set(y,p.key),l.set(y,A)):null})}return g.length?(a.trim?g.shift():g=g.concat([i]),a.reverse||(g=g.reverse()),a.cost?{path:g,cost:f}:g):a.cost?{path:null,cost:0}:null}shortestPath(...i){return this.path(...i)}}return ot=o,ot}var Ot=Yt();const Pt=Nt(Ot),Vt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"};class Wt{constructor(t){this.cache=new Map,this.mapReader=t,this.graph=this.buildGraph()}buildGraph(){const t={};return this.mapReader.getRooms().forEach(e=>{const s={},o=new Set((e.exitLocks??[]).map(i=>Vt[i]).filter(i=>!!i)),n=new Set(e.mSpecialExitLocks??[]);Object.entries(e.exits??{}).forEach(([i,r])=>{o.has(i)||this.mapReader.getRoom(r)&&(s[r.toString()]=1)}),Object.values(e.specialExits??{}).forEach(i=>{n.has(i)||this.mapReader.getRoom(i)&&(s[i.toString()]=1)}),t[e.id.toString()]=s}),new Pt(t)}findPath(t,e){const s=`${t}->${e}`;if(this.cache.has(s))return this.cache.get(s);if(t===e){const r=this.mapReader.getRoom(t)?[t]:null;return this.cache.set(s,r),r}if(!this.mapReader.getRoom(t)||!this.mapReader.getRoom(e))return this.cache.set(s,null),null;const o=this.graph.path(t.toString(),e.toString()),n=Array.isArray(o)?o:o?.path,i=n?n.map(r=>Number(r)):null;return this.cache.set(s,i),i}}const Tt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},Z=class Z{};Z.areaWidth=150,Z.areaHeight=80,Z.areaSpacing=50,Z.fontSize=14,Z.connectionLineWidth=2,Z.areaFillColor="#2a2a3e",Z.areaStrokeColor="#4a4a6e",Z.textColor="#e0e0e0",Z.connectionColor="#6a6a8e",Z.highlightColor="#ff9900";let z=Z;class Ft{constructor(t,e){this.areaNodes=new Map,this.connectionGroups=[],this.currentZoom=1,this.domainInfo=new Map,this.domainFilter="all",this.dotsMode=!1,this.stage=new v.Stage({container:t,width:t.clientWidth,height:t.clientHeight,draggable:!0}),this.backgroundLayer=new v.Layer({listening:!1}),this.stage.add(this.backgroundLayer),this.connectionLayer=new v.Layer({listening:!1}),this.stage.add(this.connectionLayer),this.areaLayer=new v.Layer,this.stage.add(this.areaLayer),this.mapReader=e,this.initScaling(),this.initResize(t)}initResize(t){new ResizeObserver(()=>{this.stage.width(t.clientWidth),this.stage.height(t.clientHeight),this.stage.batchDraw()}).observe(t)}initScaling(){this.stage.on("wheel",e=>{e.evt.preventDefault();const s=this.stage.scaleX(),o=this.stage.getPointerPosition();if(!o)return;const n={x:(o.x-this.stage.x())/s,y:(o.y-this.stage.y())/s},r=(e.evt.deltaY>0?-1:1)>0?this.currentZoom*1.1:this.currentZoom/1.1;this.setZoom(r);const a=this.stage.scaleX(),c={x:o.x-n.x*a,y:o.y-n.y*a};this.stage.position(c),this.stage.batchDraw()})}setZoom(t){this.currentZoom=Math.max(.1,Math.min(5,t)),this.stage.scale({x:this.currentZoom,y:this.currentZoom})}getZoom(){return this.currentZoom}setDomainInfo(t){this.domainInfo.clear();for(const[e,s]of Object.entries(t))this.domainInfo.set(Number(e),s)}setDomainFilter(t){this.domainFilter=t}getDomainFilter(){return this.domainFilter}setBackgroundImage(t){this.backgroundConfig={url:t.url,x:t.x,y:t.y,width:t.width,height:t.height,opacity:t.opacity??.3}}clearBackgroundImage(){this.backgroundConfig=void 0,this.backgroundImage=void 0,this.backgroundLayer.destroyChildren(),this.backgroundLayer.batchDraw()}redrawBackground(){this.drawBackground()}setDotsMode(t){this.dotsMode=t}getDotsMode(){return this.dotsMode}redraw(){this.drawBackground(),this.drawConnections(),this.drawAreas(),this.stage.batchDraw()}isAreaInDomain(t){const e=this.domainInfo.get(t);if(!e)return this.domainFilter==="interdomain"||this.domainFilter==="all";switch(this.domainFilter){case"ishtar":return e.isIshtar;case"empire":return e.isEmpire;case"interdomain":return!e.isIshtar&&!e.isEmpire;case"all":return!0}}areAreasInSameDomain(t,e){const s=this.domainInfo.get(t),o=this.domainInfo.get(e);return!s||!o?!1:!!(s.isIshtar&&o.isIshtar||s.isEmpire&&o.isEmpire||!s.isIshtar&&!s.isEmpire&&!o.isIshtar&&!o.isEmpire)}render(){this.analyzeConnections(),this.layoutAreas(),this.drawBackground(),this.drawConnections(),this.drawAreas(),this.centerView(),this.stage.batchDraw()}drawBackground(){if(this.backgroundLayer.destroyChildren(),!this.backgroundConfig)return;const t=new Image;t.crossOrigin="anonymous",t.onload=()=>{this.backgroundImage=new v.Image({x:this.backgroundConfig.x,y:this.backgroundConfig.y,image:t,width:this.backgroundConfig.width,height:this.backgroundConfig.height,opacity:this.backgroundConfig.opacity,listening:!1}),this.backgroundLayer.add(this.backgroundImage),this.backgroundLayer.batchDraw()},t.onerror=()=>{console.error("Failed to load background image:",this.backgroundConfig?.url)},t.src=this.backgroundConfig.url}analyzeConnections(){this.areaNodes.clear(),this.connectionGroups=[];const t=this.mapReader.getRooms(),e=this.mapReader.getAreas(),s=new Map;for(const c of e){const l=c.getAreaId(),h=c.getRooms();if(h.length===0)continue;let g=1/0,f=-1/0,u=1/0,p=-1/0,m=0;for(const I of h)I.z===0&&(m++,g=Math.min(g,I.x),f=Math.max(f,I.x),u=Math.min(u,I.y),p=Math.max(p,I.y));if(m===0)for(const I of h)g=Math.min(g,I.x),f=Math.max(f,I.x),u=Math.min(u,I.y),p=Math.max(p,I.y);const x=(g+f)/2,y=(u+p)/2;s.set(l,{minX:g,maxX:f,minY:u,maxY:p,centerX:x,centerY:y,roomCount:h.length})}let o=1;for(const c of s.values()){const l=c.maxX-c.minX,h=c.maxY-c.minY;o=Math.max(o,l,h)}const n=200,i=100,r=n/o;for(const c of e){const l=c.getAreaId(),h=s.get(l);if(!h||!this.isAreaInDomain(l))continue;const g=h.maxX-h.minX,f=h.maxY-h.minY;let u=Math.max(i,g*r),p=Math.max(i,f*r);const m=u/p;m>3?p=u/3:m<1/3&&(u=p/3),this.areaNodes.set(l,{areaId:l,name:c.getAreaName(),x:0,y:0,width:u,height:p,connections:[],roomCount:h.roomCount,realCenterX:h.centerX,realCenterY:h.centerY})}const a=new Map;for(const c of t){const l=c.area;if(!this.areaNodes.has(l))continue;const h=this.getLockedDirections(c),g=new Set(c.mSpecialExitLocks??[]);for(const[f,u]of Object.entries(c.exits??{})){if(h.has(f))continue;const p=this.mapReader.getRoom(u);if(!p||p.area===l||!this.areaNodes.has(p.area)||!this.areAreasInSameDomain(l,p.area))continue;const m=this.createConnection(c,p,f);m&&this.addConnection(a,m)}for(const[f,u]of Object.entries(c.specialExits??{})){if(g.has(u))continue;const p=this.mapReader.getRoom(u);if(!p||p.area===l||!this.areaNodes.has(p.area)||!this.areAreasInSameDomain(l,p.area))continue;const m=this.parseDirection(f),x=this.createConnection(c,p,m);x&&this.addConnection(a,x)}}for(const[c,l]of a){const[h,g]=c.split("-").map(Number),f=this.createConnectionGroup(h,g,l);this.connectionGroups.push(f);const u=this.areaNodes.get(h),p=this.areaNodes.get(g);if(u&&u.connections.push(...l),p)for(const m of l)p.connections.push({...m,fromAreaId:m.toAreaId,toAreaId:m.fromAreaId,fromRoomId:m.toRoomId,toRoomId:m.fromRoomId,direction:m.direction?pt[m.direction]:null,fromRoomPosition:m.toRoomPosition,toRoomPosition:m.fromRoomPosition})}}getLockedDirections(t){return new Set((t.exitLocks??[]).map(e=>Tt[e]).filter(e=>!!e))}createConnection(t,e,s){const o=this.toPlanarDirection(s);return{fromAreaId:t.area,toAreaId:e.area,fromRoomId:t.id,toRoomId:e.id,direction:o,fromRoomPosition:{x:t.x,y:t.y},toRoomPosition:{x:e.x,y:e.y}}}addConnection(t,e){const s=e.fromAreaId<e.toAreaId?`${e.fromAreaId}-${e.toAreaId}`:`${e.toAreaId}-${e.fromAreaId}`;t.has(s)||t.set(s,[]),t.get(s).push(e)}createConnectionGroup(t,e,s){const o=new Map;let n=0,i=0;for(const c of s)c.direction&&o.set(c.direction,(o.get(c.direction)??0)+1),n+=c.toRoomPosition.x-c.fromRoomPosition.x,i+=c.toRoomPosition.y-c.fromRoomPosition.y;let r=null,a=0;for(const[c,l]of o)l>a&&(a=l,r=c);return{fromAreaId:t,toAreaId:e,connections:s,primaryDirection:r,averageOffset:{x:n/s.length,y:i/s.length}}}parseDirection(t){const e=t.toLowerCase().trim();return{n:"north",north:"north",s:"south",south:"south",e:"east",east:"east",w:"west",west:"west",ne:"northeast",northeast:"northeast",nw:"northwest",northwest:"northwest",se:"southeast",southeast:"southeast",sw:"southwest",southwest:"southwest",u:"up",up:"up",d:"down",down:"down",i:"in",in:"in",o:"out",out:"out"}[e]??null}toPlanarDirection(t){return t&&it.includes(t)?t:null}layoutAreas(){if(Array.from(this.areaNodes.values()).length===0)return;const e=this.findConnectedComponents();let s=0;const o=z.areaWidth*3;for(const n of e)if(n.length===1){const i=this.areaNodes.get(n[0]);i&&(i.x=s,i.y=0),s+=z.areaWidth+o}else{const i=this.forceDirectedLayout(n);for(const a of n){const c=this.areaNodes.get(a);c&&isFinite(i.minX)&&isFinite(i.minY)&&(c.x-=i.minX,c.x+=s,c.y-=i.minY)}const r=isFinite(i.maxX-i.minX)?i.maxX-i.minX:z.areaWidth;s+=r+o}}findConnectedComponents(){const t=new Set,e=[];for(const[s]of this.areaNodes){if(t.has(s))continue;const o=[],n=[s];for(;n.length>0;){const i=n.shift();if(t.has(i))continue;t.add(i),o.push(i);const r=this.areaNodes.get(i);if(r)for(const a of r.connections)t.has(a.toAreaId)||n.push(a.toAreaId)}e.push(o)}return e}forceDirectedLayout(t){const e=new Map;for(const w of t){const b=this.areaNodes.get(w);if(!b)continue;const C=new Set(b.connections.map(D=>D.toAreaId));e.set(w,C)}const s=new Set,o=new Set;for(const[w,b]of e)b.size>=3&&s.add(w);for(const[w,b]of e){if(s.has(w)||o.has(w)||b.size>2)continue;const C=[w];o.add(w);const D=Array.from(b);for(const N of D){let L=N,R=w;for(;L&&!o.has(L)&&!s.has(L);){const S=e.get(L);if(!S)break;if(S.size>=3){s.add(L);break}C.push(L),o.add(L);let M=!1;for(const O of S)if(O!==R&&!o.has(O)){R=L,L=O,M=!0;break}if(!M)break}}let E=!1;for(const N of C){const L=e.get(N);if(L){for(const R of L)if(s.has(R)){E=!0;break}}if(E)break}if(!E&&C.length>0){let N=C[0],L=e.get(C[0])?.size??0;for(const R of C){const S=e.get(R)?.size??0;S>L&&(L=S,N=R)}s.add(N),o.delete(N)}}for(const w of t){const b=e.get(w);(!b||b.size===0)&&s.add(w)}const n=new Map,i=new Map;for(const w of s)n.set(w,w),i.set(w,[]);const r=new Set(s);for(const w of s){const b=e.get(w)??new Set;for(const C of b){if(r.has(C))continue;const D=[];let E=C,N=w;for(;E&&!r.has(E);){D.push(E),n.set(E,w),r.add(E);const L=e.get(E)??new Set;let R;for(const S of L)if(S!==N&&!r.has(S)){R=S;break}N=E,E=R}D.length>0&&i.get(w).push(D)}}const a=new Set,c=[],l=s.values().next().value,h=l!==void 0?l:t[0];if(h!==void 0){const w=this.areaNodes.get(h);w&&(w.x=0,w.y=0,a.add(h),c.push(h))}for(;c.length>0;){const w=c.shift(),b=this.areaNodes.get(w),C=new Map;for(const D of b.connections){const E=D.toAreaId;if(a.has(E)||!s.has(E))continue;const N=this.areaNodes.get(E);if(!N)continue;const L=D.direction??"none";C.has(L)||C.set(L,[]),C.get(L).push({id:E,node:N,conn:D})}for(const[D,E]of C){const N=this.getDirectionOffset(D==="none"?null:D);E.sort((S,M)=>Math.abs(N.x)>Math.abs(N.y)?M.node.realCenterY-S.node.realCenterY:S.node.realCenterX-M.node.realCenterX);const L=z.areaWidth+z.areaSpacing,R=z.areaHeight+z.areaSpacing;E.forEach((S,M)=>{if(S.node.x=b.x+N.x*L,S.node.y=b.y+N.y*R,E.length>1){const O=(M-(E.length-1)/2)*.5;Math.abs(N.x)>Math.abs(N.y)?S.node.y+=O*R:S.node.x+=O*L}a.add(S.id),c.push(S.id)})}}const g=Array.from(s);g.length>1&&this.applyForces(g,80);const f=z.areaWidth+z.areaSpacing+30,u=z.areaHeight+z.areaSpacing+30,p=new Map,m=["east","west","north","south","northeast","northwest","southeast","southwest"];for(const[w,b]of i){const C=this.areaNodes.get(w);if(!C)continue;let D=0;const E=new Map;for(const N of b){let L=w,R=C.x,S=C.y,M=null;for(const O of N){const X=this.areaNodes.get(O);if(!X)continue;const T=this.areaNodes.get(L);let V=null;if(T){for(const G of T.connections)if(G.toAreaId===O){V=G.direction;break}}!V&&L===w?(M=m[D%m.length],D++,V=M):!V&&M&&(V=M);const P=this.getDirectionOffset(V);let $=0;if(L===w&&V){const G=V,at=E.get(G)??0;E.set(G,at+1),$=at}X.x=R+P.x*f,X.y=S+P.y*u,$>0&&(P.x!==0&&P.y===0?X.y+=$*u*1.2:P.y!==0&&P.x===0?X.x+=$*f*1.2:(X.x+=$*f*1.2,X.y-=$*u*1.2)),p.set(O,{dx:X.x-C.x,dy:X.y-C.y,hubId:w}),L=O,R=X.x,S=X.y}}}const x=new Map,y=new Map;for(const w of s){const b=this.areaNodes.get(w);if(!b)continue;let C=b.x,D=b.y,E=b.x+b.width,N=b.y+b.height;const L=i.get(w)??[];for(const R of L)for(const S of R){const M=this.areaNodes.get(S);M&&(C=Math.min(C,M.x),D=Math.min(D,M.y),E=Math.max(E,M.x+M.width),N=Math.max(N,M.y+M.height))}x.set(w,{minX:C,minY:D,maxX:E,maxY:N}),y.set(w,{dx:C-b.x,dy:D-b.y})}this.applyClusterForces(g,x,y,60);for(const[w,b]of p){const C=this.areaNodes.get(w),D=this.areaNodes.get(b.hubId);!C||!D||(C.x=D.x+b.dx,C.y=D.y+b.dy)}let I=1/0,A=1/0,Y=-1/0,W=-1/0;for(const w of t){const b=this.areaNodes.get(w);I=Math.min(I,b.x),A=Math.min(A,b.y),Y=Math.max(Y,b.x+b.width),W=Math.max(W,b.y+b.height)}return{minX:I,minY:A,maxX:Y,maxY:W}}getDirectionOffset(t){const e={north:{x:0,y:-1},south:{x:0,y:1},east:{x:1,y:0},west:{x:-1,y:0},northeast:{x:.75,y:-.75},northwest:{x:-.75,y:-.75},southeast:{x:.75,y:.75},southwest:{x:-.75,y:.75}};return t&&e[t]?e[t]:{x:1,y:0}}applyClusterForces(t,e,s,o){const r=new Map;for(const a of t)r.set(a,{vx:0,vy:0});for(let a=0;a<o;a++){for(const c of t){const l=this.areaNodes.get(c),h=e.get(c),g=s.get(c);if(!l||!h||!g)continue;const f=h.maxX-h.minX,u=h.maxY-h.minY;h.minX=l.x+g.dx,h.minY=l.y+g.dy,h.maxX=h.minX+f,h.maxY=h.minY+u}for(const c of t){const l=this.areaNodes.get(c),h=r.get(c),g=e.get(c);if(!(!l||!h||!g)){for(const f of t){if(c===f)continue;const u=e.get(f);if(!u)continue;const p=(g.minX+g.maxX)/2,m=(g.minY+g.maxY)/2,x=(u.minX+u.maxX)/2,y=(u.minY+u.maxY)/2,I=p-x,A=m-y,Y=(g.maxX-g.minX)/2,W=(g.maxY-g.minY)/2,w=(u.maxX-u.minX)/2,b=(u.maxY-u.minY)/2,C=Y+w+50,D=W+b+50,E=C-Math.abs(I),N=D-Math.abs(A);if(E>0&&N>0)if(E<N){const L=E*(I>=0?1:-1)*.5;h.vx+=L}else{const L=N*(A>=0?1:-1)*.5;h.vy+=L}}for(const f of l.connections){const u=this.areaNodes.get(f.toAreaId);if(!u||!t.includes(f.toAreaId))continue;const p=u.x-l.x,m=u.y-l.y,x=Math.sqrt(p*p+m*m)||1,y=z.areaWidth+z.areaSpacing+50,A=(x-y)*.015;h.vx+=p/x*A,h.vy+=m/x*A}}}for(const c of t){const l=this.areaNodes.get(c),h=r.get(c);!l||!h||(l.x+=h.vx,l.y+=h.vy,h.vx*=.8,h.vy*=.8)}}}applyForces(t,e){const n=z.areaWidth+z.areaSpacing,i=z.areaWidth/2+60,r=new Set(t),a=[],c=new Set;for(const h of t){const g=this.areaNodes.get(h);if(g)for(const f of g.connections){if(!r.has(f.toAreaId))continue;const u=Math.min(h,f.toAreaId)+"-"+Math.max(h,f.toAreaId);c.has(u)||(c.add(u),a.push({from:h,to:f.toAreaId}))}}const l=new Map;for(const h of t)l.set(h,{vx:0,vy:0});for(let h=0;h<e;h++){for(const g of t){const f=this.areaNodes.get(g),u=l.get(g);if(!f||!u)continue;const p=f.x+f.width/2,m=f.y+f.height/2;for(const x of t){if(g===x)continue;const y=this.areaNodes.get(x);if(!y)continue;const I=(f.width+y.width)/2+20,A=(f.height+y.height)/2+20,Y=f.x+f.width/2,W=f.y+f.height/2,w=y.x+y.width/2,b=y.y+y.height/2,C=Y-w,D=W-b,E=I-Math.abs(C),N=A-Math.abs(D);E>0&&N>0&&(E<N?u.vx+=(C>=0?1:-1)*E*.5:u.vy+=(D>=0?1:-1)*N*.5)}for(const x of a){if(x.from===g||x.to===g)continue;const y=this.areaNodes.get(x.from),I=this.areaNodes.get(x.to);if(!y||!I)continue;const A=y.x+y.width/2,Y=y.y+y.height/2,W=I.x+I.width/2,w=I.y+I.height/2,b=this.closestPointOnSegment(p,m,A,Y,W,w),C=p-b.x,D=m-b.y,E=Math.sqrt(C*C+D*D)||1;if(E<i){const N=(i-E)*.6;u.vx+=C/E*N,u.vy+=D/E*N}}for(const x of f.connections){if(!r.has(x.toAreaId))continue;const y=this.areaNodes.get(x.toAreaId);if(!y)continue;const I=y.x-f.x,A=y.y-f.y,Y=Math.sqrt(I*I+A*A)||1,w=(Y-n)*.03;u.vx+=I/Y*w,u.vy+=A/Y*w;const b=this.getDirectionOffset(x.direction),C=f.x+b.x*n,D=f.y+b.y*n,E=l.get(x.toAreaId);E&&(E.vx+=(C-y.x)*.01,E.vy+=(D-y.y)*.01)}}for(const g of t){const f=this.areaNodes.get(g),u=l.get(g);!f||!u||(f.x+=u.vx,f.y+=u.vy,u.vx*=.8,u.vy*=.8)}}}closestPointOnSegment(t,e,s,o,n,i){const r=n-s,a=i-o,c=t-s,l=e-o,h=r*r+a*a;if(h===0)return{x:s,y:o};let g=(c*r+l*a)/h;return g=Math.max(0,Math.min(1,g)),{x:s+g*r,y:o+g*a}}edgesIntersect(t,e,s,o,n,i,r,a){const c=(l,h,g,f,u,p)=>(p-h)*(g-l)>(f-h)*(u-l);return c(t,e,n,i,r,a)!==c(s,o,n,i,r,a)&&c(t,e,s,o,n,i)!==c(t,e,s,o,r,a)}drawConnections(){this.connectionLayer.destroyChildren();for(const t of this.connectionGroups){const e=this.areaNodes.get(t.fromAreaId),s=this.areaNodes.get(t.toAreaId);if(!e||!s||!isFinite(e.x)||!isFinite(e.y)||!isFinite(s.x)||!isFinite(s.y))continue;const o={x:e.x+e.width/2,y:e.y+e.height/2},n={x:s.x+s.width/2,y:s.y+s.height/2};let i,r;if(this.dotsMode?(i=o,r=n):(i=this.getEdgePoint(e,n),r=this.getEdgePoint(s,o)),!isFinite(i.x)||!isFinite(i.y)||!isFinite(r.x)||!isFinite(r.y))continue;const a=this.dotsMode?"#ffffff":z.connectionColor,c=this.dotsMode?1:Math.min(z.connectionLineWidth,1+t.connections.length*.5),l=new v.Line({points:[i.x,i.y,r.x,r.y],stroke:a,strokeWidth:c,lineCap:"round",listening:!1});this.connectionLayer.add(l)}}getEdgePoint(t,e){const s=t.x+t.width/2,o=t.y+t.height/2,n=e.x-s,i=e.y-o,r=t.width/2,a=t.height/2;if(n===0&&i===0)return{x:s,y:o};const c=Math.abs(n),l=Math.abs(i);let h;return c/r>l/a?h=r/c:h=a/l,{x:s+n*h,y:o+i*h}}drawAreas(){this.areaLayer.destroyChildren();for(const[,t]of this.areaNodes){if(!isFinite(t.x)||!isFinite(t.y))continue;const e=t.areaId===this.highlightedArea;if(this.dotsMode){const o=t.x+t.width/2,n=t.y+t.height/2,i=new v.Group({x:o,y:n,draggable:!0}),r=new v.Circle({radius:6,fill:e?z.highlightColor:"#ffffff",stroke:e?z.highlightColor:"#ffffff",strokeWidth:1}),a=new v.Text({text:t.name,fontSize:10,fill:"#ffffff",x:10,y:-5});i.add(r),i.add(a),i.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),i.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",r.fill(z.highlightColor),r.stroke(z.highlightColor),this.areaLayer.batchDraw()}),i.on("mouseleave",()=>{this.stage.container().style.cursor="auto",r.fill(e?z.highlightColor:"#ffffff"),r.stroke(e?z.highlightColor:"#ffffff"),this.areaLayer.batchDraw()}),i.on("dragmove",()=>{t.x=i.x()-t.width/2,t.y=i.y()-t.height/2,this.drawConnections(),this.connectionLayer.batchDraw()}),i.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),i.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(i)}else{const s=new v.Group({x:t.x,y:t.y,draggable:!0}),o=new v.Rect({width:t.width,height:t.height,fill:z.areaFillColor,stroke:e?z.highlightColor:z.areaStrokeColor,strokeWidth:e?3:2,cornerRadius:8}),n=new v.Text({text:t.name,fontSize:z.fontSize,fill:z.textColor,width:t.width-10,height:t.height-20,x:5,y:10,align:"center",verticalAlign:"middle",ellipsis:!0,wrap:"word"}),i=new v.Text({text:`${t.roomCount} rooms`,fontSize:10,fill:z.connectionColor,width:t.width-10,x:5,y:t.height-18,align:"center"});s.add(o),s.add(n),s.add(i),s.on("click tap",()=>{this.emitAreaClickEvent(t.areaId)}),s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer",o.stroke(z.highlightColor),this.areaLayer.batchDraw()}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto",o.stroke(e?z.highlightColor:z.areaStrokeColor),this.areaLayer.batchDraw()}),s.on("dragmove",()=>{t.x=s.x(),t.y=s.y(),this.drawConnections(),this.connectionLayer.batchDraw()}),s.on("dragstart",()=>{this.stage.container().style.cursor="grabbing"}),s.on("dragend",()=>{this.stage.container().style.cursor="pointer"}),this.areaLayer.add(s)}}}centerView(){let t=1/0,e=1/0,s=-1/0,o=-1/0;for(const[,u]of this.areaNodes)t=Math.min(t,u.x),e=Math.min(e,u.y),s=Math.max(s,u.x+u.width),o=Math.max(o,u.y+u.height);if(!isFinite(t))return;const n=s-t,i=o-e,r=t+n/2,a=e+i/2,c=50,l=(this.stage.width()-c*2)/n,h=(this.stage.height()-c*2)/i,g=Math.min(l,h,1.5);this.setZoom(g);const f=this.stage.scaleX();this.stage.position({x:this.stage.width()/2-r*f,y:this.stage.height()/2-a*f})}highlightArea(t){this.highlightedArea=t,this.drawAreas(),this.stage.batchDraw()}centerOnArea(t){const e=this.areaNodes.get(t);if(!e)return;const s=this.stage.scaleX(),o=e.x+e.width/2,n=e.y+e.height/2;this.stage.position({x:this.stage.width()/2-o*s,y:this.stage.height()/2-n*s}),this.stage.batchDraw()}emitAreaClickEvent(t){const e=new CustomEvent("areaclick",{detail:{areaId:t}});this.stage.container().dispatchEvent(e)}getAreaNode(t){return this.areaNodes.get(t)}getConnectionGroups(){return this.connectionGroups}destroy(){this.stage.destroy()}}exports.AreaMapRenderer=Ft;exports.AreaMapSettings=z;exports.ExplorationArea=U;exports.MapReader=Dt;exports.PathFinder=Wt;exports.Renderer=Mt;exports.Settings=d;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|