json-canvas-viewer 4.1.1 → 4.2.1

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.
Files changed (54) hide show
  1. package/dist/chimp.js +6 -5
  2. package/dist/index.d.ts +5 -5
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/kernel/BaseModule.d.ts +1 -2
  6. package/dist/kernel/BaseModule.js.map +1 -1
  7. package/dist/kernel/Controller.d.ts +12 -12
  8. package/dist/kernel/Controller.js +1 -1
  9. package/dist/kernel/Controller.js.map +1 -1
  10. package/dist/kernel/DataManager.d.ts +15 -15
  11. package/dist/kernel/DataManager.js +1 -1
  12. package/dist/kernel/DataManager.js.map +1 -1
  13. package/dist/kernel/InteractionHandler.d.ts +16 -16
  14. package/dist/kernel/InteractionHandler.js +1 -1
  15. package/dist/kernel/InteractionHandler.js.map +1 -1
  16. package/dist/kernel/OverlayManager.d.ts +29 -22
  17. package/dist/kernel/OverlayManager.js +1 -1
  18. package/dist/kernel/OverlayManager.js.map +1 -1
  19. package/dist/kernel/Renderer.d.ts +23 -22
  20. package/dist/kernel/Renderer.js +2 -1
  21. package/dist/kernel/Renderer.js.map +1 -1
  22. package/dist/kernel/StyleManager.d.ts +34 -34
  23. package/dist/kernel/StyleManager.js +1 -1
  24. package/dist/kernel/StyleManager.js.map +1 -1
  25. package/dist/kernel/index.d.ts +7 -7
  26. package/dist/kernel/index.js +1 -1
  27. package/dist/kernel/index.js.map +1 -1
  28. package/dist/kernel/types.d.ts +1 -1
  29. package/dist/kernel/utilities.d.ts +1 -27
  30. package/dist/kernel/utilities.js +1 -1
  31. package/dist/kernel/utilities.js.map +1 -1
  32. package/dist/modules/Controls/index.d.ts +21 -21
  33. package/dist/modules/Controls/index.js +1 -1
  34. package/dist/modules/Controls/index.js.map +1 -1
  35. package/dist/modules/DebugPanel/index.d.ts +4 -4
  36. package/dist/modules/DebugPanel/index.js +1 -1
  37. package/dist/modules/DebugPanel/index.js.map +1 -1
  38. package/dist/modules/Minimap/index.d.ts +17 -17
  39. package/dist/modules/Minimap/index.js +1 -1
  40. package/dist/modules/Minimap/index.js.map +1 -1
  41. package/dist/modules/MistouchPreventer/index.d.ts +11 -11
  42. package/dist/modules/MistouchPreventer/index.js +1 -1
  43. package/dist/modules/MistouchPreventer/index.js.map +1 -1
  44. package/dist/shared/index.d.ts +14 -14
  45. package/dist/utilities/{fetchCanvas.d.ts → fetch-canvas.d.ts} +2 -2
  46. package/dist/utilities/{fetchCanvas.js → fetch-canvas.js} +1 -1
  47. package/dist/utilities/fetch-canvas.js.map +1 -0
  48. package/dist/utilities/{renderToString.d.ts → render-to-string.d.ts} +2 -2
  49. package/dist/utilities/render-to-string.js +2 -0
  50. package/dist/utilities/render-to-string.js.map +1 -0
  51. package/package.json +1 -1
  52. package/dist/utilities/fetchCanvas.js.map +0 -1
  53. package/dist/utilities/renderToString.js +0 -2
  54. package/dist/utilities/renderToString.js.map +0 -1
package/dist/chimp.js CHANGED
@@ -281,7 +281,7 @@ pre .JSON-Canvas-Viewer .JCV-markdown-content code {
281
281
  background: rgba(255, 255, 255, 0.12);
282
282
  font-weight: bold;
283
283
  }
