mudlet-map-renderer 0.9.2-konva → 0.11.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.
@@ -5,6 +5,10 @@ export default class ExitRenderer {
5
5
  private mapReader;
6
6
  private mapRenderer;
7
7
  constructor(mapReader: MapReader, mapRenderer: Renderer);
8
+ /**
9
+ * Get the edge point of a room based on its shape
10
+ */
11
+ private getRoomEdgePoint;
8
12
  render(exit: Exit, zIndex: number): import('konva/lib/Group').Group | import('konva/lib/shapes/Arrow').Arrow | undefined;
9
13
  renderWithColor(exit: Exit, color: string, zIndex: number): import('konva/lib/Group').Group | import('konva/lib/shapes/Arrow').Arrow | undefined;
10
14
  private renderTwoWayExit;
@@ -2,6 +2,7 @@ import { default as MapReader } from './reader/MapReader';
2
2
  import { default as Area } from './reader/Area';
3
3
  export type LabelRenderMode = "image" | "data";
4
4
  export type CullingMode = "none" | "basic" | "indexed";
5
+ export type RoomShape = "rectangle" | "circle";
5
6
  export type RoomContextMenuEventDetail = {
6
7
  roomId: number;
7
8
  position: {
@@ -12,8 +13,19 @@ export type RoomContextMenuEventDetail = {
12
13
  export type ZoomChangeEventDetail = {
13
14
  zoom: number;
14
15
  };
16
+ export type PlayerMarkerStyle = {
17
+ strokeColor: string;
18
+ strokeAlpha: number;
19
+ fillColor: string;
20
+ fillAlpha: number;
21
+ strokeWidth: number;
22
+ sizeFactor: number;
23
+ dash?: number[];
24
+ dashEnabled: boolean;
25
+ };
15
26
  export declare class Settings {
16
27
  static roomSize: number;
28
+ static lineWidth: number;
17
29
  static lineColor: string;
18
30
  static instantMapMove: boolean;
19
31
  static highlightCurrentRoom: boolean;
@@ -27,7 +39,8 @@ export declare class Settings {
27
39
  } | null;
28
40
  static labelRenderMode: LabelRenderMode;
29
41
  static transparentLabels: boolean;
30
- static cullingDebug: boolean;
42
+ static roomShape: RoomShape;
43
+ static playerMarker: PlayerMarkerStyle;
31
44
  }
32
45
  export declare class Renderer {
33
46
  private readonly stage;
@@ -35,7 +48,6 @@ export declare class Renderer {
35
48
  private readonly linkLayer;
36
49
  private readonly overlayLayer;
37
50
  private readonly positionLayer;
38
- private readonly debugLayer;
39
51
  private mapReader;
40
52
  private exitRenderer;
41
53
  private pathRenderer;
@@ -58,9 +70,6 @@ export declare class Renderer {
58
70
  private visibleStandaloneExitNodes;
59
71
  private standaloneExitBoundsRoomSize?;
60
72
  private cullingScheduled;
61
- private cullingViewportDebug?;
62
- private cullingSearchDebug?;
63
- private cullingBucketDebug;
64
73
  constructor(container: HTMLDivElement, mapReader: MapReader);
65
74
  private onResize;
66
75
  private initScaling;
@@ -73,14 +82,12 @@ export declare class Renderer {
73
82
  private collectRoomCandidates;
74
83
  private collectStandaloneExitCandidates;
75
84
  private refreshStandaloneExitBoundsIfNeeded;
76
- private getBucketBounds;
77
85
  private emitRoomContextEvent;
78
86
  private emitZoomChangeEvent;
79
87
  setZoom(zoom: number): boolean;
80
88
  getZoom(): number;
81
89
  setCullingMode(mode: CullingMode): void;
82
90
  getCullingMode(): CullingMode;
83
- setCullingDebug(enabled: boolean): void;
84
91
  getCurrentArea(): Area | undefined;
85
92
  setPosition(roomId: number): void;
86
93
  renderPath(locations: number[], color?: string): import('konva/lib/shapes/Line').Line<{
@@ -89,7 +96,7 @@ export declare class Renderer {
89
96
  strokeWidth: number;
90
97
  }> | undefined;
91
98
  clearPaths(): void;
92
- renderHighlight(roomId: number, color: string): import('konva/lib/shapes/Circle').Circle | undefined;
99
+ renderHighlight(roomId: number, color: string): import('konva/lib/Shape').Shape<import('konva/lib/Shape').ShapeConfig> | undefined;
93
100
  clearHighlights(): void;
94
101
  private refreshHighlights;
95
102
  private createHighlightShape;
@@ -97,7 +104,6 @@ export declare class Renderer {
97
104
  private renderRooms;
98
105
  private scheduleRoomCulling;
99
106
  private updateRoomCulling;
100
- private updateCullingDebugVisuals;
101
107
  private clearCurrentRoomOverlay;
102
108
  private updateCurrentRoomOverlay;
103
109
  private createOverlayRoomGroup;
@@ -5,3 +5,12 @@ export declare function movePoint(x: number, y: number, direction?: MapData.dire
5
5
  x: number;
6
6
  y: number;
7
7
  };
8
+ /**
9
+ * Calculate the edge point of a circle for a given direction
10
+ * For circles, we need to calculate the exact point on the circle's circumference
11
+ * based on the angle to the direction
12
+ */
13
+ export declare function movePointCircle(x: number, y: number, direction?: MapData.direction, radius?: number): {
14
+ x: number;
15
+ y: number;
16
+ };
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("konva"),K=["north","south","east","west","northeast","northwest","southeast","southwest"],O={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},it={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}},Q=["north","south","east","west","northeast","northwest","southeast","southwest"],dt={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function ut(g){return g?Object.prototype.hasOwnProperty.call(it,g):!1}function S(g,t,e,s=1){if(!ut(e))return{x:g,y:t};const i=it[e];return{x:g+i.x*s,y:t+i.y*s}}const A={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)"},gt={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},ft=["up","down","in","out"];function mt(g){switch(g){case 1:return A.OPEN_DOOR;case 2:return A.CLOSED_DOOR;default:return A.LOCKED_DOOR}}class pt{constructor(t,e){this.mapReader=t,this.mapRenderer=e}render(t,e){return this.renderWithColor(t,h.lineColor,e)}renderWithColor(t,e,s){return t.aDir&&t.bDir?this.renderTwoWayExit(t,e,s):this.renderOneWayExit(t,e)}renderTwoWayExit(t,e,s){const i=this.mapReader.getRoom(t.a),o=this.mapReader.getRoom(t.b);if(!i||!o||!t.aDir||!t.bDir||!K.includes(t.aDir)||!K.includes(t.bDir)||i.customLines[O[t.aDir]]&&o.customLines[O[t.bDir]]||i.z!==o.z&&(s!==o.z&&i.customLines[O[t.aDir]]||s!==i.z&&o.customLines[O[t.bDir]]))return;const n=new f.Group,r=[];if(r.push(...Object.values(S(i.x,i.y,t.aDir,h.roomSize/2))),r.push(...Object.values(S(o.x,o.y,t.bDir,h.roomSize/2))),i.doors[O[t.aDir]]||o.doors[O[t.bDir]]){const d=this.renderDoor(r,i.doors[O[t.aDir]]??o.doors[O[t.bDir]]);n.add(d)}const a=new f.Line({points:r,stroke:e,strokeWidth:.025,perfectDrawEnabled:!1});return n.add(a),n}renderOneWayExit(t,e){const s=t.aDir?this.mapReader.getRoom(t.a):this.mapReader.getRoom(t.b),i=t.aDir?this.mapReader.getRoom(t.b):this.mapReader.getRoom(t.a),o=t.aDir?t.aDir:t.bDir;if(!o||!s||!i||s.customLines[O[o]||o])return;if(s.area!=i.area&&o)return this.renderAreaExit(s,o,e);let n={x:i.x,y:i.y};(i.area!==s.area||i.z!==s.z)&&(n=S(s.x,s.y,o,h.roomSize/2));const r=S(s.x,s.y,o,.3),a=r.x-(r.x-n.x)/2,d=r.y-(r.y-n.y)/2,u=new f.Group,l=[];l.push(...Object.values(S(s.x,s.y,o,h.roomSize/2))),l.push(n.x,n.y);const y=new f.Line({points:l,stroke:e,strokeWidth:.025,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1});u.add(y);const c=new f.Arrow({points:[l[0],l[1],a,d],pointerLength:.5,pointerWidth:.35,strokeWidth:.035,stroke:e,fill:A.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return u.add(c),u}renderAreaExit(t,e,s){const i=S(t.x,t.y,e,h.roomSize/2),o=S(t.x,t.y,e,h.roomSize*1.5),n=s??this.mapReader.getColorValue(t.env);return new f.Arrow({points:[i.x,i.y,o.x,o.y],pointerLength:.3,pointerWidth:.3,strokeWidth:.035,stroke:n,fill:n})}renderSpecialExits(t,e){return Object.entries(t.customLines).map(([s,i])=>{const o=[t.x,t.y];i.points.reduce((u,l)=>(u.push(l.x,-l.y),u),o);const n=i.attributes.arrow?f.Arrow:f.Line,r=e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g}, ${i.attributes.color.b})`,a=new n({points:o,strokeWidth:.025,stroke:r,fill:e??`rgb(${i.attributes.color.r}, ${i.attributes.color.g} , ${i.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1});let d=i.attributes.style;return d==="dot line"?(a.dash([.05,.05]),a.dashOffset(.1)):d==="dash line"?a.dash([.4,.2]):d==="solid line"||d!==void 0&&console.log("Brak opisu stylu: "+d),a})}renderStubs(t,e=h.lineColor){return t.stubs.map(s=>{const i=gt[s],o=S(t.x,t.y,i,h.roomSize/2),n=S(t.x,t.y,i,h.roomSize/2+.5),r=[o.x,o.y,n.x,n.y];return new f.Line({points:r,stroke:e,strokeWidth:.025})})}renderInnerExits(t){return ft.map(e=>{if(t.exits[e]){const s=new f.Group,i=new f.RegularPolygon({x:t.x,y:t.y,sides:3,fill:this.mapReader.getSymbolColor(t.env,.6),stroke:this.mapReader.getSymbolColor(t.env),strokeWidth:.025,radius:h.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1});s.add(i);let o=t.doors[e];if(o!==void 0)switch(o){case 1:i.stroke(A.OPEN_DOOR);break;case 2:i.stroke(A.CLOSED_DOOR);break;default:i.stroke(A.LOCKED_DOOR)}switch(e){case"up":i.position(S(t.x,t.y,"south",h.roomSize/4));break;case"down":i.rotation(180),i.position(S(t.x,t.y,"north",h.roomSize/4));break;case"in":const n=i.clone();n.rotation(-90),n.position(S(t.x,t.y,"east",h.roomSize/4)),s.add(n),i.rotation(90),i.position(S(t.x,t.y,"west",h.roomSize/4));break;case"out":const r=i.clone();r.rotation(90),r.position(S(t.x,t.y,"east",h.roomSize/4)),s.add(r),i.rotation(-90),i.position(S(t.x,t.y,"west",h.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 f.Rect({x:s.x-h.roomSize/4,y:s.y-h.roomSize/4,width:h.roomSize/2,height:h.roomSize/2,stroke:mt(e),strokeWidth:.025})}}class ot{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 ${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,i])=>(e[+s]=new ot(i,this.area.labels.filter(o=>o.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,i){if(t===e)return;const o=Math.min(t,e),n=Math.max(t,e),r=`${o}-${n}`;let a=this.exits.get(r);a||(a={a:o,b:n,zIndex:[s]}),o==t?a.aDir=i:a.bDir=i,a.zIndex.push(s),this.exits.set(r,a)}}class U extends ot{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 B extends ${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 U(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 U(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 i=this.visitedRooms.has(s);this.visitedRooms.add(s),!i&&this.areaRoomIds.has(s)&&e++}return e>0&&this.markDirty(),e}}class bt{constructor(t,e){this.paths=[],this.mapReader=t,this.overlayLayer=e}renderPath(t,e,s,i="#66E64D"){if(e===void 0||s===void 0)return;const o=t.map(l=>this.mapReader.getRoom(l)).filter(l=>l!==void 0),n=[];let r=null;const a=()=>{r&&(r.length<4&&n.pop(),r=null)},d=()=>(r||(r=[],n.push(r)),r);o.forEach((l,y)=>{if(!this.isRoomVisible(l,e,s))return;const c=y>0?o[y-1]:void 0,m=y<o.length-1?o[y+1]:void 0;if(this.isRoomVisible(c,e,s))d();else{a();const R=d();if(c){const p=this.getDirectionTowards(l,c);if(p){const D=S(l.x,l.y,p,h.roomSize);R.push(D.x,D.y)}}}if(r==null||r.push(l.x,l.y),!this.isRoomVisible(m,e,s)&&m){const R=this.getDirectionTowards(l,m);if(R){const p=S(l.x,l.y,R,h.roomSize);r==null||r.push(p.x,p.y)}a()}}),a();const u=n.filter(l=>l.length>=4).map(l=>new f.Line({points:l,stroke:i,strokeWidth:.1}));return u.forEach(l=>{this.overlayLayer.add(l),this.paths.push(l)}),u[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 Q)if(t.exits[s]===e.id)return s;for(const s of Q)if(e.exits[s]===t.id)return dt[s]}}const rt=.6,Y=75,xt="rgb(225, 255, 225)",W="rgb(120, 72, 0)",I=class I{};I.roomSize=rt,I.lineColor=xt,I.instantMapMove=!1,I.highlightCurrentRoom=!0,I.cullingEnabled=!0,I.cullingMode="indexed",I.cullingBounds=null,I.labelRenderMode="image",I.cullingDebug=!1;let h=I;class yt{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.cullingBucketDebug=[],this.stage=new f.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 f.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new f.Layer,this.stage.add(this.roomLayer),this.overlayLayer=new f.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.debugLayer=new f.Layer({listening:!1}),this.stage.add(this.debugLayer),this.positionLayer=new f.Layer({listening:!1}),this.stage.add(this.positionLayer),this.mapReader=e,this.exitRenderer=new pt(e,this),this.pathRenderer=new bt(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){f.hitOnDragEnabled=!0;let e,s=!1,i=!1;this.stage.on("touchstart",o=>{const n=o.evt.touches;n&&n.length>1?(i=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(i=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",o=>{e=void 0;const n=o.evt.touches;(!n||n.length<=1)&&(i=!1,this.stage.draggable(!0))}),this.stage.on("wheel",o=>{o.evt.preventDefault();const n=this.stage.scaleX(),r=this.stage.getPointerPosition();if(!r)return;const a={x:(r.x-this.stage.x())/n,y:(r.y-this.stage.y())/n};let d=o.evt.deltaY>0?-1:1;o.evt.ctrlKey&&(d=-d);const u=d>0?this.currentZoom*t:this.currentZoom/t,l=u*Y,y=this.setZoom(u),c={x:r.x-a.x*l,y:r.y-a.y*l};this.stage.position(c),this.scheduleRoomCulling(),y&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",o=>{const n=o.evt.touches,r=n==null?void 0:n[0],a=n==null?void 0:n[1];if(a||i&&(i=!1,this.stage.draggable(!0)),r&&!a&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!r||!a){e=void 0;return}o.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),i||(i=!0,this.stage.draggable(!1));const d=this.stage.container().getBoundingClientRect(),u={x:r.clientX-d.left,y:r.clientY-d.top},l={x:a.clientX-d.left,y:a.clientY-d.top},y=Math.hypot(u.x-l.x,u.y-l.y);if(e===void 0){e=y;return}if(e===0)return;const c=this.stage.scaleX(),m=this.stage.x(),w=this.stage.y(),b={x:this.stage.width()/2,y:this.stage.height()/2},R={x:(b.x-m)/c,y:(b.y-w)/c},p=this.currentZoom*(y/e),D=this.setZoom(p),C=this.stage.scaleX(),z={x:b.x-R.x*C,y:b.y-R.y*C};this.stage.position(z),this.stage.batchDraw(),this.scheduleRoomCulling(),e=y,D&&this.emitZoomChangeEvent()})}drawArea(t,e){const s=this.mapReader.getArea(t);if(!s)return;const i=s.getPlane(e);i&&(this.currentArea=t,this.currentAreaInstance=s,this.currentZIndex=e,this.currentAreaVersion=s.getVersion(),this.clearCurrentRoomOverlay(),this.roomLayer.destroyChildren(),this.linkLayer.destroyChildren(),this.debugLayer.destroyChildren(),this.roomNodes.clear(),this.standaloneExitNodes=[],this.standaloneExitBoundsRoomSize=void 0,this.roomSpatialIndex.clear(),this.exitSpatialIndex.clear(),this.visibleRooms.clear(),this.visibleStandaloneExitNodes.clear(),this.cullingViewportDebug=void 0,this.cullingSearchDebug=void 0,this.cullingBucketDebug=[],this.spatialBucketSize=this.computeSpatialBucketSize(),this.stage.scale({x:Y*this.currentZoom,y:Y*this.currentZoom}),this.renderLabels(i.getLabels()),this.renderExits(s.getLinkExits(e)),this.renderRooms(i.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}computeSpatialBucketSize(){return Math.max(h.roomSize*10,5)}getBucketKey(t,e){return`${t},${e}`}forEachBucket(t,e,s,i,o){const n=this.spatialBucketSize,r=Math.min(t,s),a=Math.max(t,s),d=Math.min(e,i),u=Math.max(e,i),l=Math.floor(r/n),y=Math.floor(a/n),c=Math.floor(d/n),m=Math.floor(u/n);for(let w=l;w<=y;w++)for(let b=c;b<=m;b++)o(this.getBucketKey(w,b))}addRoomToSpatialIndex(t){const e=h.roomSize/2,s=t.room.x-e,i=t.room.x+e,o=t.room.y-e,n=t.room.y+e;this.forEachBucket(s,o,i,n,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,i=e.x+e.width,o=e.y,n=e.y+e.height;this.forEachBucket(s,o,i,n,r=>{let a=this.exitSpatialIndex.get(r);a||(a=new Set,this.exitSpatialIndex.set(r,a)),a.add(t)})}collectRoomCandidates(t,e,s,i,o){const n=new Set;return this.forEachBucket(t,e,s,i,r=>{o&&o.add(r);const a=this.roomSpatialIndex.get(r);a==null||a.forEach(d=>n.add(d))}),n}collectStandaloneExitCandidates(t,e,s,i,o){const n=new Set;return this.forEachBucket(t,e,s,i,r=>{o&&o.add(r);const a=this.exitSpatialIndex.get(r);a==null||a.forEach(d=>n.add(d))}),n}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==h.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(t=>{t.bounds=t.node.getClientRect({relativeTo:this.linkLayer}),this.addStandaloneExitToSpatialIndex(t)}),this.standaloneExitBoundsRoomSize=h.roomSize)}getBucketBounds(t){const[e,s]=t.split(","),i=Number.parseInt(e,10),o=Number.parseInt(s,10),n=this.spatialBucketSize;return{x:i*n,y:o*n,width:n,height:n}}emitRoomContextEvent(t,e,s){const i=this.stage.container(),o=i.getBoundingClientRect(),n={roomId:t,position:{x:e-o.left,y:s-o.top}},r=new CustomEvent("roomcontextmenu",{detail:n});i.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:Y*t,y:Y*t}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}setCullingMode(t){h.cullingMode=t,h.cullingEnabled=t!=="none",this.scheduleRoomCulling()}getCullingMode(){return h.cullingMode}setCullingDebug(t){h.cullingDebug=t,this.scheduleRoomCulling()}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}setPosition(t){const e=this.mapReader.getRoom(t);if(!e)return;const s=this.mapReader.getArea(e.area),i=s==null?void 0:s.getVersion();let o=this.currentArea!==e.area||this.currentZIndex!==e.z;(this.currentArea!==e.area||this.currentZIndex!==e.z||i!==void 0&&this.currentAreaVersion!==i||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(e.area,e.z),this.positionRender||(this.positionRender=new f.Circle({x:e.x,y:e.y,radius:rt*.85,stroke:"rgb(0, 229, 178)",strokeWidth:.1,dash:[.05,.05],dashEnabled:!0}),this.positionLayer.add(this.positionRender)),this.centerOnRoom(e,o),this.updateCurrentRoomOverlay(e)}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 i=this.highlights.get(t);i!=null&&i.shape&&(i.shape.destroy(),delete i.shape);const o={color:e,area:s.area,z:s.z};if(this.highlights.set(t,o),s.area===this.currentArea&&s.z===this.currentZIndex){const n=this.createHighlightShape(s,e);return this.overlayLayer.add(n),o.shape=n,this.overlayLayer.batchDraw(),n}return o.shape}clearHighlights(){this.highlights.forEach(({shape:t})=>t==null?void 0:t.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((t,e)=>{var o;if((o=t.shape)==null||o.destroy(),delete t.shape,t.area!==this.currentArea||t.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(e);if(!s)return;const i=this.createHighlightShape(s,t.color);this.overlayLayer.add(i),t.shape=i}),this.overlayLayer.batchDraw()}createHighlightShape(t,e){return new f.Circle({x:t.x,y:t.y,radius:h.roomSize*.9,stroke:e,strokeWidth:.15,dash:[.1,.05],dashEnabled:!0,listening:!1})}centerOnRoom(t,e=!1){var d;this.currentRoomId=t.id;const s={x:t.x,y:t.y};(d=this.positionRender)==null||d.position(t);const o=this.stage.getAbsoluteTransform().point(s),n={x:this.stage.width()/2,y:this.stage.height()/2},r=n.x-o.x,a=n.y-o.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),e||h.instantMapMove?(this.stage.position({x:this.stage.x()+r,y:this.stage.y()+a}),this.scheduleRoomCulling()):(this.currentTransition=new f.Tween({node:this.stage,x:this.stage.x()+r,y:this.stage.y()+a,duration:.2,easing:f.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(t){t.forEach(e=>{const s=new f.Group({x:e.x-h.roomSize/2,y:e.y-h.roomSize/2}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(e.env),strokeWidth:.025,stroke:h.lineColor,perfectDrawEnabled:!1}),o=(c,m)=>this.emitRoomContextEvent(e.id,c,m);s.on("mouseenter",()=>{this.stage.container().style.cursor="pointer"}),s.on("mouseleave",()=>{this.stage.container().style.cursor="auto"}),s.on("contextmenu",c=>{c.evt.preventDefault();const m=c.evt;o(m.clientX,m.clientY)});let n,r,a;const d=()=>{a!==void 0&&(this.stage.draggable(a),a=void 0)},u=()=>{n!==void 0&&(window.clearTimeout(n),n=void 0),r=void 0,d()};s.on("touchstart",c=>{var w;if(u(),c.evt.touches&&c.evt.touches.length>1)return;const m=(w=c.evt.touches)==null?void 0:w[0];m&&(r={clientX:m.clientX,clientY:m.clientY},a=this.stage.draggable(),this.stage.draggable(!1),n=window.setTimeout(()=>{r&&o(r.clientX,r.clientY),u()},500))}),s.on("touchend",u),s.on("touchmove",c=>{var D;if(!r)return;const m=(D=c.evt.touches)==null?void 0:D[0];if(!m){u();return}const w=m.clientX-r.clientX,b=m.clientY-r.clientY,R=w*w+b*b,p=10;if(R>p*p){const C=a;u(),C&&this.stage.startDrag()}}),s.on("touchcancel",u),s.add(i),this.renderSymbol(e,s),this.roomLayer.add(s);const l=[];this.exitRenderer.renderSpecialExits(e).forEach(c=>{this.linkLayer.add(c),l.push(c)}),this.exitRenderer.renderStubs(e).forEach(c=>{this.linkLayer.add(c),l.push(c)}),this.exitRenderer.renderInnerExits(e).forEach(c=>{this.roomLayer.add(c)});const y={room:e,group:s,linkNodes:l};this.roomNodes.set(e.id,y),this.addRoomToSpatialIndex(y)})}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=h.roomSize/2,i=h.cullingBounds,o=i?i.x:0,n=i?i.x+i.width:this.stage.width(),r=i?i.y:0,a=i?i.y+i.height:this.stage.height(),d=Math.min(o,n),u=Math.max(o,n),l=Math.min(r,a),y=Math.max(r,a),c=(d-e.x)/t,m=(u-e.x)/t,w=(l-e.y)/t,b=(y-e.y)/t;let R=!1,p=!1;const D=h.cullingEnabled?h.cullingMode??"indexed":"none",C=c-s,z=m+s,T=w-s,N=b+s;if(this.refreshStandaloneExitBoundsIfNeeded(),D==="none"){this.roomNodes.forEach(x=>{x.group.visible()||(x.group.visible(!0),R=!0),x.linkNodes.forEach(E=>{E.visible()||(E.visible(!0),p=!0)})}),this.standaloneExitNodes.forEach(x=>{const{node:E}=x;E.visible()||(p=!0,E.visible(!0))}),R&&this.roomLayer.batchDraw(),p&&this.linkLayer.batchDraw(),this.visibleRooms=new Set(this.roomNodes.values()),this.visibleStandaloneExitNodes=new Set(this.standaloneExitNodes),this.updateCullingDebugVisuals({mode:D,minX:c,minY:w,maxX:m,maxY:b,searchMinX:C,searchMinY:T,searchMaxX:z,searchMaxY:N});return}if(D==="basic"){const x=new Set;this.roomNodes.forEach(v=>{const V=v.room.x-s,L=v.room.x+s,M=v.room.y-s,P=v.room.y+s,k=L>=c&&V<=m&&P>=w&&M<=b;v.group.visible()!==k&&(v.group.visible(k),R=!0),v.linkNodes.forEach(X=>{X.visible()!==k&&(X.visible(k),p=!0)}),k&&x.add(v)});const E=new Set;this.standaloneExitNodes.forEach(v=>{const{node:V,bounds:L}=v,M=L.x,P=L.x+L.width,k=L.y,X=L.y+L.height,Z=P>=c&&M<=m&&X>=w&&k<=b;V.visible()!==Z&&(V.visible(Z),p=!0),Z&&E.add(v)}),this.visibleRooms=x,this.visibleStandaloneExitNodes=E,R&&this.roomLayer.batchDraw(),p&&this.linkLayer.batchDraw(),this.updateCullingDebugVisuals({mode:D,minX:c,minY:w,maxX:m,maxY:b,searchMinX:C,searchMinY:T,searchMaxX:z,searchMaxY:N});return}const j=h.cullingDebug?new Set:void 0,F=h.cullingDebug?new Set:void 0,lt=this.collectRoomCandidates(C,T,z,N,j),_=new Set,G=new Set;lt.forEach(x=>{_.add(x);const E=x.room.x-s,v=x.room.x+s,V=x.room.y-s,L=x.room.y+s,M=v>=c&&E<=m&&L>=w&&V<=b;x.group.visible()!==M&&(x.group.visible(M),R=!0),x.linkNodes.forEach(P=>{P.visible()!==M&&(P.visible(M),p=!0)}),M&&G.add(x)}),this.visibleRooms.forEach(x=>{_.has(x)||(x.group.visible()&&(x.group.visible(!1),R=!0),x.linkNodes.forEach(E=>{E.visible()&&(E.visible(!1),p=!0)}))}),this.visibleRooms=G;const ct=this.collectStandaloneExitCandidates(C,T,z,N,F),H=new Set,q=new Set;ct.forEach(x=>{H.add(x);const{node:E,bounds:v}=x,V=v.x,L=v.x+v.width,M=v.y,P=v.y+v.height,k=L>=c&&V<=m&&P>=w&&M<=b;E.visible()!==k&&(E.visible(k),p=!0),k&&q.add(x)}),this.visibleStandaloneExitNodes.forEach(x=>{const{node:E}=x;!H.has(x)&&E.visible()&&(E.visible(!1),p=!0)}),this.visibleStandaloneExitNodes=q,R&&this.roomLayer.batchDraw(),p&&this.linkLayer.batchDraw(),this.updateCullingDebugVisuals({mode:D,minX:c,minY:w,maxX:m,maxY:b,searchMinX:C,searchMinY:T,searchMaxX:z,searchMaxY:N,roomBuckets:j,exitBuckets:F})}updateCullingDebugVisuals({mode:t,minX:e,minY:s,maxX:i,maxY:o,searchMinX:n,searchMinY:r,searchMaxX:a,searchMaxY:d,roomBuckets:u,exitBuckets:l}){if(!h.cullingDebug){this.debugLayer.children.length>0&&(this.debugLayer.destroyChildren(),this.debugLayer.batchDraw()),this.cullingViewportDebug=void 0,this.cullingSearchDebug=void 0,this.cullingBucketDebug=[];return}this.debugLayer.destroyChildren();const y=Math.max(0,i-e),c=Math.max(0,o-s),m=new f.Rect({x:e,y:s,width:y,height:c,stroke:"rgba(102, 255, 204, 0.9)",strokeWidth:.1,dash:[.4,.2],listening:!1});if(this.debugLayer.add(m),this.cullingViewportDebug=m,n<e||r<s||a>i||d>o){const b=new f.Rect({x:n,y:r,width:Math.max(0,a-n),height:Math.max(0,d-r),stroke:"rgba(80, 160, 255, 0.75)",strokeWidth:.08,dash:[.3,.15],fill:"rgba(80, 160, 255, 0.15)",listening:!1});this.debugLayer.add(b),this.cullingSearchDebug=b}else this.cullingSearchDebug=void 0;if(this.cullingBucketDebug=[],t==="indexed"&&(u!=null&&u.size||l!=null&&l.size)){const b=new Map;u==null||u.forEach(R=>{const p=b.get(R);b.set(R,{rooms:!0,exits:(p==null?void 0:p.exits)??!1})}),l==null||l.forEach(R=>{const p=b.get(R);b.set(R,{rooms:(p==null?void 0:p.rooms)??!1,exits:!0})}),b.forEach(({rooms:R,exits:p},D)=>{const C=this.getBucketBounds(D),z=R&&p?"rgba(255, 196, 102, 0.18)":R?"rgba(102, 255, 204, 0.18)":"rgba(255, 196, 102, 0.12)",T=R&&p?"rgba(255, 196, 102, 0.75)":R?"rgba(102, 255, 204, 0.8)":"rgba(255, 196, 102, 0.6)",N=new f.Rect({...C,stroke:T,strokeWidth:.05,fill:z,listening:!1});this.debugLayer.add(N),this.cullingBucketDebug.push(N)})}this.debugLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(t=>t.destroy()),this.currentRoomOverlay=[],this.overlayLayer.batchDraw()}updateCurrentRoomOverlay(t){if(this.clearCurrentRoomOverlay(),t.area!==this.currentArea||t.z!==this.currentZIndex){this.overlayLayer.batchDraw();return}const e=new Map;e.set(t.id,t);const s=[],i=this.currentAreaInstance instanceof B?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 d=h.highlightCurrentRoom?this.exitRenderer.renderWithColor(a,W,this.currentZIndex):this.exitRenderer.render(a,this.currentZIndex);d&&s.push(d)});const o=h.highlightCurrentRoom?W:void 0;this.exitRenderer.renderSpecialExits(t,o).forEach(r=>{s.push(r)}),(h.highlightCurrentRoom?this.exitRenderer.renderStubs(t,W):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),d=!i||i.hasVisitedRoom(r);a&&a.area===this.currentArea&&a.z===this.currentZIndex&&d&&e.set(r,a)}),s.forEach(r=>{this.overlayLayer.add(r),this.currentRoomOverlay.push(r)}),e.forEach((r,a)=>{const d=a===t.id,u=this.createOverlayRoomGroup(r,{stroke:d&&h.highlightCurrentRoom?W:h.lineColor});this.overlayLayer.add(u),this.currentRoomOverlay.push(u),this.exitRenderer.renderInnerExits(r).forEach(l=>{this.overlayLayer.add(l),this.currentRoomOverlay.push(l)})}),this.overlayLayer.batchDraw()}createOverlayRoomGroup(t,e){const s=new f.Group({x:t.x-h.roomSize/2,y:t.y-h.roomSize/2,listening:!1}),i=new f.Rect({x:0,y:0,width:h.roomSize,height:h.roomSize,fill:this.mapReader.getColorValue(t.env),stroke:e.stroke,strokeWidth:.025,strokeEnabled:!0});return s.add(i),this.renderSymbol(t,s),s}renderSymbol(t,e){if(t.roomChar!==void 0){const s=new f.Text({x:0,y:0,text:t.roomChar,fontSize:.45,fontStyle:"bold",fill:this.mapReader.getSymbolColor(t.env),align:"center",verticalAlign:"middle",width:h.roomSize,height:h.roomSize});e.add(s)}}renderExits(t){t.forEach(e=>{const s=this.exitRenderer.render(e,this.currentZIndex);if(!s)return;this.linkLayer.add(s);const i=s.getClientRect({relativeTo:this.linkLayer}),o={node:s,bounds:i};this.standaloneExitNodes.push(o),this.addStandaloneExitToSpatialIndex(o)}),this.standaloneExitBoundsRoomSize=h.roomSize}renderLabels(t){t.forEach(e=>{if(h.labelRenderMode==="image"){if(!e.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${e.pixMap}`;const i=new f.Image({x:e.X,y:-e.Y,width:e.Width,height:e.Height,image:s,listening:!1});this.linkLayer.add(i);return}this.renderLabelAsData(e)})}renderLabelAsData(t){var r;const e=new f.Group({listening:!1}),s=new f.Rect({x:t.X,y:-t.Y,width:t.Width,height:t.Height,listening:!1});(((r=t.BgColor)==null?void 0:r.alpha)??0)>0&&!h.transparentLabels?s.fill(this.getLabelColor(t.BgColor)):s.fillEnabled(!1),e.add(s);const i=Math.min(.75,t.Width/Math.max(t.Text.length/2,1)),o=Math.max(.1,Math.min(i,Math.max(t.Height*.9,.1))),n=new f.Text({x:t.X,y:-t.Y,width:t.Width,height:t.Height,text:t.Text,fontSize:o,fillEnabled:!0,fill:this.getLabelColor(t.FgColor),align:"center",verticalAlign:"middle",listening:!1});e.add(n),this.linkLayer.add(e)}getLabelColor(t){const e=((t==null?void 0:t.alpha)??255)/255,s=i=>Math.min(255,Math.max(0,i??0));return`rgba(${s(t==null?void 0:t.r)}, ${s(t==null?void 0:t.g)}, ${s(t==null?void 0:t.b)}, ${e})`}}const J={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function tt(g){const t=g[0]/255,e=g[1]/255,s=g[2]/255,i=Math.max(t,e,s),o=Math.min(t,e,s);return(i+o)/2}class Rt{constructor(t,e){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},t.forEach(s=>{s.rooms.forEach(o=>{o.y=-o.y,this.rooms[o.id]=o});const i=parseInt(s.areaId);this.areas[i]=new $(s),this.areaSources[i]=s}),this.colors=e.reduce((s,i)=>({...s,[i.envId]:{rgb:i.colors,rgbValue:`rgb(${i.colors.join(",")})`,symbolColor:tt(i.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:tt(i.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 B)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 B(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 $(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 i=this.getRoom(t);if(i){const o=this.getExplorationArea(i.area);if(o)return o.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 i of t){if(this.explorationEnabled){const n=this.getRoom(i);if(n){const r=this.getExplorationArea(n.area);if(r){r.addVisitedRoom(i)&&s++;continue}}}const o=e.has(i);e.add(i),o||s++}return s}hasVisitedRoom(t){var e;return((e=this.visitedRooms)==null?void 0:e.has(t))??!1}getColorValue(t){var e;return((e=this.colors[t])==null?void 0:e.rgbValue)??J.rgbValue}getSymbolColor(t,e){var n;const s=((n=this.colors[t])==null?void 0:n.symbolColor)??J.symbolColor,i=Math.min(Math.max(e??1,0),1),o=s.join(",");return i!=1?`rgba(${o}, ${i})`:`rgba(${o})`}}function wt(g){return g&&g.__esModule&&Object.prototype.hasOwnProperty.call(g,"default")?g.default:g}class vt{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((t,e)=>t.priority-e.priority)}set(t,e){const s=Number(e);if(isNaN(s))throw new TypeError('"priority" must be a number');return this.keys.has(t)?this.queue.map(i=>(i.key===t&&Object.assign(i,{priority:s}),i)):(this.keys.add(t),this.queue.push({key:t,priority:s})),this.sort(),this.queue.length}next(){const t=this.queue.shift();return this.keys.delete(t.key),t}isEmpty(){return this.queue.length===0}has(t){return this.keys.has(t)}get(t){return this.queue.find(e=>e.key===t)}}var Et=vt;function nt(g,t){const e=new Map;for(const[s,i]of g)s!==t&&i instanceof Map?e.set(s,nt(i,t)):s!==t&&e.set(s,i);return e}var St=nt;function Dt(g){const t=Number(g);return!(isNaN(t)||t<=0)}function at(g){const t=new Map;return Object.keys(g).forEach(s=>{const i=g[s];if(i!==null&&typeof i=="object"&&!Array.isArray(i))return t.set(s,at(i));if(!Dt(i))throw new Error(`Could not add node at key "${s}", make sure it's a valid node`,i);return t.set(s,Number(i))}),t}var Ct=at;function ht(g){if(!(g instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof g}`);g.forEach((t,e)=>{if(typeof t=="object"&&t instanceof Map){ht(t);return}if(typeof t!="number"||t<=0)throw new Error(`Values must be numbers greater than 0. Found value ${t} at ${e}`)})}var Lt=ht;const Mt=Et,kt=St,et=Ct,st=Lt;class It{constructor(t){t instanceof Map?(st(t),this.graph=t):t?this.graph=et(t):this.graph=new Map}addNode(t,e){let s;return e instanceof Map?(st(e),s=e):s=et(e),this.graph.set(t,s),this}addVertex(t,e){return this.addNode(t,e)}removeNode(t){return this.graph=kt(this.graph,t),this}path(t,e,s={}){if(!this.graph.size)return s.cost?{path:null,cost:0}:null;const i=new Set,o=new Mt,n=new Map;let r=[],a=0,d=[];if(s.avoid&&(d=[].concat(s.avoid)),d.includes(t))throw new Error(`Starting node (${t}) cannot be avoided`);if(d.includes(e))throw new Error(`Ending node (${e}) cannot be avoided`);for(o.set(t,0);!o.isEmpty();){const u=o.next();if(u.key===e){a=u.priority;let y=u.key;for(;n.has(y);)r.push(y),y=n.get(y);break}i.add(u.key),(this.graph.get(u.key)||new Map).forEach((y,c)=>{if(i.has(c)||d.includes(c))return null;if(!o.has(c))return n.set(c,u.key),o.set(c,u.priority+y);const m=o.get(c).priority,w=u.priority+y;return w<m?(n.set(c,u.key),o.set(c,w)):null})}return r.length?(s.trim?r.shift():r=r.concat([t]),s.reverse||(r=r.reverse()),s.cost?{path:r,cost:a}:r):s.cost?{path:null,cost:0}:null}shortestPath(...t){return this.path(...t)}}var zt=It;const Ot=wt(zt),Nt={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 Vt{constructor(t){this.cache=new Map,this.mapReader=t,this.graph=this.buildGraph()}buildGraph(){const t={};return this.mapReader.getRooms().forEach(e=>{const s={},i=new Set((e.exitLocks??[]).map(n=>Nt[n]).filter(n=>!!n)),o=new Set(e.mSpecialExitLocks??[]);Object.entries(e.exits??{}).forEach(([n,r])=>{i.has(n)||this.mapReader.getRoom(r)&&(s[r.toString()]=1)}),Object.values(e.specialExits??{}).forEach(n=>{o.has(n)||this.mapReader.getRoom(n)&&(s[n.toString()]=1)}),t[e.id.toString()]=s}),new Ot(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 i=this.graph.path(t.toString(),e.toString()),o=Array.isArray(i)?i:i==null?void 0:i.path,n=o?o.map(r=>Number(r)):null;return this.cache.set(s,n),n}}exports.ExplorationArea=B;exports.MapReader=Rt;exports.PathFinder=Vt;exports.Renderer=yt;exports.Settings=h;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("konva"),ee=["north","south","east","west","northeast","northwest","southeast","southwest"],I={north:"n",south:"s",east:"e",west:"w",northeast:"ne",northwest:"nw",southeast:"se",southwest:"sw",up:"u",down:"d",in:"i",out:"o"},_={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}},te=["north","south","east","west","northeast","northwest","southeast","southwest"],pe={north:"south",south:"north",east:"west",west:"east",northeast:"southwest",northwest:"southeast",southeast:"northwest",southwest:"northeast"};function de(c){return c?Object.prototype.hasOwnProperty.call(_,c):!1}function S(c,e,t,s=1){if(!de(t))return{x:c,y:e};const i=_[t];return{x:c+i.x*s,y:e+i.y*s}}function fe(c,e,t,s=1){if(!de(t))return{x:c,y:e};const i=_[t],o=Math.atan2(i.y,i.x);return{x:c+Math.cos(o)*s,y:e+Math.sin(o)*s}}const V={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)"},xe={1:"north",2:"northeast",3:"northwest",4:"east",5:"west",6:"south",7:"southeast",8:"southwest",9:"up",10:"down",11:"in",12:"out"},be=["up","down","in","out"];function ye(c){switch(c){case 1:return V.OPEN_DOOR;case 2:return V.CLOSED_DOOR;default:return V.LOCKED_DOOR}}class Re{constructor(e,t){this.mapReader=e,this.mapRenderer=t}getRoomEdgePoint(e,t,s,i){return a.roomShape==="circle"?fe(e,t,s,i):S(e,t,s,i)}render(e,t){return this.renderWithColor(e,a.lineColor,t)}renderWithColor(e,t,s){return e.aDir&&e.bDir?this.renderTwoWayExit(e,t,s):this.renderOneWayExit(e,t)}renderTwoWayExit(e,t,s){const i=this.mapReader.getRoom(e.a),o=this.mapReader.getRoom(e.b);if(!i||!o||!e.aDir||!e.bDir||!ee.includes(e.aDir)||!ee.includes(e.bDir)||i.customLines[I[e.aDir]]&&o.customLines[I[e.bDir]]||i.z!==o.z&&(s!==o.z&&i.customLines[I[e.aDir]]||s!==i.z&&o.customLines[I[e.bDir]]))return;const r=new p.Group,n=[];if(n.push(...Object.values(this.getRoomEdgePoint(i.x,i.y,e.aDir,a.roomSize/2))),n.push(...Object.values(this.getRoomEdgePoint(o.x,o.y,e.bDir,a.roomSize/2))),i.doors[I[e.aDir]]||o.doors[I[e.bDir]]){const d=this.renderDoor(n,i.doors[I[e.aDir]]??o.doors[I[e.bDir]]);r.add(d)}const h=new p.Line({points:n,stroke:t,strokeWidth:a.lineWidth,perfectDrawEnabled:!1});return r.add(h),r}renderOneWayExit(e,t){const s=e.aDir?this.mapReader.getRoom(e.a):this.mapReader.getRoom(e.b),i=e.aDir?this.mapReader.getRoom(e.b):this.mapReader.getRoom(e.a),o=e.aDir?e.aDir:e.bDir;if(!o||!s||!i||s.customLines[I[o]||o])return;if(s.area!=i.area&&o)return this.renderAreaExit(s,o,t);let r={x:i.x,y:i.y};(i.area!==s.area||i.z!==s.z)&&(r=S(s.x,s.y,o,a.roomSize/2));const n=S(s.x,s.y,o,.3),h=n.x-(n.x-r.x)/2,d=n.y-(n.y-r.y)/2,u=new p.Group,l=[];l.push(...Object.values(this.getRoomEdgePoint(s.x,s.y,o,a.roomSize/2))),l.push(r.x,r.y);const b=new p.Line({points:l,stroke:t,strokeWidth:a.lineWidth,dashEnabled:!0,dash:[.1,.05],perfectDrawEnabled:!1});u.add(b);const y=new p.Arrow({points:[l[0],l[1],h,d],pointerLength:.5,pointerWidth:.35,strokeWidth:a.lineWidth*1.4,stroke:t,fill:V.ONE_WAY_FILL,dashEnabled:!0,dash:[.1,.05]});return u.add(y),u}renderAreaExit(e,t,s){const i=this.getRoomEdgePoint(e.x,e.y,t,a.roomSize/2),o=S(e.x,e.y,t,a.roomSize*1.5),r=s??this.mapReader.getColorValue(e.env);return new p.Arrow({points:[i.x,i.y,o.x,o.y],pointerLength:.3,pointerWidth:.3,strokeWidth:a.lineWidth*1.4,stroke:r,fill:r})}renderSpecialExits(e,t){return Object.entries(e.customLines).map(([s,i])=>{const o=[e.x,e.y];i.points.reduce((u,l)=>(u.push(l.x,-l.y),u),o);const r=i.attributes.arrow?p.Arrow:p.Line,n=t??`rgb(${i.attributes.color.r}, ${i.attributes.color.g}, ${i.attributes.color.b})`,h=new r({points:o,strokeWidth:a.lineWidth,stroke:n,fill:t??`rgb(${i.attributes.color.r}, ${i.attributes.color.g} , ${i.attributes.color.b})`,pointerLength:.3,pointerWidth:.2,perfectDrawEnabled:!1});let d=i.attributes.style;return d==="dot line"?(h.dash([.05,.05]),h.dashOffset(.1)):d==="dash line"?h.dash([.4,.2]):d==="solid line"||d!==void 0&&console.log("Brak opisu stylu: "+d),h})}renderStubs(e,t=a.lineColor){return e.stubs.map(s=>{const i=xe[s],o=this.getRoomEdgePoint(e.x,e.y,i,a.roomSize/2),r=S(e.x,e.y,i,a.roomSize/2+.5),n=[o.x,o.y,r.x,r.y];return new p.Line({points:n,stroke:t,strokeWidth:a.lineWidth})})}renderInnerExits(e){return be.map(t=>{if(e.exits[t]){const s=new p.Group,i=new p.RegularPolygon({x:e.x,y:e.y,sides:3,fill:this.mapReader.getSymbolColor(e.env,.6),stroke:this.mapReader.getSymbolColor(e.env),strokeWidth:a.lineWidth,radius:a.roomSize/5,scaleX:1.4,scaleY:.8,perfectDrawEnabled:!1});s.add(i);let o=e.doors[t];if(o!==void 0)switch(o){case 1:i.stroke(V.OPEN_DOOR);break;case 2:i.stroke(V.CLOSED_DOOR);break;default:i.stroke(V.LOCKED_DOOR)}switch(t){case"up":i.position(S(e.x,e.y,"south",a.roomSize/4));break;case"down":i.rotation(180),i.position(S(e.x,e.y,"north",a.roomSize/4));break;case"in":const r=i.clone();r.rotation(-90),r.position(S(e.x,e.y,"east",a.roomSize/4)),s.add(r),i.rotation(90),i.position(S(e.x,e.y,"west",a.roomSize/4));break;case"out":const n=i.clone();n.rotation(90),n.position(S(e.x,e.y,"east",a.roomSize/4)),s.add(n),i.rotation(-90),i.position(S(e.x,e.y,"west",a.roomSize/4));break}return s}}).filter(t=>t!==void 0)}renderDoor(e,t){const s={x:e[0]+(e[2]-e[0])/2,y:e[1]+(e[3]-e[1])/2};return new p.Rect({x:s.x-a.roomSize/4,y:s.y-a.roomSize/4,width:a.roomSize/2,height:a.roomSize/2,stroke:ye(t),strokeWidth:a.lineWidth})}}class ue{constructor(e,t){this.rooms=[],this.labels=[],this.rooms=e,this.bounds=this.createBounds(),this.labels=t}getRooms(){return this.rooms}getLabels(){return this.labels}getBounds(){return this.bounds}createBounds(){return this.rooms.reduce((e,t)=>({minX:Math.min(e.minX,t.x),maxX:Math.max(e.maxX,t.x),minY:Math.min(e.minY,t.y),maxY:Math.max(e.maxY,t.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY})}}class G{constructor(e){this.planes={},this.exits=new Map,this.version=0,this.area=e,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(e){return this.planes[e]}getPlanes(){return Object.values(this.planes)}getRooms(){return this.area.rooms}getLinkExits(e){return Array.from(this.exits.values()).filter(t=>t.zIndex.includes(e))}createPlanes(){const e=this.area.rooms.reduce((t,s)=>(t[s.z]||(t[s.z]=[]),t[s.z].push(s),t),{});return Object.entries(e).reduce((t,[s,i])=>(t[+s]=new ue(i,this.area.labels.filter(o=>o.Z===+s)),t),{})}createExits(){this.area.rooms.forEach(e=>{Object.entries(e.specialExits).forEach(([t,s])=>this.createHalfExit(e.id,s,e.z,t)),Object.entries(e.exits).forEach(([t,s])=>this.createHalfExit(e.id,s,e.z,t))})}createHalfExit(e,t,s,i){if(e===t)return;const o=Math.min(e,t),r=Math.max(e,t),n=`${o}-${r}`;let h=this.exits.get(n);h||(h={a:o,b:r,zIndex:[s]}),o==e?h.aDir=i:h.bDir=i,h.zIndex.push(s),this.exits.set(n,h)}}class se extends ue{constructor(e,t){super(e.getRooms(),e.getLabels()),this.basePlane=e,this.visitedRooms=t}getRooms(){return this.basePlane.getRooms().filter(e=>this.visitedRooms.has(e.id))}getLabels(){return this.basePlane.getLabels()}getBounds(){const e=this.getRooms();return e.length?e.reduce((t,s)=>({minX:Math.min(t.minX,s.x),maxX:Math.max(t.maxX,s.x),minY:Math.min(t.minY,s.y),maxY:Math.max(t.maxY,s.y)}),{minX:Number.POSITIVE_INFINITY,maxX:Number.NEGATIVE_INFINITY,minY:Number.POSITIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY}):this.basePlane.getBounds()}}class X extends G{constructor(e,t){super(e),this.planeCache=new WeakMap,this.visitedRooms=t instanceof Set?t:new Set(t??[]),this.areaRoomIds=new Set(e.rooms.map(s=>s.id))}getPlane(e){const t=super.getPlane(e);if(!t)return t;let s=this.planeCache.get(t);return s||(s=new se(t,this.visitedRooms),this.planeCache.set(t,s)),s}getPlanes(){return super.getPlanes().map(e=>{let t=this.planeCache.get(e);return t||(t=new se(e,this.visitedRooms),this.planeCache.set(e,t)),t})}getLinkExits(e){return super.getLinkExits(e).filter(t=>this.visitedRooms.has(t.a)||this.visitedRooms.has(t.b))}getVisitedRoomCount(){return super.getRooms().reduce((e,t)=>e+(this.visitedRooms.has(t.id)?1:0),0)}getTotalRoomCount(){return this.areaRoomIds.size}hasVisitedRoom(e){return this.areaRoomIds.has(e)&&this.visitedRooms.has(e)}getVisitedRoomIds(){return super.getRooms().filter(e=>this.visitedRooms.has(e.id)).map(e=>e.id)}addVisitedRoom(e){const t=this.visitedRooms.has(e);this.visitedRooms.add(e);const s=!t&&this.areaRoomIds.has(e);return s&&this.markDirty(),s}addVisitedRooms(e){let t=0;for(const s of e){const i=this.visitedRooms.has(s);this.visitedRooms.add(s),!i&&this.areaRoomIds.has(s)&&t++}return t>0&&this.markDirty(),t}}class we{constructor(e,t){this.paths=[],this.mapReader=e,this.overlayLayer=t}renderPath(e,t,s,i="#66E64D"){if(t===void 0||s===void 0)return;const o=e.map(l=>this.mapReader.getRoom(l)).filter(l=>l!==void 0),r=[];let n=null;const h=()=>{n&&(n.length<4&&r.pop(),n=null)},d=()=>(n||(n=[],r.push(n)),n);o.forEach((l,b)=>{if(!this.isRoomVisible(l,t,s))return;const y=b>0?o[b-1]:void 0,w=b<o.length-1?o[b+1]:void 0;if(this.isRoomVisible(y,t,s))d();else{h();const g=d();if(y){const f=this.getDirectionTowards(l,y);if(f){const M=S(l.x,l.y,f,a.roomSize);g.push(M.x,M.y)}}}if(n?.push(l.x,l.y),!this.isRoomVisible(w,t,s)&&w){const g=this.getDirectionTowards(l,w);if(g){const f=S(l.x,l.y,g,a.roomSize);n?.push(f.x,f.y)}h()}}),h();const u=r.filter(l=>l.length>=4).map(l=>new p.Line({points:l,stroke:i,strokeWidth:a.lineWidth*4}));return u.forEach(l=>{this.overlayLayer.add(l),this.paths.push(l)}),u[0]}clearPaths(){this.paths.forEach(e=>{e.destroy()}),this.paths=[]}isRoomVisible(e,t,s){return e?e.area===t&&e.z===s:!1}getDirectionTowards(e,t){for(const s of te)if(e.exits[s]===t.id)return s;for(const s of te)if(t.exits[s]===e.id)return pe[s]}}const ve=.6,T=75,Ee=.025,Se="rgb(225, 255, 225)",W="rgb(120, 72, 0)";function ie(c,e){const t=parseInt(c.slice(1,3),16),s=parseInt(c.slice(3,5),16),i=parseInt(c.slice(5,7),16);return`rgba(${t}, ${s}, ${i}, ${e})`}const k=class k{};k.roomSize=ve,k.lineWidth=Ee,k.lineColor=Se,k.instantMapMove=!1,k.highlightCurrentRoom=!0,k.cullingEnabled=!0,k.cullingMode="indexed",k.cullingBounds=null,k.labelRenderMode="image",k.roomShape="rectangle",k.playerMarker={strokeColor:"#00e5b2",strokeAlpha:1,fillColor:"#00e5b2",fillAlpha:0,strokeWidth:.1,sizeFactor:1.7,dash:[.05,.05],dashEnabled:!0};let a=k;class ke{constructor(e,t){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 p.Stage({container:e,width:e.clientWidth,height:e.clientHeight,draggable:!0}),window.addEventListener("resize",()=>{this.onResize(e)}),e.addEventListener("resize",()=>{this.onResize(e)}),this.linkLayer=new p.Layer({listening:!1}),this.stage.add(this.linkLayer),this.roomLayer=new p.Layer,this.stage.add(this.roomLayer),this.positionLayer=new p.Layer({listening:!1}),this.stage.add(this.positionLayer),this.overlayLayer=new p.Layer({listening:!1}),this.stage.add(this.overlayLayer),this.mapReader=t,this.exitRenderer=new Re(t,this),this.pathRenderer=new we(t,this.overlayLayer),this.initScaling(1.1),this.stage.on("dragmove",()=>this.scheduleRoomCulling()),this.stage.on("dragend",()=>this.scheduleRoomCulling())}onResize(e){this.stage.width(e.clientWidth),this.stage.height(e.clientHeight),this.currentRoomId&&this.centerOnRoom(this.mapReader.getRoom(this.currentRoomId),!1),this.stage.batchDraw(),this.scheduleRoomCulling()}initScaling(e){p.hitOnDragEnabled=!0;let t,s=!1,i=!1;this.stage.on("touchstart",o=>{const r=o.evt.touches;r&&r.length>1?(i=!0,this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),this.stage.draggable(!1)):(i=!1,this.stage.draggable(!0))}),this.stage.on("touchend touchcancel",o=>{t=void 0;const r=o.evt.touches;(!r||r.length<=1)&&(i=!1,this.stage.draggable(!0))}),this.stage.on("wheel",o=>{o.evt.preventDefault();const r=this.stage.scaleX(),n=this.stage.getPointerPosition();if(!n)return;const h={x:(n.x-this.stage.x())/r,y:(n.y-this.stage.y())/r};let d=o.evt.deltaY>0?-1:1;o.evt.ctrlKey&&(d=-d);const u=d>0?this.currentZoom*e:this.currentZoom/e,l=u*T,b=this.setZoom(u),y={x:n.x-h.x*l,y:n.y-h.y*l};this.stage.position(y),this.scheduleRoomCulling(),b&&this.emitZoomChangeEvent()}),this.stage.on("touchmove",o=>{const r=o.evt.touches,n=r?.[0],h=r?.[1];if(h||i&&(i=!1,this.stage.draggable(!0)),n&&!h&&s&&!this.stage.isDragging()&&(this.stage.startDrag(),s=!1),!n||!h){t=void 0;return}o.evt.preventDefault(),this.stage.isDragging()&&(this.stage.stopDrag(),s=!0),i||(i=!0,this.stage.draggable(!1));const d=this.stage.container().getBoundingClientRect(),u={x:n.clientX-d.left,y:n.clientY-d.top},l={x:h.clientX-d.left,y:h.clientY-d.top},b=Math.hypot(u.x-l.x,u.y-l.y);if(t===void 0){t=b;return}if(t===0)return;const y=this.stage.scaleX(),w=this.stage.x(),R=this.stage.y(),m={x:this.stage.width()/2,y:this.stage.height()/2},g={x:(m.x-w)/y,y:(m.y-R)/y},f=this.currentZoom*(b/t),M=this.setZoom(f),L=this.stage.scaleX(),P={x:m.x-g.x*L,y:m.y-g.y*L};this.stage.position(P),this.stage.batchDraw(),this.scheduleRoomCulling(),t=b,M&&this.emitZoomChangeEvent()})}drawArea(e,t){const s=this.mapReader.getArea(e);if(!s)return;const i=s.getPlane(t);i&&(this.currentArea=e,this.currentAreaInstance=s,this.currentZIndex=t,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:T*this.currentZoom,y:T*this.currentZoom}),this.renderLabels(i.getLabels()),this.renderExits(s.getLinkExits(t)),this.renderRooms(i.getRooms()??[]),this.refreshHighlights(),this.stage.batchDraw(),this.scheduleRoomCulling())}computeSpatialBucketSize(){return Math.max(a.roomSize*10,5)}getBucketKey(e,t){return`${e},${t}`}forEachBucket(e,t,s,i,o){const r=this.spatialBucketSize,n=Math.min(e,s),h=Math.max(e,s),d=Math.min(t,i),u=Math.max(t,i),l=Math.floor(n/r),b=Math.floor(h/r),y=Math.floor(d/r),w=Math.floor(u/r);for(let R=l;R<=b;R++)for(let m=y;m<=w;m++)o(this.getBucketKey(R,m))}addRoomToSpatialIndex(e){const t=a.roomSize/2,s=e.room.x-t,i=e.room.x+t,o=e.room.y-t,r=e.room.y+t;this.forEachBucket(s,o,i,r,n=>{let h=this.roomSpatialIndex.get(n);h||(h=new Set,this.roomSpatialIndex.set(n,h)),h.add(e)})}addStandaloneExitToSpatialIndex(e){const{bounds:t}=e,s=t.x,i=t.x+t.width,o=t.y,r=t.y+t.height;this.forEachBucket(s,o,i,r,n=>{let h=this.exitSpatialIndex.get(n);h||(h=new Set,this.exitSpatialIndex.set(n,h)),h.add(e)})}collectRoomCandidates(e,t,s,i){const o=new Set;return this.forEachBucket(e,t,s,i,r=>{this.roomSpatialIndex.get(r)?.forEach(h=>o.add(h))}),o}collectStandaloneExitCandidates(e,t,s,i){const o=new Set;return this.forEachBucket(e,t,s,i,r=>{this.exitSpatialIndex.get(r)?.forEach(h=>o.add(h))}),o}refreshStandaloneExitBoundsIfNeeded(){this.standaloneExitBoundsRoomSize!==a.roomSize&&(this.exitSpatialIndex.clear(),this.standaloneExitNodes.forEach(e=>{e.bounds=e.node.getClientRect({relativeTo:this.linkLayer}),this.addStandaloneExitToSpatialIndex(e)}),this.standaloneExitBoundsRoomSize=a.roomSize)}emitRoomContextEvent(e,t,s){const i=this.stage.container(),o=i.getBoundingClientRect(),r={roomId:e,position:{x:t-o.left,y:s-o.top}},n=new CustomEvent("roomcontextmenu",{detail:r});i.dispatchEvent(n)}emitZoomChangeEvent(){const e=new CustomEvent("zoom",{detail:{zoom:this.currentZoom}});this.stage.container().dispatchEvent(e)}setZoom(e){return this.currentZoom===e?!1:(this.currentZoom=e,this.stage.scale({x:T*e,y:T*e}),this.scheduleRoomCulling(),!0)}getZoom(){return this.currentZoom}setCullingMode(e){a.cullingMode=e,a.cullingEnabled=e!=="none",this.scheduleRoomCulling()}getCullingMode(){return a.cullingMode}getCurrentArea(){return this.currentArea?this.mapReader.getArea(this.currentArea):void 0}setPosition(e){const t=this.mapReader.getRoom(e);if(!t)return;const s=this.mapReader.getArea(t.area),i=s?.getVersion();let o=this.currentArea!==t.area||this.currentZIndex!==t.z;(this.currentArea!==t.area||this.currentZIndex!==t.z||i!==void 0&&this.currentAreaVersion!==i||s!==void 0&&this.currentAreaInstance!==s)&&this.drawArea(t.area,t.z),this.centerOnRoom(t,o),this.updateCurrentRoomOverlay(t);const r=ie(a.playerMarker.strokeColor,a.playerMarker.strokeAlpha),n=ie(a.playerMarker.fillColor,a.playerMarker.fillAlpha),h=a.roomSize/2*a.playerMarker.sizeFactor;this.positionRender?(this.positionRender.radius(h),this.positionRender.stroke(r),this.positionRender.fill(n),this.positionRender.strokeWidth(a.playerMarker.strokeWidth),this.positionRender.dash(a.playerMarker.dash??[]),this.positionRender.dashEnabled(a.playerMarker.dashEnabled)):(this.positionRender=new p.Circle({x:t.x,y:t.y,radius:h,stroke:r,fill:n,strokeWidth:a.playerMarker.strokeWidth,dash:a.playerMarker.dash,dashEnabled:a.playerMarker.dashEnabled}),this.positionLayer.add(this.positionRender))}renderPath(e,t){return this.pathRenderer.renderPath(e,this.currentArea,this.currentZIndex,t)}clearPaths(){this.pathRenderer.clearPaths()}renderHighlight(e,t){const s=this.mapReader.getRoom(e);if(!s)return;const i=this.highlights.get(e);i?.shape&&(i.shape.destroy(),delete i.shape);const o={color:t,area:s.area,z:s.z};if(this.highlights.set(e,o),s.area===this.currentArea&&s.z===this.currentZIndex){const r=this.createHighlightShape(s,t);return this.overlayLayer.add(r),o.shape=r,this.overlayLayer.batchDraw(),r}return o.shape}clearHighlights(){this.highlights.forEach(({shape:e})=>e?.destroy()),this.highlights.clear(),this.overlayLayer.batchDraw()}refreshHighlights(){this.highlights.forEach((e,t)=>{if(e.shape?.destroy(),delete e.shape,e.area!==this.currentArea||e.z!==this.currentZIndex)return;const s=this.mapReader.getRoom(t);if(!s)return;const i=this.createHighlightShape(s,e.color);this.overlayLayer.add(i),e.shape=i}),this.overlayLayer.batchDraw()}createHighlightShape(e,t){return a.roomShape==="circle"?new p.Circle({x:e.x,y:e.y,radius:a.roomSize/2*1.5,stroke:t,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1}):new p.Rect({x:e.x-a.roomSize/2*1.5,y:e.y-a.roomSize/2*1.5,width:a.roomSize*1.5,height:a.roomSize*1.5,stroke:t,strokeWidth:.1,dash:[.05,.05],dashEnabled:!0,listening:!1})}centerOnRoom(e,t=!1){this.currentRoomId=e.id;const s={x:e.x,y:e.y};this.positionRender?.position(e);const o=this.stage.getAbsoluteTransform().point(s),r={x:this.stage.width()/2,y:this.stage.height()/2},n=r.x-o.x,h=r.y-o.y;this.currentTransition&&(this.currentTransition.pause(),this.currentTransition.destroy(),delete this.currentTransition),t||a.instantMapMove?(this.stage.position({x:this.stage.x()+n,y:this.stage.y()+h}),this.scheduleRoomCulling()):(this.currentTransition=new p.Tween({node:this.stage,x:this.stage.x()+n,y:this.stage.y()+h,duration:.2,easing:p.Easings.EaseInOut,onUpdate:()=>this.scheduleRoomCulling(),onFinish:()=>this.scheduleRoomCulling()}),this.currentTransition.play())}renderRooms(e){e.forEach(t=>{const s=new p.Group({x:t.x-a.roomSize/2,y:t.y-a.roomSize/2}),i=this.mapReader.getColorValue(t.env),o=a.lineColor,n=a.roomShape==="circle"?new p.Circle({x:a.roomSize/2,y:a.roomSize/2,radius:a.roomSize/2,fill:i,strokeWidth:a.lineWidth,stroke:o,perfectDrawEnabled:!1}):new p.Rect({x:0,y:0,width:a.roomSize,height:a.roomSize,fill:i,strokeWidth:a.lineWidth,stroke:o,perfectDrawEnabled:!1}),h=(m,g)=>this.emitRoomContextEvent(t.id,m,g);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 g=m.evt;h(g.clientX,g.clientY)});let d,u,l;const b=()=>{l!==void 0&&(this.stage.draggable(l),l=void 0)},y=()=>{d!==void 0&&(window.clearTimeout(d),d=void 0),u=void 0,b()};s.on("touchstart",m=>{if(y(),m.evt.touches&&m.evt.touches.length>1)return;const g=m.evt.touches?.[0];g&&(u={clientX:g.clientX,clientY:g.clientY},l=this.stage.draggable(),this.stage.draggable(!1),d=window.setTimeout(()=>{u&&h(u.clientX,u.clientY),y()},500))}),s.on("touchend",y),s.on("touchmove",m=>{if(!u)return;const g=m.evt.touches?.[0];if(!g){y();return}const f=g.clientX-u.clientX,M=g.clientY-u.clientY,L=f*f+M*M,P=10;if(L>P*P){const Y=l;y(),Y&&this.stage.startDrag()}}),s.on("touchcancel",y),s.add(n),this.renderSymbol(t,s),this.roomLayer.add(s);const w=[];this.exitRenderer.renderSpecialExits(t).forEach(m=>{this.linkLayer.add(m);const g=m.getClientRect({relativeTo:this.linkLayer}),f={node:m,bounds:g};this.standaloneExitNodes.push(f),this.addStandaloneExitToSpatialIndex(f)}),this.exitRenderer.renderStubs(t).forEach(m=>{this.linkLayer.add(m),w.push(m)}),this.exitRenderer.renderInnerExits(t).forEach(m=>{this.roomLayer.add(m)});const R={room:t,group:s,linkNodes:w};this.roomNodes.set(t.id,R),this.addRoomToSpatialIndex(R)})}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 e=this.stage.scaleX();if(!e)return;const t=this.stage.position(),s=a.roomSize/2,i=a.cullingBounds,o=i?i.x:0,r=i?i.x+i.width:this.stage.width(),n=i?i.y:0,h=i?i.y+i.height:this.stage.height(),d=Math.min(o,r),u=Math.max(o,r),l=Math.min(n,h),b=Math.max(n,h),y=(d-t.x)/e,w=(u-t.x)/e,R=(l-t.y)/e,m=(b-t.y)/e;let g=!1,f=!1;const M=a.cullingEnabled?a.cullingMode??"indexed":"none",L=y-s,P=w+s,Y=R-s,H=m+s;if(this.refreshStandaloneExitBoundsIfNeeded(),M==="none"){this.roomNodes.forEach(x=>{x.group.visible()||(x.group.visible(!0),g=!0),x.linkNodes.forEach(E=>{E.visible()||(E.visible(!0),f=!0)})}),this.standaloneExitNodes.forEach(x=>{const{node:E}=x;E.visible()||(f=!0,E.visible(!0))}),g&&this.roomLayer.batchDraw(),f&&this.linkLayer.batchDraw(),this.visibleRooms=new Set(this.roomNodes.values()),this.visibleStandaloneExitNodes=new Set(this.standaloneExitNodes);return}if(M==="basic"){const x=new Set;this.roomNodes.forEach(v=>{const O=v.room.x-s,C=v.room.x+s,D=v.room.y-s,N=v.room.y+s,z=C>=y&&O<=w&&N>=R&&D<=m;v.group.visible()!==z&&(v.group.visible(z),g=!0),v.linkNodes.forEach(A=>{A.visible()!==z&&(A.visible(z),f=!0)}),z&&x.add(v)});const E=new Set;this.standaloneExitNodes.forEach(v=>{const{node:O,bounds:C}=v,D=C.x,N=C.x+C.width,z=C.y,A=C.y+C.height,B=N>=y&&D<=w&&A>=R&&z<=m;O.visible()!==B&&(O.visible(B),f=!0),B&&E.add(v)}),this.visibleRooms=x,this.visibleStandaloneExitNodes=E,g&&this.roomLayer.batchDraw(),f&&this.linkLayer.batchDraw();return}const ge=this.collectRoomCandidates(L,Y,P,H),K=new Set,Q=new Set;ge.forEach(x=>{K.add(x);const E=x.room.x-s,v=x.room.x+s,O=x.room.y-s,C=x.room.y+s,D=v>=y&&E<=w&&C>=R&&O<=m;x.group.visible()!==D&&(x.group.visible(D),g=!0),x.linkNodes.forEach(N=>{N.visible()!==D&&(N.visible(D),f=!0)}),D&&Q.add(x)}),this.visibleRooms.forEach(x=>{K.has(x)||(x.group.visible()&&(x.group.visible(!1),g=!0),x.linkNodes.forEach(E=>{E.visible()&&(E.visible(!1),f=!0)}))}),this.visibleRooms=Q;const me=this.collectStandaloneExitCandidates(L,Y,P,H),U=new Set,J=new Set;me.forEach(x=>{U.add(x);const{node:E,bounds:v}=x,O=v.x,C=v.x+v.width,D=v.y,N=v.y+v.height,z=C>=y&&O<=w&&N>=R&&D<=m;E.visible()!==z&&(E.visible(z),f=!0),z&&J.add(x)}),this.visibleStandaloneExitNodes.forEach(x=>{const{node:E}=x;!U.has(x)&&E.visible()&&(E.visible(!1),f=!0)}),this.visibleStandaloneExitNodes=J,g&&this.roomLayer.batchDraw(),f&&this.linkLayer.batchDraw()}clearCurrentRoomOverlay(){this.currentRoomOverlay.forEach(e=>e.destroy()),this.currentRoomOverlay=[],this.positionLayer.batchDraw()}updateCurrentRoomOverlay(e){if(this.clearCurrentRoomOverlay(),e.area!==this.currentArea||e.z!==this.currentZIndex){this.positionLayer.batchDraw();return}const t=new Map;t.set(e.id,e);const s=[],i=this.currentAreaInstance instanceof X?this.currentAreaInstance:void 0;this.currentAreaInstance&&this.currentZIndex!==void 0&&this.currentAreaInstance.getLinkExits(this.currentZIndex).filter(h=>h.a===e.id||h.b===e.id).forEach(h=>{const d=a.highlightCurrentRoom?this.exitRenderer.renderWithColor(h,W,this.currentZIndex):this.exitRenderer.render(h,this.currentZIndex);d&&s.push(d)});const o=a.highlightCurrentRoom?W:void 0;this.exitRenderer.renderSpecialExits(e,o).forEach(n=>{s.push(n)}),(a.highlightCurrentRoom?this.exitRenderer.renderStubs(e,W):this.exitRenderer.renderStubs(e)).forEach(n=>{s.push(n)}),[...Object.values(e.exits),...Object.values(e.specialExits)].forEach(n=>{const h=this.mapReader.getRoom(n),d=!i||i.hasVisitedRoom(n);h&&h.area===this.currentArea&&h.z===this.currentZIndex&&d&&t.set(n,h)}),s.forEach(n=>{this.positionLayer.add(n),this.currentRoomOverlay.push(n)}),t.forEach((n,h)=>{const d=h===e.id,u=this.createOverlayRoomGroup(n,{stroke:d&&a.highlightCurrentRoom?W:a.lineColor});this.positionLayer.add(u),this.currentRoomOverlay.push(u),this.exitRenderer.renderInnerExits(n).forEach(l=>{this.positionLayer.add(l),this.currentRoomOverlay.push(l)})}),this.positionRender&&this.positionRender.moveToTop(),this.positionLayer.batchDraw()}createOverlayRoomGroup(e,t){const s=new p.Group({x:e.x-a.roomSize/2,y:e.y-a.roomSize/2,listening:!1}),i=this.mapReader.getColorValue(e.env),o=t.stroke,r=a.roomShape==="circle"?new p.Circle({x:a.roomSize/2,y:a.roomSize/2,radius:a.roomSize/2,fill:i,stroke:o,strokeWidth:a.lineWidth}):new p.Rect({x:0,y:0,width:a.roomSize,height:a.roomSize,fill:i,stroke:o,strokeWidth:a.lineWidth});return s.add(r),this.renderSymbol(e,s),s}renderSymbol(e,t){if(e.roomChar!==void 0){const s=new p.Text({x:0,y:0,text:e.roomChar,fontSize:.45,fontStyle:"bold",fill:this.mapReader.getSymbolColor(e.env),align:"center",verticalAlign:"middle",width:a.roomSize,height:a.roomSize});t.add(s)}}renderExits(e){e.forEach(t=>{const s=this.exitRenderer.render(t,this.currentZIndex);if(!s)return;this.linkLayer.add(s);const i=s.getClientRect({relativeTo:this.linkLayer}),o={node:s,bounds:i};this.standaloneExitNodes.push(o),this.addStandaloneExitToSpatialIndex(o)}),this.standaloneExitBoundsRoomSize=a.roomSize}renderLabels(e){e.forEach(t=>{if(a.labelRenderMode==="image"){if(!t.pixMap)return;const s=new Image;s.src=`data:image/png;base64,${t.pixMap}`;const i=new p.Image({x:t.X,y:-t.Y,width:t.Width,height:t.Height,image:s,listening:!1});this.linkLayer.add(i);return}this.renderLabelAsData(t)})}renderLabelAsData(e){const t=new p.Group({listening:!1}),s=new p.Rect({x:e.X,y:-e.Y,width:e.Width,height:e.Height,listening:!1});(e.BgColor?.alpha??0)>0&&!a.transparentLabels?s.fill(this.getLabelColor(e.BgColor)):s.fillEnabled(!1),t.add(s);const i=Math.min(.75,e.Width/Math.max(e.Text.length/2,1)),o=Math.max(.1,Math.min(i,Math.max(e.Height*.9,.1))),r=new p.Text({x:e.X,y:-e.Y,width:e.Width,height:e.Height,text:e.Text,fontSize:o,fillEnabled:!0,fill:this.getLabelColor(e.FgColor),align:"center",verticalAlign:"middle",listening:!1});t.add(r),this.linkLayer.add(t)}getLabelColor(e){const t=(e?.alpha??255)/255,s=i=>Math.min(255,Math.max(0,i??0));return`rgba(${s(e?.r)}, ${s(e?.g)}, ${s(e?.b)}, ${t})`}}const oe={rgbValue:"rgb(114, 1, 0)",symbolColor:[225,225,225]};function re(c){const e=c[0]/255,t=c[1]/255,s=c[2]/255,i=Math.max(e,t,s),o=Math.min(e,t,s);return(i+o)/2}class Me{constructor(e,t){this.rooms={},this.areas={},this.areaSources={},this.explorationEnabled=!1,this.colors={},e.forEach(s=>{s.rooms.forEach(o=>{o.y=-o.y,this.rooms[o.id]=o});const i=parseInt(s.areaId);this.areas[i]=new G(s),this.areaSources[i]=s}),this.colors=t.reduce((s,i)=>({...s,[i.envId]:{rgb:i.colors,rgbValue:`rgb(${i.colors.join(",")})`,symbolColor:re(i.colors)>.41?[25,25,25]:[225,255,255],symbolColorValue:re(i.colors)>.41?"rgb(25,25,25)":"rgb(225,255,255)"}}),{})}getArea(e){return this.areas[e]}getExplorationArea(e){const t=this.areas[e];if(t instanceof X)return t}getAreas(){return Object.values(this.areas)}getRooms(){return Object.values(this.rooms)}getRoom(e){return this.rooms[e]}ensureVisitedRooms(){return this.visitedRooms||(this.visitedRooms=new Set),this.visitedRooms}applyExplorationDecoration(){this.visitedRooms&&Object.entries(this.areaSources).forEach(([e,t])=>{const s=parseInt(e,10);this.areas[s]=new X(t,this.visitedRooms)})}decorateWithExploration(e){return e!==void 0?this.setVisitedRooms(e):this.ensureVisitedRooms(),this.applyExplorationDecoration(),this.explorationEnabled=!0,this.visitedRooms}getVisitedRooms(){return this.visitedRooms}clearExplorationDecoration(){Object.entries(this.areaSources).forEach(([e,t])=>{const s=parseInt(e,10);this.areas[s]=new G(t)}),this.explorationEnabled=!1}isExplorationEnabled(){return this.explorationEnabled}setVisitedRooms(e){return this.visitedRooms=e instanceof Set?e:new Set(e),this.explorationEnabled&&this.applyExplorationDecoration(),this.visitedRooms}addVisitedRoom(e){if(this.explorationEnabled){const i=this.getRoom(e);if(i){const o=this.getExplorationArea(i.area);if(o)return o.addVisitedRoom(e)}}const t=this.ensureVisitedRooms(),s=t.has(e);return t.add(e),!s}addVisitedRooms(e){const t=this.ensureVisitedRooms();let s=0;for(const i of e){if(this.explorationEnabled){const r=this.getRoom(i);if(r){const n=this.getExplorationArea(r.area);if(n){n.addVisitedRoom(i)&&s++;continue}}}const o=t.has(i);t.add(i),o||s++}return s}hasVisitedRoom(e){return this.visitedRooms?.has(e)??!1}getColorValue(e){return this.colors[e]?.rgbValue??oe.rgbValue}getSymbolColor(e,t){const s=this.colors[e]?.symbolColor??oe.symbolColor,i=Math.min(Math.max(t??1,0),1),o=s.join(",");return i!=1?`rgba(${o}, ${i})`:`rgba(${o})`}}function Ce(c){return c&&c.__esModule&&Object.prototype.hasOwnProperty.call(c,"default")?c.default:c}var Z,ne;function De(){if(ne)return Z;ne=1;class c{constructor(){this.keys=new Set,this.queue=[]}sort(){this.queue.sort((t,s)=>t.priority-s.priority)}set(t,s){const i=Number(s);if(isNaN(i))throw new TypeError('"priority" must be a number');return this.keys.has(t)?this.queue.map(o=>(o.key===t&&Object.assign(o,{priority:i}),o)):(this.keys.add(t),this.queue.push({key:t,priority:i})),this.sort(),this.queue.length}next(){const t=this.queue.shift();return this.keys.delete(t.key),t}isEmpty(){return this.queue.length===0}has(t){return this.keys.has(t)}get(t){return this.queue.find(s=>s.key===t)}}return Z=c,Z}var $,ae;function ze(){if(ae)return $;ae=1;function c(e,t){const s=new Map;for(const[i,o]of e)i!==t&&o instanceof Map?s.set(i,c(o,t)):i!==t&&s.set(i,o);return s}return $=c,$}var F,he;function Le(){if(he)return F;he=1;function c(t){const s=Number(t);return!(isNaN(s)||s<=0)}function e(t){const s=new Map;return Object.keys(t).forEach(o=>{const r=t[o];if(r!==null&&typeof r=="object"&&!Array.isArray(r))return s.set(o,e(r));if(!c(r))throw new Error(`Could not add node at key "${o}", make sure it's a valid node`,r);return s.set(o,Number(r))}),s}return F=e,F}var j,le;function Ie(){if(le)return j;le=1;function c(e){if(!(e instanceof Map))throw new Error(`Invalid graph: Expected Map instead found ${typeof e}`);e.forEach((t,s)=>{if(typeof t=="object"&&t instanceof Map){c(t);return}if(typeof t!="number"||t<=0)throw new Error(`Values must be numbers greater than 0. Found value ${t} at ${s}`)})}return j=c,j}var q,ce;function Oe(){if(ce)return q;ce=1;const c=De(),e=ze(),t=Le(),s=Ie();class i{constructor(r){r instanceof Map?(s(r),this.graph=r):r?this.graph=t(r):this.graph=new Map}addNode(r,n){let h;return n instanceof Map?(s(n),h=n):h=t(n),this.graph.set(r,h),this}addVertex(r,n){return this.addNode(r,n)}removeNode(r){return this.graph=e(this.graph,r),this}path(r,n,h={}){if(!this.graph.size)return h.cost?{path:null,cost:0}:null;const d=new Set,u=new c,l=new Map;let b=[],y=0,w=[];if(h.avoid&&(w=[].concat(h.avoid)),w.includes(r))throw new Error(`Starting node (${r}) cannot be avoided`);if(w.includes(n))throw new Error(`Ending node (${n}) cannot be avoided`);for(u.set(r,0);!u.isEmpty();){const R=u.next();if(R.key===n){y=R.priority;let g=R.key;for(;l.has(g);)b.push(g),g=l.get(g);break}d.add(R.key),(this.graph.get(R.key)||new Map).forEach((g,f)=>{if(d.has(f)||w.includes(f))return null;if(!u.has(f))return l.set(f,R.key),u.set(f,R.priority+g);const M=u.get(f).priority,L=R.priority+g;return L<M?(l.set(f,R.key),u.set(f,L)):null})}return b.length?(h.trim?b.shift():b=b.concat([r]),h.reverse||(b=b.reverse()),h.cost?{path:b,cost:y}:b):h.cost?{path:null,cost:0}:null}shortestPath(...r){return this.path(...r)}}return q=i,q}var Ne=Oe();const Pe=Ce(Ne),Ve={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 Te{constructor(e){this.cache=new Map,this.mapReader=e,this.graph=this.buildGraph()}buildGraph(){const e={};return this.mapReader.getRooms().forEach(t=>{const s={},i=new Set((t.exitLocks??[]).map(r=>Ve[r]).filter(r=>!!r)),o=new Set(t.mSpecialExitLocks??[]);Object.entries(t.exits??{}).forEach(([r,n])=>{i.has(r)||this.mapReader.getRoom(n)&&(s[n.toString()]=1)}),Object.values(t.specialExits??{}).forEach(r=>{o.has(r)||this.mapReader.getRoom(r)&&(s[r.toString()]=1)}),e[t.id.toString()]=s}),new Pe(e)}findPath(e,t){const s=`${e}->${t}`;if(this.cache.has(s))return this.cache.get(s);if(e===t){const n=this.mapReader.getRoom(e)?[e]:null;return this.cache.set(s,n),n}if(!this.mapReader.getRoom(e)||!this.mapReader.getRoom(t))return this.cache.set(s,null),null;const i=this.graph.path(e.toString(),t.toString()),o=Array.isArray(i)?i:i?.path,r=o?o.map(n=>Number(n)):null;return this.cache.set(s,r),r}}exports.ExplorationArea=X;exports.MapReader=Me;exports.PathFinder=Te;exports.Renderer=ke;exports.Settings=a;
2
2
  //# sourceMappingURL=index.cjs.map