json-canvas-viewer 3.2.0 → 3.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.
- package/README.md +2 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/baseModule.d.ts +3 -4
- package/dist/types/controls/index.d.ts +1 -1
- package/dist/types/dataManager.d.ts +2 -3
- package/dist/types/declarations.d.ts +21 -14
- package/dist/types/index.d.ts +2 -0
- package/dist/types/interactionHandler.d.ts +2 -7
- package/dist/types/overlayManager.d.ts +8 -3
- package/dist/types/renderToString.d.ts +2 -0
- package/dist/types/shared.d.ts +0 -12
- package/dist/types/utilities.d.ts +10 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -15,7 +15,8 @@ A **TypeScript-based** viewer for **JSON Canvas** files. View and interact with
|
|
|
15
15
|
|
|
16
16
|
This project is derived from [sofanati-nour/obsidian-canvas-web-renderer](https://github.com/sofanati-nour/obsidian-canvas-web-renderer), but is far more developed and optimized.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
- **Documentation**: [project wiki](https://github.com/hesprs/json-canvas-viewer/wiki)
|
|
19
|
+
- **More about JSON Canvas**: [jsoncanvas.org](https://jsoncanvas.org/)
|
|
19
20
|
|
|
20
21
|
## 🐶 Features
|
|
21
22
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("pointeract"),e=require("dompurify"),i=require("micromark"),n=require("micromark-extension-gfm");class s{constructor(t,e,i){this.container=t,this.utilities=i,Object.assign(this.options,e)}options={};dispose}function o(t){return"function"==typeof t}function r(t){const e=[];let i=t;for(;Object.getPrototypeOf(i).name;){const t=Object.getPrototypeOf(i);e.push(t),i=t}return e}function a(t){if(null==t)throw Error("Expected value to be not null or undefined");return t}function l(t,e){if(t.length>1)throw e();const i=t.at(0);if(void 0===i)throw e();return i}function c(t){return o(t)}function h(t){return"provide"in t&&"useClass"in t}function d(t){return"provide"in t&&"useFactory"in t}function p(t){return d(t)&&!0===t.async}function u(t){return"provide"in t&&"useExisting"in t}function m(t){return"provide"in t&&"multi"in t&&!0===t.multi}class f{description;options;constructor(t,e){this.description=t,this.options=e}toString(){return`InjectionToken "${String(this.description)}"`}}function g(t){return o(t)}function v(t){return o(t)?t.name:"symbol"==typeof t?t.description??String(t):t instanceof f?t.toString():t}function x(t){return c(t)?t:t.provide}const w=Symbol("injectable");class b{container;underConstruction=[];constructor(t){this.container=t}construct(t,e){if(p(t))throw new y(e);try{if(this.underConstruction.includes(t)){const e=[...this.underConstruction,t].map(x).map(v);throw new C(e)}return this.underConstruction.push(t),this.doConstruct(t)}finally{this.underConstruction.pop()}}async constructAsync(t){try{if(this.underConstruction.includes(t)){const e=[...this.underConstruction,t].map(x).map(v);throw new C(e)}if(this.underConstruction.push(t),p(t))return[await t.useFactory(this.container)];if(h(t)||c(t)){const e=c(t)?()=>[new t]:()=>[new t.useClass];return async function(t,e,i){for(;;)try{return await e()}catch(n){if(!(n instanceof t))throw n;await i(n)}}(y,async()=>e(),async t=>{await this.container.getAsync(t.token,{multi:!0,optional:!0})})}return this.doConstruct(t)}finally{this.underConstruction.pop()}}doConstruct(t){return c(t)?[new t]:h(t)?[new t.useClass]:function(t){return"provide"in t&&"useValue"in t}(t)?[t.useValue]:d(t)?[t.useFactory(this.container)]:u(t)?this.container.get(t.useExisting,{multi:!0}):function(){throw new Error("invalid state")}()}}class y extends Error{token;constructor(t){super(`Some providers for token ${v(t)} are async, please use injectAsync() or container.getAsync() instead`),this.token=t}}class C extends Error{constructor(t){super(`Detected circular dependency: ${t.join(" -> ")}. Please change your dependency graph or use lazy injection instead.`)}}class M{container;constructor(t){this.container=t}run(t){const e=k;try{return k=this,t(this.container)}finally{k=e}}async runAsync(t){const e=k;try{return k=this,await t(this.container)}finally{k=e}}}let k=new class{run(){throw new _}runAsync(){throw new _}};function z(t){return new M(t)}class _ extends Error{constructor(){super("You can only invoke inject() or injectAsync() within an injection context")}}class D{providers=new Map;singletons=new Map;parent;factory;constructor(t){this.parent=t,this.factory=new b(this),this.bind({provide:D,useValue:this})}bindAll(...t){return t.forEach(t=>this.bind(t)),this}bind(t){const e=x(t);if(u(t)&&t.provide===t.useExisting)throw Error(`The provider for token ${v(e)} with "useExisting" cannot refer to itself.`);if(!u(t)&&this.singletons.has(e))throw Error(`Cannot bind a new provider for ${v(e)}, since the existing provider was already constructed.`);if(u(t)&&m(t)&&this.existingProviderAlreadyProvided(e,t.useExisting))return this;const i=this.providers.get(e)??[],n=m(t);if(n&&i.some(t=>!m(t)))throw Error(`Cannot bind ${v(e)} as multi-provider, since there is already a provider which is not a multi-provider.`);if(!n&&i.some(t=>m(t))&&!i.every(u))throw Error(`Cannot bind ${v(e)} as provider, since there are already provider(s) that are multi-providers.`);return this.providers.set(e,n?[...i,t]:[t]),g(e)&&(h(t)||c(t))&&function(t,e=2){const i=[];return t.some((n,s)=>{if(s+e>t.length)return!0;i.push(t.slice(s,s+e))}),i}([e,...r(e)]).forEach(([t,e])=>{const i={provide:e,useExisting:t,multi:!0},n=this.providers.get(e)??[];this.existingProviderAlreadyProvided(e,t)||this.providers.set(e,[...n,i])}),this}unbind(t){const e=x(t);return this.providers.delete(e),this.singletons.delete(e),this}unbindAll(){return this.providers.clear(),this.singletons.clear(),this}get(t,e){if(e?.lazy??!1)return()=>this.get(t,{...e,lazy:!1});this.autoBindIfNeeded(t);const i=e?.optional??!1;if(!this.providers.has(t)){if(this.parent)return this.parent.get(t,{...e,lazy:!1});if(i)return;throw Error(`No provider(s) found for ${v(t)}`)}const n=a(this.providers.get(t));this.singletons.has(t)||z(this).run(()=>{const e=n.flatMap(e=>this.factory.construct(e,t));this.singletons.set(t,e)});const s=a(this.singletons.get(t));return e?.multi??!1?s:l(s,()=>Error(`Requesting a single value for ${v(t)}, but multiple values were provided. Consider passing "{ multi: true }" to inject all values, or adjust your bindings accordingly.`))}getAsync(t,e){return e?.lazy??!1?()=>this.getAsync(t,{...e,lazy:!1}):async function(t){return await new Promise(e=>e(t()))}(async()=>{this.autoBindIfNeeded(t);const i=e?.optional??!1;if(!this.providers.has(t)){if(i)return;throw Error(`No provider(s) found for ${v(t)}`)}const n=a(this.providers.get(t));this.singletons.has(t)||await z(this).runAsync(async()=>{const e=await Promise.all(n.map(t=>this.factory.constructAsync(t)));this.singletons.set(t,e.flat())});const s=a(this.singletons.get(t));return e?.multi??!1?s:l(s,()=>new Error(`Requesting a single value for ${v(t)}, but multiple values were provided. Consider passing "{ multi: true }" to inject all values, or adjust your bindings accordingly.`))})}createChild(){return new D(this)}has(t){return this.providers.has(t)||(this.parent?.has(t)??!1)}autoBindIfNeeded(t){if(!this.singletons.has(t))if(g(t)&&t.hasOwnProperty(w)){const e=function(t){return t[w]}(t);e.filter(t=>!this.providers.has(t)).forEach(t=>{this.bind({provide:t,useClass:t,multi:!0})})}else if(!this.providers.has(t)&&function(t){return t instanceof f}(t)&&t.options?.factory){const e=t.options.async;e?e&&this.bind({provide:t,async:!0,useFactory:t.options.factory}):this.bind({provide:t,async:!1,useFactory:t.options.factory})}}existingProviderAlreadyProvided(t,e){return(this.providers.get(t)??[]).some(i=>u(i)&&i.provide===t&&i.useExisting===e)}}const E=new Error("[JSONCanvasViewer] This error is unexpected, probably caused by canvas file corruption. If you assure the error is not by accident, please contact the developer and show how to reproduce."),B=new Error("[JSONCanvasViewer] Resource hasn't been set up or has been disposed.");function P(){const t=(...e)=>{t.subs.forEach(t=>{t(...e)})};return t.subs=new Set,t.subscribe=e=>{t.subs.add(e)},t.unsubscribe=e=>{t.subs.delete(e)},t}const S=800;class L extends s{spatialGrid=null;hooks={onToggleFullscreen:P(),onCanvasFetched:P()};data={canvasData:void 0,nodeMap:{},canvasBaseDir:void 0,nodeBounds:void 0,offsetX:0,offsetY:0,scale:1,container:document.createElement("div")};loadCanvas=async()=>{const t=this.options.canvasPath;try{this.resolvePath(t),this.data.canvasData=await fetch(t).then(t=>t.json()),this.data.canvasData.nodes.forEach(t=>{if("file"===t.type&&t.file&&!t.file.includes("http")){const e=t.file.split("/");t.file=e[e.length-1]}this.data.nodeMap[t.id]=t}),this.data.nodeBounds=this.calculateNodeBounds(),this.buildSpatialGrid(),this.hooks.onCanvasFetched()}catch(e){console.error("Failed to load canvas data:",e)}};resolvePath=t=>{if(/^https?:\/\//.test(t))this.data.canvasBaseDir=t.substring(0,t.lastIndexOf("/")+1);else{const e=t.lastIndexOf("/");this.data.canvasBaseDir=-1!==e?t.substring(0,e+1):"./"}};findNodeAt=t=>{const{x:e,y:i}=this.C2W(this.C2C({x:t.x,y:t.y}));let n=[];if(this.spatialGrid){const t=`${Math.floor(e/S)},${Math.floor(i/S)}`;n=this.spatialGrid[t]||[]}else n=this.data.canvasData.nodes;for(const s of n)if(!(e<s.x||e>s.x+s.width||i<s.y||i>s.y+s.height||"non-interactive"===this.judgeInteract(s)))return s;return null};judgeInteract=t=>{switch(t?t.type:"default"){case"text":case"link":return"select";case"file":{const e=t?.file;if(!e)throw E;return e.match(/\.(md|wav|mp3)$/i)?"select":"non-interactive"}default:return"non-interactive"}};calculateNodeBounds(){let t=1/0,e=1/0,i=-1/0,n=-1/0;this.data.canvasData.nodes.forEach(s=>{t=Math.min(t,s.x),e=Math.min(e,s.y),i=Math.max(i,s.x+s.width),n=Math.max(n,s.y+s.height)});const s=i-t,o=n-e;return{minX:t,minY:e,maxX:i,maxY:n,width:s,height:o,centerX:t+s/2,centerY:e+o/2}}buildSpatialGrid(){const t=this.data.canvasData;if(!(t.nodes.length<50)){this.spatialGrid={};for(const e of t.nodes){const t=Math.floor(e.x/S),i=Math.floor((e.x+e.width)/S),n=Math.floor(e.y/S),s=Math.floor((e.y+e.height)/S);for(let o=t;o<=i;o++)for(let t=n;t<=s;t++){const i=`${o},${t}`;this.spatialGrid[i]||(this.spatialGrid[i]=[]),this.spatialGrid[i].push(e)}}}}zoom=(t,e)=>{const i=this.data.scale*t;this.zoomToScale(i,e)};zoomToScale=(t,e)=>{const i=Math.max(Math.min(t,20),.05),n=this.data.scale;if(i===n)return;const s=this.C2C(e);this.data.offsetX=e.x-s.x*i/n,this.data.offsetY=e.y-s.y*i/n,this.data.scale=i};pan=({x:t,y:e})=>{this.data.offsetX=this.data.offsetX+t,this.data.offsetY=this.data.offsetY+e};panToCoords=({x:t,y:e})=>{this.data.offsetX=t,this.data.offsetY=e};shiftFullscreen=(t="toggle")=>{document.fullscreenElement||"toggle"!==t&&"enter"!==t?!document.fullscreenElement||"toggle"!==t&&"exit"!==t||(document.exitFullscreen(),this.hooks.onToggleFullscreen(!1)):(this.data.container.requestFullscreen(),this.hooks.onToggleFullscreen(!0))};resetView=()=>{const t=this.data.nodeBounds,e=this.data.container;if(!t||!e)return;const i=t.width+200,n=t.height+200,s=e.clientWidth,o=e.clientHeight,r=s/i,a=o/n,l=Math.round(1e3*Math.min(r,a))/1e3,c={scale:l,offsetX:s/2-t.centerX*l,offsetY:o/2-t.centerY*l};this.data.offsetX=c.offsetX,this.data.offsetY=c.offsetY,this.data.scale=c.scale};C2C=({x:t,y:e})=>({x:t-this.data.offsetX,y:e-this.data.offsetY});C2W=({x:t,y:e})=>({x:t/this.data.scale,y:e/this.data.scale});middleViewer=()=>{const t=this.data.container;return{x:t.clientWidth/2,y:t.clientHeight/2,width:t.clientWidth,height:t.clientHeight}};dispose=()=>{this.data.container.remove()}}class I extends s{animationId=null;resizeAnimationId=null;DM;perFrame={lastScale:1,lastOffsets:{x:0,y:0}};lastResizeCenter={x:null,y:null};hooks={onResize:P(),onRefresh:P()};constructor(...t){super(...t),this.DM=this.container.get(L),this.DM.hooks.onCanvasFetched.subscribe(this.onFetched);const e=this.options.container;for(;e.firstElementChild;)e.firstElementChild.remove();e.innerHTML="";const i=this.options.noShadow||!1?e:e.attachShadow({mode:"open"});this.utilities.applyStyles(i,".full,.click-layer,.link-iframe,.audio{top:0;left:0;width:100%;height:100%;position:absolute}.flex-center,.overlay-container.markdown-content{display:flex;justify-content:center;align-items:center}.container{--contentTransition: color .2s, opacity .2s, text-shadow .2s, fill .2s;--containerTransition: background .2s, opacity .2s, box-shadow .2s, border .2s, filter .2s, backdrop-filter .2s;color:#fff;fill:#fff;stroke:#fff;position:relative;width:100%;height:100%;overflow:hidden;background-color:#141414}.container.numb,.container.numb *{pointer-events:none!important}.main-canvas{width:100%;height:100%;transform-origin:top left}.overlays{position:absolute;top:0;left:0;width:100%;height:100%;transform-origin:top left;will-change:transform}.parsed-content-wrapper{font-family:sans-serif;box-sizing:border-box;max-width:100%;max-height:100%;padding:10px 6px;pointer-events:none;overflow:hidden;scrollbar-gutter:stable both-edges;display:flex;flex-direction:column;gap:12px}@supports not (scrollbar-gutter: stable both-edges){.parsed-content-wrapper{padding:10px}}.overlay-container{position:absolute;box-sizing:border-box;border-radius:12px;overflow:hidden;-webkit-user-select:none;user-select:none;contain:strict;content-visibility:auto}.overlay-container:hover{box-shadow:0 2px 12px #00000080}.overlay-container{transition:var(--containerTransition)}.overlay-container .overlay-border{box-sizing:border-box;pointer-events:none;position:absolute;top:0;left:0;width:100%;height:100%;border-width:2px;border-style:solid;border-radius:12px;transition:var(--containerTransition)}.overlay-container img{width:100%;height:100%;object-fit:cover;pointer-events:none}.overlay-container.active .overlay-border{border:6px solid var(--active-color)}.overlay-container.markdown-content{position:absolute;padding:0 7px}.overlay-container.markdown-content.active .parsed-content-wrapper{overflow:auto;-webkit-user-select:text;user-select:text;pointer-events:auto}.overlay-container.markdown-content.rtl{direction:rtl;text-align:right}.link-iframe,.audio{border:none;background:transparent}.click-layer{background:transparent;pointer-events:auto}.active .click-layer{pointer-events:none}::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background-color:transparent}::-webkit-scrollbar-thumb{border-radius:2px;background:#ffffff40}::-webkit-scrollbar-thumb:hover{background:#1e1e1ebf}p{font-size:16px;line-height:21px}.parsed-content-wrapper img{width:100%;border-radius:8px}h1{font-size:25px}h2{font-size:23px}h3{font-size:22px}h4{font-size:20px}h5{font-size:19px}h6{font-size:17px}p,h1,h2,h3,h4,h5,h6,ol,ul{margin:0}h1,h2{font-weight:800}h3,h4{font-weight:700}h5,h6{font-weight:600}code{background:#ffffff1a;padding:2px 4px;border-radius:8px}pre code{display:block;box-sizing:border-box;width:100%}pre:has(code),table{margin:6px 0}strong{color:#fe8e7c}em{color:#5affb2}a{text-decoration:none;color:#6dadd0;font-weight:800;font-style:italic;cursor:pointer;transition:var(--contentTransition)}a:hover{color:#86d3fd}hr{height:1px;width:100%;background-color:#fff3;border:none}li{margin:5px 0}ul{padding-left:16px}ol{padding-left:15px;padding-right:7.5px}table{border-collapse:collapse;border-radius:8px;overflow:hidden;width:100%}table th,table td{border:1px solid rgba(255,255,255,.2);padding:6px 10px;background:#ffffff0f;text-align:left}table th{background:#ffffff1f;font-weight:700}");const n=this.DM.data.container;n.classList.add("container"),i.appendChild(n)}onFetched=()=>{this.DM.resetView(),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,this.perFrame.lastOffsets={x:this.DM.data.offsetX,y:this.DM.data.offsetY},this.hooks.onRefresh()};onResize=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{const t=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+t.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+t.y-this.lastResizeCenter.y),this.lastResizeCenter.x=t.x,this.lastResizeCenter.y=t.y,this.hooks.onResize(t.width,t.height),this.refresh()})};resizeObserver=new ResizeObserver(this.onResize);dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}}class O extends s{_overlaysLayer=document.createElement("div");overlays={};selectedId=null;eventListeners={};DM;IH;parser=t=>i.micromark(t,{extensions:[n.gfm()],htmlExtensions:[n.gfmHtml()]});get overlaysLayer(){if(!this._overlaysLayer)throw B;return this._overlaysLayer}hooks={onInteractionStart:P(),onInteractionEnd:P()};constructor(...t){super(...t),this.DM=this.container.get(L),this.IH=this.container.get(T,{lazy:!0});const e=this.container.get(I);this.DM.hooks.onCanvasFetched.subscribe(this.onFetched),e.hooks.onRefresh.subscribe(this.updateOverlays),this._overlaysLayer=document.createElement("div"),this._overlaysLayer.className="overlays",this.DM.data.container.appendChild(this.overlaysLayer)}onFetched=()=>{this.IH().onClick.subscribe(this.select);const t=this.DM.data.canvasBaseDir,e={text:t=>{if(!t.text)throw E;this.updateOrCreateOverlay(t,t.text,"text")},file:e=>{if(!e.file)throw E;e.file.match(/\.md$/i)?this.loadMarkdownForNode(e):e.file.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i)?this.updateOrCreateOverlay(e,t+e.file,"image"):e.file.match(/\.(mp3|wav)$/i)&&this.updateOrCreateOverlay(e,t+e.file,"audio")},link:t=>{if(!t.url)throw E;this.updateOrCreateOverlay(t,t.url,"link")},group:()=>{}};Object.values(this.DM.data.nodeMap).forEach(t=>{e[t.type](t)})};select=t=>{const e=this.selectedId?this.overlays[this.selectedId]:null,i=t?this.overlays[t]:null;e&&e.classList.remove("active"),i?(i.classList.add("active"),this.hooks.onInteractionStart()):this.hooks.onInteractionEnd(),this.selectedId=t};loadMarkdownForNode=async t=>{if(!t.mdContent){t.mdContent="Loading...",this.updateOrCreateOverlay(t,t.mdContent,"markdown");try{if(!t.file)throw E;const i=await fetch(this.DM.data.canvasBaseDir+t.file),n=await i.text(),s=n.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(s){const i=s[1].split("\n").reduce((t,e)=>{const[i,n]=e.split(":").map(t=>t.trim());return t[i]=n,t},{});t.mdContent=e.sanitize(this.parser(s[2].trim())),t.mdFrontmatter=i}else t.mdContent=e.sanitize(this.parser(n))}catch(i){console.error("[JSONCanvasViewer] Failed to load markdown:",i),t.mdContent="Failed to load content."}}this.updateOrCreateOverlay(t,t.mdContent,"markdown")};updateOverlays=()=>{const t=this.DM.data;this.overlaysLayer.style.transform=`translate(${t.offsetX}px, ${t.offsetY}px) scale(${t.scale})`};async updateOrCreateOverlay(t,e,i){let n=this.overlays[t.id];if(n||(n=await this.constructOverlay(t,e,i),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`),"none"===n.style.display&&(n.style.display="flex"),"markdown"===i){const e=n.getElementsByClassName("parsed-content-wrapper")[0];if(!t.mdContent)throw E;e.innerHTML!==t.mdContent&&(e.innerHTML=t.mdContent),n.classList.contains("rtl")||"rtl"!==t.mdFrontmatter?.direction||n.classList.add("rtl")}}async constructOverlay(t,i,n){const s=this.utilities.getColor(t.color),o=document.createElement("div");switch(o.classList.add("overlay-container"),o.id=t.id,o.style.backgroundColor=s.background,o.style.setProperty("--active-color",s.active),n){case"text":case"markdown":{o.classList.add("markdown-content");const t=document.createElement("div");t.innerHTML=e.sanitize(this.parser(i||"")),t.classList.add("parsed-content-wrapper"),o.appendChild(t);break}case"link":{const t=document.createElement("iframe");t.src=i,t.sandbox="allow-scripts allow-same-origin",t.className="link-iframe",t.loading="lazy",o.appendChild(t);break}case"audio":{const t=document.createElement("audio");t.className="audio",t.src=i,t.controls=!0,o.appendChild(t);break}case"image":{const t=document.createElement("img");t.src=i,t.loading="lazy",o.appendChild(t)}}switch(n){case"link":case"audio":{const t=document.createElement("div");t.className="click-layer",o.appendChild(t)}}const r=document.createElement("div");r.className="overlay-border",r.style.borderColor=s.border,o.appendChild(r);const a=()=>{t.id===this.selectedId&&this.hooks.onInteractionStart()},l=()=>{t.id===this.selectedId&&this.hooks.onInteractionEnd()};return o.addEventListener("pointerenter",a),o.addEventListener("pointerleave",l),o.addEventListener("touchstart",a),o.addEventListener("touchend",l),this.eventListeners[t.id]=[a,l],o}dispose=()=>{for(;this.overlaysLayer.firstElementChild;){const t=this.overlaysLayer.firstElementChild;if(this.eventListeners[t.id]){const e=this.eventListeners[t.id][0],i=this.eventListeners[t.id][1];if(!e||!i)throw B;t.removeEventListener("pointerenter",e),t.removeEventListener("pointerleave",i),t.removeEventListener("touchstart",e),t.removeEventListener("touchend",i),this.eventListeners[t.id][0]=null,this.eventListeners[t.id][1]=null}t.remove()}this.overlaysLayer.remove(),this._overlaysLayer=null}}class T extends s{pointeract;DM;OM;onClick=P();constructor(...e){super(...e),this.DM=this.container.get(L),this.OM=this.container.get(O);const i=Object.assign({proControlSchema:!1,zoomFactor:.1,lockControlSchema:!1},this.options.interactions||{});this.pointeract=new t.Pointeract(this.DM.data.container,[t.Click,t.Drag,t.WheelPanZoom,t.PreventDefault,t.MultitouchPanZoom],i),this.startInteraction=this.pointeract.start,this.stopInteraction=this.pointeract.stop;const n=this.container.get(O);n.hooks.onInteractionStart.subscribe(this.stopInteraction),n.hooks.onInteractionEnd.subscribe(this.startInteraction),this.DM.hooks.onCanvasFetched.subscribe(this.onFetched)}stopInteraction;startInteraction;onFetched=()=>{this.pointeract.on("pan",this.onPan),this.pointeract.on("drag",this.onPan),this.pointeract.on("zoom",this.onZoom),this.pointeract.on("trueClick",this.onTrueClick),this.pointeract.start()};onPan=t=>{this.DM.pan(t.detail)};onZoom=t=>{const e=t.detail;this.DM.zoom(e.factor,{x:e.x,y:e.y})};onTrueClick=t=>{const e=t.detail;if((i=t.detail.target)&&(i.closest(".controls")||i.closest("button")||i.closest("input")))return;var i;const n=this.DM.findNodeAt({x:e.x,y:e.y});this.onClick(n?n.id:null)};dispose=()=>{this.pointeract.off("pan",this.onPan),this.pointeract.off("zoom",this.onZoom),this.pointeract.off("trueClick",this.onTrueClick),this.pointeract.dispose()}}const F="#fff";class R extends s{_canvas;ctx;DM;zoomInOptimize={lastDrawnScale:0,lastDrawnViewport:{left:0,right:0,top:0,bottom:0},timeout:null,lastCallTime:0};get canvas(){if(null===this._canvas)throw B;return this._canvas}constructor(...t){super(...t);const e=this.container.get(I);e.hooks.onRefresh.subscribe(this.redraw),e.hooks.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(L),this._canvas=document.createElement("canvas"),this._canvas.className="main-canvas",this.ctx=this._canvas.getContext("2d"),this.DM.data.container.appendChild(this._canvas)}optimizeDPR=()=>{const t=this.DM.data.container;this.utilities.resizeCanvasForDPR(this.canvas,t.offsetWidth,t.offsetHeight)};redraw=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null);const t=Date.now(),e=this.DM.data.offsetX,i=this.DM.data.offsetY,n=this.DM.data.scale,s=this.getCurrentViewport(e,i,n);if(this.isViewportInside(s,this.zoomInOptimize.lastDrawnViewport)&&n!==this.zoomInOptimize.lastDrawnScale){if(t-this.zoomInOptimize.lastCallTime<500)return this.zoomInOptimize.timeout=setTimeout(()=>{this.trueRedraw(e,i,n,s),this.zoomInOptimize.lastCallTime=t,this.zoomInOptimize.timeout=null},60),void this.fakeRedraw(s,n)}this.zoomInOptimize.lastCallTime=t,this.trueRedraw(e,i,n,s)};trueRedraw(t,e,i,n){this.zoomInOptimize.lastDrawnViewport=n,this.zoomInOptimize.lastDrawnScale=i,this.canvas.style.transform="",this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(i,i);const s=this.DM.data.canvasData;s.nodes.forEach(t=>{switch(t.type){case"group":this.drawGroup(t,i);break;case"file":this.drawFileNode(t)}}),s.edges.forEach(t=>{this.drawEdge(t)}),this.ctx.restore()}fakeRedraw(t,e){const i=e/this.zoomInOptimize.lastDrawnScale,n=(this.zoomInOptimize.lastDrawnViewport.left-t.left)*e,s=(this.zoomInOptimize.lastDrawnViewport.top-t.top)*e;this.canvas.style.transform=`translate(${n}px, ${s}px) scale(${i})`}isViewportInside=(t,e)=>t.left>e.left&&t.top>e.top&&t.right<e.right&&t.bottom<e.bottom;getCurrentViewport=(t,e,i)=>{const n=-t/i,s=-e/i,o=this.DM.data.container;return{left:n,top:s,right:n+o.clientWidth/i,bottom:s+o.clientHeight/i}};drawLabelBar=(t,e,i,n,s)=>{const o=30*s,r=6*s,a=8*s,l=16*s,c=6*s;this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(1/s,1/s),this.ctx.font=`${l}px 'Inter', sans-serif`;const h=this.ctx.measureText(i).width+2*c;this.ctx.translate(0,-o-a),this.ctx.fillStyle=n,this.ctx.beginPath(),this.ctx.moveTo(r,0),this.ctx.lineTo(h-r,0),this.ctx.quadraticCurveTo(h,0,h,r),this.ctx.lineTo(h,o-r),this.ctx.quadraticCurveTo(h,o,h-r,o),this.ctx.lineTo(r,o),this.ctx.quadraticCurveTo(0,o,0,o-r),this.ctx.lineTo(0,r),this.ctx.quadraticCurveTo(0,0,r,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=F,this.ctx.fillText(i,c,.65*o),this.ctx.restore()};drawNodeBackground=t=>{const e=this.utilities.getColor(t.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=e.background,this.utilities.drawRoundRect(this.ctx,t.x+1,t.y+1,t.width-2,t.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=e.border,this.ctx.lineWidth=2,this.utilities.drawRoundRect(this.ctx,t.x,t.y,t.width,t.height,12),this.ctx.stroke()};drawGroup=(t,e)=>{this.drawNodeBackground(t),t.label&&this.drawLabelBar(t.x,t.y,t.label,this.utilities.getColor(t.color).border,e)};drawFileNode=t=>{if(!t.file)throw E;this.ctx.fillStyle=F,this.ctx.font="16px sans-serif",this.ctx.fillText(t.file,t.x+5,t.y-10)};drawEdge=t=>{const{fromNode:e,toNode:i}=this.getEdgeNodes(t);if(!e||!i)throw E;const n=this.utilities.getAnchorCoord,[s,o]=n(e,t.fromSide),[r,a]=n(i,t.toSide);let[l,c,h,d]=[0,0,0,0];if(t.controlPoints?[l,c,h,d]=t.controlPoints:([l,c,h,d]=this.getControlPoints(s,o,r,a,t.fromSide,t.toSide),t.controlPoints=[l,c,h,d]),this.drawCurvedPath(s,o,r,a,l,c,h,d),this.drawArrowhead(r,a,h,d),t.label){const e=.5,i=(1-e)**3*s+3*(1-e)**2*e*l+3*(1-e)*e*e*h+e**3*r,n=(1-e)**3*o+3*(1-e)**2*e*c+3*(1-e)*e*e*d+e**3*a;this.ctx.font="18px sans-serif";const p=8,u=this.ctx.measureText(t.label).width+2*p,m=20;this.ctx.fillStyle="#222",this.ctx.beginPath(),this.utilities.drawRoundRect(this.ctx,i-u/2,n-m/2-2,u,m,4),this.ctx.fill(),this.ctx.fillStyle="#ccc",this.ctx.textAlign="center",this.ctx.textBaseline="middle",this.ctx.fillText(t.label,i,n-2),this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic"}};getEdgeNodes=t=>({fromNode:this.DM.data.nodeMap[t.fromNode],toNode:this.DM.data.nodeMap[t.toNode]});getControlPoints=(t,e,i,n,s,o)=>{const r=i-t,a=n-e,l=Math.min(Math.abs(r),Math.abs(a))+.3*Math.max(Math.abs(r),Math.abs(a)),c=(h=.5*l,d=60,p=300,Math.max(d,Math.min(p,h)));var h,d,p;let u=t,m=e,f=i,g=n;switch(s){case"top":m=e-c;break;case"bottom":m=e+c;break;case"left":u=t-c;break;case"right":u=t+c}switch(o){case"top":g=n-c;break;case"bottom":g=n+c;break;case"left":f=i-c;break;case"right":f=i+c}return[u,m,f,g]};drawCurvedPath=(t,e,i,n,s,o,r,a)=>{this.ctx.beginPath(),this.ctx.moveTo(t,e),this.ctx.bezierCurveTo(s,o,r,a,i,n),this.ctx.strokeStyle="#ccc",this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(t,e,i,n)=>{const s=t-i,o=e-n,r=Math.sqrt(s*s+o*o);if(0===r)return;const a=s/r,l=o/r,c=t-12*a-7*l,h=e-12*l+7*a,d=t-12*a+7*l,p=e-12*l-7*a;this.ctx.beginPath(),this.ctx.fillStyle="#ccc",this.ctx.moveTo(t,e),this.ctx.lineTo(c,h),this.ctx.lineTo(d,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}}const N={round:function(t,e){const i=10**e;return Math.round(t*i)/i},resizeCanvasForDPR:function(t,e,i){const n=window.devicePixelRatio||1,s=t.getContext("2d");if(!s)throw E;t.width=Math.round(e*n),t.height=Math.round(i*n),s.setTransform(1,0,0,1,0,0),s.scale(n,n)},applyStyles:function(t,e){const i=document.createElement("style");i.innerHTML=e,t.appendChild(i)},drawRoundRect:function(t,e,i,n,s,o){t.beginPath(),t.moveTo(e+o,i),t.lineTo(e+n-o,i),t.quadraticCurveTo(e+n,i,e+n,i+o),t.lineTo(e+n,i+s-o),t.quadraticCurveTo(e+n,i+s,e+n-o,i+s),t.lineTo(e+o,i+s),t.quadraticCurveTo(e,i+s,e,i+s-o),t.lineTo(e,i+o),t.quadraticCurveTo(e,i,e+o,i),t.closePath()},getAnchorCoord:function(t,e){const i=t.x+t.width/2,n=t.y+t.height/2;switch(e){case"top":return[i,t.y];case"bottom":return[i,t.y+t.height];case"left":return[t.x,n];case"right":return[t.x+t.width,n];default:return[i,n]}},getColor:function(t="0"){let e=null;if(1===t.length)switch(t){case"1":e="rgba(255, 120, 129, ?)";break;case"2":e="rgba(251, 187, 131, ?)";break;case"3":e="rgba(255, 232, 139, ?)";break;case"4":e="rgba(124, 211, 124, ?)";break;case"5":e="rgba(134, 223, 226, ?)";break;case"6":e="rgba(203, 158, 255, ?)";break;default:e="rgba(140, 140, 140, ?)"}else{const i=function(t){const e=t.replace("#","");return{r:parseInt(e.substring(0,2),16),g:parseInt(e.substring(2,4),16),b:parseInt(e.substring(4,6),16)}}(t);e=`rgba(${i.r}, ${i.g}, ${i.b}, ?)`}return{border:e.replace("?","0.75"),background:e.replace("?","0.1"),active:e.replace("?","1")}}};const V={Controller:I,DataManager:L,InteractionHandler:T,Renderer:R,OverlayManager:O};exports.BaseModule=s,exports.Controls=class extends s{_controlsPanel=null;_toggleCollapseBtn=null;_toggleFullscreenBtn=null;_zoomOutBtn=null;_zoomSlider=null;_zoomInBtn=null;_resetViewBtn=null;DM;collapsed;get controlsPanel(){if(null===this._controlsPanel)throw B;return this._controlsPanel}get toggleCollapseBtn(){if(null===this._toggleCollapseBtn)throw B;return this._toggleCollapseBtn}get toggleFullscreenBtn(){if(null===this._toggleFullscreenBtn)throw B;return this._toggleFullscreenBtn}get zoomOutBtn(){if(null===this._zoomOutBtn)throw B;return this._zoomOutBtn}get zoomSlider(){if(null===this._zoomSlider)throw B;return this._zoomSlider}get zoomInBtn(){if(null===this._zoomInBtn)throw B;return this._zoomInBtn}get resetViewBtn(){if(null===this._resetViewBtn)throw B;return this._resetViewBtn}constructor(...t){super(...t),this.collapsed=this.options.controlsCollapsed||!1,this.DM=this.container.get(L),this.DM.hooks.onToggleFullscreen.subscribe(this.updateFullscreenBtn),this.container.get(I).hooks.onRefresh.subscribe(this.updateSlider),this._controlsPanel=document.createElement("div"),this._controlsPanel.className="controls",this._controlsPanel.classList.toggle("collapsed",this.collapsed),this.utilities.applyStyles(this._controlsPanel,".collapse-button{border-radius:8px;transition:transform .2s}.collapse-button:hover{background:#444c}button{cursor:pointer;font-size:18px;height:32px;border:none;transition:var(--containerTransition);text-align:center;background-color:#444;width:32px;padding:5px 0}button svg{width:100%;height:100%}.controls{position:absolute;top:10px;right:10px;display:flex;align-items:center;transition:transform .2s;border-radius:8px;gap:10px}.controls.collapsed{transform:translate(calc(100% - 32px))}.controls.collapsed .collapse-button{transform:rotate(180deg)}.controls .controls-content{display:flex;gap:1px;align-items:center;border-radius:8px;overflow:hidden;background:#333c}.controls button:hover{background:#555}.zoom-slider{width:100px;margin:0 10px}"),this._toggleCollapseBtn=document.createElement("button"),this._toggleCollapseBtn.className="collapse-button",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);const e=document.createElement("div");e.className="controls-content",this._toggleFullscreenBtn=document.createElement("button"),this._toggleFullscreenBtn.innerHTML='<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>',e.appendChild(this._toggleFullscreenBtn),this._zoomOutBtn=document.createElement("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>',e.appendChild(this._zoomOutBtn),this._zoomSlider=document.createElement("input"),this._zoomSlider.type="range",this._zoomSlider.className="zoom-slider",this._zoomSlider.min="-30",this._zoomSlider.max="30",this._zoomSlider.value="0",e.appendChild(this._zoomSlider),this._zoomInBtn=document.createElement("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>',e.appendChild(this._zoomInBtn),this._resetViewBtn=document.createElement("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>',e.appendChild(this._resetViewBtn),this._controlsPanel.appendChild(e),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)}toggleCollapse=()=>this.controlsPanel.classList.toggle("collapsed");zoomIn=()=>this.DM.zoom(1.1,this.DM.middleViewer());zoomOut=()=>this.DM.zoom(1/1.1,this.DM.middleViewer());slide=()=>this.DM.zoomToScale(1.1**Number(this.zoomSlider.value),this.DM.middleViewer());updateFullscreenBtn=t=>{this.toggleFullscreenBtn.innerHTML=t?'<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>':'<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>'};toggleFullscreen=()=>this.DM.shiftFullscreen("toggle");updateSlider=()=>{this.zoomSlider.value=String(this.scaleToSlider(this.DM.data.scale))};scaleToSlider=t=>Math.log(t)/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}},exports.DebugPanel=class extends s{_debugPanel=null;DM;get debugPanel(){if(!this._debugPanel)throw B;return this._debugPanel}constructor(...t){super(...t),this.DM=this.container.get(L),this.container.get(I).hooks.onRefresh.subscribe(this.update),this._debugPanel=document.createElement("div"),this._debugPanel.className="debug-panel";const e=this.DM.data.container;this.utilities.applyStyles(e,".debug-panel{position:absolute;bottom:12px;left:12px;background:#0006;border-radius:12px;padding:12px;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);color:#fff;font-size:calc(14px + .3vw);line-height:calc(17px + .3vw);pointer-events:none}"),e.appendChild(this._debugPanel)}update=()=>{const t=this.utilities.round,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=null}},exports.JSONCanvasViewer=class{options;allModules;container;constructor(t,e){this.container=new D,this.options=t;this.allModules=[L,I,O,T,R,...e||[]],this.allModules.forEach(t=>{this.container.bind({provide:t,useFactory:()=>new t(this.container,this.options,N)})}),this.allModules.forEach(t=>{this.container.get(t)}),this.container.get(L).loadCanvas()}dispose=()=>{const t=this.options.container;for(;t.firstChild;)t.firstChild.remove();this.allModules.reverse(),this.allModules.forEach(t=>{const e=this.container.get(t);e.dispose&&e.dispose()})}},exports.Minimap=class extends s{_minimapCtx=null;_viewportRectangle=null;_minimap=null;_minimapContainer=null;_toggleMinimapBtn=null;minimapCache={scale:1,centerX:0,centerY:0};DM;collapsed;get minimap(){if(null===this._minimap)throw B;return this._minimap}get minimapCtx(){if(null===this._minimapCtx)throw B;return this._minimapCtx}get viewportRectangle(){if(null===this._viewportRectangle)throw B;return this._viewportRectangle}get minimapContainer(){if(null===this._minimapContainer)throw B;return this._minimapContainer}get toggleMinimapBtn(){if(null===this._toggleMinimapBtn)throw B;return this._toggleMinimapBtn}constructor(...t){super(...t),this.collapsed=this.options.minimapCollapsed||!1,this.container.get(I).hooks.onRefresh.subscribe(this.updateViewportRectangle),this.DM=this.container.get(L),this.DM.hooks.onCanvasFetched.subscribe(this.drawMinimap),this._minimapContainer=document.createElement("div"),this._minimapContainer.className="minimap-container",this.utilities.applyStyles(this._minimapContainer,".collapse-button{border-radius:8px;transition:transform .2s}.collapse-button:hover{background:#444c}button{cursor:pointer;font-size:18px;height:32px;border:none;transition:var(--containerTransition);text-align:center;background-color:#444;width:32px;padding:5px 0}button svg{width:100%;height:100%}.minimap-container{position:absolute;bottom:10px;right:10px;display:flex;pointer-events:none;transition:transform .2s}.minimap-container.collapsed{transform:translate(calc(100% - 32px))}@media(max-width:768px){.minimap-container{transform:translateY(60px) translate(80px)}.minimap-container.collapsed{transform:translateY(60px) translate(calc(100% - 32px))}}.toggle-minimap{margin:auto 10px 0 0;pointer-events:auto}.collapsed .toggle-minimap{transform:rotate(180deg)}@media(max-width:768px){.toggle-minimap{transform:translateY(-60px)}.collapsed .toggle-minimap{transform:translateY(-60px) rotate(180deg)}}.minimap{position:relative;width:200px;height:150px;overflow:hidden;border-radius:12px;background:#202020;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);transform-origin:0 0}@media(max-width:768px){.minimap{transform:scale(.6)}}.minimap .minimap-canvas{width:100%;height:100%}.minimap .viewport-rectangle{position:absolute;top:0;left:0;pointer-events:none;border:2px solid #fff;border-radius:6px;box-sizing:border-box;background:transparent}"),this._toggleMinimapBtn=document.createElement("button"),this._toggleMinimapBtn.className="toggle-minimap collapse-button",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="minimap";const e=document.createElement("canvas");e.className="minimap-canvas",e.width=200,e.height=150,this._minimap.appendChild(e),this._minimapCtx=e.getContext("2d"),this._viewportRectangle=document.createElement("div"),this._viewportRectangle.className="viewport-rectangle",this._minimap.appendChild(this._viewportRectangle),this._minimapContainer.appendChild(this._minimap),this.DM.data.container.appendChild(this._minimapContainer),this._minimapContainer.classList.toggle("collapsed",this.collapsed),this._toggleMinimapBtn.addEventListener("click",this.toggleCollapse),this.utilities.resizeCanvasForDPR(e,e.width,e.height)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.minimapContainer.classList.toggle("collapsed",this.collapsed),this.collapsed||this.updateViewportRectangle()};drawMinimap=()=>{const t=this.DM.data.nodeBounds;if(!t)return;const e=this.minimap.clientWidth,i=this.minimap.clientHeight,n=e/t.width,s=i/t.height;this.minimapCache.scale=.9*Math.min(n,s),this.minimapCache.centerX=e/2,this.minimapCache.centerY=i/2,this.minimapCtx.clearRect(0,0,e,i),this.minimapCtx.save(),this.minimapCtx.translate(this.minimapCache.centerX,this.minimapCache.centerY),this.minimapCtx.scale(this.minimapCache.scale,this.minimapCache.scale),this.minimapCtx.translate(-t.centerX,-t.centerY);const o=this.DM.data.canvasData;for(const r of o.edges)this.drawMinimapEdge(r);for(const r of o.nodes)this.drawMinimapNode(r);this.minimapCtx.restore()};drawMinimapNode=t=>{const e=this.utilities.getColor(t.color);this.minimapCtx.fillStyle=e.border,this.minimapCtx.globalAlpha=.3,this.utilities.drawRoundRect(this.minimapCtx,t.x,t.y,t.width,t.height,25),this.minimapCtx.fill(),this.minimapCtx.globalAlpha=1};drawMinimapEdge=t=>{const e=this.DM.data.nodeMap,i=e[t.fromNode],n=e[t.toNode];if(!i||!n)return;const[s,o]=this.utilities.getAnchorCoord(i,t.fromSide),[r,a]=this.utilities.getAnchorCoord(n,t.toSide);this.minimapCtx.beginPath(),this.minimapCtx.moveTo(s,o),this.minimapCtx.lineTo(r,a),this.minimapCtx.strokeStyle="#555",this.minimapCtx.lineWidth=10,this.minimapCtx.stroke()};updateViewportRectangle=()=>{if(this.collapsed)return;const t=this.DM.data.nodeBounds,e=this.DM.data.container,i=this.DM.data.scale;if(!t)return;const n=e.clientWidth/i,s=e.clientHeight/i,o=-this.DM.data.offsetX/i+e.clientWidth/(2*i),r=-this.DM.data.offsetY/i+e.clientHeight/(2*i),a=this.minimapCache.centerX+(o-n/2-t.centerX)*this.minimapCache.scale,l=this.minimapCache.centerY+(r-s/2-t.centerY)*this.minimapCache.scale,c=n*this.minimapCache.scale,h=s*this.minimapCache.scale;this.viewportRectangle.style.left=`${a}px`,this.viewportRectangle.style.top=`${l}px`,this.viewportRectangle.style.width=`${c}px`,this.viewportRectangle.style.height=`${h}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}},exports.MistouchPreventer=class extends s{_preventionContainer=null;preventMt=!1;DM;preventMistouch={record:!1,lastX:0,lastY:0,initialX:0,initialY:0};get preventionContainer(){if(null===this._preventionContainer)throw B;return this._preventionContainer}constructor(...t){super(...t);const e=Object.assign({preventAtStart:!0,labelText:"Click on to unlock."},this.options.mistouchPreventer||{}),i=document.createElement("div");i.className="prevention-banner",i.textContent=e.labelText,this.DM=this.container.get(L),this._preventionContainer=document.createElement("div"),this._preventionContainer.className="prevention-container hidden",this.utilities.applyStyles(this._preventionContainer,".full,.prevention-container{top:0;left:0;width:100%;height:100%;position:absolute}.flex-center,.prevention-container{display:flex;justify-content:center;align-items:center}.prevention-container{overflow:visible;transition:background .2s,opacity .2s,box-shadow .2s,border .2s,filter .2s,backdrop-filter .2s}.prevention-container.hidden{pointer-events:none;opacity:0}.prevention-container .prevention-banner{background:#0006;border-radius:12px;padding:12px;margin:12px;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);color:#fff;font-size:calc(14px + .3vw);line-height:calc(17px + .3vw);text-align:center}"),this._preventionContainer.appendChild(i),this.DM.data.container.appendChild(this._preventionContainer),e.preventAtStart&&this.startPrevention(),window.addEventListener("pointerdown",this.onPointerDown),window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp)}onPointerDown=t=>{const e=this.DM.data.container.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?this.preventMt||this.startPrevention():this.preventMt&&(this.preventMistouch.initialX=t.clientX,this.preventMistouch.initialY=t.clientY,this.preventMistouch.lastX=t.clientX,this.preventMistouch.lastY=t.clientY,this.preventMistouch.record=!0)};onPointerMove=t=>{this.preventMistouch.record&&(this.preventMistouch.lastX=t.clientX,this.preventMistouch.lastY=t.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("hidden"),this.DM.data.container.classList.add("numb"),this.preventMt=!0};endPrevention=()=>{this.preventMt=!1,this.preventionContainer.classList.add("hidden"),setTimeout(()=>this.DM.data.container.classList.remove("numb"),50)};dispose=()=>{window.removeEventListener("pointerdown",this.onPointerDown),window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),this.preventionContainer.remove(),this._preventionContainer=null}},exports.developerSuite=V;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("pointeract"),e=require("micromark");class i{constructor(t,e){this.container=t,Object.assign(this.options,e)}options={};dispose}function n(t){return"function"==typeof t}function s(t){const e=[];let i=t;for(;Object.getPrototypeOf(i).name;){const t=Object.getPrototypeOf(i);e.push(t),i=t}return e}function o(t){if(null==t)throw Error("Expected value to be not null or undefined");return t}function a(t,e){if(t.length>1)throw e();const i=t.at(0);if(void 0===i)throw e();return i}function r(t){return n(t)}function l(t){return"provide"in t&&"useClass"in t}function c(t){return"provide"in t&&"useFactory"in t}function h(t){return c(t)&&!0===t.async}function d(t){return"provide"in t&&"useExisting"in t}function p(t){return"provide"in t&&"multi"in t&&!0===t.multi}class u{description;options;constructor(t,e){this.description=t,this.options=e}toString(){return`InjectionToken "${String(this.description)}"`}}function m(t){return n(t)}function f(t){return n(t)?t.name:"symbol"==typeof t?t.description??String(t):t instanceof u?t.toString():t}function g(t){return r(t)?t:t.provide}const v=Symbol("injectable");class x{container;underConstruction=[];constructor(t){this.container=t}construct(t,e){if(h(t))throw new b(e);try{if(this.underConstruction.includes(t)){const e=[...this.underConstruction,t].map(g).map(f);throw new w(e)}return this.underConstruction.push(t),this.doConstruct(t)}finally{this.underConstruction.pop()}}async constructAsync(t){try{if(this.underConstruction.includes(t)){const e=[...this.underConstruction,t].map(g).map(f);throw new w(e)}if(this.underConstruction.push(t),h(t))return[await t.useFactory(this.container)];if(l(t)||r(t)){const e=r(t)?()=>[new t]:()=>[new t.useClass];return async function(t,e,i){for(;;)try{return await e()}catch(n){if(!(n instanceof t))throw n;await i(n)}}(b,async()=>e(),async t=>{await this.container.getAsync(t.token,{multi:!0,optional:!0})})}return this.doConstruct(t)}finally{this.underConstruction.pop()}}doConstruct(t){return r(t)?[new t]:l(t)?[new t.useClass]:function(t){return"provide"in t&&"useValue"in t}(t)?[t.useValue]:c(t)?[t.useFactory(this.container)]:d(t)?this.container.get(t.useExisting,{multi:!0}):function(){throw new Error("invalid state")}()}}class b extends Error{token;constructor(t){super(`Some providers for token ${f(t)} are async, please use injectAsync() or container.getAsync() instead`),this.token=t}}class w extends Error{constructor(t){super(`Detected circular dependency: ${t.join(" -> ")}. Please change your dependency graph or use lazy injection instead.`)}}class y{container;constructor(t){this.container=t}run(t){const e=C;try{return C=this,t(this.container)}finally{C=e}}async runAsync(t){const e=C;try{return C=this,await t(this.container)}finally{C=e}}}let C=new class{run(){throw new k}runAsync(){throw new k}};function M(t){return new y(t)}class k extends Error{constructor(){super("You can only invoke inject() or injectAsync() within an injection context")}}class z{providers=new Map;singletons=new Map;parent;factory;constructor(t){this.parent=t,this.factory=new x(this),this.bind({provide:z,useValue:this})}bindAll(...t){return t.forEach(t=>this.bind(t)),this}bind(t){const e=g(t);if(d(t)&&t.provide===t.useExisting)throw Error(`The provider for token ${f(e)} with "useExisting" cannot refer to itself.`);if(!d(t)&&this.singletons.has(e))throw Error(`Cannot bind a new provider for ${f(e)}, since the existing provider was already constructed.`);if(d(t)&&p(t)&&this.existingProviderAlreadyProvided(e,t.useExisting))return this;const i=this.providers.get(e)??[],n=p(t);if(n&&i.some(t=>!p(t)))throw Error(`Cannot bind ${f(e)} as multi-provider, since there is already a provider which is not a multi-provider.`);if(!n&&i.some(t=>p(t))&&!i.every(d))throw Error(`Cannot bind ${f(e)} as provider, since there are already provider(s) that are multi-providers.`);return this.providers.set(e,n?[...i,t]:[t]),m(e)&&(l(t)||r(t))&&function(t,e=2){const i=[];return t.some((n,s)=>{if(s+e>t.length)return!0;i.push(t.slice(s,s+e))}),i}([e,...s(e)]).forEach(([t,e])=>{const i={provide:e,useExisting:t,multi:!0},n=this.providers.get(e)??[];this.existingProviderAlreadyProvided(e,t)||this.providers.set(e,[...n,i])}),this}unbind(t){const e=g(t);return this.providers.delete(e),this.singletons.delete(e),this}unbindAll(){return this.providers.clear(),this.singletons.clear(),this}get(t,e){if(e?.lazy??!1)return()=>this.get(t,{...e,lazy:!1});this.autoBindIfNeeded(t);const i=e?.optional??!1;if(!this.providers.has(t)){if(this.parent)return this.parent.get(t,{...e,lazy:!1});if(i)return;throw Error(`No provider(s) found for ${f(t)}`)}const n=o(this.providers.get(t));this.singletons.has(t)||M(this).run(()=>{const e=n.flatMap(e=>this.factory.construct(e,t));this.singletons.set(t,e)});const s=o(this.singletons.get(t));return e?.multi??!1?s:a(s,()=>Error(`Requesting a single value for ${f(t)}, but multiple values were provided. Consider passing "{ multi: true }" to inject all values, or adjust your bindings accordingly.`))}getAsync(t,e){return e?.lazy??!1?()=>this.getAsync(t,{...e,lazy:!1}):async function(t){return await new Promise(e=>e(t()))}(async()=>{this.autoBindIfNeeded(t);const i=e?.optional??!1;if(!this.providers.has(t)){if(i)return;throw Error(`No provider(s) found for ${f(t)}`)}const n=o(this.providers.get(t));this.singletons.has(t)||await M(this).runAsync(async()=>{const e=await Promise.all(n.map(t=>this.factory.constructAsync(t)));this.singletons.set(t,e.flat())});const s=o(this.singletons.get(t));return e?.multi??!1?s:a(s,()=>new Error(`Requesting a single value for ${f(t)}, but multiple values were provided. Consider passing "{ multi: true }" to inject all values, or adjust your bindings accordingly.`))})}createChild(){return new z(this)}has(t){return this.providers.has(t)||(this.parent?.has(t)??!1)}autoBindIfNeeded(t){if(!this.singletons.has(t))if(m(t)&&t.hasOwnProperty(v)){const e=function(t){return t[v]}(t);e.filter(t=>!this.providers.has(t)).forEach(t=>{this.bind({provide:t,useClass:t,multi:!0})})}else if(!this.providers.has(t)&&function(t){return t instanceof u}(t)&&t.options?.factory){const e=t.options.async;e?e&&this.bind({provide:t,async:!0,useFactory:t.options.factory}):this.bind({provide:t,async:!1,useFactory:t.options.factory})}}existingProviderAlreadyProvided(t,e){return(this.providers.get(t)??[]).some(i=>d(i)&&i.provide===t&&i.useExisting===e)}}const _={round:function(t,e){const i=10**e;return Math.round(t*i)/i},resizeCanvasForDPR:function(t,e,i){const n=window.devicePixelRatio||1,s=t.getContext("2d");if(!s)throw new Error("[JSONCanvasViewer] This error is unexpected, probably caused uncontrollable runtime errors. Please contact the developer and show how to reproduce.");t.width=Math.round(e*n),t.height=Math.round(i*n),s.setTransform(1,0,0,1,0,0),s.scale(n,n)},applyStyles:function(t,e){const i=document.createElement("style");i.innerHTML=e,t.appendChild(i)},drawRoundRect:function(t,e,i,n,s,o){t.beginPath(),t.moveTo(e+o,i),t.lineTo(e+n-o,i),t.quadraticCurveTo(e+n,i,e+n,i+o),t.lineTo(e+n,i+s-o),t.quadraticCurveTo(e+n,i+s,e+n-o,i+s),t.lineTo(e+o,i+s),t.quadraticCurveTo(e,i+s,e,i+s-o),t.lineTo(e,i+o),t.quadraticCurveTo(e,i,e+o,i),t.closePath()},getAnchorCoord:function(t,e){const i=t.x+t.width/2,n=t.y+t.height/2;switch(e){case"top":return[i,t.y];case"bottom":return[i,t.y+t.height];case"left":return[t.x,n];case"right":return[t.x+t.width,n];default:return[i,n]}},getColor:function(t="0"){let e=null;if(1===t.length)switch(t){case"1":e="rgba(255, 120, 129, ?)";break;case"2":e="rgba(251, 187, 131, ?)";break;case"3":e="rgba(255, 232, 139, ?)";break;case"4":e="rgba(124, 211, 124, ?)";break;case"5":e="rgba(134, 223, 226, ?)";break;case"6":e="rgba(203, 158, 255, ?)";break;default:e="rgba(140, 140, 140, ?)"}else{const i=function(t){const e=t.replace("#","");return{r:parseInt(e.substring(0,2),16),g:parseInt(e.substring(2,4),16),b:parseInt(e.substring(4,6),16)}}(t);e=`rgba(${i.r}, ${i.g}, ${i.b}, ?)`}return{border:e.replace("?","0.75"),background:e.replace("?","0.1"),active:e.replace("?","1")}},resolvePath:function(t){if(/^https?:\/\//.test(t))return t.substring(0,t.lastIndexOf("/")+1);{const e=t.lastIndexOf("/");return-1!==e?t.substring(0,e+1):"./"}},makeHook:function(){const t=(...e)=>{t.subs.forEach(t=>{t(...e)})};return t.subs=new Set,t.subscribe=e=>{t.subs.add(e)},t.unsubscribe=e=>{t.subs.delete(e)},t}};const D=800;class E extends i{spatialGrid=null;hooks={onToggleFullscreen:_.makeHook(),onCanvasFetched:_.makeHook()};data={canvasData:void 0,nodeMap:{},canvasBaseDir:void 0,nodeBounds:void 0,offsetX:0,offsetY:0,scale:1,container:document.createElement("div")};loadCanvas=async()=>{const t=this.options.canvasPath;try{this.data.canvasBaseDir=_.resolvePath(t),this.data.canvasData=Object.assign({nodes:[],edges:[]},await fetch(t).then(t=>t.json())),this.data.canvasData.nodes.forEach(t=>{if("file"===t.type&&!t.file.includes("http")){const e=t.file.split("/");t.file=e[e.length-1]}this.data.nodeMap[t.id]=t}),this.data.nodeBounds=this.calculateNodeBounds(),this.buildSpatialGrid(),this.hooks.onCanvasFetched()}catch(e){console.error("Failed to load canvas data:",e)}};findNodeAt=t=>{const{x:e,y:i}=this.C2W(this.C2C({x:t.x,y:t.y}));let n=[];if(this.spatialGrid){const t=`${Math.floor(e/D)},${Math.floor(i/D)}`;n=this.spatialGrid[t]||[]}else n=this.data.canvasData.nodes;for(const s of n)if(!(e<s.x||e>s.x+s.width||i<s.y||i>s.y+s.height||"non-interactive"===this.judgeInteract(s)))return s;return null};judgeInteract=t=>{switch(t?.type){case"text":case"link":return"select";case"file":return t.file.match(/\.(md|wav|mp3)$/i)?"select":"non-interactive";default:return"non-interactive"}};calculateNodeBounds(){let t=1/0,e=1/0,i=-1/0,n=-1/0;this.data.canvasData.nodes.forEach(s=>{t=Math.min(t,s.x),e=Math.min(e,s.y),i=Math.max(i,s.x+s.width),n=Math.max(n,s.y+s.height)});const s=i-t,o=n-e;return{minX:t,minY:e,maxX:i,maxY:n,width:s,height:o,centerX:t+s/2,centerY:e+o/2}}buildSpatialGrid(){const t=this.data.canvasData;if(!(t.nodes.length<50)){this.spatialGrid={};for(const e of t.nodes){const t=Math.floor(e.x/D),i=Math.floor((e.x+e.width)/D),n=Math.floor(e.y/D),s=Math.floor((e.y+e.height)/D);for(let o=t;o<=i;o++)for(let t=n;t<=s;t++){const i=`${o},${t}`;this.spatialGrid[i]||(this.spatialGrid[i]=[]),this.spatialGrid[i].push(e)}}}}zoom=(t,e)=>{const i=this.data.scale*t;this.zoomToScale(i,e)};zoomToScale=(t,e)=>{const i=Math.max(Math.min(t,20),.05),n=this.data.scale;if(i===n)return;const s=this.C2C(e);this.data.offsetX=e.x-s.x*i/n,this.data.offsetY=e.y-s.y*i/n,this.data.scale=i};pan=({x:t,y:e})=>{this.data.offsetX=this.data.offsetX+t,this.data.offsetY=this.data.offsetY+e};panToCoords=({x:t,y:e})=>{this.data.offsetX=t,this.data.offsetY=e};shiftFullscreen=(t="toggle")=>{document.fullscreenElement||"toggle"!==t&&"enter"!==t?!document.fullscreenElement||"toggle"!==t&&"exit"!==t||(document.exitFullscreen(),this.hooks.onToggleFullscreen(!1)):(this.data.container.requestFullscreen(),this.hooks.onToggleFullscreen(!0))};resetView=()=>{const t=this.data.nodeBounds,e=this.data.container;if(!t||!e)return;const i=t.width+200,n=t.height+200,s=e.clientWidth,o=e.clientHeight,a=s/i,r=o/n,l=Math.round(1e3*Math.min(a,r))/1e3,c={scale:l,offsetX:s/2-t.centerX*l,offsetY:o/2-t.centerY*l};this.data.offsetX=c.offsetX,this.data.offsetY=c.offsetY,this.data.scale=c.scale};C2C=({x:t,y:e})=>({x:t-this.data.offsetX,y:e-this.data.offsetY});C2W=({x:t,y:e})=>({x:t/this.data.scale,y:e/this.data.scale});middleViewer=()=>{const t=this.data.container;return{x:t.clientWidth/2,y:t.clientHeight/2,width:t.clientWidth,height:t.clientHeight}};dispose=()=>{this.data.container.remove()}}class B extends i{animationId=null;resizeAnimationId=null;DM;perFrame={lastScale:1,lastOffsets:{x:0,y:0}};lastResizeCenter={x:null,y:null};hooks={onResize:_.makeHook(),onRefresh:_.makeHook()};constructor(...t){super(...t),this.DM=this.container.get(E),this.DM.hooks.onCanvasFetched.subscribe(this.onFetched);const e=this.options.container;for(;e.firstElementChild;)e.firstElementChild.remove();e.innerHTML="";const i=this.options.noShadow||!1?e:e.attachShadow({mode:"open"});_.applyStyles(i,".full,.click-layer,.link-iframe,.audio{top:0;left:0;width:100%;height:100%;position:absolute}.flex-center,.overlay-container.markdown-content{display:flex;justify-content:center;align-items:center}.container{--contentTransition: color .2s, opacity .2s, text-shadow .2s, fill .2s;--containerTransition: background .2s, opacity .2s, box-shadow .2s, border .2s, filter .2s, backdrop-filter .2s;color:#fff;fill:#fff;stroke:#fff;position:relative;width:100%;height:100%;overflow:hidden;background-color:#141414}.container.numb,.container.numb *{pointer-events:none!important}.main-canvas{width:100%;height:100%;transform-origin:top left}.overlays{position:absolute;top:0;left:0;width:100%;height:100%;transform-origin:top left;will-change:transform}.parsed-content-wrapper{font-family:sans-serif;box-sizing:border-box;max-width:100%;max-height:100%;padding:10px 6px;pointer-events:none;overflow:hidden;scrollbar-gutter:stable both-edges;display:flex;flex-direction:column;gap:12px}@supports not (scrollbar-gutter: stable both-edges){.parsed-content-wrapper{padding:10px}}.overlay-container{position:absolute;box-sizing:border-box;border-radius:12px;overflow:hidden;-webkit-user-select:none;user-select:none;contain:strict;content-visibility:auto}.overlay-container:hover{box-shadow:0 2px 12px #00000080}.overlay-container{transition:var(--containerTransition)}.overlay-container .overlay-border{box-sizing:border-box;pointer-events:none;position:absolute;top:0;left:0;width:100%;height:100%;border-width:2px;border-style:solid;border-radius:12px;transition:var(--containerTransition)}.overlay-container img{width:100%;height:100%;object-fit:cover;pointer-events:none}.overlay-container.active .overlay-border{border:6px solid var(--active-color)}.overlay-container.markdown-content{position:absolute;padding:0 7px}.overlay-container.markdown-content.active .parsed-content-wrapper{overflow:auto;-webkit-user-select:text;user-select:text;pointer-events:auto}.overlay-container.markdown-content.rtl{direction:rtl;text-align:right}.link-iframe,.audio{border:none;background:transparent}.click-layer{background:transparent;pointer-events:auto}.active .click-layer{pointer-events:none}::-webkit-scrollbar{width:4px}::-webkit-scrollbar-track{background-color:transparent}::-webkit-scrollbar-thumb{border-radius:2px;background:#ffffff40}::-webkit-scrollbar-thumb:hover{background:#1e1e1ebf}p{font-size:16px;line-height:21px}.parsed-content-wrapper img{width:100%;border-radius:8px}h1{font-size:25px}h2{font-size:23px}h3{font-size:22px}h4{font-size:20px}h5{font-size:19px}h6{font-size:17px}p,h1,h2,h3,h4,h5,h6,ol,ul{margin:0}h1,h2{font-weight:800}h3,h4{font-weight:700}h5,h6{font-weight:600}code{background:#ffffff1a;padding:2px 4px;border-radius:8px}pre code{display:block;box-sizing:border-box;width:100%}pre:has(code),table{margin:6px 0}strong{color:#fe8e7c}em{color:#5affb2}a{text-decoration:none;color:#6dadd0;font-weight:800;font-style:italic;cursor:pointer;transition:var(--contentTransition)}a:hover{color:#86d3fd}hr{height:1px;width:100%;background-color:#fff3;border:none}li{margin:5px 0}ul{padding-left:16px}ol{padding-left:15px;padding-right:7.5px}table{border-collapse:collapse;border-radius:8px;overflow:hidden;width:100%}table th,table td{border:1px solid rgba(255,255,255,.2);padding:6px 10px;background:#ffffff0f;text-align:left}table th{background:#ffffff1f;font-weight:700}");const n=this.DM.data.container;n.classList.add("container"),i.appendChild(n)}onFetched=()=>{this.DM.resetView(),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,this.perFrame.lastOffsets={x:this.DM.data.offsetX,y:this.DM.data.offsetY},this.hooks.onRefresh()};onResize=()=>{this.resizeAnimationId=requestAnimationFrame(()=>{const t=this.DM.middleViewer();this.lastResizeCenter.x&&this.lastResizeCenter.y&&(this.DM.data.offsetX=this.DM.data.offsetX+t.x-this.lastResizeCenter.x,this.DM.data.offsetY=this.DM.data.offsetY+t.y-this.lastResizeCenter.y),this.lastResizeCenter.x=t.x,this.lastResizeCenter.y=t.y,this.hooks.onResize(t.width,t.height),this.refresh()})};resizeObserver=new ResizeObserver(this.onResize);dispose=()=>{this.animationId&&cancelAnimationFrame(this.animationId),this.resizeAnimationId&&cancelAnimationFrame(this.resizeAnimationId),this.resizeObserver.disconnect()}}const P=new Error("[JSONCanvasViewer] Resource hasn't been set up or has been disposed.");class S extends i{_overlaysLayer=document.createElement("div");overlays={};selectedId=null;eventListeners={};DM;IH;parse;get overlaysLayer(){if(!this._overlaysLayer)throw P;return this._overlaysLayer}hooks={onInteractionStart:_.makeHook(),onInteractionEnd:_.makeHook()};constructor(...t){super(...t),this.parse=t=>e.micromark(t,this.options.micromark),this.DM=this.container.get(E),this.IH=this.container.get(I,{lazy:!0});const i=this.container.get(B);this.DM.hooks.onCanvasFetched.subscribe(this.onFetched),i.hooks.onRefresh.subscribe(this.updateOverlays),this._overlaysLayer=document.createElement("div"),this._overlaysLayer.className="overlays",this.DM.data.container.appendChild(this.overlaysLayer)}onFetched=()=>{this.IH().onClick.subscribe(this.select);const t=this.DM.data.canvasBaseDir,e=async e=>{switch(e.type){case"text":this.updateOverlay(e,e.text,"text");break;case"file":e.file.match(/\.md$/i)?this.loadMarkdownForNode(e):e.file.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i)?this.updateOverlay(e,t+e.file,"image"):e.file.match(/\.(mp3|wav)$/i)&&this.updateOverlay(e,t+e.file,"audio");break;case"link":this.updateOverlay(e,e.url,"link")}};Object.values(this.DM.data.nodeMap).forEach(t=>{e(t)})};select=t=>{const e=this.selectedId?this.overlays[this.selectedId]:null,i=t?this.overlays[t]:null;e&&e.classList.remove("active"),i?(i.classList.add("active"),this.hooks.onInteractionStart()):this.hooks.onInteractionEnd(),this.selectedId=t};loadMarkdownForNode=async t=>{let e;this.updateOverlay(t,"Loading...","text");try{const i=await fetch(this.DM.data.canvasBaseDir+t.file),n=await i.text(),s=n.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);e=s?this.parse(s[2]):this.parse(n)}catch(i){console.error("[JSONCanvasViewer] Failed to load markdown:",i),e="Failed to load content."}this.updateOverlay(t,e,"text")};updateOverlays=()=>{const t=this.DM.data;this.overlaysLayer.style.transform=`translate(${t.offsetX}px, ${t.offsetY}px) scale(${t.scale})`};updateOverlay(t,e,i){let n=this.overlays[t.id];if(n){if("text"===i){n.getElementsByClassName("parsed-content-wrapper")[0].innerHTML=e}}else n=this.constructOverlay(t,e,i),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(t,e,i){const n=_.getColor(t.color),s=document.createElement("div");switch(s.classList.add("overlay-container"),s.id=t.id,s.style.backgroundColor=n.background,s.style.setProperty("--active-color",n.active),i){case"text":{s.classList.add("markdown-content");const t=document.createElement("div");t.innerHTML=this.parse(e||""),t.classList.add("parsed-content-wrapper"),s.appendChild(t);break}case"link":{const t=document.createElement("iframe");t.src=e,t.sandbox="allow-scripts allow-same-origin",t.className="link-iframe",t.loading="lazy",s.appendChild(t);break}case"audio":{const t=document.createElement("audio");t.className="audio",t.src=e,t.controls=!0,s.appendChild(t);break}case"image":{const t=document.createElement("img");t.src=e,t.loading="lazy",s.appendChild(t)}}switch(i){case"link":case"audio":{const t=document.createElement("div");t.className="click-layer",s.appendChild(t)}}const o=document.createElement("div");o.className="overlay-border",o.style.borderColor=n.border,s.appendChild(o);const a=()=>{t.id===this.selectedId&&this.hooks.onInteractionStart()},r=()=>{t.id===this.selectedId&&this.hooks.onInteractionEnd()};return s.addEventListener("pointerenter",a),s.addEventListener("pointerleave",r),s.addEventListener("touchstart",a),s.addEventListener("touchend",r),this.eventListeners[t.id]=[a,r],s}dispose=()=>{for(;this.overlaysLayer.firstElementChild;){const t=this.overlaysLayer.firstElementChild;if(this.eventListeners[t.id]){const e=this.eventListeners[t.id][0],i=this.eventListeners[t.id][1];if(!e||!i)throw P;t.removeEventListener("pointerenter",e),t.removeEventListener("pointerleave",i),t.removeEventListener("touchstart",e),t.removeEventListener("touchend",i),this.eventListeners[t.id][0]=null,this.eventListeners[t.id][1]=null}t.remove()}this.overlaysLayer.remove(),this._overlaysLayer=null}}class I extends i{pointeract;DM;onClick=_.makeHook();constructor(...e){super(...e),this.DM=this.container.get(E);const i=Object.assign(this.options.pointeract||{},{coordinateOutput:"relative"});this.pointeract=new t.Pointeract(this.DM.data.container,[t.Click,t.Drag,t.WheelPanZoom,t.PreventDefault,t.MultitouchPanZoom],i),this.startInteraction=this.pointeract.start,this.stopInteraction=this.pointeract.stop;const n=this.container.get(S);n.hooks.onInteractionStart.subscribe(this.stopInteraction),n.hooks.onInteractionEnd.subscribe(this.startInteraction),this.DM.hooks.onCanvasFetched.subscribe(this.onFetched)}stopInteraction;startInteraction;onFetched=()=>{this.pointeract.on("pan",this.onPan),this.pointeract.on("drag",this.onPan),this.pointeract.on("zoom",this.onZoom),this.pointeract.on("trueClick",this.onTrueClick),this.pointeract.start()};onPan=t=>{this.DM.pan(t.detail)};onZoom=t=>{const e=t.detail;this.DM.zoom(e.factor,{x:e.x,y:e.y})};onTrueClick=t=>{const e=t.detail;if((i=t.detail.target)&&(i.closest(".controls")||i.closest("button")||i.closest("input")))return;var i;const n=this.DM.findNodeAt({x:e.x,y:e.y});this.onClick(n?n.id:null)};dispose=()=>{this.pointeract.off("pan",this.onPan),this.pointeract.off("zoom",this.onZoom),this.pointeract.off("trueClick",this.onTrueClick),this.pointeract.dispose()}}const L="#fff";class T extends i{_canvas;ctx;DM;zoomInOptimize={lastDrawnScale:0,lastDrawnViewport:{left:0,right:0,top:0,bottom:0},timeout:null,lastCallTime:0};get canvas(){if(null===this._canvas)throw P;return this._canvas}constructor(...t){super(...t);const e=this.container.get(B);e.hooks.onRefresh.subscribe(this.redraw),e.hooks.onResize.subscribe(this.optimizeDPR),this.DM=this.container.get(E),this._canvas=document.createElement("canvas"),this._canvas.className="main-canvas",this.ctx=this._canvas.getContext("2d"),this.DM.data.container.appendChild(this._canvas)}optimizeDPR=()=>{const t=this.DM.data.container;_.resizeCanvasForDPR(this.canvas,t.offsetWidth,t.offsetHeight)};redraw=()=>{this.zoomInOptimize.timeout&&(clearTimeout(this.zoomInOptimize.timeout),this.zoomInOptimize.timeout=null);const t=Date.now(),e=this.DM.data.offsetX,i=this.DM.data.offsetY,n=this.DM.data.scale,s=this.getCurrentViewport(e,i,n);if(this.isViewportInside(s,this.zoomInOptimize.lastDrawnViewport)&&n!==this.zoomInOptimize.lastDrawnScale){if(t-this.zoomInOptimize.lastCallTime<500)return this.zoomInOptimize.timeout=setTimeout(()=>{this.trueRedraw(e,i,n,s),this.zoomInOptimize.lastCallTime=t,this.zoomInOptimize.timeout=null},60),void this.fakeRedraw(s,n)}this.zoomInOptimize.lastCallTime=t,this.trueRedraw(e,i,n,s)};trueRedraw(t,e,i,n){this.zoomInOptimize.lastDrawnViewport=n,this.zoomInOptimize.lastDrawnScale=i,this.canvas.style.transform="",this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(i,i);const s=this.DM.data.canvasData;s.nodes.forEach(t=>{switch(t.type){case"group":this.drawGroup(t,i);break;case"file":this.drawFileNode(t)}}),s.edges.forEach(t=>{this.drawEdge(t)}),this.ctx.restore()}fakeRedraw(t,e){const i=e/this.zoomInOptimize.lastDrawnScale,n=(this.zoomInOptimize.lastDrawnViewport.left-t.left)*e,s=(this.zoomInOptimize.lastDrawnViewport.top-t.top)*e;this.canvas.style.transform=`translate(${n}px, ${s}px) scale(${i})`}isViewportInside=(t,e)=>t.left>e.left&&t.top>e.top&&t.right<e.right&&t.bottom<e.bottom;getCurrentViewport=(t,e,i)=>{const n=-t/i,s=-e/i,o=this.DM.data.container;return{left:n,top:s,right:n+o.clientWidth/i,bottom:s+o.clientHeight/i}};drawLabelBar=(t,e,i,n,s)=>{const o=30*s,a=6*s,r=8*s,l=16*s,c=6*s;this.ctx.save(),this.ctx.translate(t,e),this.ctx.scale(1/s,1/s),this.ctx.font=`${l}px 'Inter', sans-serif`;const h=this.ctx.measureText(i).width+2*c;this.ctx.translate(0,-o-r),this.ctx.fillStyle=n,this.ctx.beginPath(),this.ctx.moveTo(a,0),this.ctx.lineTo(h-a,0),this.ctx.quadraticCurveTo(h,0,h,a),this.ctx.lineTo(h,o-a),this.ctx.quadraticCurveTo(h,o,h-a,o),this.ctx.lineTo(a,o),this.ctx.quadraticCurveTo(0,o,0,o-a),this.ctx.lineTo(0,a),this.ctx.quadraticCurveTo(0,0,a,0),this.ctx.closePath(),this.ctx.fill(),this.ctx.fillStyle=L,this.ctx.fillText(i,c,.65*o),this.ctx.restore()};drawNodeBackground=t=>{const e=_.getColor(t.color);this.ctx.globalAlpha=1,this.ctx.fillStyle=e.background,_.drawRoundRect(this.ctx,t.x+1,t.y+1,t.width-2,t.height-2,12),this.ctx.fill(),this.ctx.strokeStyle=e.border,this.ctx.lineWidth=2,_.drawRoundRect(this.ctx,t.x,t.y,t.width,t.height,12),this.ctx.stroke()};drawGroup=(t,e)=>{this.drawNodeBackground(t),t.label&&this.drawLabelBar(t.x,t.y,t.label,_.getColor(t.color).border,e)};drawFileNode=t=>{this.ctx.fillStyle=L,this.ctx.font="16px sans-serif",this.ctx.fillText(t.file,t.x+5,t.y-10)};drawEdge=t=>{const{fromNode:e,toNode:i}=this.getEdgeNodes(t),n=_.getAnchorCoord,[s,o]=n(e,t.fromSide),[a,r]=n(i,t.toSide);let[l,c,h,d]=[0,0,0,0];if(t.controlPoints?[l,c,h,d]=t.controlPoints:([l,c,h,d]=this.getControlPoints(s,o,a,r,t.fromSide,t.toSide),t.controlPoints=[l,c,h,d]),this.drawCurvedPath(s,o,a,r,l,c,h,d),this.drawArrowhead(a,r,h,d),t.label){const e=.5,i=(1-e)**3*s+3*(1-e)**2*e*l+3*(1-e)*e*e*h+e**3*a,n=(1-e)**3*o+3*(1-e)**2*e*c+3*(1-e)*e*e*d+e**3*r;this.ctx.font="18px sans-serif";const p=8,u=this.ctx.measureText(t.label).width+2*p,m=20;this.ctx.fillStyle="#222",this.ctx.beginPath(),_.drawRoundRect(this.ctx,i-u/2,n-m/2-2,u,m,4),this.ctx.fill(),this.ctx.fillStyle="#ccc",this.ctx.textAlign="center",this.ctx.textBaseline="middle",this.ctx.fillText(t.label,i,n-2),this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic"}};getEdgeNodes=t=>({fromNode:this.DM.data.nodeMap[t.fromNode],toNode:this.DM.data.nodeMap[t.toNode]});getControlPoints=(t,e,i,n,s,o)=>{const a=i-t,r=n-e,l=Math.min(Math.abs(a),Math.abs(r))+.3*Math.max(Math.abs(a),Math.abs(r)),c=(h=.5*l,d=60,p=300,Math.max(d,Math.min(p,h)));var h,d,p;let u=t,m=e,f=i,g=n;switch(s){case"top":m=e-c;break;case"bottom":m=e+c;break;case"left":u=t-c;break;case"right":u=t+c}switch(o){case"top":g=n-c;break;case"bottom":g=n+c;break;case"left":f=i-c;break;case"right":f=i+c}return[u,m,f,g]};drawCurvedPath=(t,e,i,n,s,o,a,r)=>{this.ctx.beginPath(),this.ctx.moveTo(t,e),this.ctx.bezierCurveTo(s,o,a,r,i,n),this.ctx.strokeStyle="#ccc",this.ctx.lineWidth=2,this.ctx.stroke()};drawArrowhead=(t,e,i,n)=>{const s=t-i,o=e-n,a=Math.sqrt(s*s+o*o);if(0===a)return;const r=s/a,l=o/a,c=t-12*r-7*l,h=e-12*l+7*r,d=t-12*r+7*l,p=e-12*l-7*r;this.ctx.beginPath(),this.ctx.fillStyle="#ccc",this.ctx.moveTo(t,e),this.ctx.lineTo(c,h),this.ctx.lineTo(d,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}}const O={Controller:B,DataManager:E,InteractionHandler:I,Renderer:T,OverlayManager:S};exports.BaseModule=i,exports.CanvasUtils=_,exports.Controls=class extends i{_controlsPanel=null;_toggleCollapseBtn=null;_toggleFullscreenBtn=null;_zoomOutBtn=null;_zoomSlider=null;_zoomInBtn=null;_resetViewBtn=null;DM;collapsed;get controlsPanel(){if(null===this._controlsPanel)throw P;return this._controlsPanel}get toggleCollapseBtn(){if(null===this._toggleCollapseBtn)throw P;return this._toggleCollapseBtn}get toggleFullscreenBtn(){if(null===this._toggleFullscreenBtn)throw P;return this._toggleFullscreenBtn}get zoomOutBtn(){if(null===this._zoomOutBtn)throw P;return this._zoomOutBtn}get zoomSlider(){if(null===this._zoomSlider)throw P;return this._zoomSlider}get zoomInBtn(){if(null===this._zoomInBtn)throw P;return this._zoomInBtn}get resetViewBtn(){if(null===this._resetViewBtn)throw P;return this._resetViewBtn}constructor(...t){super(...t),this.collapsed=this.options.controlsCollapsed||!1,this.DM=this.container.get(E),this.DM.hooks.onToggleFullscreen.subscribe(this.updateFullscreenBtn),this.container.get(B).hooks.onRefresh.subscribe(this.updateSlider),this._controlsPanel=document.createElement("div"),this._controlsPanel.className="controls",this._controlsPanel.classList.toggle("collapsed",this.collapsed),_.applyStyles(this._controlsPanel,".collapse-button{border-radius:8px;transition:transform .2s}.collapse-button:hover{background:#444c}button{cursor:pointer;font-size:18px;height:32px;border:none;transition:var(--containerTransition);text-align:center;background-color:#444;width:32px;padding:5px 0}button svg{width:100%;height:100%}.controls{position:absolute;top:10px;right:10px;display:flex;align-items:center;transition:transform .2s;border-radius:8px;gap:10px}.controls.collapsed{transform:translate(calc(100% - 32px))}.controls.collapsed .collapse-button{transform:rotate(180deg)}.controls .controls-content{display:flex;gap:1px;align-items:center;border-radius:8px;overflow:hidden;background:#333c}.controls button:hover{background:#555}.zoom-slider{width:100px;margin:0 10px}"),this._toggleCollapseBtn=document.createElement("button"),this._toggleCollapseBtn.className="collapse-button",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);const e=document.createElement("div");e.className="controls-content",this._toggleFullscreenBtn=document.createElement("button"),this._toggleFullscreenBtn.innerHTML='<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>',e.appendChild(this._toggleFullscreenBtn),this._zoomOutBtn=document.createElement("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>',e.appendChild(this._zoomOutBtn),this._zoomSlider=document.createElement("input"),this._zoomSlider.type="range",this._zoomSlider.className="zoom-slider",this._zoomSlider.min="-30",this._zoomSlider.max="30",this._zoomSlider.value="0",e.appendChild(this._zoomSlider),this._zoomInBtn=document.createElement("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>',e.appendChild(this._zoomInBtn),this._resetViewBtn=document.createElement("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>',e.appendChild(this._resetViewBtn),this._controlsPanel.appendChild(e),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)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.controlsPanel.classList.toggle("collapsed",this.collapsed),this.collapsed||this.updateSlider()};zoomIn=()=>this.DM.zoom(1.1,this.DM.middleViewer());zoomOut=()=>this.DM.zoom(1/1.1,this.DM.middleViewer());slide=()=>this.DM.zoomToScale(1.1**Number(this.zoomSlider.value),this.DM.middleViewer());updateFullscreenBtn=t=>{this.toggleFullscreenBtn.innerHTML=t?'<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>':'<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>'};toggleFullscreen=()=>this.DM.shiftFullscreen("toggle");updateSlider=()=>{this.collapsed||(this.zoomSlider.value=String(this.scaleToSlider(this.DM.data.scale)))};scaleToSlider=t=>Math.log(t)/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}},exports.DebugPanel=class extends i{_debugPanel=null;DM;get debugPanel(){if(!this._debugPanel)throw P;return this._debugPanel}constructor(...t){super(...t),this.DM=this.container.get(E),this.container.get(B).hooks.onRefresh.subscribe(this.update),this._debugPanel=document.createElement("div"),this._debugPanel.className="debug-panel";const e=this.DM.data.container;_.applyStyles(e,".debug-panel{position:absolute;bottom:12px;left:12px;background:#0006;border-radius:12px;padding:12px;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);color:#fff;font-size:calc(14px + .3vw);line-height:calc(17px + .3vw);pointer-events:none}"),e.appendChild(this._debugPanel)}update=()=>{const t=_.round,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=null}},exports.JSONCanvasViewer=class{options;allModules;container;constructor(t,e){this.container=new z,this.options=t;this.allModules=[E,B,S,I,T,...e||[]],this.allModules.forEach(t=>{this.container.bind({provide:t,useFactory:()=>new t(this.container,this.options)})}),this.allModules.forEach(t=>{this.container.get(t)}),this.container.get(E).loadCanvas()}dispose=()=>{const t=this.options.container;for(;t.firstChild;)t.firstChild.remove();this.allModules.reverse(),this.allModules.forEach(t=>{const e=this.container.get(t);e.dispose&&e.dispose()})}},exports.Minimap=class extends i{_minimapCtx=null;_viewportRectangle=null;_minimap=null;_minimapContainer=null;_toggleMinimapBtn=null;minimapCache={scale:1,centerX:0,centerY:0};DM;collapsed;get minimap(){if(null===this._minimap)throw P;return this._minimap}get minimapCtx(){if(null===this._minimapCtx)throw P;return this._minimapCtx}get viewportRectangle(){if(null===this._viewportRectangle)throw P;return this._viewportRectangle}get minimapContainer(){if(null===this._minimapContainer)throw P;return this._minimapContainer}get toggleMinimapBtn(){if(null===this._toggleMinimapBtn)throw P;return this._toggleMinimapBtn}constructor(...t){super(...t),this.collapsed=this.options.minimapCollapsed||!1,this.container.get(B).hooks.onRefresh.subscribe(this.updateViewportRectangle),this.DM=this.container.get(E),this.DM.hooks.onCanvasFetched.subscribe(this.drawMinimap),this._minimapContainer=document.createElement("div"),this._minimapContainer.className="minimap-container",_.applyStyles(this._minimapContainer,".collapse-button{border-radius:8px;transition:transform .2s}.collapse-button:hover{background:#444c}button{cursor:pointer;font-size:18px;height:32px;border:none;transition:var(--containerTransition);text-align:center;background-color:#444;width:32px;padding:5px 0}button svg{width:100%;height:100%}.minimap-container{position:absolute;bottom:10px;right:10px;display:flex;pointer-events:none;transition:transform .2s}.minimap-container.collapsed{transform:translate(calc(100% - 32px))}@media(max-width:768px){.minimap-container{transform:translateY(60px) translate(80px)}.minimap-container.collapsed{transform:translateY(60px) translate(calc(100% - 32px))}}.toggle-minimap{margin:auto 10px 0 0;pointer-events:auto}.collapsed .toggle-minimap{transform:rotate(180deg)}@media(max-width:768px){.toggle-minimap{transform:translateY(-60px)}.collapsed .toggle-minimap{transform:translateY(-60px) rotate(180deg)}}.minimap{position:relative;width:200px;height:150px;overflow:hidden;border-radius:12px;background:#202020;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);transform-origin:0 0}@media(max-width:768px){.minimap{transform:scale(.6)}}.minimap .minimap-canvas{width:100%;height:100%}.minimap .viewport-rectangle{position:absolute;top:0;left:0;pointer-events:none;border:2px solid #fff;border-radius:6px;box-sizing:border-box;background:transparent}"),this._toggleMinimapBtn=document.createElement("button"),this._toggleMinimapBtn.className="toggle-minimap collapse-button",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="minimap";const e=document.createElement("canvas");e.className="minimap-canvas",e.width=200,e.height=150,this._minimap.appendChild(e),this._minimapCtx=e.getContext("2d"),this._viewportRectangle=document.createElement("div"),this._viewportRectangle.className="viewport-rectangle",this._minimap.appendChild(this._viewportRectangle),this._minimapContainer.appendChild(this._minimap),this.DM.data.container.appendChild(this._minimapContainer),this._minimapContainer.classList.toggle("collapsed",this.collapsed),this._toggleMinimapBtn.addEventListener("click",this.toggleCollapse),_.resizeCanvasForDPR(e,e.width,e.height)}toggleCollapse=()=>{this.collapsed=!this.collapsed,this.minimapContainer.classList.toggle("collapsed",this.collapsed),this.collapsed||this.updateViewportRectangle()};drawMinimap=()=>{const t=this.DM.data.nodeBounds;if(!t)return;const e=this.minimap.clientWidth,i=this.minimap.clientHeight,n=e/t.width,s=i/t.height;this.minimapCache.scale=.9*Math.min(n,s),this.minimapCache.centerX=e/2,this.minimapCache.centerY=i/2,this.minimapCtx.clearRect(0,0,e,i),this.minimapCtx.save(),this.minimapCtx.translate(this.minimapCache.centerX,this.minimapCache.centerY),this.minimapCtx.scale(this.minimapCache.scale,this.minimapCache.scale),this.minimapCtx.translate(-t.centerX,-t.centerY);const o=this.DM.data.canvasData;for(const a of o.edges)this.drawMinimapEdge(a);for(const a of o.nodes)this.drawMinimapNode(a);this.minimapCtx.restore()};drawMinimapNode=t=>{const e=_.getColor(t.color);this.minimapCtx.fillStyle=e.border,this.minimapCtx.globalAlpha=.3,_.drawRoundRect(this.minimapCtx,t.x,t.y,t.width,t.height,25),this.minimapCtx.fill(),this.minimapCtx.globalAlpha=1};drawMinimapEdge=t=>{const e=this.DM.data.nodeMap,i=e[t.fromNode],n=e[t.toNode];if(!i||!n)return;const[s,o]=_.getAnchorCoord(i,t.fromSide),[a,r]=_.getAnchorCoord(n,t.toSide);this.minimapCtx.beginPath(),this.minimapCtx.moveTo(s,o),this.minimapCtx.lineTo(a,r),this.minimapCtx.strokeStyle="#555",this.minimapCtx.lineWidth=10,this.minimapCtx.stroke()};updateViewportRectangle=()=>{if(this.collapsed)return;const t=this.DM.data.nodeBounds,e=this.DM.data.container,i=this.DM.data.scale;if(!t)return;const n=e.clientWidth/i,s=e.clientHeight/i,o=-this.DM.data.offsetX/i+e.clientWidth/(2*i),a=-this.DM.data.offsetY/i+e.clientHeight/(2*i),r=this.minimapCache.centerX+(o-n/2-t.centerX)*this.minimapCache.scale,l=this.minimapCache.centerY+(a-s/2-t.centerY)*this.minimapCache.scale,c=n*this.minimapCache.scale,h=s*this.minimapCache.scale;this.viewportRectangle.style.left=`${r}px`,this.viewportRectangle.style.top=`${l}px`,this.viewportRectangle.style.width=`${c}px`,this.viewportRectangle.style.height=`${h}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}},exports.MistouchPreventer=class extends i{_preventionContainer=null;preventMt=!1;DM;preventMistouch={record:!1,lastX:0,lastY:0,initialX:0,initialY:0};get preventionContainer(){if(null===this._preventionContainer)throw P;return this._preventionContainer}constructor(...t){super(...t);const e=Object.assign({preventAtStart:!0,labelText:"Click on to unlock."},this.options.mistouchPreventer||{}),i=document.createElement("div");i.className="prevention-banner",i.textContent=e.labelText,this.DM=this.container.get(E),this._preventionContainer=document.createElement("div"),this._preventionContainer.className="prevention-container hidden",_.applyStyles(this._preventionContainer,".full,.prevention-container{top:0;left:0;width:100%;height:100%;position:absolute}.flex-center,.prevention-container{display:flex;justify-content:center;align-items:center}.prevention-container{overflow:visible;transition:background .2s,opacity .2s,box-shadow .2s,border .2s,filter .2s,backdrop-filter .2s}.prevention-container.hidden{pointer-events:none;opacity:0}.prevention-container .prevention-banner{background:#0006;border-radius:12px;padding:12px;margin:12px;-webkit-backdrop-filter:blur(8px) saturate(1.5);backdrop-filter:blur(8px) saturate(1.5);border:2px solid rgba(140,140,140,.75);color:#fff;font-size:calc(14px + .3vw);line-height:calc(17px + .3vw);text-align:center}"),this._preventionContainer.appendChild(i),this.DM.data.container.appendChild(this._preventionContainer),e.preventAtStart&&this.startPrevention(),window.addEventListener("pointerdown",this.onPointerDown),window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp)}onPointerDown=t=>{const e=this.DM.data.container.getBoundingClientRect();t.clientX<e.left||t.clientX>e.right||t.clientY<e.top||t.clientY>e.bottom?this.preventMt||this.startPrevention():this.preventMt&&(this.preventMistouch.initialX=t.clientX,this.preventMistouch.initialY=t.clientY,this.preventMistouch.lastX=t.clientX,this.preventMistouch.lastY=t.clientY,this.preventMistouch.record=!0)};onPointerMove=t=>{this.preventMistouch.record&&(this.preventMistouch.lastX=t.clientX,this.preventMistouch.lastY=t.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("hidden"),this.DM.data.container.classList.add("numb"),this.preventMt=!0};endPrevention=()=>{this.preventMt=!1,this.preventionContainer.classList.add("hidden"),setTimeout(()=>this.DM.data.container.classList.remove("numb"),50)};dispose=()=>{window.removeEventListener("pointerdown",this.onPointerDown),window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp),this.preventionContainer.remove(),this._preventionContainer=null}},exports.developerSuite=O,exports.renderToString=async function(t,i){const n=t=>e.micromark(t,i),s=t=>function(t,e){switch(t.type){case"text":return e(t.text);case"file":return function(t,e){if(t.file.match(/\.md$/i))return async function(t,e){let i;try{const n=await fetch(t),s=await n.text(),o=s.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);i=e(o?o[2]:s)}catch{i="Failed to load content."}return i}(t.file,e);if(t.file.match(/\.(png|jpg|jpeg|gif|svg|webp)$/i))return`<img src="${t.file}" alt="${t.file.split("/").pop()}">`;if(t.file.match(/\.(mp3|wav)$/i))return`<audio src="${t.file}" controls></audio>`}(t,e);case"link":return`<a href="${t.url}" target="_blank" rel="nofollow noreferrer">${t.url}</a>`;default:return""}}(t,n),o=Object.assign({nodes:[],edges:[]},await fetch(t).then(t=>t.json())).nodes,a=_.resolvePath(t);o.forEach(t=>{if("file"===t.type&&!t.file.includes("http")){const e=t.file.split("/");t.file=a+e.pop()}});let r="";return o.forEach(t=>{r+=s(t)}),r};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|