284
- `,b={round:E,resizeCanvasForDPR:T,applyStyles:S,drawRoundRect:C,getAnchorCoord:w,makeHook:D};const x=Error(`[JSONCanvasViewer] Resource hasn't been set up or has been disposed.`);function S(e,t){let n=document.createElement(`style`);n.innerHTML=t,e.appendChild(n)}function C(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath()}function w(e,t){let n=e.x+e.width/2,r=e.y+e.height/2;switch(t){case`top`:return{x:n,y:e.y};case`bottom`:return{x:n,y:e.y+e.height};case`left`:return{x:e.x,y:r};case`right`:return{x:e.x+e.width,y:r};default:return{x:n,y:r}}}function T(e,t,n){let r=window.devicePixelRatio??1,i=e.getContext(`2d`);if(!i)throw Error(`[JSONCanvasViewer] This error is unexpected, probably caused uncontrollable runtime errors. Please contact the developer and show how to reproduce.`);e.width=Math.round(t*r),e.height=Math.round(n*r),i.setTransform(1,0,0,1,0,0),i.scale(r,r)}function E(e,t){let n=10**t;return Math.round(e*n)/n}function D(e=!1,t=!1){let n=t?async(...t)=>{if(e){let e=Array.from(n.subs).reverse();for(let n of e)await n(...t)}else for(let e of n.subs)await e(...t)}:(...t)=>{if(e){let e=Array.from(n.subs).reverse();for(let n of e)n(...t)}else for(let e of n.subs)e(...t)};return n.subs=new Set,n.subscribe=e=>{n.subs.add(e)},n.unsubscribe=e=>{n.subs.delete(e)},n}var O=class extends v{onToggleFullscreen=b.makeHook();data={canvasData:{nodes:[],edges:[]},nodeMap:{},edgeMap:{},canvasBaseDir:`./`,nodeBounds:{maxX:0,maxY:0,minX:0,minY:0,width:0,height:0,centerX:0,centerY:0},offsetX:0,offsetY:0,scale:1,container:document.createElement(`div`)};constructor(...e){super(...e);let t=this.options.container;for(;t.firstElementChild;)t.firstElementChild.remove();t.innerHTML=``;let n=this.options.shadowed?t.attachShadow({mode:`open`}):t;b.applyStyles(n,y+this.options.extraCSS),this.data.container.classList.add(`JSON-Canvas-Viewer`),n.appendChild(this.data.container),this.augment({resetView:this.resetView,toggleFullscreen:this.toggleFullscreen,onToggleFullscreen:this.onToggleFullscreen}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}start=()=>{let e=Object.assign({nodes:[],edges:[]},this.options.canvas);Object.assign(this.data,{canvasData:e,nodeMap:{},edgeMap:{},canvasBaseDir:this.processBaseDir(this.options.attachmentDir),nodeBounds:this.calculateNodeBounds(e),offsetX:0,offsetY:0,scale:1}),this.data.canvasData.nodes.forEach(e=>{let t={ref:e,box:this.getNodeBox(e)};if(this.data.nodeMap[e.id]=t,e.type===`file`){let n=e.file.split(`/`).pop()??``;if(t.fileName=n,!e.file.startsWith(`http://`)&&!e.file.startsWith(`https://`)){let t=this.options.attachments?.[n];t?e.file=t:this.options.noAttachmentRelocation||(e.file=this.data.canvasBaseDir+n)}}}),this.data.canvasData.edges.forEach(e=>{this.data.edgeMap[e.id]={ref:e,box:this.getEdgeBox(e)}}),this.resetView()};processBaseDir=e=>e?e?.slice(-1)===`/`?e:`${e}/`:`./`;getNodeBox=e=>({left:e.x,top:e.type===`file`||e.type===`group`?e.y-40:e.y,right:e.width+e.x,bottom:e.y+e.height});getEdgeBox=e=>{let t=this.data.nodeMap,n=t[e.fromNode].ref,r=t[e.toNode].ref,i=b.getAnchorCoord(n,e.fromSide),a=b.getAnchorCoord(r,e.toSide),o={left:Math.min(i.x,a.x),top:Math.min(i.y,a.y),right:Math.max(i.x,a.x),bottom:Math.max(i.y,a.y)},s=o.right-o.left,c=o.bottom-o.top,l=Math.min(s,c),u=Math.log2(Math.max(s,c)/(l===0?1:l))*10;return{left:o.left-u,top:o.top-u,right:o.right+u,bottom:o.bottom+u}};calculateNodeBounds(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;e.nodes.forEach(e=>{t=Math.min(t,e.x),n=Math.min(n,e.y),r=Math.max(r,e.x+e.width),i=Math.max(i,e.y+e.height)});let a=r-t,o=i-n,s=t+a/2,c=n+o/2;return{minX:t,minY:n,maxX:r,maxY:i,width:a,height:o,centerX:s,centerY:c}}toggleFullscreen=async e=>{!document.fullscreenElement&&(!e||e===`enter`)?(await this.data.container.requestFullscreen(),this.onToggleFullscreen(`enter`)):document.fullscreenElement&&(!e||e===`exit`)&&(await document.exitFullscreen(),this.onToggleFullscreen(`exit`))};resetView=()=>{let e=this.data.nodeBounds,t=this.data.container;if(!e||!t)return;let n=e.width+200,r=e.height+200,i=t.clientWidth,a=t.clientHeight,o=i/n,s=a/r,c=Math.round(Math.min(o,s)*1e3)/1e3,l=e.centerX,u=e.centerY,d={scale:c,offsetX:i/2-l*c,offsetY:a/2-u*c};this.data.offsetX=d.offsetX,this.data.offsetY=d.offsetY,this.data.scale=d.scale};middleViewer=()=>{let e=this.data.container;return{x:e.clientWidth/2,y:e.clientHeight/2,width:e.clientWidth,height:e.clientHeight}};dispose=()=>{this.data.container.remove()}},k=class extends v{theme=`light`;onChangeTheme=b.makeHook();definedColors={light:{0:{hue:0,saturation:0,lightness:72},1:{hue:358,saturation:81,lightness:55},2:{hue:19,saturation:87,lightness:58},3:{hue:41,saturation:79,lightness:52},4:{hue:150,saturation:100,lightness:37},5:{hue:221,saturation:100,lightness:59},6:{hue:257,saturation:81,lightness:62}},dark:{0:{hue:0,saturation:0,lightness:40},1:{hue:358,saturation:100,lightness:65},2:{hue:23,saturation:86,lightness:63},3:{hue:39,saturation:91,lightness:70},4:{hue:153,saturation:80,lightness:45},5:{hue:217,saturation:100,lightness:62},6:{hue:259,saturation:100,lightness:75}}};namedColors={light:{dots:`hsla(0, 0%, 72%, 0.4)`,text:`rgb(30, 30, 30)`,background:`rgb(250, 250, 250)`,"background-secondary":`rgb(255, 255, 255)`,shadow:`0px 0px 8px rgb(0, 0, 0, 0.1)`,border:`hsla(0, 0%, 82%, 0.7)`},dark:{dots:`hsla(0, 0%, 40%, 0.3)`,text:`rgb(242, 242, 242)`,background:`rgb(30, 30, 30)`,"background-secondary":`rgb(37, 37, 40)`,shadow:`0px 0px 8px rgb(0, 0, 0, 0.2)`,border:`hsla(0, 0%, 30%, 0.7)`}};colorCache={dark:{},light:{}};constructor(...e){super(...e);let t=this.options.colors;t&&[`light`,`dark`].forEach(e=>{if(!(e in t))return;let n=t[e];n&&Object.entries(n).forEach(([t,n])=>{if(!n)return;let r=this.namedColors[e],i=this.definedColors[e];if(t in r)r[t]=n;else if(t in i){let e=this.parseColor(n);if(!e){console.warn(`[JSON Canvas Viewer] Color ${n} unsupported.`);return}i[t]=e}})}),this.changeTheme(this.options.theme??`light`),this.augment({changeTheme:this.changeTheme,onChangeTheme:this.onChangeTheme})}hslProcessor=e=>{let{hue:t,saturation:n,lightness:r}=e,a;return a=this.theme===`dark`?{active:e,card:{hue:t,saturation:n/3,lightness:r/3},border:{...e,alpha:.7},background:{...e,alpha:.1},text:e.lightness>=70?`rgb(30, 30, 30)`:`rgb(242, 242, 242)`}:{active:e,card:t===0?{hue:t,saturation:n,lightness:100}:{hue:t,saturation:n*.4,lightness:90},border:{...e,alpha:.7},background:{...e,alpha:.1},text:e.lightness>=70?`rgb(30, 30, 30)`:`rgb(242, 242, 242)`},{active:i(a.active),card:i(a.card),border:i(a.border),background:i(a.background),text:a.text}};parseColor=i=>{if(i.startsWith(`rgb`))return r(n(i));if(i.startsWith(`#`))return r(e(i));if(i.startsWith(`hsl`))return t(i)};getColor=(t=`0`)=>{let n=this.theme,i;if(this.colorCache[n][t])return this.colorCache[n][t];i=t in this.definedColors[n]?this.hslProcessor(this.definedColors[n][t]):this.hslProcessor(r(e(t)));let a={...i,"border-width":t===`0`?`1px`:`2px`};return this.colorCache[n][t]=a,a};getNamedColor=e=>this.namedColors[this.theme][e];changeTheme=e=>{this.theme=e||(this.theme===`dark`?`light`:`dark`);let t=this.container.get(O).data.container;Object.entries(this.namedColors[this.theme]).forEach(([e,n])=>{t.style.setProperty(`--${e}`,n)}),this.onChangeTheme(this.theme)}},A=class extends v{animationId=null;resizeAnimationId=null;DM;SM;resizeObserver;perFrame={lastScale:1,lastOffsets:{x:0,y:0}};lastResizeCenter={x:null,y:null};onResize=b.makeHook();onRefresh=b.makeHook();constructor(...e){super(...e),this.DM=this.container.get(O),this.SM=this.container.get(k),this.resizeObserver=new ResizeObserver(this.onResizeCallback),this.SM.onChangeTheme.subscribe(this.refresh),this.augment({refresh:this.refresh,onRefresh:this.onRefresh,onResize:this.onResize}),this.onStart(this.start),this.onRestart(this.refresh),this.onDispose(this.dispose)}start=()=>{this.resizeObserver.observe(this.DM.data.container),this.animationId=requestAnimationFrame(this.draw)};draw=()=>{(this.perFrame.lastScale!==this.DM.data.scale||this.perFrame.lastOffsets.x!==this.DM.data.offsetX||this.perFrame.lastOffsets.y!==this.DM.data.offsetY)&&this.refresh(),this.animationId=requestAnimationFrame(this.draw)};refresh=()=>{this.perFrame={lastScale:this.DM.data.scale,lastOffsets:{x:this.DM.data.offsetX,y:this.DM.data.offsetY}},this.onRefresh()};onResizeCallback=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{let e=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+e.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+e.y-this.lastResizeCenter.y),this.lastResizeCenter.x=e.x,this.lastResizeCenter.y=e.y,this.onResize(e.width,e.height),this.refresh()})};dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}};const j={markdown:/\.(md|mdx|markdown|txt)$/i,image:/\.(png|jpg|jpeg|gif|svg|webp|avif|bmp|ico|heic|heif)$/i,audio:/\.(mp3|wav|ogg|opus|aac|m4a|flac)$/i,video:/\.(mp4|webm|ogv|mov|m3u8|mpd)$/i},M=[`markdown`,`image`,`audio`,`video`];var N=class extends v{_overlaysLayer=document.createElement(`div`);overlays={};selectedId=null;aborted=!1;eventListeners={};DM;SM;parse;componentDict={text:(e,t)=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.innerHTML=t,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n)},markdown:async(e,t)=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.textContent=`Loading...`,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n);let r;try{let e=await(await fetch(t)).text(),n=e.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);r=n?await this.parse(n[2]):await this.parse(e)}catch(e){console.error(`[JSON Canvas Viewer] Failed to load markdown:`,e),r=`Failed to load content.`}n.innerHTML=r},link:(e,t)=>{let n=document.createElement(`iframe`);n.src=t,n.sandbox=`allow-scripts allow-same-origin`,n.className=`JCV-link-iframe`,n.loading=`lazy`,e.appendChild(n)},audio:(e,t)=>{let n=document.createElement(`audio`);n.className=`JCV-audio`,n.src=t,n.controls=!0,e.appendChild(n)},image:(e,t)=>{let n=document.createElement(`img`);n.className=`JCV-img`,n.src=t,n.loading=`lazy`,e.appendChild(n)},video:(e,t)=>{let n=document.createElement(`video`);n.className=`JCV-video`,n.src=t,n.controls=!0,e.appendChild(n)}};get overlaysLayer(){if(!this._overlaysLayer)throw x;return this._overlaysLayer}onInteractionStart=b.makeHook();onInteractionEnd=b.makeHook();onNodeActive=b.makeHook();onNodeLosesActive=b.makeHook();constructor(...e){super(...e),this.parse=this.options.parser||(e=>e),this.DM=this.container.get(O),this.SM=this.container.get(k),this.container.get(A).onRefresh.subscribe(this.updateOverlays),this.SM.onChangeTheme.subscribe(this.themeChanged),this._overlaysLayer=document.createElement(`div`),this._overlaysLayer.className=`JCV-overlays`,this._overlaysLayer.id=`overlays`,this.DM.data.container.appendChild(this.overlaysLayer);let t=this.options.nodeComponents;t&&Object.assign(this.componentDict,t),this.augment({onNodeActive:this.onNodeActive,onNodeLosesActive:this.onNodeLosesActive}),this.onStart(this.start),this.onRestart(this.restart),this.onDispose(this.dispose)}start=()=>{this.container.get(P).onClick.subscribe(this.select),this.renderOverlays()};restart=()=>{this.clearOverlays(),this.renderOverlays()};renderOverlays=()=>{let e=async e=>{switch(e.type){case`text`:this.createOverlay(e,await this.parse(e.text),`text`);break;case`file`:for(let t of M)if(e.file.match(j[t])){this.createOverlay(e,e.file,t);break}break;case`link`:this.createOverlay(e,e.url,`link`);break}};Object.values(this.DM.data.nodeMap).forEach(async t=>{await e(t.ref)})};themeChanged=()=>{Object.values(this.overlays).forEach(e=>{let t=this.DM.data.nodeMap[e.id].ref,n=this.SM.getColor(t.color);this.setOverlayColor(e,n)})};select=e=>{let t=this.selectedId,n=t?this.overlays[t]:null,r=e?this.overlays[e]:null;if(n&&t){n.classList.remove(`JCV-active`);let e=this.DM.data.nodeMap[t];this.onNodeLosesActive(e.ref),e.onLoseActive?.()}if(r&&e){r.classList.add(`JCV-active`),this.onInteractionStart();let t=this.DM.data.nodeMap[e];this.onNodeActive(t.ref),t.onActive?.()}else this.onInteractionEnd();this.selectedId=e};updateOverlays=()=>{let e=this.DM.data;this.overlaysLayer.style.transform=`translate(${e.offsetX}px, ${e.offsetY}px) scale(${e.scale})`};createOverlay=(...e)=>{if(this.aborted)return;let t=e[0],n=this.overlays[t.id];if(!n){if(n=this.constructOverlay(...e),this.aborted)return;this.overlaysLayer.appendChild(n),this.overlays[t.id]=n,n.style.left=`${t.x}px`,n.style.top=`${t.y}px`,n.style.width=`${t.width}px`,n.style.height=`${t.height}px`}};constructOverlay=(...e)=>{let t=e[0],n=document.createElement(`div`);n.classList.add(`JCV-overlay-container`),n.id=t.id,this.setOverlayColor(n,this.SM.getColor(t.color));let r=document.createElement(`div`);r.classList.add(`JCV-content`),n.appendChild(r);let i=document.createElement(`div`);i.className=`JCV-click-layer`,n.appendChild(i);let a=document.createElement(`div`);a.className=`JCV-overlay-border`,n.appendChild(a);let o=this.DM.data.nodeMap[t.id];o.onActive=b.makeHook(),o.onLoseActive=b.makeHook(),o.onBeforeUnmount=b.makeHook(),this.componentDict[e[2]](r,e[1],e[0],o.onBeforeUnmount,o.onActive,o.onLoseActive);let s=()=>{t.id===this.selectedId&&this.onInteractionStart()},c=()=>{t.id===this.selectedId&&this.onInteractionEnd()};return n.addEventListener(`pointerenter`,s),n.addEventListener(`pointerleave`,c),n.addEventListener(`touchstart`,s),n.addEventListener(`touchend`,c),this.eventListeners[t.id]=[s,c],n};setOverlayColor=(e,t)=>{Object.entries(t).forEach(([t,n])=>{e.style.setProperty(`--overlay-${t}`,n)})};clearOverlays=()=>{Object.entries(this.overlays).forEach(([e,t])=>{if(this.DM.data.nodeMap[e].onBeforeUnmount?.(),this.eventListeners[e]){let n=this.eventListeners[e][0],r=this.eventListeners[e][1];if(!n||!r)throw x;t.removeEventListener(`pointerenter`,n),t.removeEventListener(`pointerleave`,r),t.removeEventListener(`touchstart`,n),t.removeEventListener(`touchend`,r),this.eventListeners[e][0]=null,this.eventListeners[e][1]=null}t.remove(),delete this.overlays[e]})};dispose=()=>{this.aborted=!0,this.clearOverlays(),this.overlaysLayer.remove(),this._overlaysLayer=null}},P=class extends v{pointeract;DM;onClick=b.makeHook();constructor(...e){super(...e),this.DM=this.container.get(O);let t=Object.assign(this.options.pointeract??{},{coordinateOutput:`relative`,element:this.DM.data.container,lubricator:{pan:p,zoom:m,drag:f}});this.pointeract=new l(t,[a,o,d,u,c,s]);let n=this.container.get(N);n.onInteractionStart.subscribe(this.stopInteract),n.onInteractionEnd.subscribe(this.startInteract),this.augment({pan:this.pan,panToCoords:this.panToCoords,zoom:this.zoom,zoomToScale:this.zoomToScale}),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.pointeract.on(`pan`,this.onPan).on(`drag`,this.onPan).on(`zoom`,this.onZoom).on(`trueClick`,this.onTrueClick).start()};startInteract=()=>{this.pointeract.start()};stopInteract=()=>{this.pointeract.stop()};onPan=e=>{this.truePan({x:e.deltaX,y:e.deltaY})};onZoom=e=>{this.trueZoom(e.factor,e)};trueZoom=(e,t)=>{let n=Math.max(Math.min(this.DM.data.scale*e,20),.05);if(n===this.DM.data.scale)return;let r=n/this.DM.data.scale,i=this.C2C(t);this.DM.data.offsetX=t.x-i.x*r,this.DM.data.offsetY=t.y-i.y*r,this.DM.data.scale=n};truePan=({x:e,y:t})=>{this.DM.data.offsetX=this.DM.data.offsetX+e,this.DM.data.offsetY=this.DM.data.offsetY+t};zoom=(e,t)=>{this.pointeract.dispatch(`zoom`,{factor:e,...t})};pan=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e,deltaY:t})};zoomToScale=(e,t)=>{let n=e/this.DM.data.scale;this.pointeract.dispatch(`zoom`,{factor:n,...t})};panToCoords=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e-this.DM.data.offsetX,deltaY:t-this.DM.data.offsetY})};C2C=({x:e,y:t})=>({x:e-this.DM.data.offsetX,y:t-this.DM.data.offsetY});onTrueClick=e=>{let t=e.target;if(this.isUIControl(t))return;let n=this.findNodeId(t);this.onClick(n)};isUIControl=e=>e?e.closest(`.controls`)||e.closest(`button`)||e.closest(`input`):!1;findNodeId=e=>{if(!e)return null;let t=e;for(;(!t.id||t.id===``)&&t.parentElement;)t=t.parentElement;return t.id===`overlays`||!t.id||t.id===``?null:t.id};dispose=()=>this.pointeract.dispose()},F=`.JSON-Canvas-Viewer > .JCV-controls {
284
+ `;const b=Error(`[JSONCanvasViewer] Resource hasn't been set up or has been disposed.`);function x(e,t){let n=document.createElement(`style`);n.innerHTML=t,e.appendChild(n)}function S(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath()}function C(e,t){let n=e.x+e.width/2,r=e.y+e.height/2;switch(t){case`top`:return{x:n,y:e.y};case`bottom`:return{x:n,y:e.y+e.height};case`left`:return{x:e.x,y:r};case`right`:return{x:e.x+e.width,y:r};default:return{x:n,y:r}}}function w(e,t,n){let r=window.devicePixelRatio??1,i=e.getContext(`2d`);if(!i)throw Error(`[JSONCanvasViewer] This error is unexpected, probably caused uncontrollable runtime errors. Please contact the developer and show how to reproduce.`);e.width=Math.round(t*r),e.height=Math.round(n*r),i.setTransform(1,0,0,1,0,0),i.scale(r,r)}function T(e,t){let n=10**t;return Math.round(e*n)/n}function E(e=!1,t=!1){let n=t?async(...t)=>{if(e){let e=[...n.subs].reverse();for(let n of e)await n(...t)}else for(let e of n.subs)await e(...t)}:(...t)=>{if(e){let e=[...n.subs].reverse();for(let n of e)n(...t)}else for(let e of n.subs)e(...t)};return n.subs=new Set,n.subscribe=e=>{n.subs.add(e)},n.unsubscribe=e=>{n.subs.delete(e)},n}var D=class extends v{onToggleFullscreen=E();data={canvasBaseDir:`./`,canvasData:{edges:[],nodes:[]},container:document.createElement(`div`),edgeMap:{},nodeBounds:{centerX:0,centerY:0,height:0,maxX:0,maxY:0,minX:0,minY:0,width:0},nodeMap:{},offsetX:0,offsetY:0,scale:1};constructor(...e){super(...e);let t=this.options.container;for(;t.firstElementChild;)t.firstElementChild.remove();t.innerHTML=``;let n=this.options.shadowed?t.attachShadow({mode:`open`}):t;x(n,y+this.options.extraCSS),this.data.container.classList.add(`JSON-Canvas-Viewer`),n.appendChild(this.data.container),this.augment({onToggleFullscreen:this.onToggleFullscreen,resetView:this.resetView,toggleFullscreen:this.toggleFullscreen}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}start=()=>{let e={edges:[],nodes:[],...this.options.canvas};Object.assign(this.data,{canvasBaseDir:this.processBaseDir(this.options.attachmentDir),canvasData:e,edgeMap:{},nodeBounds:this.calculateNodeBounds(e),nodeMap:{},offsetX:0,offsetY:0,scale:1}),this.data.canvasData.nodes.forEach(e=>{let t={box:this.getNodeBox(e),ref:e};if(this.data.nodeMap[e.id]=t,e.type===`file`){let n=e.file.split(`/`).pop()??``;if(t.fileName=n,!e.file.startsWith(`http://`)&&!e.file.startsWith(`https://`)){let t=this.options.attachments?.[n];t?e.file=t:this.options.noAttachmentRelocation||(e.file=this.data.canvasBaseDir+n)}}}),this.data.canvasData.edges.forEach(e=>{this.data.edgeMap[e.id]={box:this.getEdgeBox(e),ref:e}}),this.resetView()};processBaseDir=e=>e?e?.slice(-1)===`/`?e:`${e}/`:`./`;getNodeBox=e=>({bottom:e.y+e.height,left:e.x,right:e.width+e.x,top:e.type===`file`||e.type===`group`?e.y-40:e.y});getEdgeBox=e=>{let t=this.data.nodeMap,n=t[e.fromNode].ref,r=t[e.toNode].ref,i=C(n,e.fromSide),a=C(r,e.toSide),o={bottom:Math.max(i.y,a.y),left:Math.min(i.x,a.x),right:Math.max(i.x,a.x),top:Math.min(i.y,a.y)},s=o.right-o.left,c=o.bottom-o.top,l=Math.min(s,c),u=Math.log2(Math.max(s,c)/(l===0?1:l))*10;return{bottom:o.bottom+u,left:o.left-u,right:o.right+u,top:o.top-u}};calculateNodeBounds(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;e.nodes.forEach(e=>{t=Math.min(t,e.x),n=Math.min(n,e.y),r=Math.max(r,e.x+e.width),i=Math.max(i,e.y+e.height)});let a=r-t,o=i-n;return{centerX:t+a/2,centerY:n+o/2,height:o,maxX:r,maxY:i,minX:t,minY:n,width:a}}toggleFullscreen=async e=>{!document.fullscreenElement&&(!e||e===`enter`)?(await this.data.container.requestFullscreen(),this.onToggleFullscreen(`enter`)):document.fullscreenElement&&(!e||e===`exit`)&&(await document.exitFullscreen(),this.onToggleFullscreen(`exit`))};resetView=()=>{let e=this.data.nodeBounds,t=this.data.container;if(!e||!t)return;let n=e.width+200,r=e.height+200,i=t.clientWidth,a=t.clientHeight,o=i/n,s=a/r,c=Math.round(Math.min(o,s)*1e3)/1e3,l=e.centerX,u=e.centerY,d={offsetX:i/2-l*c,offsetY:a/2-u*c,scale:c};this.data.offsetX=d.offsetX,this.data.offsetY=d.offsetY,this.data.scale=d.scale};middleViewer=()=>{let e=this.data.container;return{height:e.clientHeight,width:e.clientWidth,x:e.clientWidth/2,y:e.clientHeight/2}};dispose=()=>{this.data.container.remove()}},O=class extends v{theme=`light`;onChangeTheme=E();definedColors={dark:{0:{hue:0,lightness:40,saturation:0},1:{hue:358,lightness:65,saturation:100},2:{hue:23,lightness:63,saturation:86},3:{hue:39,lightness:70,saturation:91},4:{hue:153,lightness:45,saturation:80},5:{hue:217,lightness:62,saturation:100},6:{hue:259,lightness:75,saturation:100}},light:{0:{hue:0,lightness:72,saturation:0},1:{hue:358,lightness:55,saturation:81},2:{hue:19,lightness:58,saturation:87},3:{hue:41,lightness:52,saturation:79},4:{hue:150,lightness:37,saturation:100},5:{hue:221,lightness:59,saturation:100},6:{hue:257,lightness:62,saturation:81}}};namedColors={dark:{background:`rgb(30, 30, 30)`,"background-secondary":`rgb(37, 37, 40)`,border:`hsla(0, 0%, 30%, 0.7)`,dots:`hsla(0, 0%, 40%, 0.3)`,shadow:`0px 0px 8px rgb(0, 0, 0, 0.2)`,text:`rgb(242, 242, 242)`},light:{background:`rgb(250, 250, 250)`,"background-secondary":`rgb(255, 255, 255)`,border:`hsla(0, 0%, 82%, 0.7)`,dots:`hsla(0, 0%, 72%, 0.4)`,shadow:`0px 0px 8px rgb(0, 0, 0, 0.1)`,text:`rgb(30, 30, 30)`}};colorCache={dark:{},light:{}};constructor(...e){super(...e);let t=this.options.colors;t&&[`light`,`dark`].forEach(e=>{if(!(e in t))return;let n=t[e];n&&Object.entries(n).forEach(([t,n])=>{if(!n)return;let r=this.namedColors[e],i=this.definedColors[e];if(t in r)r[t]=n;else if(t in i){let e=this.parseColor(n);if(!e){console.warn(`[JSON Canvas Viewer] Color ${n} unsupported.`);return}i[t]=e}})}),this.changeTheme(this.options.theme??`light`),this.augment({changeTheme:this.changeTheme,onChangeTheme:this.onChangeTheme})}hslProcessor=e=>{let{hue:t,saturation:n,lightness:r}=e,a=this.theme===`dark`?{active:e,background:{...e,alpha:.1},border:{...e,alpha:.7},card:{hue:t,lightness:r/3,saturation:n/3},text:e.lightness>=70?`rgb(30, 30, 30)`:`rgb(242, 242, 242)`}:{active:e,background:{...e,alpha:.1},border:{...e,alpha:.7},card:t===0?{hue:t,lightness:100,saturation:n}:{hue:t,lightness:90,saturation:n*.4},text:e.lightness>=70?`rgb(30, 30, 30)`:`rgb(242, 242, 242)`};return{active:i(a.active),background:i(a.background),border:i(a.border),card:i(a.card),text:a.text}};parseColor=i=>{if(i.startsWith(`rgb`))return r(n(i));if(i.startsWith(`#`))return r(e(i));if(i.startsWith(`hsl`))return t(i)};getColor=(t=`0`)=>{let n=this.theme,i;if(this.colorCache[n][t])return this.colorCache[n][t];i=t in this.definedColors[n]?this.hslProcessor(this.definedColors[n][t]):this.hslProcessor(r(e(t)));let a={...i,"border-width":t===`0`?`1px`:`2px`};return this.colorCache[n][t]=a,a};getNamedColor=e=>this.namedColors[this.theme][e];changeTheme=e=>{this.theme=e??(this.theme===`dark`?`light`:`dark`);let t=this.container.get(D).data.container;Object.entries(this.namedColors[this.theme]).forEach(([e,n])=>{t.style.setProperty(`--${e}`,n)}),this.onChangeTheme(this.theme)}},k=class extends v{animationId;resizeAnimationId;DM;SM;resizeObserver;perFrame={lastOffsets:{x:0,y:0},lastScale:1};lastResizeCenter={};onResize=E();onRefresh=E();constructor(...e){super(...e),this.DM=this.container.get(D),this.SM=this.container.get(O),this.resizeObserver=new ResizeObserver(this.onResizeCallback),this.SM.onChangeTheme.subscribe(this.refresh),this.augment({onRefresh:this.onRefresh,onResize:this.onResize,refresh:this.refresh}),this.onStart(this.start),this.onRestart(this.refresh),this.onDispose(this.dispose)}start=()=>{this.resizeObserver.observe(this.DM.data.container),this.animationId=requestAnimationFrame(this.draw)};draw=()=>{(this.perFrame.lastScale!==this.DM.data.scale||this.perFrame.lastOffsets.x!==this.DM.data.offsetX||this.perFrame.lastOffsets.y!==this.DM.data.offsetY)&&this.refresh(),this.animationId=requestAnimationFrame(this.draw)};refresh=()=>{this.perFrame={lastOffsets:{x:this.DM.data.offsetX,y:this.DM.data.offsetY},lastScale:this.DM.data.scale},this.onRefresh()};onResizeCallback=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{let e=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+e.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+e.y-this.lastResizeCenter.y),this.lastResizeCenter.x=e.x,this.lastResizeCenter.y=e.y,this.onResize(e.width,e.height),this.refresh()})};dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}};const A={audio:/\.(mp3|wav|ogg|opus|aac|m4a|flac)$/i,image:/\.(png|jpg|jpeg|gif|svg|webp|avif|bmp|ico|heic|heif)$/i,markdown:/\.(md|mdx|markdown|txt)$/i,video:/\.(mp4|webm|ogv|mov|m3u8|mpd)$/i},j=[`markdown`,`image`,`audio`,`video`];var M=class extends v{_overlaysLayer=document.createElement(`div`);overlays={};selectedId;aborted=!1;eventListeners={};DM;SM;parse;componentDict={audio:({container:e,content:t})=>{let n=document.createElement(`audio`);n.className=`JCV-audio`,n.src=t,n.controls=!0,e.appendChild(n)},image:({container:e,content:t})=>{let n=document.createElement(`img`);n.className=`JCV-img`,n.src=t,n.loading=`lazy`,e.appendChild(n)},link:({container:e,content:t})=>{let n=document.createElement(`iframe`);n.src=t,n.sandbox=`allow-scripts allow-same-origin`,n.className=`JCV-link-iframe`,n.loading=`lazy`,e.appendChild(n)},markdown:async({container:e,content:t})=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.textContent=`Loading...`,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n);let r;try{let e=await(await fetch(t)).text(),n=/^---\n([\s\S]*?)\n---\n([\s\S]*)$/.exec(e);r=await this.parse(n?n[2]:e)}catch(e){console.error(`[JSON Canvas Viewer] Failed to load markdown:`,e),r=`Failed to load content.`}n.innerHTML=r},text:({container:e,content:t})=>{e.classList.add(`JCV-markdown-content`);let n=document.createElement(`div`);n.innerHTML=t,n.classList.add(`JCV-parsed-content-wrapper`),e.appendChild(n)},video:({container:e,content:t})=>{let n=document.createElement(`video`);n.className=`JCV-video`,n.src=t,n.controls=!0,e.appendChild(n)}};get overlaysLayer(){if(!this._overlaysLayer)throw b;return this._overlaysLayer}onInteractionStart=E();onInteractionEnd=E();onNodeActive=E();onNodeLosesActive=E();constructor(...e){super(...e),this.parse=this.options.parser??(e=>e),this.DM=this.container.get(D),this.SM=this.container.get(O),this.container.get(k).onRefresh.subscribe(this.updateOverlays),this.SM.onChangeTheme.subscribe(this.themeChanged),this._overlaysLayer=document.createElement(`div`),this._overlaysLayer.className=`JCV-overlays`,this._overlaysLayer.id=`overlays`,this.DM.data.container.appendChild(this.overlaysLayer);let t=this.options.nodeComponents;t&&Object.assign(this.componentDict,t),this.augment({onNodeActive:this.onNodeActive,onNodeLosesActive:this.onNodeLosesActive}),this.onStart(this.start),this.onRestart(this.restart),this.onDispose(this.dispose)}start=()=>{this.container.get(N).onClick.subscribe(this.select),this.renderOverlays()};restart=()=>{this.clearOverlays(),this.renderOverlays()};renderOverlays=()=>{let e=async e=>{switch(e.type){case`text`:this.createOverlay(e,await this.parse(e.text),`text`);break;case`file`:for(let t of j)if(e.file.match(A[t])){this.createOverlay(e,e.file,t);break}break;case`link`:this.createOverlay(e,e.url,`link`);break}};Object.values(this.DM.data.nodeMap).forEach(async t=>{await e(t.ref)})};themeChanged=()=>{Object.values(this.overlays).forEach(e=>{let t=this.DM.data.nodeMap[e.id].ref,n=this.SM.getColor(t.color);this.setOverlayColor(e,n)})};select=e=>{let t=this.selectedId,n=t?this.overlays[t]:void 0,r=e?this.overlays[e]:void 0;if(n&&t){n.classList.remove(`JCV-active`);let e=this.DM.data.nodeMap[t];this.onNodeLosesActive(e.ref),e.onLoseActive?.()}if(r&&e){r.classList.add(`JCV-active`),this.onInteractionStart();let t=this.DM.data.nodeMap[e];this.onNodeActive(t.ref),t.onActive?.()}else this.onInteractionEnd();this.selectedId=e};updateOverlays=()=>{let e=this.DM.data;this.overlaysLayer.style.transform=`translate(${e.offsetX}px, ${e.offsetY}px) scale(${e.scale})`};createOverlay=(...e)=>{if(this.aborted)return;let t=e[0],n=this.overlays[t.id];if(!n){if(n=this.constructOverlay(...e),this.aborted)return;this.overlaysLayer.appendChild(n),this.overlays[t.id]=n,n.style.left=`${t.x}px`,n.style.top=`${t.y}px`,n.style.width=`${t.width}px`,n.style.height=`${t.height}px`}};constructOverlay=(...e)=>{let t=e[0],n=document.createElement(`div`);n.classList.add(`JCV-overlay-container`),n.id=t.id,this.setOverlayColor(n,this.SM.getColor(t.color));let r=document.createElement(`div`);r.classList.add(`JCV-content`),n.appendChild(r);let i=document.createElement(`div`);i.className=`JCV-click-layer`,n.appendChild(i);let a=document.createElement(`div`);a.className=`JCV-overlay-border`,n.appendChild(a);let o=this.DM.data.nodeMap[t.id];o.onActive=E(),o.onLoseActive=E(),o.onBeforeUnmount=E(),this.componentDict[e[2]]({container:r,content:e[1],node:e[0],onActive:o.onActive,onBeforeUnmount:o.onBeforeUnmount,onLoseActive:o.onLoseActive});let s=()=>{t.id===this.selectedId&&this.onInteractionStart()},c=()=>{t.id===this.selectedId&&this.onInteractionEnd()};return n.addEventListener(`pointerenter`,s),n.addEventListener(`pointerleave`,c),n.addEventListener(`touchstart`,s),n.addEventListener(`touchend`,c),this.eventListeners[t.id]=[s,c],n};setOverlayColor=(e,t)=>{Object.entries(t).forEach(([t,n])=>{e.style.setProperty(`--overlay-${t}`,n)})};clearOverlays=()=>{Object.entries(this.overlays).forEach(([e,t])=>{if(this.DM.data.nodeMap[e].onBeforeUnmount?.(),this.eventListeners[e]){let n=this.eventListeners[e][0],r=this.eventListeners[e][1];if(!n||!r)throw b;t.removeEventListener(`pointerenter`,n),t.removeEventListener(`pointerleave`,r),t.removeEventListener(`touchstart`,n),t.removeEventListener(`touchend`,r),this.eventListeners[e][0]=void 0,this.eventListeners[e][1]=void 0}t.remove(),delete this.overlays[e]})};dispose=()=>{this.aborted=!0,this.clearOverlays(),this.overlaysLayer.remove(),this._overlaysLayer=void 0}},N=class extends v{pointeract;DM;onClick=E();constructor(...e){super(...e),this.DM=this.container.get(D);let t=Object.assign(this.options.pointeract??{},{coordinateOutput:`relative`,element:this.DM.data.container,lubricator:{drag:f,pan:p,zoom:m}});this.pointeract=new l(t,[a,o,d,u,c,s]);let n=this.container.get(M);n.onInteractionStart.subscribe(this.stopInteract),n.onInteractionEnd.subscribe(this.startInteract),this.augment({pan:this.pan,panToCoords:this.panToCoords,zoom:this.zoom,zoomToScale:this.zoomToScale}),this.onStart(this.start),this.onDispose(this.dispose)}start=()=>{this.pointeract.on(`pan`,this.onPan).on(`drag`,this.onPan).on(`zoom`,this.onZoom).on(`trueClick`,this.onTrueClick).start()};startInteract=()=>{this.pointeract.start()};stopInteract=()=>{this.pointeract.stop()};onPan=e=>{this.truePan({x:e.deltaX,y:e.deltaY})};onZoom=e=>{this.trueZoom(e.factor,e)};trueZoom=(e,t)=>{let n=Math.max(Math.min(this.DM.data.scale*e,20),.05);if(n===this.DM.data.scale)return;let r=n/this.DM.data.scale,i=this.C2C(t);this.DM.data.offsetX=t.x-i.x*r,this.DM.data.offsetY=t.y-i.y*r,this.DM.data.scale=n};truePan=({x:e,y:t})=>{this.DM.data.offsetX+=e,this.DM.data.offsetY+=t};zoom=(e,t)=>{this.pointeract.dispatch(`zoom`,{factor:e,...t})};pan=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e,deltaY:t})};zoomToScale=(e,t)=>{let n=e/this.DM.data.scale;this.pointeract.dispatch(`zoom`,{factor:n,...t})};panToCoords=({x:e,y:t})=>{this.pointeract.dispatch(`pan`,{deltaX:e-this.DM.data.offsetX,deltaY:t-this.DM.data.offsetY})};C2C=({x:e,y:t})=>({x:e-this.DM.data.offsetX,y:t-this.DM.data.offsetY});onTrueClick=e=>{let t=e.target?e.target:void 0;if(this.isUIControl(t))return;let n=this.findNodeId(t);this.onClick(n)};isUIControl=e=>e?e.closest(`.controls`)||e.closest(`button`)||e.closest(`input`):!1;findNodeId=e=>{if(!e)return;let t=e;for(;(!t.id||t.id===``)&&t.parentElement;)t=t.parentElement;if(!(t.id===`overlays`||!t.id||t.id===``))return t.id};dispose=()=>this.pointeract.dispose()},P=`.JSON-Canvas-Viewer > .JCV-controls {
285
285
  position: absolute;
286
286
  top: 10px;
287
287
  right: 10px;
@@ -308,7 +308,7 @@ pre .JSON-Canvas-Viewer .JCV-markdown-content code {
308
308
  width: 100px;
309
309
  margin: 0 10px;
310
310
  }
311
- `;const I=`<svg viewBox="-5.28 -5.28 34.56 34.56" fill="none"><path d="M4 9V5.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C4.76 4 5.04 4 5.6 4H9M4 15v3.4c0 .56 0 .84.109 1.054a1 1 0 0 0 .437.437C4.76 20 5.04 20 5.6 20H9m6-16h3.4c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C20 4.76 20 5.04 20 5.6V9m0 6v3.4c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C19.24 20 18.96 20 18.4 20H15" stroke-width="2.4" stroke-linecap="round"/></svg>`;var L=class extends v{_controlsPanel=null;_toggleCollapseBtn=null;_toggleFullscreenBtn=null;_zoomOutBtn=null;_zoomSlider=null;_zoomInBtn=null;_resetViewBtn=null;DM;IH;collapsed;get controlsPanel(){if(this._controlsPanel===null)throw x;return this._controlsPanel}get toggleCollapseBtn(){if(this._toggleCollapseBtn===null)throw x;return this._toggleCollapseBtn}get toggleFullscreenBtn(){if(this._toggleFullscreenBtn===null)throw x;return this._toggleFullscreenBtn}get zoomOutBtn(){if(this._zoomOutBtn===null)throw x;return this._zoomOutBtn}get zoomSlider(){if(this._zoomSlider===null)throw x;return this._zoomSlider}get zoomInBtn(){if(this._zoomInBtn===null)throw x;return this._zoomInBtn}get resetViewBtn(){if(this._resetViewBtn===null)throw x;return this._resetViewBtn}constructor(...e){super(...e),this.collapsed=this.options.controlsCollapsed??!1,this.DM=this.container.get(O),this.IH=this.container.get(P),this.DM.onToggleFullscreen.subscribe(this.updateFullscreenBtn),this.container.get(A).onRefresh.subscribe(this.updateSlider),this._controlsPanel=document.createElement(`div`),this._controlsPanel.className=`JCV-controls`,this._controlsPanel.classList.toggle(`JCV-collapsed`,this.collapsed),b.applyStyles(this._controlsPanel,F),this._toggleCollapseBtn=document.createElement(`button`),this._toggleCollapseBtn.className=`JCV-button JCV-collapse-button JCV-border-shadow-bg`,this._toggleCollapseBtn.innerHTML=`<svg viewBox="-3.6 -3.6 31.2 31.2" stroke-width=".4"><path d="M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z" /></svg>`,this._controlsPanel.appendChild(this._toggleCollapseBtn);let t=document.createElement(`div`);t.className=`JCV-controls-content`,this._toggleFullscreenBtn=document.createElement(`button`),this._toggleFullscreenBtn.className=`JCV-button`,this._toggleFullscreenBtn.innerHTML=I,t.appendChild(this._toggleFullscreenBtn),this._zoomOutBtn=document.createElement(`button`),this.zoomOutBtn.className=`JCV-button`,this._zoomOutBtn.innerHTML=`<svg viewBox="-1.2 -1.2 26.4 26.4"><path d="M6 12h12" stroke-width="2" stroke-linecap="round" /></svg>`,t.appendChild(this._zoomOutBtn),this._zoomSlider=document.createElement(`input`),this._zoomSlider.type=`range`,this._zoomSlider.className=`JCV-zoom-slider`,this._zoomSlider.min=`-30`,this._zoomSlider.max=`30`,this._zoomSlider.value=`0`,t.appendChild(this._zoomSlider),this._zoomInBtn=document.createElement(`button`),this._zoomInBtn.className=`JCV-button`,this._zoomInBtn.innerHTML=`<svg viewBox="-1.2 -1.2 26.4 26.4"><path d="M6 12h12m-6-6v12" stroke-width="2" stroke-linecap="round" /></svg>`,t.appendChild(this._zoomInBtn),this._resetViewBtn=document.createElement(`button`),this._resetViewBtn.className=`JCV-button`,this._resetViewBtn.innerHTML=`<svg viewBox="-6 -6 30 30" stroke-width=".08"><path d="m14.955 7.986.116.01a1 1 0 0 1 .85 1.13 8 8 0 0 1-13.374 4.728l-.84.84c-.63.63-1.707.184-1.707-.707V10h3.987c.89 0 1.337 1.077.707 1.707l-.731.731a6 6 0 0 0 8.347-.264 6 6 0 0 0 1.63-3.33 1 1 0 0 1 1.131-.848zM11.514.813a8 8 0 0 1 1.942 1.336l.837-.837c.63-.63 1.707-.184 1.707.707V6h-3.981c-.89 0-1.337-1.077-.707-1.707l.728-.729a6 6 0 0 0-9.98 3.591 1 1 0 1 1-1.98-.281A8 8 0 0 1 11.514.813Z" /></svg>`,t.appendChild(this._resetViewBtn),this._controlsPanel.appendChild(t),this.DM.data.container.appendChild(this._controlsPanel),this._toggleCollapseBtn.addEventListener(`click`,this.toggleCollapse),this._zoomInBtn.addEventListener(`click`,this.zoomIn),this._zoomOutBtn.addEventListener(`click`,this.zoomOut),this._zoomSlider.addEventListener(`input`,this.slide),this._resetViewBtn.addEventListener(`click`,this.DM.resetView),this._toggleFullscreenBtn.addEventListener(`click`,this.toggleFullscreen),this.augment({toggleControlsCollapse:this.toggleCollapse}),this.onDispose(this.dispose)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.controlsPanel.classList.toggle(`JCV-collapsed`,this.collapsed),this.collapsed||this.updateSlider()};zoomIn=()=>this.IH.zoom(1.3,this.DM.middleViewer());zoomOut=()=>this.IH.zoom(1/1.3,this.DM.middleViewer());slide=()=>this.IH.trueZoom(1.1**Number(this.zoomSlider.value)/this.DM.data.scale,this.DM.middleViewer());updateFullscreenBtn=e=>{e===`enter`?this.toggleFullscreenBtn.innerHTML=`<svg viewBox="-40.32 -40.32 176.64 176.64"><path d="M30 60H6a6 6 0 0 0 0 12h18v18a6 6 0 0 0 12 0V66a5.997 5.997 0 0 0-6-6Zm60 0H66a5.997 5.997 0 0 0-6 6v24a6 6 0 0 0 12 0V72h18a6 6 0 0 0 0-12ZM66 36h24a6 6 0 0 0 0-12H72V6a6 6 0 0 0-12 0v24a5.997 5.997 0 0 0 6 6ZM30 0a5.997 5.997 0 0 0-6 6v18H6a6 6 0 0 0 0 12h24a5.997 5.997 0 0 0 6-6V6a5.997 5.997 0 0 0-6-6Z"/></svg>`:this.toggleFullscreenBtn.innerHTML=I};toggleFullscreen=()=>this.DM.toggleFullscreen();updateSlider=()=>{this.collapsed||(this.zoomSlider.value=String(this.scaleToSlider(this.DM.data.scale)))};scaleToSlider=e=>Math.log(e)/Math.log(1.1);dispose=()=>{this.toggleCollapseBtn.removeEventListener(`click`,this.toggleCollapse),this.zoomInBtn.removeEventListener(`click`,this.zoomIn),this.zoomOutBtn.removeEventListener(`click`,this.zoomOut),this.zoomSlider.removeEventListener(`input`,this.slide),this.resetViewBtn.removeEventListener(`click`,this.DM.resetView),this.toggleFullscreenBtn.removeEventListener(`click`,this.toggleFullscreen),this.controlsPanel.remove(),this._controlsPanel=null,this._toggleCollapseBtn=null,this._zoomInBtn=null,this._zoomOutBtn=null,this._zoomSlider=null,this._resetViewBtn=null,this._toggleFullscreenBtn=null}},R=`.JSON-Canvas-Viewer > .JCV-debug-panel {
311
+ `;const F=`<svg viewBox="-5.28 -5.28 34.56 34.56" fill="none"><path d="M4 9V5.6c0-.56 0-.84.109-1.054a1 1 0 0 1 .437-.437C4.76 4 5.04 4 5.6 4H9M4 15v3.4c0 .56 0 .84.109 1.054a1 1 0 0 0 .437.437C4.76 20 5.04 20 5.6 20H9m6-16h3.4c.56 0 .84 0 1.054.109a1 1 0 0 1 .437.437C20 4.76 20 5.04 20 5.6V9m0 6v3.4c0 .56 0 .84-.109 1.054a1 1 0 0 1-.437.437C19.24 20 18.96 20 18.4 20H15" stroke-width="2.4" stroke-linecap="round"/></svg>`;var I=class extends v{_controlsPanel;_toggleCollapseBtn;_toggleFullscreenBtn;_zoomOutBtn;_zoomSlider;_zoomInBtn;_resetViewBtn;DM;IH;collapsed;get controlsPanel(){if(!this._controlsPanel)throw b;return this._controlsPanel}get toggleCollapseBtn(){if(!this._toggleCollapseBtn)throw b;return this._toggleCollapseBtn}get toggleFullscreenBtn(){if(!this._toggleFullscreenBtn)throw b;return this._toggleFullscreenBtn}get zoomOutBtn(){if(!this._zoomOutBtn)throw b;return this._zoomOutBtn}get zoomSlider(){if(!this._zoomSlider)throw b;return this._zoomSlider}get zoomInBtn(){if(!this._zoomInBtn)throw b;return this._zoomInBtn}get resetViewBtn(){if(!this._resetViewBtn)throw b;return this._resetViewBtn}constructor(...e){super(...e),this.collapsed=this.options.controlsCollapsed??!1,this.DM=this.container.get(D),this.IH=this.container.get(N),this.DM.onToggleFullscreen.subscribe(this.updateFullscreenBtn),this.container.get(k).onRefresh.subscribe(this.updateSlider),this._controlsPanel=document.createElement(`div`),this._controlsPanel.className=`JCV-controls`,this._controlsPanel.classList.toggle(`JCV-collapsed`,this.collapsed),x(this._controlsPanel,P),this._toggleCollapseBtn=document.createElement(`button`),this._toggleCollapseBtn.className=`JCV-button JCV-collapse-button JCV-border-shadow-bg`,this._toggleCollapseBtn.innerHTML=`<svg viewBox="-3.6 -3.6 31.2 31.2" stroke-width=".4"><path d="M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z" /></svg>`,this._controlsPanel.appendChild(this._toggleCollapseBtn);let t=document.createElement(`div`);t.className=`JCV-controls-content`,this._toggleFullscreenBtn=document.createElement(`button`),this._toggleFullscreenBtn.className=`JCV-button`,this._toggleFullscreenBtn.innerHTML=F,t.appendChild(this._toggleFullscreenBtn),this._zoomOutBtn=document.createElement(`button`),this.zoomOutBtn.className=`JCV-button`,this._zoomOutBtn.innerHTML=`<svg viewBox="-1.2 -1.2 26.4 26.4"><path d="M6 12h12" stroke-width="2" stroke-linecap="round" /></svg>`,t.appendChild(this._zoomOutBtn),this._zoomSlider=document.createElement(`input`),this._zoomSlider.type=`range`,this._zoomSlider.className=`JCV-zoom-slider`,this._zoomSlider.min=`-30`,this._zoomSlider.max=`30`,this._zoomSlider.value=`0`,t.appendChild(this._zoomSlider),this._zoomInBtn=document.createElement(`button`),this._zoomInBtn.className=`JCV-button`,this._zoomInBtn.innerHTML=`<svg viewBox="-1.2 -1.2 26.4 26.4"><path d="M6 12h12m-6-6v12" stroke-width="2" stroke-linecap="round" /></svg>`,t.appendChild(this._zoomInBtn),this._resetViewBtn=document.createElement(`button`),this._resetViewBtn.className=`JCV-button`,this._resetViewBtn.innerHTML=`<svg viewBox="-6 -6 30 30" stroke-width=".08"><path d="m14.955 7.986.116.01a1 1 0 0 1 .85 1.13 8 8 0 0 1-13.374 4.728l-.84.84c-.63.63-1.707.184-1.707-.707V10h3.987c.89 0 1.337 1.077.707 1.707l-.731.731a6 6 0 0 0 8.347-.264 6 6 0 0 0 1.63-3.33 1 1 0 0 1 1.131-.848zM11.514.813a8 8 0 0 1 1.942 1.336l.837-.837c.63-.63 1.707-.184 1.707.707V6h-3.981c-.89 0-1.337-1.077-.707-1.707l.728-.729a6 6 0 0 0-9.98 3.591 1 1 0 1 1-1.98-.281A8 8 0 0 1 11.514.813Z" /></svg>`,t.appendChild(this._resetViewBtn),this._controlsPanel.appendChild(t),this.DM.data.container.appendChild(this._controlsPanel),this._toggleCollapseBtn.addEventListener(`click`,this.toggleCollapse),this._zoomInBtn.addEventListener(`click`,this.zoomIn),this._zoomOutBtn.addEventListener(`click`,this.zoomOut),this._zoomSlider.addEventListener(`input`,this.slide),this._resetViewBtn.addEventListener(`click`,this.DM.resetView),this._toggleFullscreenBtn.addEventListener(`click`,this.toggleFullscreen),this.augment({toggleControlsCollapse:this.toggleCollapse}),this.onDispose(this.dispose)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.controlsPanel.classList.toggle(`JCV-collapsed`,this.collapsed),this.collapsed||this.updateSlider()};zoomIn=()=>this.IH.zoom(1.3,this.DM.middleViewer());zoomOut=()=>this.IH.zoom(1/1.3,this.DM.middleViewer());slide=()=>this.IH.trueZoom(1.1**Number(this.zoomSlider.value)/this.DM.data.scale,this.DM.middleViewer());updateFullscreenBtn=e=>{this.toggleFullscreenBtn.innerHTML=e===`enter`?`<svg viewBox="-40.32 -40.32 176.64 176.64"><path d="M30 60H6a6 6 0 0 0 0 12h18v18a6 6 0 0 0 12 0V66a5.997 5.997 0 0 0-6-6Zm60 0H66a5.997 5.997 0 0 0-6 6v24a6 6 0 0 0 12 0V72h18a6 6 0 0 0 0-12ZM66 36h24a6 6 0 0 0 0-12H72V6a6 6 0 0 0-12 0v24a5.997 5.997 0 0 0 6 6ZM30 0a5.997 5.997 0 0 0-6 6v18H6a6 6 0 0 0 0 12h24a5.997 5.997 0 0 0 6-6V6a5.997 5.997 0 0 0-6-6Z"/></svg>`:F};toggleFullscreen=()=>this.DM.toggleFullscreen();updateSlider=()=>{this.collapsed||(this.zoomSlider.value=String(this.scaleToSlider(this.DM.data.scale)))};scaleToSlider=e=>Math.log(e)/Math.log(1.1);dispose=()=>{this.toggleCollapseBtn.removeEventListener(`click`,this.toggleCollapse),this.zoomInBtn.removeEventListener(`click`,this.zoomIn),this.zoomOutBtn.removeEventListener(`click`,this.zoomOut),this.zoomSlider.removeEventListener(`input`,this.slide),this.resetViewBtn.removeEventListener(`click`,this.DM.resetView),this.toggleFullscreenBtn.removeEventListener(`click`,this.toggleFullscreen),this.controlsPanel.remove(),this._controlsPanel=void 0,this._toggleCollapseBtn=void 0,this._zoomInBtn=void 0,this._zoomOutBtn=void 0,this._zoomSlider=void 0,this._resetViewBtn=void 0,this._toggleFullscreenBtn=void 0}},L=`.JSON-Canvas-Viewer > .JCV-debug-panel {
312
312
  position: absolute;
313
313
  bottom: 12px;
314
314
  left: 12px;
@@ -319,7 +319,7 @@ pre .JSON-Canvas-Viewer .JCV-markdown-content code {
319
319
  line-height: calc(17px + 0.3vw);
320
320
  pointer-events: none;
321
321
  }
322
- `,z=class extends v{_debugPanel=null;DM;get debugPanel(){if(!this._debugPanel)throw x;return this._debugPanel}constructor(...e){super(...e),this.DM=this.container.get(O),this.container.get(A).onRefresh.subscribe(this.update),this._debugPanel=document.createElement(`div`),this._debugPanel.className=`JCV-debug-panel JCV-border-shadow-bg`;let t=this.DM.data.container;b.applyStyles(t,R),t.appendChild(this._debugPanel),this.onDispose(this.dispose)}update=()=>{let e=b.round,t=this.DM.data;this.debugPanel.innerHTML=`<p>Scale: ${e(t.scale,3)}</p><p>Offset: ${e(t.offsetX,1)}, ${e(t.offsetY,1)}</p>`};dispose=()=>{this.debugPanel.remove(),this._debugPanel=null}},B=`.JSON-Canvas-Viewer > .JCV-minimap-container {
322
+ `,R=class extends v{_debugPanel;DM;get debugPanel(){if(!this._debugPanel)throw b;return this._debugPanel}constructor(...e){super(...e),this.DM=this.container.get(D),this.container.get(k).onRefresh.subscribe(this.update),this._debugPanel=document.createElement(`div`),this._debugPanel.className=`JCV-debug-panel JCV-border-shadow-bg`;let t=this.DM.data.container;x(t,L),t.appendChild(this._debugPanel),this.onDispose(this.dispose)}update=()=>{let e=this.DM.data;this.debugPanel.innerHTML=`<p>Scale: ${T(e.scale,3)}</p><p>Offset: ${T(e.offsetX,1)}, ${T(e.offsetY,1)}</p>`};dispose=()=>{this.debugPanel.remove(),this._debugPanel=void 0}},z=`.JSON-Canvas-Viewer > .JCV-minimap-container {
323
323
  position: absolute;
324
324
  bottom: 10px;
325
325
  right: 10px;
@@ -373,7 +373,7 @@ pre .JSON-Canvas-Viewer .JCV-markdown-content code {
373
373
  transform: translateY(60px) translateX(calc(100% - 32px));
374
374
  }
375
375
  }
376
- `,V=class extends v{_minimapCtx=null;_viewportRectangle=null;_minimap=null;_minimapContainer=null;_toggleMinimapBtn=null;minimapCache={scale:1,centerX:0,centerY:0};DM;SM;collapsed;get minimap(){if(this._minimap===null)throw x;return this._minimap}get minimapCtx(){if(this._minimapCtx===null)throw x;return this._minimapCtx}get viewportRectangle(){if(this._viewportRectangle===null)throw x;return this._viewportRectangle}get minimapContainer(){if(this._minimapContainer===null)throw x;return this._minimapContainer}get toggleMinimapBtn(){if(this._toggleMinimapBtn===null)throw x;return this._toggleMinimapBtn}constructor(...e){super(...e),this.collapsed=this.options.minimapCollapsed??!1,this.container.get(A).onRefresh.subscribe(this.updateViewportRectangle),this.DM=this.container.get(O),this.SM=this.container.get(k),this._minimapContainer=document.createElement(`div`),this._minimapContainer.className=`JCV-minimap-container`,b.applyStyles(this._minimapContainer,B),this._toggleMinimapBtn=document.createElement(`button`),this._toggleMinimapBtn.className=`JCV-button JCV-toggle-minimap JCV-collapse-button JCV-border-shadow-bg`,this._toggleMinimapBtn.innerHTML=`<svg viewBox="-3.6 -3.6 31.2 31.2" stroke-width=".4"><path d="M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z" /></svg>`,this._minimapContainer.appendChild(this._toggleMinimapBtn),this._minimap=document.createElement(`div`),this._minimap.className=`JCV-minimap JCV-border-shadow-bg`;let t=document.createElement(`canvas`);t.className=`JCV-minimap-canvas`,t.width=200,t.height=150,this._minimap.appendChild(t),this._minimapCtx=t.getContext(`2d`),this._viewportRectangle=document.createElement(`div`),this._viewportRectangle.className=`JCV-viewport-rectangle`,this._minimap.appendChild(this._viewportRectangle),this._minimapContainer.appendChild(this._minimap),this.DM.data.container.appendChild(this._minimapContainer),this._minimapContainer.classList.toggle(`JCV-collapsed`,this.collapsed),this._toggleMinimapBtn.addEventListener(`click`,this.toggleCollapse),b.resizeCanvasForDPR(t,t.width,t.height),this.augment({toggleMinimapCollapse:this.toggleCollapse}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.minimapContainer.classList.toggle(`JCV-collapsed`,this.collapsed),this.collapsed||this.updateViewportRectangle()};start=()=>{let e=this.DM.data.nodeBounds;if(!e)return;let t=this.minimap.clientWidth,n=this.minimap.clientHeight,r=t/e.width,i=n/e.height;this.minimapCache.scale=Math.min(r,i)*.9,this.minimapCache.centerX=t/2,this.minimapCache.centerY=n/2,this.minimapCtx.clearRect(0,0,t,n),this.minimapCtx.save(),this.minimapCtx.translate(this.minimapCache.centerX,this.minimapCache.centerY),this.minimapCtx.scale(this.minimapCache.scale,this.minimapCache.scale),this.minimapCtx.translate(-e.centerX,-e.centerY);let a=this.DM.data.canvasData;for(let e of a.edges)this.drawMinimapEdge(e);for(let e of a.nodes)this.drawMinimapNode(e);this.minimapCtx.restore()};drawMinimapNode=e=>{let t=this.SM.getColor(e.color);this.minimapCtx.fillStyle=t.border,b.drawRoundRect(this.minimapCtx,e.x,e.y,e.width,e.height,25),this.minimapCtx.fill()};drawMinimapEdge=e=>{let t=this.DM.data.nodeMap,n=t[e.fromNode].ref,r=t[e.toNode].ref;if(!n||!r)return;let{x:i,y:a}=b.getAnchorCoord(n,e.fromSide),{x:o,y:s}=b.getAnchorCoord(r,e.toSide);this.minimapCtx.beginPath(),this.minimapCtx.moveTo(i,a),this.minimapCtx.lineTo(o,s),this.minimapCtx.strokeStyle=this.SM.getColor(e.color).active,this.minimapCtx.lineWidth=10,this.minimapCtx.stroke()};updateViewportRectangle=()=>{if(this.collapsed)return;let e=this.DM.data.nodeBounds,t=this.DM.data.container,n=this.DM.data.scale;if(!e)return;let r=t.clientWidth/n,i=t.clientHeight/n,a=-this.DM.data.offsetX/n+t.clientWidth/(2*n),o=-this.DM.data.offsetY/n+t.clientHeight/(2*n),s=this.minimapCache.centerX+(a-r/2-e.centerX)*this.minimapCache.scale,c=this.minimapCache.centerY+(o-i/2-e.centerY)*this.minimapCache.scale,l=r*this.minimapCache.scale,u=i*this.minimapCache.scale;this.viewportRectangle.style.left=`${s}px`,this.viewportRectangle.style.top=`${c}px`,this.viewportRectangle.style.width=`${l}px`,this.viewportRectangle.style.height=`${u}px`};dispose=()=>{this.toggleMinimapBtn.removeEventListener(`click`,this.toggleCollapse),this.minimapCtx.clearRect(0,0,this.minimap.clientWidth,this.minimap.clientHeight),this.minimapContainer.remove(),this._minimapContainer=null,this._toggleMinimapBtn=null,this._viewportRectangle=null,this._minimap=null}},H=`.JSON-Canvas-Viewer.JCV-numb, .JSON-Canvas-Viewer.JCV-numb * {
376
+ `,B=class extends v{_minimapCtx;_viewportRectangle;_minimap;_minimapContainer;_toggleMinimapBtn;minimapCache={centerX:0,centerY:0,scale:1};DM;SM;collapsed;get minimap(){if(!this._minimap)throw b;return this._minimap}get minimapCtx(){if(!this._minimapCtx)throw b;return this._minimapCtx}get viewportRectangle(){if(!this._viewportRectangle)throw b;return this._viewportRectangle}get minimapContainer(){if(!this._minimapContainer)throw b;return this._minimapContainer}get toggleMinimapBtn(){if(!this._toggleMinimapBtn)throw b;return this._toggleMinimapBtn}constructor(...e){super(...e),this.collapsed=this.options.minimapCollapsed??!1,this.container.get(k).onRefresh.subscribe(this.updateViewportRectangle),this.DM=this.container.get(D),this.SM=this.container.get(O),this._minimapContainer=document.createElement(`div`),this._minimapContainer.className=`JCV-minimap-container`,x(this._minimapContainer,z),this._toggleMinimapBtn=document.createElement(`button`),this._toggleMinimapBtn.className=`JCV-button JCV-toggle-minimap JCV-collapse-button JCV-border-shadow-bg`,this._toggleMinimapBtn.innerHTML=`<svg viewBox="-3.6 -3.6 31.2 31.2" stroke-width=".4"><path d="M15.707 4.293a1 1 0 0 1 0 1.414L9.414 12l6.293 6.293a1 1 0 0 1-1.414 1.414l-7-7a1 1 0 0 1 0-1.414l7-7a1 1 0 0 1 1.414 0Z" /></svg>`,this._minimapContainer.appendChild(this._toggleMinimapBtn),this._minimap=document.createElement(`div`),this._minimap.className=`JCV-minimap JCV-border-shadow-bg`;let t=document.createElement(`canvas`);t.className=`JCV-minimap-canvas`,t.width=200,t.height=150,this._minimap.appendChild(t),this._minimapCtx=t.getContext(`2d`),this._viewportRectangle=document.createElement(`div`),this._viewportRectangle.className=`JCV-viewport-rectangle`,this._minimap.appendChild(this._viewportRectangle),this._minimapContainer.appendChild(this._minimap),this.DM.data.container.appendChild(this._minimapContainer),this._minimapContainer.classList.toggle(`JCV-collapsed`,this.collapsed),this._toggleMinimapBtn.addEventListener(`click`,this.toggleCollapse),w(t,t.width,t.height),this.augment({toggleMinimapCollapse:this.toggleCollapse}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.minimapContainer.classList.toggle(`JCV-collapsed`,this.collapsed),this.collapsed||this.updateViewportRectangle()};start=()=>{let e=this.DM.data.nodeBounds;if(!e)return;let t=this.minimap.clientWidth,n=this.minimap.clientHeight,r=t/e.width,i=n/e.height;this.minimapCache.scale=Math.min(r,i)*.9,this.minimapCache.centerX=t/2,this.minimapCache.centerY=n/2,this.minimapCtx.clearRect(0,0,t,n),this.minimapCtx.save(),this.minimapCtx.translate(this.minimapCache.centerX,this.minimapCache.centerY),this.minimapCtx.scale(this.minimapCache.scale,this.minimapCache.scale),this.minimapCtx.translate(-e.centerX,-e.centerY);let a=this.DM.data.canvasData;for(let e of a.edges)this.drawMinimapEdge(e);for(let e of a.nodes)this.drawMinimapNode(e);this.minimapCtx.restore()};drawMinimapNode=e=>{let t=this.SM.getColor(e.color);this.minimapCtx.fillStyle=t.border,S(this.minimapCtx,e.x,e.y,e.width,e.height,25),this.minimapCtx.fill()};drawMinimapEdge=e=>{let t=this.DM.data.nodeMap,n=t[e.fromNode].ref,r=t[e.toNode].ref;if(!n||!r)return;let{x:i,y:a}=C(n,e.fromSide),{x:o,y:s}=C(r,e.toSide);this.minimapCtx.beginPath(),this.minimapCtx.moveTo(i,a),this.minimapCtx.lineTo(o,s),this.minimapCtx.strokeStyle=this.SM.getColor(e.color).active,this.minimapCtx.lineWidth=10,this.minimapCtx.stroke()};updateViewportRectangle=()=>{if(this.collapsed)return;let e=this.DM.data.nodeBounds,t=this.DM.data.container,n=this.DM.data.scale;if(!e)return;let r=t.clientWidth/n,i=t.clientHeight/n,a=-this.DM.data.offsetX/n+t.clientWidth/(2*n),o=-this.DM.data.offsetY/n+t.clientHeight/(2*n),s=this.minimapCache.centerX+(a-r/2-e.centerX)*this.minimapCache.scale,c=this.minimapCache.centerY+(o-i/2-e.centerY)*this.minimapCache.scale,l=r*this.minimapCache.scale,u=i*this.minimapCache.scale;this.viewportRectangle.style.left=`${s}px`,this.viewportRectangle.style.top=`${c}px`,this.viewportRectangle.style.width=`${l}px`,this.viewportRectangle.style.height=`${u}px`};dispose=()=>{this.toggleMinimapBtn.removeEventListener(`click`,this.toggleCollapse),this.minimapCtx.clearRect(0,0,this.minimap.clientWidth,this.minimap.clientHeight),this.minimapContainer.remove(),this._minimapContainer=void 0,this._toggleMinimapBtn=void 0,this._viewportRectangle=void 0,this._minimap=void 0}},V=`.JSON-Canvas-Viewer.JCV-numb, .JSON-Canvas-Viewer.JCV-numb * {
377
377
  pointer-events: none !important;
378
378
  }
379
379
  .JSON-Canvas-Viewer .JCV-prevention-container {
@@ -392,4 +392,5 @@ pre .JSON-Canvas-Viewer .JCV-markdown-content code {
392
392
  line-height: calc(17px + 0.3vw);
393
393
  text-align: center;
394
394
  }
395
- `,U=class extends v{_preventionContainer=null;preventMt=!1;DM;preventMistouch={record:!1,lastX:0,lastY:0,initialX:0,initialY:0};get preventionContainer(){if(this._preventionContainer===null)throw x;return this._preventionContainer}constructor(...e){super(...e);let t=document.createElement(`div`);t.className=`JCV-prevention-banner JCV-border-shadow-bg`,t.textContent=this.options.mistouchPreventerBannerText??`Click on to unlock.`,this.DM=this.container.get(O),this._preventionContainer=document.createElement(`div`),this._preventionContainer.className=`JCV-prevention-container JCV-hidden JCV-full JCV-flex-center`,b.applyStyles(this._preventionContainer,H),this._preventionContainer.appendChild(t),this.DM.data.container.appendChild(this._preventionContainer),this.options.preventMistouchAtStart&&this.startPrevention(),window.addEventListener(`pointerdown`,this.onPointerDown),window.addEventListener(`pointermove`,this.onPointerMove),window.addEventListener(`pointerup`,this.onPointerUp),this.augment({startMistouchPrevention:this.startPrevention,endMistouchPrevention:this.endPrevention}),this.onDispose(this.dispose)}onPointerDown=e=>{let t=this.DM.data.container.getBoundingClientRect();e.clientX<t.left||e.clientX>t.right||e.clientY<t.top||e.clientY>t.bottom?this.preventMt||this.startPrevention():this.preventMt&&(this.preventMistouch.initialX=e.clientX,this.preventMistouch.initialY=e.clientY,this.preventMistouch.lastX=e.clientX,this.preventMistouch.lastY=e.clientY,this.preventMistouch.record=!0)};onPointerMove=e=>{this.preventMistouch.record&&(this.preventMistouch.lastX=e.clientX,this.preventMistouch.lastY=e.clientY)};onPointerUp=()=>{this.preventMistouch.record&&(this.preventMistouch.record=!1,Math.abs(this.preventMistouch.lastX-this.preventMistouch.initialX)+Math.abs(this.preventMistouch.lastY-this.preventMistouch.initialY)<5&&this.endPrevention())};startPrevention=()=>{this.preventionContainer.classList.remove(`JCV-hidden`),this.DM.data.container.classList.add(`JCV-numb`),this.preventMt=!0};endPrevention=()=>{this.preventMt=!1,this.preventionContainer.classList.add(`JCV-hidden`),setTimeout(()=>this.DM.data.container.classList.remove(`JCV-numb`),50)};dispose=()=>{window.removeEventListener(`pointerdown`,this.onPointerDown),window.removeEventListener(`pointermove`,this.onPointerMove),window.removeEventListener(`pointerup`,this.onPointerUp),this.preventionContainer.remove(),this._preventionContainer=null}};const W=[O,k,A,N,P,class extends v{_canvas;ctx;DM;SM;zoomInOptimize={lastDrawnScale:0,lastDrawnViewport:{left:0,right:0,top:0,bottom:0},timeout:null,lastCallTime:0};get canvas(){if(!this._canvas)throw x;return this._canvas}constructor(...e){super(...e);let t=this.container.get(A);this.SM=this.container.get(k),t.onRefresh.subscribe(this.redraw),t.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(O),this._canvas=document.createElement(`canvas`),this._canvas.className=`JCV-main-canvas`,this.ctx=this._canvas.getContext(`2d`),this.DM.data.container.appendChild(this._canvas),this.onDispose(this.dispose)}optimizeDPR=()=>{let e=this.DM.data.container;b.resizeCanvasForDPR(this.canvas,e.offsetWidth,e.offsetHeight)};redraw=()=>{let e=this.DM.data.offsetX,t=this.DM.data.offsetY,n=this.DM.data.scale,r=this.getCurrentViewport(e,t,n);if(!this.options.zoomInOptimization){this.trueRedraw(e,t,n,r);return}this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null);let i=Date.now();if(this.isInside(r,this.zoomInOptimize.lastDrawnViewport)&&n!==this.zoomInOptimize.lastDrawnScale&&i-this.zoomInOptimize.lastCallTime<500){this.zoomInOptimize.timeout=window.setTimeout(()=>{this.trueRedraw(e,t,n,r),this.zoomInOptimize.lastCallTime=i,this.zoomInOptimize.timeout=null},60),this.fakeRedraw(r,n);return}this.zoomInOptimize.lastCallTime=i,this.trueRedraw(e,t,n,r)};trueRedraw(e,t,n,r){this.zoomInOptimize.lastDrawnViewport=r,this.zoomInOptimize.lastDrawnScale=n,this.canvas.style.transform=``,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.drawGridDots(n,e,t),this.ctx.translate(e,t),this.ctx.scale(n,n),Object.values(this.DM.data.nodeMap).forEach(e=>{if(this.isOutside(e.box,r))return;let t=e.ref;t.type===`file`?this.drawFile(e):t.type===`group`&&this.drawGroup(t,n)}),Object.values(this.DM.data.edgeMap).forEach(e=>{this.isOutside(e.box,r)||this.drawEdge(e)}),this.ctx.restore()}fakeRedraw(e,t){let n=t/this.zoomInOptimize.lastDrawnScale,r=(this.zoomInOptimize.lastDrawnViewport.left-e.left)*t,i=(this.zoomInOptimize.lastDrawnViewport.top-e.top)*t;this.canvas.style.transform=`translate(${r}px, ${i}px) scale(${n})`}isInside=(e,t)=>e.left>t.left&&e.top>t.top&&e.right<t.right&&e.bottom<t.bottom;isOutside=(e,t)=>e.right<t.left||e.bottom<t.top||e.left>t.right||e.top>t.bottom;getCurrentViewport=(e,t,n)=>{let r=-e/n,i=-t/n,a=this.DM.data.container;return{left:r,top:i,right:r+a.clientWidth/n,bottom:i+a.clientHeight/n}};drawLabelBar=(e,t,n,r,i,a)=>{let o=30*a,s=6*a,c=8*a,l=16*a,u=6*a;this.ctx.save(),this.ctx.translate(e,t),this.ctx.scale(1/a,1/a),this.ctx.font=`${l}px 'Inter', sans-serif`;let d=this.ctx.measureText(n).width+2*u;this.ctx.translate(0,-o-c),this.ctx.fillStyle=r,this.ctx.beginPath(),this.ctx.moveTo(s,0),this.ctx.lineTo(d-s,0),this.ctx.quadraticCurveTo(d,0,d,s),this.ctx.lineTo(d,o-s),this.ctx.quadraticCurveTo(d,o,d-s,o),this.ctx.lineTo(s,o),this.ctx.quadraticCurveTo(0,o,0,o-s),this.ctx.lineTo(0,s),this.ctx.quadraticCurveTo(0,0,s,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=i,this.ctx.fillText(n,u,o*.65),this.ctx.restore()};drawNodeBackground=e=>{let t=this.SM.getColor(e.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=t.background,b.drawRoundRect(this.ctx,e.x+1,e.y+1,e.width-2,e.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=t.border,this.ctx.lineWidth=2,b.drawRoundRect(this.ctx,e.x,e.y,e.width,e.height,12),this.ctx.stroke()};drawGroup=(e,t)=>{if(this.drawNodeBackground(e),e.label){let n=this.SM.getColor(e.color);this.drawLabelBar(e.x,e.y,e.label,n.active,n.text,t)}};drawFile=e=>{this.ctx.fillStyle=this.SM.getColor().text;let t=e.ref;this.ctx.font=`16px sans-serif`,this.ctx.fillText(e.fileName??``,t.x+5,t.y-10)};drawEdge=e=>{let t=e.ref,n=this.DM.data.nodeMap[t.fromNode].ref,r=this.DM.data.nodeMap[t.toNode].ref,i=b.getAnchorCoord,{x:a,y:o}=i(n,t.fromSide),{x:s,y:c}=i(r,t.toSide),l=this.SM.getColor(t.color),[u,d,f,p]=[0,0,0,0];if(e.controlPoints?[u,d,f,p]=e.controlPoints:([u,d,f,p]=this.getControlPoints(a,o,s,c,t.fromSide,t.toSide),e.controlPoints=[u,d,f,p]),this.drawCurvedPath(a,o,s,c,u,d,f,p,l.active),this.drawArrowhead(s,c,f,p,l.active),t.label){let e=.5,n=(1-e)**3*a+3*(1-e)**2*e*u+3*(1-e)*e*e*f+e**3*s,r=(1-e)**3*o+3*(1-e)**2*e*d+3*(1-e)*e*e*p+e**3*c;this.ctx.font=`18px sans-serif`;let i=this.ctx.measureText(t.label).width+16;this.ctx.fillStyle=l.active,this.ctx.beginPath(),b.drawRoundRect(this.ctx,n-i/2,r-20/2-2,i,20,4),this.ctx.fill(),this.ctx.fillStyle=l.text,this.ctx.textAlign=`center`,this.ctx.textBaseline=`middle`,this.ctx.fillText(t.label,n,r-2),this.ctx.textAlign=`left`,this.ctx.textBaseline=`alphabetic`}};getControlPoints=(e,t,n,r,i,a)=>{let o=n-e,s=r-t,c=((e,t,n)=>Math.max(t,Math.min(n,e)))((Math.min(Math.abs(o),Math.abs(s))+.3*Math.max(Math.abs(o),Math.abs(s)))*.5,60,300),l=e,u=t,d=n,f=r;switch(i){case`top`:u=t-c;break;case`bottom`:u=t+c;break;case`left`:l=e-c;break;case`right`:l=e+c;break}switch(a){case`top`:f=r-c;break;case`bottom`:f=r+c;break;case`left`:d=n-c;break;case`right`:d=n+c;break}return[l,u,d,f]};drawGridDots=(e,t,n)=>{let r=10*2**-Math.floor(Math.log2(e))*e,i=this.canvas.width,a=this.canvas.height,o=t%r,s=n%r;this.ctx.fillStyle=this.SM.getNamedColor(`dots`);for(let e=o;e<=i;e+=r)for(let t=s;t<=a;t+=r)this.ctx.beginPath(),this.ctx.arc(e,t,1,0,2*Math.PI),this.ctx.fill()};drawCurvedPath=(e,t,n,r,i,a,o,s,c)=>{this.ctx.beginPath(),this.ctx.moveTo(e,t),this.ctx.bezierCurveTo(i,a,o,s,n,r),this.ctx.strokeStyle=c,this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(e,t,n,r,i)=>{let a=e-n,o=t-r,s=Math.sqrt(a*a+o*o);if(s===0)return;let c=a/s,l=o/s,u=e-c*12-l*4,d=t-l*12+c*4,f=e-c*12+l*4,p=t-l*12-c*4;this.ctx.beginPath(),this.ctx.fillStyle=i,this.ctx.moveTo(e,t),this.ctx.lineTo(u,d),this.ctx.lineTo(f,p),this.ctx.closePath(),this.ctx.fill()};dispose=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null),this.canvas.remove(),this._canvas=null}}];var G=class{allModules;IO=null;started=!1;disposed=!1;options;container;onDispose=b.makeHook(!0);onStart=b.makeHook();onRestart=b.makeHook();constructor(e,t){this.container=new h,this.options=e;let n=e=>{this.container.bind({provide:e,useFactory:()=>new e(this.container,this.options,this.onStart,this.onDispose,this.onRestart,this.augment)})};this.allModules=[...W,...t??[]],this.allModules.forEach(n),this.allModules.forEach(e=>{this.container.get(e)});let r=this.options.loading??`normal`;r===`normal`?this.load():r===`lazy`&&(this.IO=new IntersectionObserver(this.onVisibilityCheck,{root:null,rootMargin:`50px`,threshold:0}),this.IO.observe(this.options.container))}onVisibilityCheck=e=>{e.forEach(e=>{if(e.isIntersecting){this.load(),this.IO?.disconnect(),this.IO=null;return}})};augment=e=>{let t=Object.getOwnPropertyDescriptors(e);Object.defineProperties(this,t)};load=e=>{this.disposed||(e&&Object.assign(this.options,e),this.started?this.onRestart():(this.onStart(),this.started=!0))};dispose=()=>{if(!this.started||this.disposed)return;this.IO?.disconnect(),this.IO=null;let e=this.options.container;for(;e.firstChild;)e.firstChild.remove();this.onDispose(),this.container.unbindAll(),this.disposed=!0}};async function K(e){return g.sanitize(await _(e))}async function q(e){return await fetch(e).then(e=>e.json())}export{L as Controls,z as DebugPanel,G as JSONCanvasViewer,V as Minimap,U as MistouchPreventer,q as fetchCanvas,K as parser};
395
+ `,H=class extends v{_preventionContainer;preventMt=!1;DM;preventMistouch={initialX:0,initialY:0,lastX:0,lastY:0,record:!1};get preventionContainer(){if(!this._preventionContainer)throw b;return this._preventionContainer}constructor(...e){super(...e);let t=document.createElement(`div`);t.className=`JCV-prevention-banner JCV-border-shadow-bg`,t.textContent=this.options.mistouchPreventerBannerText??`Click on to unlock.`,this.DM=this.container.get(D),this._preventionContainer=document.createElement(`div`),this._preventionContainer.className=`JCV-prevention-container JCV-hidden JCV-full JCV-flex-center`,x(this._preventionContainer,V),this._preventionContainer.appendChild(t),this.DM.data.container.appendChild(this._preventionContainer),this.options.preventMistouchAtStart&&this.startPrevention(),window.addEventListener(`pointerdown`,this.onPointerDown),window.addEventListener(`pointermove`,this.onPointerMove),window.addEventListener(`pointerup`,this.onPointerUp),this.augment({endMistouchPrevention:this.endPrevention,startMistouchPrevention:this.startPrevention}),this.onDispose(this.dispose)}onPointerDown=e=>{let t=this.DM.data.container.getBoundingClientRect();e.clientX<t.left||e.clientX>t.right||e.clientY<t.top||e.clientY>t.bottom?this.preventMt||this.startPrevention():this.preventMt&&(this.preventMistouch.initialX=e.clientX,this.preventMistouch.initialY=e.clientY,this.preventMistouch.lastX=e.clientX,this.preventMistouch.lastY=e.clientY,this.preventMistouch.record=!0)};onPointerMove=e=>{this.preventMistouch.record&&(this.preventMistouch.lastX=e.clientX,this.preventMistouch.lastY=e.clientY)};onPointerUp=()=>{this.preventMistouch.record&&(this.preventMistouch.record=!1,Math.abs(this.preventMistouch.lastX-this.preventMistouch.initialX)+Math.abs(this.preventMistouch.lastY-this.preventMistouch.initialY)<5&&this.endPrevention())};startPrevention=()=>{this.preventionContainer.classList.remove(`JCV-hidden`),this.DM.data.container.classList.add(`JCV-numb`),this.preventMt=!0};endPrevention=()=>{this.preventMt=!1,this.preventionContainer.classList.add(`JCV-hidden`),setTimeout(()=>this.DM.data.container.classList.remove(`JCV-numb`),50)};dispose=()=>{window.removeEventListener(`pointerdown`,this.onPointerDown),window.removeEventListener(`pointermove`,this.onPointerMove),window.removeEventListener(`pointerup`,this.onPointerUp),this.preventionContainer.remove(),this._preventionContainer=void 0}};const U=[D,O,k,M,N,class extends v{_canvas;ctx;DM;SM;zoomInOptimize={lastCallTime:0,lastDrawnScale:0,lastDrawnViewport:{bottom:0,left:0,right:0,top:0}};get canvas(){if(!this._canvas)throw b;return this._canvas}constructor(...e){super(...e);let t=this.container.get(k);this.SM=this.container.get(O),t.onRefresh.subscribe(this.redraw),t.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(D),this._canvas=document.createElement(`canvas`),this._canvas.className=`JCV-main-canvas`,this.ctx=this._canvas.getContext(`2d`),this.DM.data.container.appendChild(this._canvas),this.onDispose(this.dispose)}optimizeDPR=()=>{let e=this.DM.data.container;w(this.canvas,e.offsetWidth,e.offsetHeight)};redraw=()=>{let e=this.DM.data.offsetX,t=this.DM.data.offsetY,n=this.DM.data.scale,r=this.getCurrentViewport(e,t,n);if(!this.options.zoomInOptimization){this.trueRedraw(e,t,n,r);return}this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=void 0);let i=Date.now();if(this.isInside(r,this.zoomInOptimize.lastDrawnViewport)&&n!==this.zoomInOptimize.lastDrawnScale&&i-this.zoomInOptimize.lastCallTime<500){this.zoomInOptimize.timeout=window.setTimeout(()=>{this.trueRedraw(e,t,n,r),this.zoomInOptimize.lastCallTime=i,this.zoomInOptimize.timeout=void 0},60),this.fakeRedraw(r,n);return}this.zoomInOptimize.lastCallTime=i,this.trueRedraw(e,t,n,r)};trueRedraw(e,t,n,r){this.zoomInOptimize.lastDrawnViewport=r,this.zoomInOptimize.lastDrawnScale=n,this.canvas.style.transform=``,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.drawGridDots(n,e,t),this.ctx.translate(e,t),this.ctx.scale(n,n),Object.values(this.DM.data.nodeMap).forEach(e=>{if(this.isOutside(e.box,r))return;let t=e.ref;t.type===`file`?this.drawFile(e):t.type===`group`&&this.drawGroup(t,n)}),Object.values(this.DM.data.edgeMap).forEach(e=>{this.isOutside(e.box,r)||this.drawEdge(e)}),this.ctx.restore()}fakeRedraw(e,t){let n=t/this.zoomInOptimize.lastDrawnScale,r=(this.zoomInOptimize.lastDrawnViewport.left-e.left)*t,i=(this.zoomInOptimize.lastDrawnViewport.top-e.top)*t;this.canvas.style.transform=`translate(${r}px, ${i}px) scale(${n})`}isInside=(e,t)=>e.left>t.left&&e.top>t.top&&e.right<t.right&&e.bottom<t.bottom;isOutside=(e,t)=>e.right<t.left||e.bottom<t.top||e.left>t.right||e.top>t.bottom;getCurrentViewport=(e,t,n)=>{let r=-e/n,i=-t/n,a=this.DM.data.container,o=r+a.clientWidth/n;return{bottom:i+a.clientHeight/n,left:r,right:o,top:i}};drawLabelBar=(e,t,n,r,i,a)=>{let o=30*a,s=6*a,c=8*a,l=16*a,u=6*a;this.ctx.save(),this.ctx.translate(e,t),this.ctx.scale(1/a,1/a),this.ctx.font=`${l}px 'Inter', sans-serif`;let d=this.ctx.measureText(n).width+2*u;this.ctx.translate(0,-o-c),this.ctx.fillStyle=r,this.ctx.beginPath(),this.ctx.moveTo(s,0),this.ctx.lineTo(d-s,0),this.ctx.quadraticCurveTo(d,0,d,s),this.ctx.lineTo(d,o-s),this.ctx.quadraticCurveTo(d,o,d-s,o),this.ctx.lineTo(s,o),this.ctx.quadraticCurveTo(0,o,0,o-s),this.ctx.lineTo(0,s),this.ctx.quadraticCurveTo(0,0,s,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=i,this.ctx.fillText(n,u,o*.65),this.ctx.restore()};drawNodeBackground=e=>{let t=this.SM.getColor(e.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=t.background,S(this.ctx,e.x+1,e.y+1,e.width-2,e.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=t.border,this.ctx.lineWidth=2,S(this.ctx,e.x,e.y,e.width,e.height,12),this.ctx.stroke()};drawGroup=(e,t)=>{if(this.drawNodeBackground(e),e.label){let n=this.SM.getColor(e.color);this.drawLabelBar(e.x,e.y,e.label,n.active,n.text,t)}};drawFile=e=>{this.ctx.fillStyle=this.SM.getColor().text;let t=e.ref;this.ctx.font=`16px sans-serif`,this.ctx.fillText(e.fileName??``,t.x+5,t.y-10)};drawEdge=e=>{let t=e.ref,n=this.DM.data.nodeMap[t.fromNode].ref,r=this.DM.data.nodeMap[t.toNode].ref,{x:i,y:a}=C(n,t.fromSide),{x:o,y:s}=C(r,t.toSide),c=this.SM.getColor(t.color),l,u,d,f;e.controlPoints?[l,u,d,f]=e.controlPoints:([l,u,d,f]=this.getControlPoints(i,a,o,s,t.fromSide,t.toSide),e.controlPoints=[l,u,d,f]),this.drawCurvedPath(i,a,o,s,l,u,d,f,c.active),this.drawArrowhead(o,s,d,f,c.active),t.label&&this.drawEdgeLabel(i,a,o,s,l,u,d,f,t.label,c.active,c.text)};drawEdgeLabel=(e,t,n,r,i,a,o,s,c,l,u)=>{let d=.5,f=(1-d)**3*e+3*(1-d)**2*d*i+3*(1-d)*d*d*o+d**3*n,p=(1-d)**3*t+3*(1-d)**2*d*a+3*(1-d)*d*d*s+d**3*r;this.ctx.font=`18px sans-serif`;let m=c.split(`
396
+ `),h=0;for(let e of m){let t=this.ctx.measureText(e).width;t>h&&(h=t)}let g=h+16,_=m.length*17+6;this.ctx.fillStyle=l,this.ctx.beginPath(),S(this.ctx,f-g/2,p-_/2-2,g,_,4),this.ctx.fill(),this.ctx.fillStyle=u,this.ctx.textAlign=`center`,this.ctx.textBaseline=`middle`;for(let e=0;e<m.length;e++){let t=(e-(m.length-1)/2)*17;this.ctx.fillText(m[e],f,p-2+t)}this.ctx.textAlign=`left`,this.ctx.textBaseline=`alphabetic`};getControlPoints=(e,t,n,r,i,a)=>{let o=n-e,s=r-t,c=((e,t,n)=>Math.max(t,Math.min(n,e)))((Math.min(Math.abs(o),Math.abs(s))+.3*Math.max(Math.abs(o),Math.abs(s)))*.5,60,300),l=e,u=t,d=n,f=r;switch(i){case`top`:u=t-c;break;case`bottom`:u=t+c;break;case`left`:l=e-c;break;case`right`:l=e+c;break}switch(a){case`top`:f=r-c;break;case`bottom`:f=r+c;break;case`left`:d=n-c;break;case`right`:d=n+c;break}return[l,u,d,f]};drawGridDots=(e,t,n)=>{let r=10*2**-Math.floor(Math.log2(e))*e,i=this.canvas.width,a=this.canvas.height,o=t%r,s=n%r;this.ctx.fillStyle=this.SM.getNamedColor(`dots`);for(let e=o;e<=i;e+=r)for(let t=s;t<=a;t+=r)this.ctx.beginPath(),this.ctx.arc(e,t,1,0,2*Math.PI),this.ctx.fill()};drawCurvedPath=(e,t,n,r,i,a,o,s,c)=>{this.ctx.beginPath(),this.ctx.moveTo(e,t),this.ctx.bezierCurveTo(i,a,o,s,n,r),this.ctx.strokeStyle=c,this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(e,t,n,r,i)=>{let a=e-n,o=t-r,s=Math.sqrt(a*a+o*o);if(s===0)return;let c=a/s,l=o/s,u=e-c*12-l*4,d=t-l*12+c*4,f=e-c*12+l*4,p=t-l*12-c*4;this.ctx.beginPath(),this.ctx.fillStyle=i,this.ctx.moveTo(e,t),this.ctx.lineTo(u,d),this.ctx.lineTo(f,p),this.ctx.closePath(),this.ctx.fill()};dispose=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=void 0),this.canvas.remove(),this._canvas=void 0}}];var W=class{allModules;IO;started=!1;disposed=!1;options;container;onDispose=E(!0);onStart=E();onRestart=E();constructor(e,t){this.container=new h,this.options=e;let n=e=>{this.container.bind({provide:e,useFactory:()=>new e(this.container,this.options,this.onStart,this.onDispose,this.onRestart,this.augment)})};this.allModules=[...U,...t??[]],this.allModules.forEach(n),this.allModules.forEach(e=>{this.container.get(e)});let r=this.options.loading??`normal`;r===`normal`?this.load():r===`lazy`&&(this.IO=new IntersectionObserver(this.onVisibilityCheck,{rootMargin:`50px`,threshold:0}),this.IO.observe(this.options.container))}onVisibilityCheck=e=>{e.forEach(e=>{if(e.isIntersecting){this.load(),this.IO?.disconnect(),this.IO=void 0;return}})};augment=e=>{let t=Object.getOwnPropertyDescriptors(e);Object.defineProperties(this,t)};load=e=>{this.disposed||(e&&Object.assign(this.options,e),this.started?this.onRestart():(this.onStart(),this.started=!0))};dispose=()=>{if(!this.started||this.disposed)return;this.IO?.disconnect(),this.IO=void 0;let e=this.options.container;for(;e.firstChild;)e.firstChild.remove();this.onDispose(),this.container.unbindAll(),this.disposed=!0}};async function G(e){return g.sanitize(await _(e))}async function K(e){return await fetch(e).then(e=>e.json())}export{I as Controls,R as DebugPanel,W as JSONCanvasViewer,B as Minimap,H as MistouchPreventer,K as fetchCanvas,G as parser};
package/dist/index.d.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  import { JSONCanvas, JSONCanvasEdge, JSONCanvasFileNode, JSONCanvasGroupNode, JSONCanvasLinkNode, JSONCanvasNode, JSONCanvasTextNode, Parser } from "./shared/index.js";
2
- import { Hook, _default as _default$1 } from "./kernel/utilities.js";
2
+ import { Hook } from "./kernel/utilities.js";
3
3
  import { BaseArgs, BaseModule, GeneralModule, GeneralModuleCtor } from "./kernel/BaseModule.js";
4
- import { Controller } from "./kernel/Controller.js";
5
4
  import { DataManager } from "./kernel/DataManager.js";
6
5
  import { InteractionHandler } from "./kernel/InteractionHandler.js";
7
6
  import { OverlayManager } from "./kernel/OverlayManager.js";
8
7
  import { Renderer } from "./kernel/Renderer.js";
9
8
  import { StyleManager } from "./kernel/StyleManager.js";
10
9
  import { AllOptions, BaseOptions, JSONCanvasViewerInterface, _default } from "./kernel/index.js";
11
- import { renderToString } from "./utilities/renderToString.js";
10
+ import { Controller } from "./kernel/Controller.js";
11
+ import { renderToString } from "./utilities/render-to-string.js";
12
12
  import { Controls } from "./modules/Controls/index.js";
13
13
  import { DebugPanel } from "./modules/DebugPanel/index.js";
14
14
  import { Minimap } from "./modules/Minimap/index.js";
15
15
  import { MistouchPreventer } from "./modules/MistouchPreventer/index.js";
16
- import { fetchCanvas } from "./utilities/fetchCanvas.js";
16
+ import { fetchCanvas } from "./utilities/fetch-canvas.js";
17
17
  import { parser } from "./utilities/parser.js";
18
18
 
19
19
  //#region src/index.d.ts
@@ -26,5 +26,5 @@ declare const internal: {
26
26
  StyleManager: typeof StyleManager;
27
27
  };
28
28
  //#endregion
29
- export { type BaseArgs, BaseModule, type BaseOptions, Controls, DebugPanel, type GeneralModule, type GeneralModuleCtor, type Hook, JSONCanvas, JSONCanvasEdge, JSONCanvasFileNode, JSONCanvasGroupNode, JSONCanvasLinkNode, JSONCanvasNode, JSONCanvasTextNode, _default as JSONCanvasViewer, type JSONCanvasViewerInterface, Minimap, MistouchPreventer, type AllOptions as Options, Parser, _default$1 as canvasUtils, fetchCanvas, internal, parser, renderToString };
29
+ export { type BaseArgs, BaseModule, type BaseOptions, Controls, DebugPanel, type GeneralModule, type GeneralModuleCtor, type Hook, JSONCanvas, JSONCanvasEdge, JSONCanvasFileNode, JSONCanvasGroupNode, JSONCanvasLinkNode, JSONCanvasNode, JSONCanvasTextNode, _default as JSONCanvasViewer, type JSONCanvasViewerInterface, Minimap, MistouchPreventer, type AllOptions as Options, Parser, fetchCanvas, internal, parser, renderToString };
30
30
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{BaseModule as e}from"./kernel/BaseModule.js";import t from"./kernel/utilities.js";import n from"./kernel/DataManager.js";import r from"./kernel/StyleManager.js";import i from"./kernel/Controller.js";import a from"./kernel/OverlayManager.js";import o from"./kernel/InteractionHandler.js";import s from"./kernel/Renderer.js";import c from"./kernel/index.js";import l from"./utilities/renderToString.js";import u from"./modules/Controls/index.js";import d from"./modules/DebugPanel/index.js";import f from"./modules/Minimap/index.js";import p from"./modules/MistouchPreventer/index.js";import m from"./utilities/fetchCanvas.js";import h from"./utilities/parser.js";const g={Controller:i,DataManager:n,InteractionHandler:o,OverlayManager:a,Renderer:s,StyleManager:r};export{e as BaseModule,u as Controls,d as DebugPanel,c as JSONCanvasViewer,f as Minimap,p as MistouchPreventer,t as canvasUtils,m as fetchCanvas,g as internal,h as parser,l as renderToString};
1
+ import{BaseModule as e}from"./kernel/BaseModule.js";import t from"./kernel/DataManager.js";import n from"./kernel/StyleManager.js";import r from"./kernel/Controller.js";import i from"./kernel/OverlayManager.js";import a from"./kernel/InteractionHandler.js";import o from"./kernel/Renderer.js";import s from"./kernel/index.js";import c from"./utilities/render-to-string.js";import l from"./modules/Controls/index.js";import u from"./modules/DebugPanel/index.js";import d from"./modules/Minimap/index.js";import f from"./modules/MistouchPreventer/index.js";import p from"./utilities/fetch-canvas.js";import m from"./utilities/parser.js";const h={Controller:r,DataManager:t,InteractionHandler:a,OverlayManager:i,Renderer:o,StyleManager:n};export{e as BaseModule,l as Controls,u as DebugPanel,s as JSONCanvasViewer,d as Minimap,f as MistouchPreventer,p as fetchCanvas,h as internal,m as parser,c as renderToString};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export {\n\tdefault as JSONCanvasViewer,\n\ttype JSONCanvasViewerInterface,\n\ttype AllOptions as Options,\n} from '$';\nexport { default as renderToString } from '@/utilities/renderToString.ts';\nexport {\n\ttype GeneralModule,\n\ttype GeneralModuleCtor,\n\ttype BaseArgs,\n\tBaseModule,\n} from '$/BaseModule';\nexport type { BaseOptions } from '$';\nexport { default as Controls } from '@/modules/Controls';\nexport { default as DebugPanel } from '@/modules/DebugPanel';\nexport { default as Minimap } from '@/modules/Minimap';\nexport { default as MistouchPreventer } from '@/modules/MistouchPreventer';\nexport { default as canvasUtils, type Hook } from '$/utilities';\nexport { default as fetchCanvas } from '@/utilities/fetchCanvas';\nexport { default as parser } from '@/utilities/parser';\nexport type * from '@repo/shared';\n\nimport Controller from '$/Controller';\nimport DataManager from '$/DataManager';\nimport InteractionHandler from '$/InteractionHandler';\nimport OverlayManager from '$/OverlayManager';\nimport Renderer from '$/Renderer';\nimport StyleManager from '$/StyleManager';\nexport const internal = {\n\tController,\n\tDataManager,\n\tInteractionHandler,\n\tOverlayManager,\n\tRenderer,\n\tStyleManager,\n};\n\n// must import env.d.ts, otherwise tsdown will throw at '*.scss?inline'\nimport './env.d.ts';\n"],"mappings":"6pBA4BA,MAAa,EAAW,CACvB,aACA,cACA,qBACA,iBACA,WACA,eACA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import Controller from '$/Controller';\nimport DataManager from '$/DataManager';\nimport InteractionHandler from '$/InteractionHandler';\nimport OverlayManager from '$/OverlayManager';\nimport Renderer from '$/Renderer';\nimport StyleManager from '$/StyleManager';\n// Must import env.d.ts, otherwise tsdown will throw at '*.scss?inline'\nimport './env.d.ts';\n\nexport {\n\tdefault as JSONCanvasViewer,\n\ttype JSONCanvasViewerInterface,\n\ttype AllOptions as Options,\n} from '$';\nexport { default as renderToString } from '@/utilities/render-to-string.ts';\nexport {\n\ttype GeneralModule,\n\ttype GeneralModuleCtor,\n\ttype BaseArgs,\n\tBaseModule,\n} from '$/BaseModule';\nexport type { BaseOptions } from '$';\nexport { default as Controls } from '@/modules/Controls';\nexport { default as DebugPanel } from '@/modules/DebugPanel';\nexport { default as Minimap } from '@/modules/Minimap';\nexport { default as MistouchPreventer } from '@/modules/MistouchPreventer';\nexport { type Hook } from '$/utilities';\nexport { default as fetchCanvas } from '@/utilities/fetch-canvas.ts';\nexport { default as parser } from '@/utilities/parser';\nexport type * from '@repo/shared';\nexport const internal = {\n\tController,\n\tDataManager,\n\tInteractionHandler,\n\tOverlayManager,\n\tRenderer,\n\tStyleManager,\n};\n"],"mappings":"2nBA8BA,MAAa,EAAW,CACvB,aACA,cACA,qBACA,iBACA,WACA,eACA"}
@@ -1,10 +1,9 @@
1
1
  import { General, GeneralObject, ModuleInput as ModuleInput$1, Orchestratable } from "./types.js";
2
- import { _default } from "./utilities.js";
2
+ import { Hook } from "./utilities.js";
3
3
  import { BaseOptions } from "./index.js";
4
4
  import { Container } from "@needle-di/core";
5
5
 
6
6
  //#region src/kernel/BaseModule.d.ts
7
- type Hook = ReturnType<typeof _default.makeHook>;
8
7
  type GeneralModuleCtor = typeof BaseModule<General, General>;
9
8
  type GeneralModule = BaseModule<General, General>;
10
9
  type ModuleInputCtor = Array<GeneralModuleCtor>;
@@ -1 +1 @@
1
- {"version":3,"file":"BaseModule.js","names":[],"sources":["../../src/kernel/BaseModule.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { General, GeneralObject, ModuleInput as MI, Orchestratable } from '$/types';\nimport type utilities from '$/utilities';\nimport type { Container } from '@needle-di/core';\n\ntype Hook = ReturnType<typeof utilities.makeHook>;\n\nexport type GeneralModuleCtor = typeof BaseModule<General, General>;\nexport type GeneralModule = BaseModule<General, General>;\n\nexport type ModuleInputCtor = Array<GeneralModuleCtor>;\nexport type ModuleInput = MI<GeneralModuleCtor>;\nexport type Options<M extends ModuleInput> = Orchestratable<M, 'options'>;\nexport type Augmentation<M extends ModuleInput> = Orchestratable<M, '_Augmentation'>;\n\nexport type BaseArgs = ConstructorParameters<GeneralModuleCtor>;\n\nexport class BaseModule<O extends BaseOptions = BaseOptions, A extends GeneralObject = {}> {\n\t// https://github.com/timocov/dts-bundle-generator/issues/360\n\tdeclare private static readonly _BaseModuleBrand: unique symbol; // Nominal marker\n\tdeclare _Augmentation: A;\n\tonStart: Hook['subscribe'];\n\tonRestart: Hook['subscribe'];\n\tonDispose: Hook['subscribe'];\n\tconstructor(\n\t\tprotected container: Container,\n\t\toptions: GeneralObject,\n\t\tonStart: Hook,\n\t\tonDispose: Hook,\n\t\tonRestart: Hook,\n\t\tprotected augment: (aug: A) => void,\n\t) {\n\t\tthis.options = options as O;\n\t\tthis.onStart = onStart.subscribe;\n\t\tthis.onDispose = onDispose.subscribe;\n\t\tthis.onRestart = onRestart.subscribe;\n\t}\n\toptions: O;\n}\n"],"mappings":"AAiBA,IAAa,EAAb,KAA2F,CAI1F,QACA,UACA,UACA,YACC,EACA,EACA,EACA,EACA,EACA,EACC,CANS,KAAA,UAAA,EAKA,KAAA,QAAA,EAEV,KAAK,QAAU,EACf,KAAK,QAAU,EAAQ,UACvB,KAAK,UAAY,EAAU,UAC3B,KAAK,UAAY,EAAU,UAE5B"}
1
+ {"version":3,"file":"BaseModule.js","names":[],"sources":["../../src/kernel/BaseModule.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { General, GeneralObject, ModuleInput as MI, Orchestratable } from '$/types';\nimport type { Hook } from '$/utilities';\nimport type { Container } from '@needle-di/core';\n\nexport type GeneralModuleCtor = typeof BaseModule<General, General>;\nexport type GeneralModule = BaseModule<General, General>;\n\nexport type ModuleInputCtor = Array<GeneralModuleCtor>;\nexport type ModuleInput = MI<GeneralModuleCtor>;\nexport type Options<M extends ModuleInput> = Orchestratable<M, 'options'>;\nexport type Augmentation<M extends ModuleInput> = Orchestratable<M, '_Augmentation'>;\n\nexport type BaseArgs = ConstructorParameters<GeneralModuleCtor>;\n\nexport class BaseModule<O extends BaseOptions = BaseOptions, A extends GeneralObject = {}> {\n\tdeclare private static readonly _BaseModuleBrand: unique symbol; // Nominal marker\n\tdeclare _Augmentation: A;\n\tonStart: Hook['subscribe'];\n\tonRestart: Hook['subscribe'];\n\tonDispose: Hook['subscribe'];\n\n\tconstructor(\n\t\tprotected container: Container,\n\t\toptions: GeneralObject,\n\t\tonStart: Hook,\n\t\tonDispose: Hook,\n\t\tonRestart: Hook,\n\t\tprotected augment: (aug: A) => void,\n\t) {\n\t\tthis.options = options as O;\n\t\tthis.onStart = onStart.subscribe;\n\t\tthis.onDispose = onDispose.subscribe;\n\t\tthis.onRestart = onRestart.subscribe;\n\t}\n\toptions: O;\n}\n"],"mappings":"AAeA,IAAa,EAAb,KAA2F,CAG1F,QACA,UACA,UAEA,YACC,EACA,EACA,EACA,EACA,EACA,EACC,CANS,KAAA,UAAA,EAKA,KAAA,QAAA,EAEV,KAAK,QAAU,EACf,KAAK,QAAU,EAAQ,UACvB,KAAK,UAAY,EAAU,UAC3B,KAAK,UAAY,EAAU,UAE5B"}
@@ -3,27 +3,27 @@ import { BaseArgs, BaseModule } from "./BaseModule.js";
3
3
  import { BaseOptions } from "./index.js";
4
4
 
5
5
  //#region src/kernel/Controller.d.ts
6
- interface Augmentation {
6
+ type Augmentation = {
7
7
  refresh: Controller['refresh'];
8
8
  onRefresh: Controller['onRefresh'];
9
9
  onResize: Controller['onResize'];
10
- }
10
+ };
11
11
  declare class Controller extends BaseModule<BaseOptions, Augmentation> {
12
- private animationId;
13
- private resizeAnimationId;
14
- private DM;
15
- private SM;
16
- private resizeObserver;
12
+ private animationId?;
13
+ private resizeAnimationId?;
14
+ private readonly DM;
15
+ private readonly SM;
16
+ private readonly resizeObserver;
17
17
  private perFrame;
18
- private lastResizeCenter;
18
+ private readonly lastResizeCenter;
19
19
  onResize: Hook<[number, number], false>;
20
20
  onRefresh: Hook<[], false>;
21
21
  constructor(...args: BaseArgs);
22
- private start;
23
- private draw;
22
+ private readonly start;
23
+ private readonly draw;
24
24
  refresh: () => void;
25
- private onResizeCallback;
26
- private dispose;
25
+ private readonly onResizeCallback;
26
+ private readonly dispose;
27
27
  }
28
28
  //#endregion
29
29
  export { Controller };
@@ -1,2 +1,2 @@
1
- import{BaseModule as e}from"./BaseModule.js";import t from"./utilities.js";import n from"./DataManager.js";import r from"./StyleManager.js";var i=class extends e{animationId=null;resizeAnimationId=null;DM;SM;resizeObserver;perFrame={lastScale:1,lastOffsets:{x:0,y:0}};lastResizeCenter={x:null,y:null};onResize=t.makeHook();onRefresh=t.makeHook();constructor(...e){super(...e),this.DM=this.container.get(n),this.SM=this.container.get(r),this.resizeObserver=new ResizeObserver(this.onResizeCallback),this.SM.onChangeTheme.subscribe(this.refresh),this.augment({refresh:this.refresh,onRefresh:this.onRefresh,onResize:this.onResize}),this.onStart(this.start),this.onRestart(this.refresh),this.onDispose(this.dispose)}start=()=>{this.resizeObserver.observe(this.DM.data.container),this.animationId=requestAnimationFrame(this.draw)};draw=()=>{(this.perFrame.lastScale!==this.DM.data.scale||this.perFrame.lastOffsets.x!==this.DM.data.offsetX||this.perFrame.lastOffsets.y!==this.DM.data.offsetY)&&this.refresh(),this.animationId=requestAnimationFrame(this.draw)};refresh=()=>{this.perFrame={lastScale:this.DM.data.scale,lastOffsets:{x:this.DM.data.offsetX,y:this.DM.data.offsetY}},this.onRefresh()};onResizeCallback=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{let e=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+e.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+e.y-this.lastResizeCenter.y),this.lastResizeCenter.x=e.x,this.lastResizeCenter.y=e.y,this.onResize(e.width,e.height),this.refresh()})};dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}};export{i as default};
1
+ import{BaseModule as e}from"./BaseModule.js";import{makeHook as t}from"./utilities.js";import n from"./DataManager.js";import r from"./StyleManager.js";var i=class extends e{animationId;resizeAnimationId;DM;SM;resizeObserver;perFrame={lastOffsets:{x:0,y:0},lastScale:1};lastResizeCenter={};onResize=t();onRefresh=t();constructor(...e){super(...e),this.DM=this.container.get(n),this.SM=this.container.get(r),this.resizeObserver=new ResizeObserver(this.onResizeCallback),this.SM.onChangeTheme.subscribe(this.refresh),this.augment({onRefresh:this.onRefresh,onResize:this.onResize,refresh:this.refresh}),this.onStart(this.start),this.onRestart(this.refresh),this.onDispose(this.dispose)}start=()=>{this.resizeObserver.observe(this.DM.data.container),this.animationId=requestAnimationFrame(this.draw)};draw=()=>{(this.perFrame.lastScale!==this.DM.data.scale||this.perFrame.lastOffsets.x!==this.DM.data.offsetX||this.perFrame.lastOffsets.y!==this.DM.data.offsetY)&&this.refresh(),this.animationId=requestAnimationFrame(this.draw)};refresh=()=>{this.perFrame={lastOffsets:{x:this.DM.data.offsetX,y:this.DM.data.offsetY},lastScale:this.DM.data.scale},this.onRefresh()};onResizeCallback=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{let e=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+e.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+e.y-this.lastResizeCenter.y),this.lastResizeCenter.x=e.x,this.lastResizeCenter.y=e.y,this.onResize(e.width,e.height),this.refresh()})};dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}};export{i as default};
2
2
  //# sourceMappingURL=Controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Controller.js","names":["utilities"],"sources":["../../src/kernel/Controller.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport { type BaseArgs, BaseModule } from '$/BaseModule';\nimport DataManager from '$/DataManager';\nimport StyleManager from '$/StyleManager';\nimport utilities from '$/utilities';\n\ninterface Augmentation {\n\trefresh: Controller['refresh'];\n\tonRefresh: Controller['onRefresh'];\n\tonResize: Controller['onResize'];\n}\n\nexport default class Controller extends BaseModule<BaseOptions, Augmentation> {\n\tprivate animationId: null | number = null;\n\tprivate resizeAnimationId: null | number = null;\n\tprivate DM: DataManager;\n\tprivate SM: StyleManager;\n\tprivate resizeObserver: ResizeObserver;\n\tprivate perFrame: {\n\t\tlastScale: number;\n\t\tlastOffsets: { x: number; y: number };\n\t} = {\n\t\tlastScale: 1,\n\t\tlastOffsets: { x: 0, y: 0 },\n\t};\n\tprivate lastResizeCenter: {\n\t\tx: null | number;\n\t\ty: null | number;\n\t} = {\n\t\tx: null,\n\t\ty: null,\n\t};\n\n\tonResize = utilities.makeHook<[number, number]>();\n\tonRefresh = utilities.makeHook();\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.SM = this.container.get(StyleManager);\n\t\tthis.resizeObserver = new ResizeObserver(this.onResizeCallback);\n\t\tthis.SM.onChangeTheme.subscribe(this.refresh);\n\t\tthis.augment({\n\t\t\trefresh: this.refresh,\n\t\t\tonRefresh: this.onRefresh,\n\t\t\tonResize: this.onResize,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.refresh);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tthis.resizeObserver.observe(this.DM.data.container);\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\tprivate draw = () => {\n\t\tif (\n\t\t\tthis.perFrame.lastScale !== this.DM.data.scale ||\n\t\t\tthis.perFrame.lastOffsets.x !== this.DM.data.offsetX ||\n\t\t\tthis.perFrame.lastOffsets.y !== this.DM.data.offsetY\n\t\t)\n\t\t\tthis.refresh();\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\trefresh = () => {\n\t\tthis.perFrame = {\n\t\t\tlastScale: this.DM.data.scale,\n\t\t\tlastOffsets: { x: this.DM.data.offsetX, y: this.DM.data.offsetY },\n\t\t};\n\t\tthis.onRefresh();\n\t};\n\n\tprivate onResizeCallback = () => {\n\t\tthis.resizeAnimationId = requestAnimationFrame(() => {\n\t\t\tconst center = this.DM.middleViewer();\n\t\t\tif (this.lastResizeCenter.x && this.lastResizeCenter.y) {\n\t\t\t\tthis.DM.data.offsetX = this.DM.data.offsetX + center.x - this.lastResizeCenter.x;\n\t\t\t\tthis.DM.data.offsetY = this.DM.data.offsetY + center.y - this.lastResizeCenter.y;\n\t\t\t}\n\t\t\tthis.lastResizeCenter.x = center.x;\n\t\t\tthis.lastResizeCenter.y = center.y;\n\t\t\tthis.onResize(center.width, center.height);\n\t\t\tthis.refresh();\n\t\t});\n\t};\n\n\tprivate dispose = () => {\n\t\tif (this.animationId) cancelAnimationFrame(this.animationId);\n\t\tif (this.resizeAnimationId) cancelAnimationFrame(this.resizeAnimationId);\n\t\tthis.resizeObserver.disconnect();\n\t};\n}\n"],"mappings":"4IAYA,IAAqB,EAArB,cAAwC,CAAsC,CAC7E,YAAqC,KACrC,kBAA2C,KAC3C,GACA,GACA,eACA,SAGI,CACH,UAAW,EACX,YAAa,CAAE,EAAG,EAAG,EAAG,EAAG,CAC3B,CACD,iBAGI,CACH,EAAG,KACH,EAAG,KACH,CAED,SAAWA,EAAU,UAA4B,CACjD,UAAYA,EAAU,UAAU,CAEhC,YAAY,GAAG,EAAgB,CAC9B,MAAM,GAAG,EAAK,CACd,KAAK,GAAK,KAAK,UAAU,IAAI,EAAY,CACzC,KAAK,GAAK,KAAK,UAAU,IAAI,EAAa,CAC1C,KAAK,eAAiB,IAAI,eAAe,KAAK,iBAAiB,CAC/D,KAAK,GAAG,cAAc,UAAU,KAAK,QAAQ,CAC7C,KAAK,QAAQ,CACZ,QAAS,KAAK,QACd,UAAW,KAAK,UAChB,SAAU,KAAK,SACf,CAAC,CACF,KAAK,QAAQ,KAAK,MAAM,CACxB,KAAK,UAAU,KAAK,QAAQ,CAC5B,KAAK,UAAU,KAAK,QAAQ,CAG7B,UAAsB,CACrB,KAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,UAAU,CACnD,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,SAAqB,EAEnB,KAAK,SAAS,YAAc,KAAK,GAAG,KAAK,OACzC,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,SAC7C,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,UAE7C,KAAK,SAAS,CACf,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,YAAgB,CACf,KAAK,SAAW,CACf,UAAW,KAAK,GAAG,KAAK,MACxB,YAAa,CAAE,EAAG,KAAK,GAAG,KAAK,QAAS,EAAG,KAAK,GAAG,KAAK,QAAS,CACjE,CACD,KAAK,WAAW,EAGjB,qBAAiC,CAChC,KAAK,kBAAoB,0BAA4B,CACpD,IAAM,EAAS,KAAK,GAAG,cAAc,CACjC,KAAK,iBAAiB,GAAK,KAAK,iBAAiB,IACpD,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,EAC/E,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,GAEhF,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,SAAS,EAAO,MAAO,EAAO,OAAO,CAC1C,KAAK,SAAS,EACb,EAGH,YAAwB,CACnB,KAAK,aAAa,qBAAqB,KAAK,YAAY,CACxD,KAAK,mBAAmB,qBAAqB,KAAK,kBAAkB,CACxE,KAAK,eAAe,YAAY"}
1
+ {"version":3,"file":"Controller.js","names":[],"sources":["../../src/kernel/Controller.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { BaseArgs } from '$/BaseModule';\nimport { BaseModule } from '$/BaseModule';\nimport DataManager from '$/DataManager';\nimport StyleManager from '$/StyleManager';\nimport { makeHook } from '$/utilities';\n\ntype Augmentation = {\n\trefresh: Controller['refresh'];\n\tonRefresh: Controller['onRefresh'];\n\tonResize: Controller['onResize'];\n};\n\nexport default class Controller extends BaseModule<BaseOptions, Augmentation> {\n\tprivate animationId?: number;\n\tprivate resizeAnimationId?: number;\n\tprivate readonly DM: DataManager;\n\tprivate readonly SM: StyleManager;\n\tprivate readonly resizeObserver: ResizeObserver;\n\tprivate perFrame: {\n\t\tlastScale: number;\n\t\tlastOffsets: { x: number; y: number };\n\t} = {\n\t\tlastOffsets: { x: 0, y: 0 },\n\t\tlastScale: 1,\n\t};\n\tprivate readonly lastResizeCenter: {\n\t\tx?: number;\n\t\ty?: number;\n\t} = {};\n\n\tonResize = makeHook<[number, number]>();\n\tonRefresh = makeHook();\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tthis.DM = this.container.get(DataManager);\n\t\tthis.SM = this.container.get(StyleManager);\n\t\tthis.resizeObserver = new ResizeObserver(this.onResizeCallback);\n\t\tthis.SM.onChangeTheme.subscribe(this.refresh);\n\t\tthis.augment({\n\t\t\tonRefresh: this.onRefresh,\n\t\t\tonResize: this.onResize,\n\t\t\trefresh: this.refresh,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.refresh);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate readonly start = () => {\n\t\tthis.resizeObserver.observe(this.DM.data.container);\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\tprivate readonly draw = () => {\n\t\tif (\n\t\t\tthis.perFrame.lastScale !== this.DM.data.scale ||\n\t\t\tthis.perFrame.lastOffsets.x !== this.DM.data.offsetX ||\n\t\t\tthis.perFrame.lastOffsets.y !== this.DM.data.offsetY\n\t\t)\n\t\t\tthis.refresh();\n\t\tthis.animationId = requestAnimationFrame(this.draw);\n\t};\n\n\trefresh = () => {\n\t\tthis.perFrame = {\n\t\t\tlastOffsets: { x: this.DM.data.offsetX, y: this.DM.data.offsetY },\n\t\t\tlastScale: this.DM.data.scale,\n\t\t};\n\t\tthis.onRefresh();\n\t};\n\n\tprivate readonly onResizeCallback = () => {\n\t\tthis.resizeAnimationId = requestAnimationFrame(() => {\n\t\t\tconst center = this.DM.middleViewer();\n\t\t\tif (this.lastResizeCenter.x && this.lastResizeCenter.y) {\n\t\t\t\tthis.DM.data.offsetX = this.DM.data.offsetX + center.x - this.lastResizeCenter.x;\n\t\t\t\tthis.DM.data.offsetY = this.DM.data.offsetY + center.y - this.lastResizeCenter.y;\n\t\t\t}\n\t\t\tthis.lastResizeCenter.x = center.x;\n\t\t\tthis.lastResizeCenter.y = center.y;\n\t\t\tthis.onResize(center.width, center.height);\n\t\t\tthis.refresh();\n\t\t});\n\t};\n\n\tprivate readonly dispose = () => {\n\t\tif (this.animationId) cancelAnimationFrame(this.animationId);\n\t\tif (this.resizeAnimationId) cancelAnimationFrame(this.resizeAnimationId);\n\t\tthis.resizeObserver.disconnect();\n\t};\n}\n"],"mappings":"wJAaA,IAAqB,EAArB,cAAwC,CAAsC,CAC7E,YACA,kBACA,GACA,GACA,eACA,SAGI,CACH,YAAa,CAAE,EAAG,EAAG,EAAG,EAAG,CAC3B,UAAW,EACX,CACD,iBAGI,EAAE,CAEN,SAAW,GAA4B,CACvC,UAAY,GAAU,CAEtB,YAAY,GAAG,EAAgB,CAC9B,MAAM,GAAG,EAAK,CACd,KAAK,GAAK,KAAK,UAAU,IAAI,EAAY,CACzC,KAAK,GAAK,KAAK,UAAU,IAAI,EAAa,CAC1C,KAAK,eAAiB,IAAI,eAAe,KAAK,iBAAiB,CAC/D,KAAK,GAAG,cAAc,UAAU,KAAK,QAAQ,CAC7C,KAAK,QAAQ,CACZ,UAAW,KAAK,UAChB,SAAU,KAAK,SACf,QAAS,KAAK,QACd,CAAC,CACF,KAAK,QAAQ,KAAK,MAAM,CACxB,KAAK,UAAU,KAAK,QAAQ,CAC5B,KAAK,UAAU,KAAK,QAAQ,CAG7B,UAA+B,CAC9B,KAAK,eAAe,QAAQ,KAAK,GAAG,KAAK,UAAU,CACnD,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,SAA8B,EAE5B,KAAK,SAAS,YAAc,KAAK,GAAG,KAAK,OACzC,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,SAC7C,KAAK,SAAS,YAAY,IAAM,KAAK,GAAG,KAAK,UAE7C,KAAK,SAAS,CACf,KAAK,YAAc,sBAAsB,KAAK,KAAK,EAGpD,YAAgB,CACf,KAAK,SAAW,CACf,YAAa,CAAE,EAAG,KAAK,GAAG,KAAK,QAAS,EAAG,KAAK,GAAG,KAAK,QAAS,CACjE,UAAW,KAAK,GAAG,KAAK,MACxB,CACD,KAAK,WAAW,EAGjB,qBAA0C,CACzC,KAAK,kBAAoB,0BAA4B,CACpD,IAAM,EAAS,KAAK,GAAG,cAAc,CACjC,KAAK,iBAAiB,GAAK,KAAK,iBAAiB,IACpD,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,EAC/E,KAAK,GAAG,KAAK,QAAU,KAAK,GAAG,KAAK,QAAU,EAAO,EAAI,KAAK,iBAAiB,GAEhF,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,iBAAiB,EAAI,EAAO,EACjC,KAAK,SAAS,EAAO,MAAO,EAAO,OAAO,CAC1C,KAAK,SAAS,EACb,EAGH,YAAiC,CAC5B,KAAK,aAAa,qBAAqB,KAAK,YAAY,CACxD,KAAK,mBAAmB,qBAAqB,KAAK,kBAAkB,CACxE,KAAK,eAAe,YAAY"}
@@ -5,32 +5,32 @@ import { BaseArgs, BaseModule } from "./BaseModule.js";
5
5
  import { BaseOptions } from "./index.js";
6
6
 
7
7
  //#region src/kernel/DataManager.d.ts
8
- interface Options extends BaseOptions {
8
+ type Options = {
9
9
  shadowed?: boolean;
10
10
  canvas?: JSONCanvas;
11
11
  attachmentDir?: string;
12
12
  extraCSS?: string;
13
13
  attachments?: Record<string, string>;
14
14
  noAttachmentRelocation?: boolean;
15
- }
16
- interface Augmentation {
15
+ } & BaseOptions;
16
+ type Augmentation = {
17
17
  resetView: DataManager['resetView'];
18
18
  toggleFullscreen: DataManager['toggleFullscreen'];
19
19
  onToggleFullscreen: DataManager['onToggleFullscreen'];
20
- }
21
- interface NodeItem {
20
+ };
21
+ type NodeItem = {
22
22
  ref: JSONCanvasNode;
23
23
  box: Box;
24
24
  fileName?: string;
25
25
  onBeforeUnmount?: Hook;
26
26
  onActive?: Hook;
27
27
  onLoseActive?: Hook;
28
- }
29
- interface EdgeItem {
28
+ };
29
+ type EdgeItem = {
30
30
  ref: JSONCanvasEdge;
31
31
  box: Box;
32
32
  controlPoints?: Array<number>;
33
- }
33
+ };
34
34
  type NodeMap = Record<string, NodeItem>;
35
35
  type EdgeMap = Record<string, EdgeItem>;
36
36
  declare class DataManager extends BaseModule<Options, Augmentation> {
@@ -47,20 +47,20 @@ declare class DataManager extends BaseModule<Options, Augmentation> {
47
47
  container: HTMLDivElement;
48
48
  };
49
49
  constructor(...args: BaseArgs);
50
- private start;
51
- private processBaseDir;
52
- private getNodeBox;
53
- private getEdgeBox;
50
+ private readonly start;
51
+ private readonly processBaseDir;
52
+ private readonly getNodeBox;
53
+ private readonly getEdgeBox;
54
54
  private calculateNodeBounds;
55
55
  toggleFullscreen: (option?: "enter" | "exit") => Promise<void>;
56
56
  resetView: () => void;
57
57
  middleViewer: () => {
58
+ height: number;
59
+ width: number;
58
60
  x: number;
59
61
  y: number;
60
- width: number;
61
- height: number;
62
62
  };
63
- private dispose;
63
+ private readonly dispose;
64
64
  }
65
65
  //#endregion
66
66
  export { DataManager };
@@ -1,2 +1,2 @@
1
- import{BaseModule as e}from"./BaseModule.js";import t from"./styles.js";import n from"./utilities.js";var r=class extends e{onToggleFullscreen=n.makeHook();data={canvasData:{nodes:[],edges:[]},nodeMap:{},edgeMap:{},canvasBaseDir:`./`,nodeBounds:{maxX:0,maxY:0,minX:0,minY:0,width:0,height:0,centerX:0,centerY:0},offsetX:0,offsetY:0,scale:1,container:document.createElement(`div`)};constructor(...e){super(...e);let r=this.options.container;for(;r.firstElementChild;)r.firstElementChild.remove();r.innerHTML=``;let i=this.options.shadowed?r.attachShadow({mode:`open`}):r;n.applyStyles(i,t+this.options.extraCSS),this.data.container.classList.add(`JSON-Canvas-Viewer`),i.appendChild(this.data.container),this.augment({resetView:this.resetView,toggleFullscreen:this.toggleFullscreen,onToggleFullscreen:this.onToggleFullscreen}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}start=()=>{let e=Object.assign({nodes:[],edges:[]},this.options.canvas);Object.assign(this.data,{canvasData:e,nodeMap:{},edgeMap:{},canvasBaseDir:this.processBaseDir(this.options.attachmentDir),nodeBounds:this.calculateNodeBounds(e),offsetX:0,offsetY:0,scale:1}),this.data.canvasData.nodes.forEach(e=>{let t={ref:e,box:this.getNodeBox(e)};if(this.data.nodeMap[e.id]=t,e.type===`file`){let n=e.file.split(`/`).pop()??``;if(t.fileName=n,!e.file.startsWith(`http://`)&&!e.file.startsWith(`https://`)){let t=this.options.attachments?.[n];t?e.file=t:this.options.noAttachmentRelocation||(e.file=this.data.canvasBaseDir+n)}}}),this.data.canvasData.edges.forEach(e=>{this.data.edgeMap[e.id]={ref:e,box:this.getEdgeBox(e)}}),this.resetView()};processBaseDir=e=>e?e?.slice(-1)===`/`?e:`${e}/`:`./`;getNodeBox=e=>({left:e.x,top:e.type===`file`||e.type===`group`?e.y-40:e.y,right:e.width+e.x,bottom:e.y+e.height});getEdgeBox=e=>{let t=this.data.nodeMap,r=t[e.fromNode].ref,i=t[e.toNode].ref,a=n.getAnchorCoord(r,e.fromSide),o=n.getAnchorCoord(i,e.toSide),s={left:Math.min(a.x,o.x),top:Math.min(a.y,o.y),right:Math.max(a.x,o.x),bottom:Math.max(a.y,o.y)},c=s.right-s.left,l=s.bottom-s.top,u=Math.min(c,l),d=Math.log2(Math.max(c,l)/(u===0?1:u))*10;return{left:s.left-d,top:s.top-d,right:s.right+d,bottom:s.bottom+d}};calculateNodeBounds(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;e.nodes.forEach(e=>{t=Math.min(t,e.x),n=Math.min(n,e.y),r=Math.max(r,e.x+e.width),i=Math.max(i,e.y+e.height)});let a=r-t,o=i-n,s=t+a/2,c=n+o/2;return{minX:t,minY:n,maxX:r,maxY:i,width:a,height:o,centerX:s,centerY:c}}toggleFullscreen=async e=>{!document.fullscreenElement&&(!e||e===`enter`)?(await this.data.container.requestFullscreen(),this.onToggleFullscreen(`enter`)):document.fullscreenElement&&(!e||e===`exit`)&&(await document.exitFullscreen(),this.onToggleFullscreen(`exit`))};resetView=()=>{let e=this.data.nodeBounds,t=this.data.container;if(!e||!t)return;let n=e.width+200,r=e.height+200,i=t.clientWidth,a=t.clientHeight,o=i/n,s=a/r,c=Math.round(Math.min(o,s)*1e3)/1e3,l=e.centerX,u=e.centerY,d={scale:c,offsetX:i/2-l*c,offsetY:a/2-u*c};this.data.offsetX=d.offsetX,this.data.offsetY=d.offsetY,this.data.scale=d.scale};middleViewer=()=>{let e=this.data.container;return{x:e.clientWidth/2,y:e.clientHeight/2,width:e.clientWidth,height:e.clientHeight}};dispose=()=>{this.data.container.remove()}};export{r as default};
1
+ import{BaseModule as e}from"./BaseModule.js";import t from"./styles.js";import{applyStyles as n,getAnchorCoord as r,makeHook as i}from"./utilities.js";var a=class extends e{onToggleFullscreen=i();data={canvasBaseDir:`./`,canvasData:{edges:[],nodes:[]},container:document.createElement(`div`),edgeMap:{},nodeBounds:{centerX:0,centerY:0,height:0,maxX:0,maxY:0,minX:0,minY:0,width:0},nodeMap:{},offsetX:0,offsetY:0,scale:1};constructor(...e){super(...e);let r=this.options.container;for(;r.firstElementChild;)r.firstElementChild.remove();r.innerHTML=``;let i=this.options.shadowed?r.attachShadow({mode:`open`}):r;n(i,t+this.options.extraCSS),this.data.container.classList.add(`JSON-Canvas-Viewer`),i.appendChild(this.data.container),this.augment({onToggleFullscreen:this.onToggleFullscreen,resetView:this.resetView,toggleFullscreen:this.toggleFullscreen}),this.onStart(this.start),this.onRestart(this.start),this.onDispose(this.dispose)}start=()=>{let e={edges:[],nodes:[],...this.options.canvas};Object.assign(this.data,{canvasBaseDir:this.processBaseDir(this.options.attachmentDir),canvasData:e,edgeMap:{},nodeBounds:this.calculateNodeBounds(e),nodeMap:{},offsetX:0,offsetY:0,scale:1}),this.data.canvasData.nodes.forEach(e=>{let t={box:this.getNodeBox(e),ref:e};if(this.data.nodeMap[e.id]=t,e.type===`file`){let n=e.file.split(`/`).pop()??``;if(t.fileName=n,!e.file.startsWith(`http://`)&&!e.file.startsWith(`https://`)){let t=this.options.attachments?.[n];t?e.file=t:this.options.noAttachmentRelocation||(e.file=this.data.canvasBaseDir+n)}}}),this.data.canvasData.edges.forEach(e=>{this.data.edgeMap[e.id]={box:this.getEdgeBox(e),ref:e}}),this.resetView()};processBaseDir=e=>e?e?.slice(-1)===`/`?e:`${e}/`:`./`;getNodeBox=e=>({bottom:e.y+e.height,left:e.x,right:e.width+e.x,top:e.type===`file`||e.type===`group`?e.y-40:e.y});getEdgeBox=e=>{let t=this.data.nodeMap,n=t[e.fromNode].ref,i=t[e.toNode].ref,a=r(n,e.fromSide),o=r(i,e.toSide),s={bottom:Math.max(a.y,o.y),left:Math.min(a.x,o.x),right:Math.max(a.x,o.x),top:Math.min(a.y,o.y)},c=s.right-s.left,l=s.bottom-s.top,u=Math.min(c,l),d=Math.log2(Math.max(c,l)/(u===0?1:u))*10;return{bottom:s.bottom+d,left:s.left-d,right:s.right+d,top:s.top-d}};calculateNodeBounds(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;e.nodes.forEach(e=>{t=Math.min(t,e.x),n=Math.min(n,e.y),r=Math.max(r,e.x+e.width),i=Math.max(i,e.y+e.height)});let a=r-t,o=i-n;return{centerX:t+a/2,centerY:n+o/2,height:o,maxX:r,maxY:i,minX:t,minY:n,width:a}}toggleFullscreen=async e=>{!document.fullscreenElement&&(!e||e===`enter`)?(await this.data.container.requestFullscreen(),this.onToggleFullscreen(`enter`)):document.fullscreenElement&&(!e||e===`exit`)&&(await document.exitFullscreen(),this.onToggleFullscreen(`exit`))};resetView=()=>{let e=this.data.nodeBounds,t=this.data.container;if(!e||!t)return;let n=e.width+200,r=e.height+200,i=t.clientWidth,a=t.clientHeight,o=i/n,s=a/r,c=Math.round(Math.min(o,s)*1e3)/1e3,l=e.centerX,u=e.centerY,d={offsetX:i/2-l*c,offsetY:a/2-u*c,scale:c};this.data.offsetX=d.offsetX,this.data.offsetY=d.offsetY,this.data.scale=d.scale};middleViewer=()=>{let e=this.data.container;return{height:e.clientHeight,width:e.clientWidth,x:e.clientWidth/2,y:e.clientHeight/2}};dispose=()=>{this.data.container.remove()}};export{a as default};
2
2
  //# sourceMappingURL=DataManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataManager.js","names":["utilities","style"],"sources":["../../src/kernel/DataManager.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { Box, NodeBounds } from '$/types';\nimport type { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from '@repo/shared';\nimport { type BaseArgs, BaseModule } from '$/BaseModule';\nimport style from '$/styles.scss?inline';\nimport utilities, { type Hook } from '$/utilities';\n\nconst INITIAL_VIEWPORT_PADDING = 100;\nconst NODE_LABEL_MARGIN = 40;\nconst EDGE_BOX_HEURISTICS_BASE_MARGIN = 10;\n\ninterface Options extends BaseOptions {\n\tshadowed?: boolean;\n\tcanvas?: JSONCanvas;\n\tattachmentDir?: string;\n\textraCSS?: string;\n\tattachments?: Record<string, string>;\n\tnoAttachmentRelocation?: boolean;\n}\n\ninterface Augmentation {\n\tresetView: DataManager['resetView'];\n\ttoggleFullscreen: DataManager['toggleFullscreen'];\n\tonToggleFullscreen: DataManager['onToggleFullscreen'];\n}\n\nexport interface NodeItem {\n\tref: JSONCanvasNode;\n\tbox: Box;\n\tfileName?: string;\n\tonBeforeUnmount?: Hook;\n\tonActive?: Hook;\n\tonLoseActive?: Hook;\n}\n\nexport interface EdgeItem {\n\tref: JSONCanvasEdge;\n\tbox: Box;\n\tcontrolPoints?: Array<number>;\n}\n\ntype NodeMap = Record<string, NodeItem>;\ntype EdgeMap = Record<string, EdgeItem>;\n\nexport default class DataManager extends BaseModule<Options, Augmentation> {\n\tonToggleFullscreen = utilities.makeHook<['enter' | 'exit']>();\n\n\tdata: {\n\t\tcanvasData: Required<JSONCanvas>;\n\t\tnodeMap: NodeMap;\n\t\tedgeMap: EdgeMap;\n\t\tcanvasBaseDir: string;\n\t\tnodeBounds: NodeBounds;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\tscale: number;\n\t\tcontainer: HTMLDivElement;\n\t} = {\n\t\tcanvasData: {\n\t\t\tnodes: [],\n\t\t\tedges: [],\n\t\t},\n\t\tnodeMap: {},\n\t\tedgeMap: {},\n\t\tcanvasBaseDir: './',\n\t\tnodeBounds: {\n\t\t\tmaxX: 0,\n\t\t\tmaxY: 0,\n\t\t\tminX: 0,\n\t\t\tminY: 0,\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\tcenterX: 0,\n\t\t\tcenterY: 0,\n\t\t},\n\t\toffsetX: 0,\n\t\toffsetY: 0,\n\t\tscale: 1,\n\t\tcontainer: document.createElement('div'),\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst viewerContainer = this.options.container;\n\t\twhile (viewerContainer.firstElementChild) viewerContainer.firstElementChild.remove();\n\t\tviewerContainer.innerHTML = '';\n\n\t\tconst realContainer = this.options.shadowed\n\t\t\t? viewerContainer.attachShadow({ mode: 'open' })\n\t\t\t: viewerContainer;\n\n\t\tutilities.applyStyles(realContainer, style + this.options.extraCSS);\n\n\t\tthis.data.container.classList.add('JSON-Canvas-Viewer');\n\t\trealContainer.appendChild(this.data.container);\n\n\t\tthis.augment({\n\t\t\tresetView: this.resetView,\n\t\t\ttoggleFullscreen: this.toggleFullscreen,\n\t\t\tonToggleFullscreen: this.onToggleFullscreen,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate start = () => {\n\t\tconst canvasData = Object.assign(\n\t\t\t{\n\t\t\t\tnodes: [],\n\t\t\t\tedges: [],\n\t\t\t},\n\t\t\tthis.options.canvas,\n\t\t);\n\n\t\tObject.assign(this.data, {\n\t\t\tcanvasData: canvasData,\n\t\t\tnodeMap: {},\n\t\t\tedgeMap: {},\n\t\t\tcanvasBaseDir: this.processBaseDir(this.options.attachmentDir),\n\t\t\tnodeBounds: this.calculateNodeBounds(canvasData),\n\t\t\toffsetX: 0,\n\t\t\toffsetY: 0,\n\t\t\tscale: 1,\n\t\t});\n\n\t\tthis.data.canvasData.nodes.forEach((node) => {\n\t\t\tconst item: NodeItem = {\n\t\t\t\tref: node,\n\t\t\t\tbox: this.getNodeBox(node),\n\t\t\t};\n\t\t\tthis.data.nodeMap[node.id] = item;\n\n\t\t\t// re-process attachments\n\t\t\tif (node.type === 'file') {\n\t\t\t\tconst path = node.file.split('/');\n\t\t\t\tconst fileName = path.pop() ?? '';\n\t\t\t\titem.fileName = fileName;\n\t\t\t\tif (!node.file.startsWith('http://') && !node.file.startsWith('https://')) {\n\t\t\t\t\tconst userDefinedAttachment = this.options.attachments?.[fileName];\n\t\t\t\t\tif (userDefinedAttachment) node.file = userDefinedAttachment;\n\t\t\t\t\telse if (!this.options.noAttachmentRelocation)\n\t\t\t\t\t\tnode.file = this.data.canvasBaseDir + fileName;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.data.canvasData.edges.forEach((edge) => {\n\t\t\tthis.data.edgeMap[edge.id] = {\n\t\t\t\tref: edge,\n\t\t\t\tbox: this.getEdgeBox(edge),\n\t\t\t};\n\t\t});\n\t\tthis.resetView();\n\t};\n\n\tprivate processBaseDir = (baseDir: string | undefined) => {\n\t\tif (!baseDir) return './';\n\t\tconst lastChar = baseDir?.slice(-1);\n\t\tif (lastChar === '/') return baseDir;\n\t\treturn `${baseDir}/`;\n\t};\n\n\tprivate getNodeBox = (node: JSONCanvasNode) => {\n\t\treturn {\n\t\t\tleft: node.x,\n\t\t\ttop:\n\t\t\t\tnode.type === 'file' || node.type === 'group' ? node.y - NODE_LABEL_MARGIN : node.y,\n\t\t\tright: node.width + node.x,\n\t\t\tbottom: node.y + node.height,\n\t\t};\n\t};\n\n\tprivate getEdgeBox = (edge: JSONCanvasEdge) => {\n\t\tconst nodes = this.data.nodeMap;\n\t\tconst from = nodes[edge.fromNode].ref;\n\t\tconst to = nodes[edge.toNode].ref;\n\t\tconst fromAnchor = utilities.getAnchorCoord(from, edge.fromSide);\n\t\tconst toAnchor = utilities.getAnchorCoord(to, edge.toSide);\n\t\tconst strictBox = {\n\t\t\tleft: Math.min(fromAnchor.x, toAnchor.x),\n\t\t\ttop: Math.min(fromAnchor.y, toAnchor.y),\n\t\t\tright: Math.max(fromAnchor.x, toAnchor.x),\n\t\t\tbottom: Math.max(fromAnchor.y, toAnchor.y),\n\t\t};\n\t\t// edge size heuristics\n\t\tconst width = strictBox.right - strictBox.left;\n\t\tconst height = strictBox.bottom - strictBox.top;\n\t\tconst _min = Math.min(width, height);\n\t\tconst min = _min === 0 ? 1 : _min;\n\t\tconst max = Math.max(width, height);\n\t\tconst edgeFactor = Math.log2(max / min);\n\t\tconst margin = edgeFactor * EDGE_BOX_HEURISTICS_BASE_MARGIN;\n\t\treturn {\n\t\t\tleft: strictBox.left - margin,\n\t\t\ttop: strictBox.top - margin,\n\t\t\tright: strictBox.right + margin,\n\t\t\tbottom: strictBox.bottom + margin,\n\t\t};\n\t};\n\n\tprivate calculateNodeBounds(canvasData: Required<JSONCanvas>) {\n\t\tlet minX = Infinity,\n\t\t\tminY = Infinity,\n\t\t\tmaxX = -Infinity,\n\t\t\tmaxY = -Infinity;\n\t\tcanvasData.nodes.forEach((node) => {\n\t\t\tminX = Math.min(minX, node.x);\n\t\t\tminY = Math.min(minY, node.y);\n\t\t\tmaxX = Math.max(maxX, node.x + node.width);\n\t\t\tmaxY = Math.max(maxY, node.y + node.height);\n\t\t});\n\t\tconst width = maxX - minX;\n\t\tconst height = maxY - minY;\n\t\tconst centerX = minX + width / 2;\n\t\tconst centerY = minY + height / 2;\n\t\treturn { minX, minY, maxX, maxY, width, height, centerX, centerY };\n\t}\n\ttoggleFullscreen = async (option?: 'enter' | 'exit') => {\n\t\tif (!document.fullscreenElement && (!option || option === 'enter')) {\n\t\t\tawait this.data.container.requestFullscreen();\n\t\t\tthis.onToggleFullscreen('enter');\n\t\t} else if (document.fullscreenElement && (!option || option === 'exit')) {\n\t\t\tawait document.exitFullscreen();\n\t\t\tthis.onToggleFullscreen('exit');\n\t\t}\n\t};\n\tresetView = () => {\n\t\tconst bounds = this.data.nodeBounds;\n\t\tconst container = this.data.container;\n\t\tif (!bounds || !container) return;\n\t\tconst contentWidth = bounds.width + INITIAL_VIEWPORT_PADDING * 2;\n\t\tconst contentHeight = bounds.height + INITIAL_VIEWPORT_PADDING * 2;\n\t\t// Use logical dimensions for scaling calculations\n\t\tconst viewWidth = container.clientWidth;\n\t\tconst viewHeight = container.clientHeight;\n\t\tconst scaleX = viewWidth / contentWidth;\n\t\tconst scaleY = viewHeight / contentHeight;\n\t\tconst newScale = Math.round(Math.min(scaleX, scaleY) * 1000) / 1000;\n\t\tconst contentCenterX = bounds.centerX;\n\t\tconst contentCenterY = bounds.centerY;\n\t\tconst initialView = {\n\t\t\tscale: newScale,\n\t\t\toffsetX: viewWidth / 2 - contentCenterX * newScale,\n\t\t\toffsetY: viewHeight / 2 - contentCenterY * newScale,\n\t\t};\n\t\tthis.data.offsetX = initialView.offsetX;\n\t\tthis.data.offsetY = initialView.offsetY;\n\t\tthis.data.scale = initialView.scale;\n\t};\n\n\tmiddleViewer = () => {\n\t\tconst container = this.data.container;\n\t\treturn {\n\t\t\tx: container.clientWidth / 2,\n\t\t\ty: container.clientHeight / 2,\n\t\t\twidth: container.clientWidth,\n\t\t\theight: container.clientHeight,\n\t\t};\n\t};\n\n\tprivate dispose = () => {\n\t\tthis.data.container.remove();\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataManager.js","names":["style"],"sources":["../../src/kernel/DataManager.ts"],"sourcesContent":["import type { BaseOptions } from '$';\nimport type { BaseArgs } from '$/BaseModule';\nimport type { Box, NodeBounds } from '$/types';\nimport type { Hook } from '$/utilities';\nimport type { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from '@repo/shared';\nimport { BaseModule } from '$/BaseModule';\nimport style from '$/styles.scss?inline';\nimport { applyStyles, getAnchorCoord, makeHook } from '$/utilities';\n\nconst INITIAL_VIEWPORT_PADDING = 100;\nconst NODE_LABEL_MARGIN = 40;\nconst EDGE_BOX_HEURISTICS_BASE_MARGIN = 10;\n\ntype Options = {\n\tshadowed?: boolean;\n\tcanvas?: JSONCanvas;\n\tattachmentDir?: string;\n\textraCSS?: string;\n\tattachments?: Record<string, string>;\n\tnoAttachmentRelocation?: boolean;\n} & BaseOptions;\n\ntype Augmentation = {\n\tresetView: DataManager['resetView'];\n\ttoggleFullscreen: DataManager['toggleFullscreen'];\n\tonToggleFullscreen: DataManager['onToggleFullscreen'];\n};\n\nexport type NodeItem = {\n\tref: JSONCanvasNode;\n\tbox: Box;\n\tfileName?: string;\n\tonBeforeUnmount?: Hook;\n\tonActive?: Hook;\n\tonLoseActive?: Hook;\n};\n\nexport type EdgeItem = {\n\tref: JSONCanvasEdge;\n\tbox: Box;\n\tcontrolPoints?: Array<number>;\n};\n\ntype NodeMap = Record<string, NodeItem>;\ntype EdgeMap = Record<string, EdgeItem>;\n\nexport default class DataManager extends BaseModule<Options, Augmentation> {\n\tonToggleFullscreen = makeHook<['enter' | 'exit']>();\n\n\tdata: {\n\t\tcanvasData: Required<JSONCanvas>;\n\t\tnodeMap: NodeMap;\n\t\tedgeMap: EdgeMap;\n\t\tcanvasBaseDir: string;\n\t\tnodeBounds: NodeBounds;\n\t\toffsetX: number;\n\t\toffsetY: number;\n\t\tscale: number;\n\t\tcontainer: HTMLDivElement;\n\t} = {\n\t\tcanvasBaseDir: './',\n\t\tcanvasData: {\n\t\t\tedges: [],\n\t\t\tnodes: [],\n\t\t},\n\t\tcontainer: document.createElement('div'),\n\t\tedgeMap: {},\n\t\tnodeBounds: {\n\t\t\tcenterX: 0,\n\t\t\tcenterY: 0,\n\t\t\theight: 0,\n\t\t\tmaxX: 0,\n\t\t\tmaxY: 0,\n\t\t\tminX: 0,\n\t\t\tminY: 0,\n\t\t\twidth: 0,\n\t\t},\n\t\tnodeMap: {},\n\t\toffsetX: 0,\n\t\toffsetY: 0,\n\t\tscale: 1,\n\t};\n\n\tconstructor(...args: BaseArgs) {\n\t\tsuper(...args);\n\t\tconst viewerContainer = this.options.container;\n\t\twhile (viewerContainer.firstElementChild) viewerContainer.firstElementChild.remove();\n\t\tviewerContainer.innerHTML = '';\n\n\t\tconst realContainer = this.options.shadowed\n\t\t\t? viewerContainer.attachShadow({ mode: 'open' })\n\t\t\t: viewerContainer;\n\n\t\tapplyStyles(realContainer, style + this.options.extraCSS);\n\n\t\tthis.data.container.classList.add('JSON-Canvas-Viewer');\n\t\trealContainer.appendChild(this.data.container);\n\n\t\tthis.augment({\n\t\t\tonToggleFullscreen: this.onToggleFullscreen,\n\t\t\tresetView: this.resetView,\n\t\t\ttoggleFullscreen: this.toggleFullscreen,\n\t\t});\n\t\tthis.onStart(this.start);\n\t\tthis.onRestart(this.start);\n\t\tthis.onDispose(this.dispose);\n\t}\n\n\tprivate readonly start = () => {\n\t\tconst canvasData = {\n\t\t\tedges: [],\n\t\t\tnodes: [],\n\t\t\t...this.options.canvas,\n\t\t};\n\n\t\tObject.assign(this.data, {\n\t\t\tcanvasBaseDir: this.processBaseDir(this.options.attachmentDir),\n\t\t\tcanvasData,\n\t\t\tedgeMap: {},\n\t\t\tnodeBounds: this.calculateNodeBounds(canvasData),\n\t\t\tnodeMap: {},\n\t\t\toffsetX: 0,\n\t\t\toffsetY: 0,\n\t\t\tscale: 1,\n\t\t});\n\n\t\tthis.data.canvasData.nodes.forEach((node) => {\n\t\t\tconst item: NodeItem = {\n\t\t\t\tbox: this.getNodeBox(node),\n\t\t\t\tref: node,\n\t\t\t};\n\t\t\tthis.data.nodeMap[node.id] = item;\n\n\t\t\t// Re-process attachments\n\t\t\tif (node.type === 'file') {\n\t\t\t\tconst path = node.file.split('/');\n\t\t\t\tconst fileName = path.pop() ?? '';\n\t\t\t\titem.fileName = fileName;\n\t\t\t\tif (!node.file.startsWith('http://') && !node.file.startsWith('https://')) {\n\t\t\t\t\tconst userDefinedAttachment = this.options.attachments?.[fileName];\n\t\t\t\t\tif (userDefinedAttachment) node.file = userDefinedAttachment;\n\t\t\t\t\telse if (!this.options.noAttachmentRelocation)\n\t\t\t\t\t\tnode.file = this.data.canvasBaseDir + fileName;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.data.canvasData.edges.forEach((edge) => {\n\t\t\tthis.data.edgeMap[edge.id] = {\n\t\t\t\tbox: this.getEdgeBox(edge),\n\t\t\t\tref: edge,\n\t\t\t};\n\t\t});\n\t\tthis.resetView();\n\t};\n\n\tprivate readonly processBaseDir = (baseDir?: string) => {\n\t\tif (!baseDir) return './';\n\t\tconst lastChar = baseDir?.slice(-1);\n\t\tif (lastChar === '/') return baseDir;\n\t\treturn `${baseDir}/`;\n\t};\n\n\tprivate readonly getNodeBox = (node: JSONCanvasNode) => ({\n\t\tbottom: node.y + node.height,\n\t\tleft: node.x,\n\t\tright: node.width + node.x,\n\t\ttop: node.type === 'file' || node.type === 'group' ? node.y - NODE_LABEL_MARGIN : node.y,\n\t});\n\n\tprivate readonly getEdgeBox = (edge: JSONCanvasEdge) => {\n\t\tconst nodes = this.data.nodeMap;\n\t\tconst from = nodes[edge.fromNode].ref;\n\t\tconst to = nodes[edge.toNode].ref;\n\t\tconst fromAnchor = getAnchorCoord(from, edge.fromSide);\n\t\tconst toAnchor = getAnchorCoord(to, edge.toSide);\n\t\tconst strictBox = {\n\t\t\tbottom: Math.max(fromAnchor.y, toAnchor.y),\n\t\t\tleft: Math.min(fromAnchor.x, toAnchor.x),\n\t\t\tright: Math.max(fromAnchor.x, toAnchor.x),\n\t\t\ttop: Math.min(fromAnchor.y, toAnchor.y),\n\t\t};\n\t\t// Edge size heuristics\n\t\tconst width = strictBox.right - strictBox.left;\n\t\tconst height = strictBox.bottom - strictBox.top;\n\t\tconst _min = Math.min(width, height);\n\t\tconst min = _min === 0 ? 1 : _min;\n\t\tconst max = Math.max(width, height);\n\t\tconst edgeFactor = Math.log2(max / min);\n\t\tconst margin = edgeFactor * EDGE_BOX_HEURISTICS_BASE_MARGIN;\n\t\treturn {\n\t\t\tbottom: strictBox.bottom + margin,\n\t\t\tleft: strictBox.left - margin,\n\t\t\tright: strictBox.right + margin,\n\t\t\ttop: strictBox.top - margin,\n\t\t};\n\t};\n\n\tprivate calculateNodeBounds(canvasData: Required<JSONCanvas>) {\n\t\tlet minX = Infinity,\n\t\t\tminY = Infinity,\n\t\t\tmaxX = -Infinity,\n\t\t\tmaxY = -Infinity;\n\t\tcanvasData.nodes.forEach((node) => {\n\t\t\tminX = Math.min(minX, node.x);\n\t\t\tminY = Math.min(minY, node.y);\n\t\t\tmaxX = Math.max(maxX, node.x + node.width);\n\t\t\tmaxY = Math.max(maxY, node.y + node.height);\n\t\t});\n\t\tconst width = maxX - minX;\n\t\tconst height = maxY - minY;\n\t\tconst centerX = minX + width / 2;\n\t\tconst centerY = minY + height / 2;\n\t\treturn { centerX, centerY, height, maxX, maxY, minX, minY, width };\n\t}\n\ttoggleFullscreen = async (option?: 'enter' | 'exit') => {\n\t\tif (!document.fullscreenElement && (!option || option === 'enter')) {\n\t\t\tawait this.data.container.requestFullscreen();\n\t\t\tthis.onToggleFullscreen('enter');\n\t\t} else if (document.fullscreenElement && (!option || option === 'exit')) {\n\t\t\tawait document.exitFullscreen();\n\t\t\tthis.onToggleFullscreen('exit');\n\t\t}\n\t};\n\tresetView = () => {\n\t\tconst bounds = this.data.nodeBounds;\n\t\tconst container = this.data.container;\n\t\tif (!bounds || !container) return;\n\t\tconst contentWidth = bounds.width + INITIAL_VIEWPORT_PADDING * 2;\n\t\tconst contentHeight = bounds.height + INITIAL_VIEWPORT_PADDING * 2;\n\t\t// Use logical dimensions for scaling calculations\n\t\tconst viewWidth = container.clientWidth;\n\t\tconst viewHeight = container.clientHeight;\n\t\tconst scaleX = viewWidth / contentWidth;\n\t\tconst scaleY = viewHeight / contentHeight;\n\t\tconst newScale = Math.round(Math.min(scaleX, scaleY) * 1000) / 1000;\n\t\tconst contentCenterX = bounds.centerX;\n\t\tconst contentCenterY = bounds.centerY;\n\t\tconst initialView = {\n\t\t\toffsetX: viewWidth / 2 - contentCenterX * newScale,\n\t\t\toffsetY: viewHeight / 2 - contentCenterY * newScale,\n\t\t\tscale: newScale,\n\t\t};\n\t\tthis.data.offsetX = initialView.offsetX;\n\t\tthis.data.offsetY = initialView.offsetY;\n\t\tthis.data.scale = initialView.scale;\n\t};\n\n\tmiddleViewer = () => {\n\t\tconst container = this.data.container;\n\t\treturn {\n\t\t\theight: container.clientHeight,\n\t\t\twidth: container.clientWidth,\n\t\t\tx: container.clientWidth / 2,\n\t\t\ty: container.clientHeight / 2,\n\t\t};\n\t};\n\n\tprivate readonly dispose = () => {\n\t\tthis.data.container.remove();\n\t};\n}\n"],"mappings":"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"}
@@ -6,25 +6,25 @@ import { Click, Drag, Lubricator, MultitouchPanZoom, Options, PointeractInterfac
6
6
 
7
7
  //#region src/kernel/InteractionHandler.d.ts
8
8
  type LoadedModules = [Click, Drag, WheelPanZoom, PreventDefault, MultitouchPanZoom, Lubricator];
9
- interface Options$1 extends BaseOptions {
9
+ type Options$1 = {
10
10
  pointeract?: Options<LoadedModules>;
11
- }
12
- interface Augmentation {
11
+ } & BaseOptions;
12
+ type Augmentation = {
13
13
  pan: InteractionHandler['pan'];
14
14
  panToCoords: InteractionHandler['panToCoords'];
15
15
  zoom: InteractionHandler['zoom'];
16
16
  zoomToScale: InteractionHandler['zoomToScale'];
17
- }
17
+ };
18
18
  declare class InteractionHandler extends BaseModule<Options$1, Augmentation> {
19
19
  pointeract: PointeractInterface<LoadedModules>;
20
- private DM;
21
- onClick: Hook<[string | null], false>;
20
+ private readonly DM;
21
+ onClick: Hook<[string | undefined], false>;
22
22
  constructor(...args: BaseArgs);
23
- private start;
24
- private startInteract;
25
- private stopInteract;
26
- private onPan;
27
- private onZoom;
23
+ private readonly start;
24
+ private readonly startInteract;
25
+ private readonly stopInteract;
26
+ private readonly onPan;
27
+ private readonly onZoom;
28
28
  trueZoom: (_factor: number, origin: Coordinates) => void;
29
29
  truePan: ({
30
30
  x,
@@ -40,11 +40,11 @@ declare class InteractionHandler extends BaseModule<Options$1, Augmentation> {
40
40
  x,
41
41
  y
42
42
  }: Coordinates) => void;
43
- private C2C;
44
- private onTrueClick;
45
- private isUIControl;
46
- private findNodeId;
47
- private dispose;
43
+ private readonly C2C;
44
+ private readonly onTrueClick;
45
+ private readonly isUIControl;
46
+ private readonly findNodeId;
47
+ private readonly dispose;
48
48
  }
49
49
  //#endregion
50
50
  export { InteractionHandler };