open-plant 1.2.12 → 1.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Sr=Object.defineProperty;var xr=(t,e,n)=>e in t?Sr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var M=(t,e,n)=>xr(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Me=require("react/jsx-runtime"),h=require("react");var Bt=typeof document<"u"?document.currentScript:null;function An(t,e,n){const r=t.createShader(e);if(!r)throw new Error("Failed to create shader.");if(t.shaderSource(r,n),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){const o=t.getShaderInfoLog(r)??"unknown shader error";throw t.deleteShader(r),new Error(o)}return r}function Ar(t,e,n){const r=An(t,t.VERTEX_SHADER,e),i=An(t,t.FRAGMENT_SHADER,n),o=t.createProgram();if(!o)throw t.deleteShader(r),t.deleteShader(i),new Error("Failed to create program.");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS)){const s=t.getProgramInfoLog(o)??"unknown link error";throw t.deleteProgram(o),new Error(s)}return o}function Lt(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`Failed to get uniform location: ${n}`);return r}function Rr(t){const e=t.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,powerPreference:"high-performance"});if(!e)throw new Error("WebGL2 is not available.");return e}let Er=class{constructor(){M(this,"viewportWidth",1);M(this,"viewportHeight",1);M(this,"viewState",{offsetX:0,offsetY:0,zoom:1})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewportSize(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){e.offsetX!==void 0&&(this.viewState.offsetX=e.offsetX),e.offsetY!==void 0&&(this.viewState.offsetY=e.offsetY),e.zoom!==void 0&&(this.viewState.zoom=Math.max(1e-4,e.zoom))}getViewState(){return{...this.viewState}}getMatrix(){const e=this.viewportWidth/this.viewState.zoom,n=this.viewportHeight/this.viewState.zoom,r=2/e,i=-2/n,o=-1-this.viewState.offsetX*r,a=1-this.viewState.offsetY*i;return new Float32Array([r,0,0,0,i,0,o,a,1])}};const Tr=`#version 300 es
1
+ "use strict";var xr=Object.defineProperty;var Ar=(t,e,n)=>e in t?xr(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var M=(t,e,n)=>Ar(t,typeof e!="symbol"?e+"":e,n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Ae=require("react/jsx-runtime"),d=require("react");var Bt=typeof document<"u"?document.currentScript:null;function An(t,e,n){const r=t.createShader(e);if(!r)throw new Error("Failed to create shader.");if(t.shaderSource(r,n),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS)){const o=t.getShaderInfoLog(r)??"unknown shader error";throw t.deleteShader(r),new Error(o)}return r}function Rr(t,e,n){const r=An(t,t.VERTEX_SHADER,e),i=An(t,t.FRAGMENT_SHADER,n),o=t.createProgram();if(!o)throw t.deleteShader(r),t.deleteShader(i),new Error("Failed to create program.");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS)){const s=t.getProgramInfoLog(o)??"unknown link error";throw t.deleteProgram(o),new Error(s)}return o}function Lt(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`Failed to get uniform location: ${n}`);return r}function Er(t){const e=t.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,preserveDrawingBuffer:!1,powerPreference:"high-performance"});if(!e)throw new Error("WebGL2 is not available.");return e}let Tr=class{constructor(){M(this,"viewportWidth",1);M(this,"viewportHeight",1);M(this,"viewState",{offsetX:0,offsetY:0,zoom:1})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewportSize(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){e.offsetX!==void 0&&(this.viewState.offsetX=e.offsetX),e.offsetY!==void 0&&(this.viewState.offsetY=e.offsetY),e.zoom!==void 0&&(this.viewState.zoom=Math.max(1e-4,e.zoom))}getViewState(){return{...this.viewState}}getMatrix(){const e=this.viewportWidth/this.viewState.zoom,n=this.viewportHeight/this.viewState.zoom,r=2/e,i=-2/n,o=-1-this.viewState.offsetX*r,a=1-this.viewState.offsetY*i;return new Float32Array([r,0,0,0,i,0,o,a,1])}};const Pr=`#version 300 es
2
2
  precision highp float;
3
3
 
4
4
  in vec2 aUnit;
@@ -18,7 +18,7 @@ void main() {
18
18
  gl_Position = vec4(clip.xy, 0.0, 1.0);
19
19
  vUv = aUv;
20
20
  }
21
- `,Pr=`#version 300 es
21
+ `,Cr=`#version 300 es
22
22
  precision highp float;
23
23
 
24
24
  in vec2 vUv;
@@ -29,7 +29,7 @@ out vec4 outColor;
29
29
  void main() {
30
30
  outColor = texture(uTexture, vUv);
31
31
  }
32
- `;class Yn{constructor(e){M(this,"canvas");M(this,"gl");M(this,"camera",new Er);M(this,"imageWidth");M(this,"imageHeight");M(this,"clearColor");M(this,"program");M(this,"vao");M(this,"quadBuffer");M(this,"uCameraLocation");M(this,"uBoundsLocation");M(this,"uTextureLocation");M(this,"resizeObserver");M(this,"tiles",[]);M(this,"frameId",null);M(this,"loadVersion",0);M(this,"destroyed",!1);M(this,"fitted",!1);M(this,"controlledViewState",!1);this.canvas=e.canvas,this.imageWidth=Math.max(1,e.imageWidth),this.imageHeight=Math.max(1,e.imageHeight),this.clearColor=e.clearColor??[.03,.05,.08,1],this.gl=Rr(this.canvas),this.program=Ar(this.gl,Tr,Pr);const n=this.gl.createVertexArray(),r=this.gl.createBuffer();if(!n||!r)throw new Error("Failed to create WebGL buffers.");this.vao=n,this.quadBuffer=r,this.gl.bindVertexArray(this.vao),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.quadBuffer);const i=new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]);this.gl.bufferData(this.gl.ARRAY_BUFFER,i,this.gl.STATIC_DRAW);const o=this.gl.getAttribLocation(this.program,"aUnit"),a=this.gl.getAttribLocation(this.program,"aUv");if(o<0||a<0)throw new Error("Failed to get attribute locations.");const s=4*Float32Array.BYTES_PER_ELEMENT;this.gl.enableVertexAttribArray(o),this.gl.vertexAttribPointer(o,2,this.gl.FLOAT,!1,s,0),this.gl.enableVertexAttribArray(a),this.gl.vertexAttribPointer(a,2,this.gl.FLOAT,!1,s,2*Float32Array.BYTES_PER_ELEMENT),this.gl.bindVertexArray(null),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.uCameraLocation=Lt(this.gl,this.program,"uCamera"),this.uBoundsLocation=Lt(this.gl,this.program,"uBounds"),this.uTextureLocation=Lt(this.gl,this.program,"uTexture"),e.initialViewState&&(this.controlledViewState=!0,this.camera.setViewState(e.initialViewState)),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this.canvas),this.resize()}async setTiles(e){if(this.destroyed)return;const n=++this.loadVersion,r=await Promise.all(e.map(async i=>await this.loadTile(i,n)));if(this.destroyed||n!==this.loadVersion){for(const i of r)i&&this.gl.deleteTexture(i.texture);return}this.disposeTiles(this.tiles),this.tiles=r.filter(i=>i!==null),this.requestRender()}setViewState(e){this.controlledViewState=!0,this.camera.setViewState(e),this.requestRender()}getViewState(){return this.camera.getViewState()}destroy(){this.destroyed||(this.destroyed=!0,this.loadVersion+=1,this.frameId!==null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.resizeObserver.disconnect(),this.disposeTiles(this.tiles),this.tiles=[],this.gl.deleteBuffer(this.quadBuffer),this.gl.deleteVertexArray(this.vao),this.gl.deleteProgram(this.program))}async loadTile(e,n){try{const r=await fetch(e.url);if(!r.ok)throw new Error(`Tile fetch failed: ${r.status} ${r.statusText}`);const i=await r.blob(),o=await createImageBitmap(i);if(this.destroyed||n!==this.loadVersion)return o.close(),null;const a=this.gl.createTexture();if(!a)throw o.close(),new Error("Failed to create tile texture.");return this.gl.bindTexture(this.gl.TEXTURE_2D,a),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,1),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),this.gl.bindTexture(this.gl.TEXTURE_2D,null),o.close(),{id:e.id,bounds:e.bounds,texture:a}}catch(r){return console.error(`[M1TileRenderer] tile load failed: ${e.id}`,r),null}}resize(){if(this.destroyed)return;const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),a=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==a)&&(this.canvas.width=o,this.canvas.height=a),this.camera.setViewport(n,r),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),!this.fitted&&!this.controlledViewState&&(this.fitToImage(),this.fitted=!0),this.requestRender()}fitToImage(){const e=this.camera.getViewportSize(),n=Math.min(e.width/this.imageWidth,e.height/this.imageHeight),r=Number.isFinite(n)&&n>0?n:1,i=e.width/r,o=e.height/r,a=(this.imageWidth-i)*.5,s=(this.imageHeight-o)*.5;this.camera.setViewState({zoom:r,offsetX:a,offsetY:s})}requestRender(){this.frameId!==null||this.destroyed||(this.frameId=requestAnimationFrame(()=>{this.frameId=null,this.render()}))}render(){if(!this.destroyed){this.gl.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.useProgram(this.program),this.gl.bindVertexArray(this.vao),this.gl.uniformMatrix3fv(this.uCameraLocation,!1,this.camera.getMatrix()),this.gl.uniform1i(this.uTextureLocation,0);for(const e of this.tiles)this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,e.texture),this.gl.uniform4f(this.uBoundsLocation,e.bounds[0],e.bounds[1],e.bounds[2],e.bounds[3]),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);this.gl.bindTexture(this.gl.TEXTURE_2D,null),this.gl.bindVertexArray(null)}}disposeTiles(e){for(const n of e)this.gl.deleteTexture(n.texture)}}const Cr=.1,vr=4e6,Ir=4096,_r=64,Ur=1,Fr=4,On=1e-6,Br=24;function Tt(t,e,n){return Math.max(e,Math.min(n,t))}function Be(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function Lr(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const n of t){if(!Array.isArray(n)||n.length<2)continue;const r=Number(n[0]),i=Number(n[1]);if(!Number.isFinite(r)||!Number.isFinite(i))continue;const o=e[e.length-1];o&&Math.abs(o[0]-r)<1e-9&&Math.abs(o[1]-i)<1e-9||e.push([r,i])}return e}function zr(t,e,n){if(e<=On||n<8)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return Be(r)}function zt(t,e){if(!t.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,u]of t)s<n&&(n=s),s>i&&(i=s),u<r&&(r=u),u>o&&(o=u);if(!Number.isFinite(n)||!Number.isFinite(r))return[];const a=Math.max(e,1);return Be([[n-a,r-a],[i+a,r-a],[i+a,o+a],[n-a,o+a]])}function Nr(t,e){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,u]of t)s<n&&(n=s),s>i&&(i=s),u<r&&(r=u),u>o&&(o=u);const a=Math.max(e,1);return[n-a,r-a,i+a,o+a]}function kr(t,e,n){const r=Math.max(Cr,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||vr)),o=Math.max(256,Math.floor(n.maxRasterSize||Ir)),a=Math.max(.001,t[2]-t[0]),s=Math.max(.001,t[3]-t[1]);let u=Math.max(r,Number.EPSILON),c=3,f=Math.ceil(a/u)+c*2+1,p=Math.ceil(s/u)+c*2+1;for(;(f>o||p>o||f*p>i)&&(u*=1.15,f=Math.ceil(a/u)+c*2+1,p=Math.ceil(s/u)+c*2+1,!(u>Math.max(a,s))););return f=Math.max(8,f),p=Math.max(8,p),{minX:t[0],minY:t[1],step:u,padding:c,width:f,height:p}}function Dr(t,e){if(typeof OffscreenCanvas<"u"){const r=new OffscreenCanvas(t,e).getContext("2d",{willReadFrequently:!0});if(r)return r}if(typeof document<"u"){const n=document.createElement("canvas");return n.width=t,n.height=e,n.getContext("2d",{willReadFrequently:!0})}return null}function Xr(t,e){return[(t[0]-e.minX)/e.step+e.padding,(t[1]-e.minY)/e.step+e.padding]}function Wr(t,e,n){const r=Dr(n.width,n.height);if(!r)return new Uint8Array(0);r.clearRect(0,0,n.width,n.height),r.fillStyle="#ffffff",r.strokeStyle="#ffffff",r.lineCap="round",r.lineJoin="round",r.lineWidth=e*2/n.step;const i=t.map(s=>Xr(s,n));if(i.length<=1){const s=i[0];if(!s)return new Uint8Array(0);r.beginPath(),r.arc(s[0],s[1],e/n.step,0,Math.PI*2),r.fill()}else{r.beginPath(),r.moveTo(i[0][0],i[0][1]);for(let s=1;s<i.length;s+=1)r.lineTo(i[s][0],i[s][1]);r.stroke()}const o=r.getImageData(0,0,n.width,n.height),a=new Uint8Array(n.width*n.height);for(let s=0;s<a.length;s+=1)a[s]=o.data[s*4+3]>=Br?1:0;return a}function Yr(t,e,n){const r=[],i=e+1,o=(s,u)=>u*i+s,a=(s,u)=>s>=0&&u>=0&&s<e&&u<n&&t[u*e+s]>0;for(let s=0;s<n;s+=1)for(let u=0;u<e;u+=1)a(u,s)&&(a(u,s-1)||r.push({start:o(u,s),end:o(u+1,s),dir:0}),a(u+1,s)||r.push({start:o(u+1,s),end:o(u+1,s+1),dir:1}),a(u,s+1)||r.push({start:o(u+1,s+1),end:o(u,s+1),dir:2}),a(u-1,s)||r.push({start:o(u,s+1),end:o(u,s),dir:3}));return r}function Or(t,e){const n=(e-t+4)%4;return n===1?0:n===0?1:n===3?2:3}function Vr(t){if(!t.length)return[];const e=new Map;for(let i=0;i<t.length;i+=1){const o=e.get(t[i].start);o?o.push(i):e.set(t[i].start,[i])}const n=new Uint8Array(t.length),r=[];for(let i=0;i<t.length;i+=1){if(n[i])continue;const o=t[i],a=o.start;let s=o.end,u=o.dir;const c=[o.start,o.end];n[i]=1;let f=0;const p=t.length*3;for(;s!==a&&f<p;){const m=e.get(s);if(!m||m.length===0)break;let g=-1,b=1/0;for(const R of m){if(n[R])continue;const _=t[R],W=Or(u,_.dir);W<b&&(b=W,g=R)}if(g<0)break;n[g]=1;const x=t[g];s=x.end,u=x.dir,c.push(s),f+=1}c.length>=4&&c[0]===c[c.length-1]&&r.push(c)}return r}function Gr(t,e,n){const r=e+1,i=[];for(const o of t){const a=o%r,s=Math.floor(o/r);i.push([n.minX+(a-n.padding)*n.step,n.minY+(s-n.padding)*n.step])}return Be(i)}function qr(t){if(t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function Hr(t,e=1e-9){const n=Be(t);if(n.length<5)return n;const r=[n[0]];for(let i=1;i<n.length-1;i+=1){const o=r[r.length-1],a=n[i],s=n[i+1],u=(a[0]-o[0])*(s[1]-a[1])-(a[1]-o[1])*(s[0]-a[0]);Math.abs(u)<=e||r.push(a)}return r.push(r[0]),Be(r)}function $r(t,e,n){const r=n[0]-e[0],i=n[1]-e[1],o=r*r+i*i;if(o<=1e-12){const p=t[0]-e[0],m=t[1]-e[1];return p*p+m*m}const a=Tt(((t[0]-e[0])*r+(t[1]-e[1])*i)/o,0,1),s=e[0]+r*a,u=e[1]+i*a,c=t[0]-s,f=t[1]-u;return c*c+f*f}function Zr(t,e){if(t.length<=2||e<=0)return t.slice();const n=new Uint8Array(t.length);n[0]=1,n[t.length-1]=1;const r=e*e,i=[[0,t.length-1]];for(;i.length>0;){const a=i.pop();if(!a)break;const[s,u]=a;if(u-s<=1)continue;let c=0,f=-1;for(let p=s+1;p<u;p+=1){const m=$r(t[p],t[s],t[u]);m>c&&(c=m,f=p)}f>=0&&c>r&&(n[f]=1,i.push([s,f],[f,u]))}const o=[];for(let a=0;a<t.length;a+=1)n[a]&&o.push(t[a]);return o}function Kr(t,e){const n=Be(t);if(n.length<5||e<=0)return n;const r=n.slice(0,-1),i=Zr(r,e);return i.length<3?n:Be(i)}function jr(t,e){let n=Be(t);if(e<=0||n.length<5)return n;for(let r=0;r<e;r+=1){const i=n.slice(0,-1);if(i.length<3)break;const o=[];for(let a=0;a<i.length;a+=1){const s=i[a],u=i[(a+1)%i.length];o.push([s[0]*.75+u[0]*.25,s[1]*.75+u[1]*.25],[s[0]*.25+u[0]*.75,s[1]*.25+u[1]*.75])}n=Be(o)}return n}function tt(t,e){return e?Be(t.map(([n,r])=>[Tt(n,e[0],e[2]),Tt(r,e[1],e[3])])):t}function Jr(t,e){const n=Lr(t),r=Math.max(On,Number(e.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(e.circleSides||_r));if(n.length===1)return tt(zr(n[0],r,i),e.clipBounds);const o=Nr(n,r),a=kr(o,r,e),s=Wr(n,r,a);if(!s.length)return tt(zt(n,r),e.clipBounds);const u=Yr(s,a.width,a.height),c=Vr(u);if(!c.length)return tt(zt(n,r),e.clipBounds);let f=[],p=0;for(const x of c){const R=Gr(x,a.width,a),_=Math.abs(qr(R));_<=p||(p=_,f=R)}if(!f.length)return tt(zt(n,r),e.clipBounds);const m=typeof e.simplifyTolerance=="number"&&Number.isFinite(e.simplifyTolerance)?Math.max(0,e.simplifyTolerance):a.step*.2,g=typeof e.smoothingPasses=="number"&&Number.isFinite(e.smoothingPasses)?Math.round(Tt(e.smoothingPasses,0,Fr)):Ur,b=Kr(jr(Hr(f,a.step*.001),g),m);return tt(b,e.clipBounds)}function Rn(t){return typeof t=="number"&&Number.isFinite(t)}function Qr(t){return Array.isArray(t)&&t.length>=2&&Rn(t[0])&&Rn(t[1])}function Vn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Qr(e))}function Gn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Vn(e))}function ei(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Gn(e))}function ti(t){if(!Array.isArray(t)||t.length<3)return[];const e=[];for(const i of t){if(!Array.isArray(i)||i.length<2)continue;const o=Number(i[0]),a=Number(i[1]);if(!Number.isFinite(o)||!Number.isFinite(a))continue;const s=e[e.length-1];s&&s[0]===o&&s[1]===a||e.push([o,a])}if(e.length<3)return[];const n=e[0],r=e[e.length-1];return(n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e.length>=4?e:[]}function Wt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function Nt(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const o of t){const a=ti(o);a.length>=4&&e.push(a)}if(e.length===0)return[];if(e.length===1)return[e[0]];let n=0,r=0;for(let o=0;o<e.length;o+=1){const a=Math.abs(Wt(e[o]));a<=r||(r=a,n=o)}const i=[e[n]];for(let o=0;o<e.length;o+=1)o!==n&&i.push(e[o]);return i}function qn(t){if(!t)return[];if(Vn(t)){const e=Nt([t]);return e.length>0?[e]:[]}if(Gn(t)){const e=Nt(t);return e.length>0?[e]:[]}if(ei(t)){const e=[];for(const n of t){const r=Nt(n);r.length>0&&e.push(r)}return e}return[]}function En(t,e,n){let r=!1;for(let i=0,o=n.length-1;i<n.length;o=i,i+=1){const a=n[i][0],s=n[i][1],u=n[o][0],c=n[o][1];s>e!=c>e&&t<(u-a)*(e-s)/(c-s||Number.EPSILON)+a&&(r=!r)}return r}function at(t){const e=[];for(const n of t??[]){const r=qn(n);for(const i of r){const o=i[0];if(!o||o.length<4)continue;let a=1/0,s=1/0,u=-1/0,c=-1/0;for(const[p,m]of o)p<a&&(a=p),p>u&&(u=p),m<s&&(s=m),m>c&&(c=m);if(!Number.isFinite(a)||!Number.isFinite(s)||!Number.isFinite(u)||!Number.isFinite(c))continue;let f=Math.abs(Wt(o));for(let p=1;p<i.length;p+=1)f-=Math.abs(Wt(i[p]));e.push({outer:o,holes:i.slice(1),minX:a,minY:s,maxX:u,maxY:c,area:Math.max(1e-6,f)})}}return e}function jt(t,e,n){if(t<n.minX||t>n.maxX||e<n.minY||e>n.maxY||!En(t,e,n.outer))return!1;for(const r of n.holes)if(En(t,e,r))return!1;return!0}function Pt(t,e,n){for(const r of n)if(jt(t,e,r))return!0;return!1}const Jt=[160,160,160,255];function ee(t,e,n){return Math.max(e,Math.min(n,t))}function Qt(t,e,n){const r=Number(t),i=Number(e),o=Number(n);return!Number.isFinite(r)||r<=0?1:!Number.isFinite(i)||!Number.isFinite(o)?r:Math.pow(2,i-o)*r}function ni(t,e,n){let i=100*Qt(t,e,n);if(Number(t)){let o="μm";return i>1e3&&(i/=1e3,o="mm"),`${i.toPrecision(3)} ${o}`}return`${Math.round(i*1e3)/1e3} pixels`}function ri(t,e){return!t&&!e?!0:!t||!e?!1:Math.abs((t.zoom??0)-(e.zoom??0))<1e-6&&Math.abs((t.offsetX??0)-(e.offsetX??0))<1e-6&&Math.abs((t.offsetY??0)-(e.offsetY??0))<1e-6&&Math.abs((t.rotationDeg??0)-(e.rotationDeg??0))<1e-6}function ii(t){const e=String(t??"").trim();if(!e)return"";if(/^bearer\s+/i.test(e)){const n=e.replace(/^bearer\s+/i,"").trim();return n?`Bearer ${n}`:""}return`Bearer ${e}`}function Hn(t){const n=String(t??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...Jt];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function oi(t){const e=[[...Jt]],n=new Map;for(const i of t??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,e.length),e.push(Hn(i?.termColor)))}const r=new Uint8Array(e.length*4);for(let i=0;i<e.length;i+=1)r[i*4]=e[i][0],r[i*4+1]=e[i][1],r[i*4+2]=e[i][2],r[i*4+3]=e[i][3];return{colors:r,termToPaletteIndex:n}}function Tn(t,e,n){const r=t.createShader(t.VERTEX_SHADER),i=t.createShader(t.FRAGMENT_SHADER);if(!r||!i)throw new Error("Shader allocation failed");if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(r)||"vertex compile failed");if(t.shaderSource(i,n),t.compileShader(i),!t.getShaderParameter(i,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(i)||"fragment compile failed");const o=t.createProgram();if(!o)throw new Error("Program allocation failed");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS))throw new Error(t.getProgramInfoLog(o)||"program link failed");return o}const si="rgba(255, 77, 79, 0.16)",ai=3,ui=2,$n=96,li=1,Pn=[],Ct=[],Cn=1e3,Zn=2,Kn=2,ci=4096,fi=.2,hi=1.12,di=.89,mi=32,gi="#000000",pi=.1,bi="#FFCF00",yi="#FF0000",wi=1.5,vn=[2,2],Mi=1,Si=.25,xi=4,Ai=1,Ri=0,Ei=4,Ti=.05,Pi=256,Ci=1.5,Ye={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},vi={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},Te={fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:12,fontWeight:500,textColor:"#ffffff",backgroundColor:"rgba(8, 14, 22, 0.88)",borderColor:"rgba(255, 77, 79, 0.85)",borderWidth:1,paddingX:6,paddingY:4,offsetY:10,borderRadius:3};function $e(t,e,n){return Math.max(e,Math.min(n,t))}function bt(t){return t==="stamp-rectangle"||t==="stamp-circle"||t==="stamp-rectangle-4096px"||t==="stamp-rectangle-2mm2"||t==="stamp-circle-2mm2"||t==="stamp-circle-hpf-0.2mm2"}function it(t,e){return typeof t!="number"||!Number.isFinite(t)||t<=0?e:t}function Ii(t){return{rectangleAreaMm2:it(t?.rectangleAreaMm2,Zn),circleAreaMm2:it(t?.circleAreaMm2,Kn),rectanglePixelSize:it(t?.rectanglePixelSize,ci)}}function _i(t,e){return typeof t!="number"||!Number.isFinite(t)?e:$e(t,0,1)}function Ui(t){if(!Array.isArray(t))return vn;const e=t.filter(n=>Number.isFinite(n)&&n>=0);return e.length>0?e:vn}function Fi(t){return typeof t!="number"||!Number.isFinite(t)?Mi:$e(t,Si,xi)}function Bi(t){return typeof t!="number"||!Number.isFinite(t)?Ai:Math.round($e(t,Ri,Ei))}function Li(t){const e=it(t?.radius,mi),n=it(t?.cursorLineWidth,wi),r=Fi(t?.edgeDetail),i=Bi(t?.edgeSmoothing);return{radius:e,edgeDetail:r,edgeSmoothing:i,clickSelectRoi:t?.clickSelectRoi===!0,fillColor:t?.fillColor||gi,fillOpacity:_i(t?.fillOpacity,pi),cursorColor:t?.cursorColor||bi,cursorActiveColor:t?.cursorActiveColor||yi,cursorLineWidth:n,cursorLineDash:Ui(t?.cursorLineDash)}}function zi(t){return t*Cn*Cn}function In(t,e){return!t||!Number.isFinite(e)||e<=0?[]:Fe([[t[0]-e,t[1]-e],[t[0]+e,t[1]-e],[t[0]+e,t[1]+e],[t[0]-e,t[1]+e]])}function Ni(t,e,n=$n){if(!t||!Number.isFinite(e)||e<=0)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return Fe(r)}function Fe(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function Yt(t,e){return!t||!e?[]:Fe([[t[0],t[1]],[e[0],t[1]],[e[0],e[1]],[t[0],e[1]]])}function Ot(t,e,n=$n){if(!t||!e)return[];const r=(t[0]+e[0])*.5,i=(t[1]+e[1])*.5,o=Math.hypot(e[0]-t[0],e[1]-t[1])*.5;if(o<1)return[];const a=[];for(let s=0;s<=n;s+=1){const u=s/n*Math.PI*2;a.push([r+Math.cos(u)*o,i+Math.sin(u)*o])}return Fe(a)}function Vt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return Math.abs(e*.5)}function _n(t){if(!Array.isArray(t)||t.length===0)return[0,0,0,0];let e=1/0,n=1/0,r=-1/0,i=-1/0;for(const[o,a]of t)o<e&&(e=o),o>r&&(r=o),a<n&&(n=a),a>i&&(i=a);return[e,n,r,i]}function Un(t){return Array.isArray(t)&&t.length>=4&&Vt(t)>li}function Gt(t,e,n=!1){if(e.length!==0){t.moveTo(e[0][0],e[0][1]);for(let r=1;r<e.length;r+=1)t.lineTo(e[r][0],e[r][1]);n&&t.closePath()}}function Oe(t,e,n,r=!1,i=!1){e.length!==0&&(t.beginPath(),Gt(t,e,r),i&&r&&(t.fillStyle=si,t.fill()),t.strokeStyle=n.color,t.lineWidth=n.width,t.lineJoin=n.lineJoin,t.lineCap=n.lineCap,t.shadowColor=n.shadowColor,t.shadowBlur=n.shadowBlur,t.shadowOffsetX=n.shadowOffsetX,t.shadowOffsetY=n.shadowOffsetY,t.setLineDash(n.lineDash),t.stroke(),t.setLineDash(Ct),t.shadowColor="rgba(0, 0, 0, 0)",t.shadowBlur=0,t.shadowOffsetX=0,t.shadowOffsetY=0)}function jn(t){const e=Array.isArray(t?.lineDash)?t.lineDash.filter(a=>Number.isFinite(a)&&a>=0):Ct,n=typeof t?.width=="number"&&Number.isFinite(t.width)?Math.max(0,t.width):Ye.width,r=typeof t?.shadowBlur=="number"&&Number.isFinite(t.shadowBlur)?Math.max(0,t.shadowBlur):Ye.shadowBlur,i=typeof t?.shadowOffsetX=="number"&&Number.isFinite(t.shadowOffsetX)?t.shadowOffsetX:Ye.shadowOffsetX,o=typeof t?.shadowOffsetY=="number"&&Number.isFinite(t.shadowOffsetY)?t.shadowOffsetY:Ye.shadowOffsetY;return{color:t?.color||Ye.color,width:n,lineDash:e.length?e:Ct,lineJoin:t?.lineJoin||Ye.lineJoin,lineCap:t?.lineCap||Ye.lineCap,shadowColor:t?.shadowColor||Ye.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function nt(t,e){return e?jn({color:e.color??t.color,width:e.width??t.width,lineDash:e.lineDash??t.lineDash,lineJoin:e.lineJoin??t.lineJoin,lineCap:e.lineCap??t.lineCap,shadowColor:e.shadowColor??t.shadowColor,shadowBlur:e.shadowBlur??t.shadowBlur,shadowOffsetX:e.shadowOffsetX??t.shadowOffsetX,shadowOffsetY:e.shadowOffsetY??t.shadowOffsetY}):t}function Fn(t,e){return t==null||e===null||e===void 0?!1:String(t)===String(e)}function ki(t){const e=t[0];return Array.isArray(e)&&Array.isArray(e[0])}function Bn(t){return typeof t=="number"&&Number.isFinite(t)}function Di(t){return Array.isArray(t)&&t.length>=2&&Bn(t[0])&&Bn(t[1])}function Xi(t){return Array.isArray(t)&&t.length>=2&&t.every(e=>Di(e))}function Jn(t,e){if(!(!Array.isArray(t)||t.length===0)){if(Xi(t)){e.push(t.map(([n,r])=>[n,r]));return}for(const n of t)Jn(n,e)}}function Ln(t,e){const n=[];Jn(t,n);const r=[];for(const i of n){if(i.length<2)continue;const o=e?Fe(i):i;o.length>=(e?4:2)&&r.push(o)}return r}function Wi(t,e,n,r){if(!(e.length<4||n.length===0)){t.save(),t.beginPath(),Gt(t,e,!0);for(const i of n)i.length<4||Gt(t,i,!0);t.fillStyle=r,t.fill("evenodd"),t.restore()}}function Yi(t){const e=typeof t?.paddingX=="number"&&Number.isFinite(t.paddingX)?Math.max(0,t.paddingX):Te.paddingX,n=typeof t?.paddingY=="number"&&Number.isFinite(t.paddingY)?Math.max(0,t.paddingY):Te.paddingY,r=typeof t?.fontSize=="number"&&Number.isFinite(t.fontSize)?Math.max(8,t.fontSize):Te.fontSize,i=typeof t?.borderWidth=="number"&&Number.isFinite(t.borderWidth)?Math.max(0,t.borderWidth):Te.borderWidth,o=typeof t?.offsetY=="number"&&Number.isFinite(t.offsetY)?t.offsetY:Te.offsetY,a=typeof t?.borderRadius=="number"&&Number.isFinite(t.borderRadius)?Math.max(0,t.borderRadius):Te.borderRadius;return{fontFamily:t?.fontFamily||Te.fontFamily,fontSize:r,fontWeight:t?.fontWeight||Te.fontWeight,textColor:t?.textColor||Te.textColor,backgroundColor:t?.backgroundColor||Te.backgroundColor,borderColor:t?.borderColor||Te.borderColor,borderWidth:i,paddingX:e,paddingY:n,offsetY:o,borderRadius:a}}function Oi(t,e,n,r,i,o){const a=Math.max(0,Math.min(o,r*.5,i*.5));t.beginPath(),t.moveTo(e+a,n),t.lineTo(e+r-a,n),t.quadraticCurveTo(e+r,n,e+r,n+a),t.lineTo(e+r,n+i-a),t.quadraticCurveTo(e+r,n+i,e+r-a,n+i),t.lineTo(e+a,n+i),t.quadraticCurveTo(e,n+i,e,n+i-a),t.lineTo(e,n+a),t.quadraticCurveTo(e,n,e+a,n),t.closePath()}function Vi(t){if(!t.length)return null;let e=1/0;for(const i of t)i[1]<e&&(e=i[1]);if(!Number.isFinite(e))return null;let n=1/0,r=-1/0;for(const i of t)Math.abs(i[1]-e)>.5||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,e]}function Gi(t){let e=null;for(const n of t){const r=Vi(n.outer);r&&(!e||r[1]<e[1]||r[1]===e[1]&&r[0]<e[0])&&(e=r)}return e}function zn(t){const e=qn(t);if(e.length===0)return[];const n=[];for(const r of e){const i=r[0];if(!i||i.length<4)continue;const o=i.map(([s,u])=>[s,u]),a=[];for(let s=1;s<r.length;s+=1){const u=r[s];!u||u.length<4||a.push(u.map(([c,f])=>[c,f]))}n.push({outer:o,holes:a})}return n}function qi(t,e,n,r,i,o){const a=e.trim();if(!a)return;t.save(),t.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,t.textAlign="center",t.textBaseline="middle";const u=t.measureText(a).width+o.paddingX*2,c=o.fontSize+o.paddingY*2,f=$e(n[0],u*.5+1,r-u*.5-1),p=$e(n[1]-o.offsetY,c*.5+1,i-c*.5-1),m=f-u*.5,g=p-c*.5;t.fillStyle=o.backgroundColor,t.strokeStyle=o.borderColor,t.lineWidth=o.borderWidth,Oi(t,m,g,u,c,o.borderRadius),t.fill(),o.borderWidth>0&&t.stroke(),t.fillStyle=o.textColor,t.fillText(a,f,p+.5),t.restore()}function yt(t,e,n){return[$e(t[0],0,e),$e(t[1],0,n)]}function rt(t){if(!Array.isArray(t)||t.length<2)return null;const e=Number(t[0]),n=Number(t[1]);return!Number.isFinite(e)||!Number.isFinite(n)?null:[e,n]}function Qn({tool:t,imageWidth:e,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:a,projectorRef:s,onBrushTap:u,onDrawComplete:c,onPatchComplete:f,enabled:p,viewStateSignal:m,persistedRegions:g,patchRegions:b,persistedPolygons:x,regionStrokeStyle:R,regionStrokeHoverStyle:_,regionStrokeActiveStyle:W,patchStrokeStyle:F,resolveRegionStrokeStyle:Y,overlayShapes:T,hoveredRegionId:z=null,activeRegionId:Z=null,regionLabelStyle:te,invalidateRef:N,className:Pe,style:Ae}){const $=h.useRef(null),Ce=h.useRef(!1),Le=h.useRef(new Map),Ze=h.useRef(t),me=h.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,points:[],stampCenter:null}),ne=p??t!=="cursor",E=h.useMemo(()=>g&&g.length>0?g:!x||x.length===0?Pn:x.map((l,d)=>({id:d,coordinates:l})),[g,x]),P=h.useMemo(()=>b??Pn,[b]),v=h.useMemo(()=>{const l=[];for(let d=0;d<E.length;d+=1){const w=E[d],S=zn(w.coordinates);S.length!==0&&l.push({region:w,regionIndex:d,regionKey:w.id??d,polygons:S})}return l},[E]),O=h.useMemo(()=>{const l=[];for(let d=0;d<P.length;d+=1){const w=P[d],S=zn(w.coordinates);S.length!==0&&l.push({region:w,regionIndex:d,regionKey:w.id??d,polygons:S})}return l},[P]),B=h.useMemo(()=>jn(R),[R]),oe=h.useMemo(()=>nt(B,_),[B,_]),re=h.useMemo(()=>nt(B,W),[B,W]),be=h.useMemo(()=>nt(vi,F),[F]),he=h.useMemo(()=>Yi(te),[te]),se=h.useMemo(()=>Ii(o),[o]),G=h.useMemo(()=>Li(a),[a]),J=h.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:ne?"auto":"none",cursor:ne?t==="brush"?"none":"crosshair":"default",...Ae}),[ne,t,Ae]),K=h.useCallback(()=>{const l=$.current;if(!l)return;const d=l.getBoundingClientRect(),w=Math.max(1,window.devicePixelRatio||1),S=Math.max(1,Math.round(d.width*w)),C=Math.max(1,Math.round(d.height*w));(l.width!==S||l.height!==C)&&(l.width=S,l.height=C)},[]),L=h.useCallback(l=>{const d=s.current;if(!d||l.length===0)return[];const w=new Array(l.length);for(let S=0;S<l.length;S+=1){const C=rt(d.worldToScreen(l[S][0],l[S][1]));if(!C)return[];w[S]=C}return w},[s]),fe=h.useCallback(l=>{const d=s.current,w=$.current;if(!d||!w)return null;const S=w.getBoundingClientRect(),C=rt(d.screenToWorld(S.left+l[0],S.top+l[1]));return C?yt(C,e,n):null},[s,e,n]),ae=h.useCallback(l=>{if(!Number.isFinite(l)||l<=0)return 0;const d=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,w=typeof i=="number"&&Number.isFinite(i)?i:0,S=s.current?.getViewState?.().zoom,C=typeof S=="number"&&Number.isFinite(S)&&S>0?S:1,k=w+Math.log2(C),X=Math.max(1e-9,Qt(d,w,k));return l/X/C},[r,i,s]),ue=h.useCallback((l,d)=>{if(!d)return[];let w=0;if(l==="stamp-rectangle-4096px"){const k=se.rectanglePixelSize*.5;return In(d,k).map(H=>yt(H,e,n))}if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"?w=l==="stamp-rectangle-2mm2"?Zn:se.rectangleAreaMm2:(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2")&&(w=l==="stamp-circle-hpf-0.2mm2"?fi:l==="stamp-circle-2mm2"?Kn:se.circleAreaMm2),!Number.isFinite(w)||w<=0)return[];const S=zi(w);let C=[];if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"){const k=ae(Math.sqrt(S)*.5);C=In(d,k)}else if(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2"){const k=ae(Math.sqrt(S/Math.PI));C=Ni(d,k)}return C.length?C.map(k=>yt(k,e,n)):[]},[ae,e,n,se]),j=h.useCallback(()=>{const l=me.current;return bt(t)?ue(t,l.stampCenter):t==="brush"?[]:l.isDrawing?t==="freehand"?l.points:t==="rectangle"?Yt(l.start,l.current):t==="circular"?Ot(l.start,l.current):[]:[]},[t,ue]),ve=h.useCallback(l=>{const d=me.current;if(!d.isDrawing||d.points.length===0)return;const w=L(d.points);if(w.length===0)return;const S=G.radius;if(!(!Number.isFinite(S)||S<=0)){if(l.save(),l.globalAlpha=G.fillOpacity,l.fillStyle=G.fillColor,l.strokeStyle=G.fillColor,l.lineCap="round",l.lineJoin="round",l.lineWidth=S*2,w.length===1)l.beginPath(),l.arc(w[0][0],w[0][1],S,0,Math.PI*2),l.fill();else{l.beginPath(),l.moveTo(w[0][0],w[0][1]);for(let C=1;C<w.length;C+=1)l.lineTo(w[C][0],w[C][1]);l.stroke()}l.restore()}},[L,G]),Re=h.useCallback(l=>{const d=me.current,w=d.cursor;if(!w)return;const S=rt(s.current?.worldToScreen(w[0],w[1])??[]);if(!S)return;const C=G.radius;!Number.isFinite(C)||C<=0||(l.save(),l.beginPath(),l.arc(S[0],S[1],C,0,Math.PI*2),l.strokeStyle=d.isDrawing?G.cursorActiveColor:G.cursorColor,l.lineWidth=G.cursorLineWidth,l.setLineDash(G.cursorLineDash),l.stroke(),l.setLineDash(Ct),l.restore())},[s,G]),Ie=h.useCallback(()=>{K();const l=$.current;if(!l)return;const d=l.getContext("2d");if(!d)return;const w=Math.max(1,window.devicePixelRatio||1),S=l.width/w,C=l.height/w;if(d.setTransform(1,0,0,1,0,0),d.clearRect(0,0,l.width,l.height),d.setTransform(w,0,0,w,0,0),v.length>0)for(const k of v){const{region:X,polygons:H,regionIndex:V,regionKey:ie}=k,Ne=Fn(Z,ie)?"active":Fn(z,ie)?"hover":"default";let ke=Ne==="active"?re:Ne==="hover"?oe:B;if(Y){const Q=Y({region:X,regionId:ie,regionIndex:V,state:Ne});ke=nt(ke,Q||void 0)}for(const Q of H){const le=L(Q.outer);le.length>=4&&Oe(d,le,ke,!0,!1);for(const pe of Q.holes){const ge=L(pe);ge.length>=4&&Oe(d,ge,ke,!0,!1)}}}if(O.length>0)for(const k of O)for(const X of k.polygons){const H=L(X.outer);H.length>=4&&Oe(d,H,be,!0,!1);for(const V of X.holes){const ie=L(V);ie.length>=4&&Oe(d,ie,be,!0,!1)}}if(Array.isArray(T)&&T.length>0){const k=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,X=L(Fe([[0,0],[e,0],[e,n],[0,n]]));for(let H=0;H<T.length;H+=1){const V=T[H];if(!V?.coordinates?.length||V.visible===!1)continue;const ie=V.closed??ki(V.coordinates),Ne=Ln(V.coordinates,ie);if(V.invertedFill?.fillColor){const Q=[],le=Ln(V.coordinates,!0);for(const pe of le){const ge=L(pe);ge.length>=4&&Q.push(ge)}if(k){const pe=String(V.id??H),ge=`${X.length}|${le.length}|${Q.length}|${V.invertedFill.fillColor}`;Le.current.get(pe)!==ge&&(Le.current.set(pe,ge),console.debug("[open-plant] invertedFill",{id:V.id??H,outerRingPoints:X.length,sourceRingCount:le.length,holeRingCount:Q.length,fillColor:V.invertedFill.fillColor}))}Wi(d,X,Q,V.invertedFill.fillColor)}if(Ne.length===0)continue;const ke=nt(B,V.stroke??V.strokeStyle);for(const Q of Ne){const le=L(Q);le.length<2||Oe(d,le,ke,ie,V.fill??!1)}}}if(ne)if(t==="brush")ve(d),Re(d);else{const k=j();if(k.length>0)if(t==="freehand"){const X=L(k);X.length>=2&&Oe(d,X,B,!1,!1),X.length>=3&&Oe(d,L(Fe(k)),B,!0,!0)}else{const X=L(k);X.length>=4&&Oe(d,X,B,!0,!0)}}if(v.length>0)for(const k of v){if(!k.region.label)continue;const X=Gi(k.polygons);if(!X)continue;const H=rt(s.current?.worldToScreen(X[0],X[1])??[]);H&&qi(d,k.region.label,H,S,C,he)}},[ne,t,j,ve,Re,K,L,e,n,s,v,T,z,Z,B,oe,re,O,be,Y,he]),U=h.useCallback(()=>{Ce.current||(Ce.current=!0,requestAnimationFrame(()=>{Ce.current=!1,Ie()}))},[Ie]),de=h.useCallback((l=!1)=>{const d=me.current,w=$.current;if(w&&d.pointerId!==null&&w.hasPointerCapture(d.pointerId))try{w.releasePointerCapture(d.pointerId)}catch{}d.isDrawing=!1,d.pointerId=null,d.start=null,d.current=null,d.points=[],d.stampCenter=null,l||(d.cursor=null)},[]),Ee=h.useCallback(l=>{const d=s.current;if(!d||e<=0||n<=0)return null;const w=rt(d.screenToWorld(l.clientX,l.clientY));return w?yt(w,e,n):null},[s,e,n]),_e=h.useCallback(()=>{const l=me.current;if(!l.isDrawing){de(!0),U();return}let d=[];if(t==="freehand")l.points.length>=ai&&(d=Fe(l.points));else if(t==="rectangle")d=Yt(l.start,l.current);else if(t==="circular")d=Ot(l.start,l.current);else if(t==="brush"){const w=l.points[l.points.length-1]??l.current??l.start;if(G.clickSelectRoi&&w&&l.points.length<=1&&u?.(w)){de(!0),U();return}const S=G.edgeDetail,C=Math.max(Ti,G.radius*2/(Pi*S)),k=L(l.points),X=Jr(k,{radius:G.radius,minRasterStep:C,circleSides:Math.max(24,Math.round(64*S)),simplifyTolerance:C*.25,smoothingPasses:G.edgeSmoothing}),H=[];for(const V of X){const ie=fe(V);ie&&H.push(ie)}d=Fe(H)}(t==="freehand"||t==="rectangle"||t==="circular"||t==="brush")&&Un(d)&&c&&c({tool:t,intent:t==="brush"?"brush":"roi",coordinates:d,bbox:_n(d),areaPx:Vt(d)}),de(!0),U()},[t,c,de,U,L,fe,G.radius,G.edgeDetail,G.edgeSmoothing,G.clickSelectRoi,u]),Je=h.useCallback((l,d)=>{const w=ue(l,d);if(!Un(w))return;const S=l==="stamp-rectangle-4096px"?"patch":"roi",C={tool:l,intent:S,coordinates:w,bbox:_n(w),areaPx:Vt(w)};c?.(C),S==="patch"&&f&&f(C)},[ue,c,f]),Ue=h.useCallback((l,d)=>{const w=s.current,S=Math.max(1e-6,w?.getViewState?.().zoom??1),C=Ci/S,k=C*C,X=l.points[l.points.length-1];if(!X){l.points.push(d),l.current=d;return}const H=d[0]-X[0],V=d[1]-X[1];H*H+V*V>=k?l.points.push(d):l.points[l.points.length-1]=d,l.current=d},[s]),ye=h.useCallback(l=>{if(!ne||t==="cursor"||l.button!==0)return;const d=Ee(l);if(!d)return;if(l.preventDefault(),l.stopPropagation(),bt(t)){const C=me.current;C.stampCenter=d,Je(t,d),U();return}const w=$.current;w&&w.setPointerCapture(l.pointerId);const S=me.current;S.isDrawing=!0,S.pointerId=l.pointerId,S.start=d,S.current=d,S.cursor=d,S.points=t==="freehand"||t==="brush"?[d]:[],U()},[ne,t,Ee,Je,U]),vt=h.useCallback(l=>{if(!ne||t==="cursor")return;const d=Ee(l);if(!d)return;if(bt(t)){const S=me.current;S.stampCenter=d,l.preventDefault(),l.stopPropagation(),U();return}const w=me.current;if(t==="brush"){if(w.cursor=d,!w.isDrawing||w.pointerId!==l.pointerId){U();return}l.preventDefault(),l.stopPropagation(),Ue(w,d),U();return}if(!(!w.isDrawing||w.pointerId!==l.pointerId)){if(l.preventDefault(),l.stopPropagation(),t==="freehand"){const S=s.current,C=Math.max(1e-6,S?.getViewState?.().zoom??1),k=ui/C,X=k*k,H=w.points[w.points.length-1];if(!H)w.points.push(d);else{const V=d[0]-H[0],ie=d[1]-H[1];V*V+ie*ie>=X&&w.points.push(d)}}else w.current=d;U()}},[ne,t,Ee,U,s,Ue]),Qe=h.useCallback(l=>{const d=me.current;if(!d.isDrawing||d.pointerId!==l.pointerId)return;l.preventDefault(),l.stopPropagation();const w=Ee(l);w&&(d.cursor=w,t==="brush"?Ue(d,w):d.current=w);const S=$.current;if(S&&S.hasPointerCapture(l.pointerId))try{S.releasePointerCapture(l.pointerId)}catch{}_e()},[_e,Ee,t,Ue]),ut=h.useCallback(()=>{const l=me.current;let d=!1;t==="brush"&&!l.isDrawing&&l.cursor&&(l.cursor=null,d=!0),bt(t)&&l.stampCenter&&(l.stampCenter=null,d=!0),d&&U()},[t,U]);return h.useEffect(()=>{K(),U();const l=$.current;if(!l)return;const d=new ResizeObserver(()=>{K(),U()});return d.observe(l),()=>{d.disconnect()}},[K,U]),h.useEffect(()=>{ne||de(),U()},[ne,U,de]),h.useEffect(()=>{Ze.current!==t&&(Ze.current=t,de(),U())},[t,de,U]),h.useEffect(()=>{U()},[m,E,T,U]),h.useEffect(()=>{if(N)return N.current=U,()=>{N.current===U&&(N.current=null)}},[N,U]),h.useEffect(()=>{if(!ne)return;const l=d=>{d.key==="Escape"&&(de(),U())};return window.addEventListener("keydown",l),()=>{window.removeEventListener("keydown",l)}},[ne,de,U]),Me.jsx("canvas",{ref:$,className:Pe,style:J,onPointerDown:ye,onPointerMove:vt,onPointerUp:Qe,onPointerCancel:Qe,onPointerLeave:ut,onContextMenu:l=>{ne&&l.preventDefault()},onWheel:l=>{if(!ne)return;const d=$.current,w=s.current;if(!d||typeof w?.zoomBy!="function")return;l.preventDefault(),l.stopPropagation();const S=d.getBoundingClientRect(),C=l.clientX-S.left,k=l.clientY-S.top;w.zoomBy(l.deltaY<0?hi:di,C,k),U()}})}function Nn(t){return String(t??"").replace(/\/+$/,"")}function er(t){const e=String(t??"");return e.startsWith("/")?e:`/${e}`}function Hi(t){const e=Nn(t);if(!e)return"";if(/\/TileGroup\d+$/i.test(e))return e;let n=null;try{n=new URL(e)}catch{n=null}if(n){const r=`${n.protocol}//${n.host}`,i=Nn(n.pathname||"");return/\/ims$/i.test(i)?`${r}${i}`:/\/tiles$/i.test(i)?`${r}${i}`:`${r}${i}/tiles`}return/\/ims$/i.test(e)?"/ims":/\/tiles$/i.test(e)?`${e}`:`${e}/tiles`}function $i(t,e){const n=t?.imsInfo||{},r=!!t?.imsInfo,i=Number(n.width??t?.width??0),o=Number(n.height??t?.height??0),a=Number(n.tileSize??t?.tileSize??0),s=Number(n.zoom??t?.zoom??0),u=String(n.path??t?.path??""),c=Number(n.mpp??t?.mpp??0);if(!i||!o||!a||!u)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const f=Array.isArray(t?.terms)?t.terms.map(b=>({termId:String(b?.termId??""),termName:String(b?.termName??""),termColor:String(b?.termColor??"")})):[],p=er(u),m=Hi(e),g=r?(b,x,R)=>`${m}${p}/${b}/${R}_${x}.webp`:void 0;return{id:t?._id||"unknown",name:t?.name||"unknown",width:i,height:o,mpp:Number.isFinite(c)&&c>0?c:void 0,tileSize:a,maxTierZoom:Number.isFinite(s)?Math.max(0,Math.floor(s)):0,tilePath:u,tileBaseUrl:e,terms:f,tileUrlBuilder:g}}function en(t,e,n,r){if(t.tileUrlBuilder)return t.tileUrlBuilder(e,n,r);const i=er(t.tilePath);return`${t.tileBaseUrl}${i}/${e}/${r}_${n}.webp`}const we={width:220,height:140,margin:16,position:"bottom-right",borderRadius:10,borderWidth:1.5,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportStrokeColor:"rgba(255, 106, 61, 0.95)",viewportFillColor:"rgba(255, 106, 61, 0.2)",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function je(t,e,n=1){return typeof t!="number"||!Number.isFinite(t)?e:Math.max(n,t)}function wt(t){return Array.isArray(t)&&t.length===4&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(t[2])&&Number.isFinite(t[3])}function tr({source:t,projectorRef:e,authToken:n="",options:r,invalidateRef:i,className:o,style:a}){const s=h.useRef(null),u=h.useRef(null),c=h.useRef(null),f=h.useRef({active:!1,pointerId:null}),p=h.useRef(null),m=h.useRef(!1),g=je(r?.width,we.width,64),b=je(r?.height,we.height,48),x=je(r?.margin,we.margin,0),R=je(r?.borderRadius,we.borderRadius,0),_=je(r?.borderWidth,we.borderWidth,0),W=Math.max(1,Math.round(je(r?.maxThumbnailTiles,we.maxThumbnailTiles,1))),F=r?.backgroundColor||we.backgroundColor,Y=r?.borderColor||we.borderColor,T=r?.viewportStrokeColor||we.viewportStrokeColor,z=r?.viewportFillColor||we.viewportFillColor,Z=r?.interactive??we.interactive,te=r?.showThumbnail??we.showThumbnail,N=r?.position||we.position,Pe=h.useMemo(()=>{const E={};return N==="top-left"||N==="bottom-left"?E.left=x:E.right=x,N==="top-left"||N==="top-right"?E.top=x:E.bottom=x,{position:"absolute",...E,width:g,height:b,borderRadius:R,overflow:"hidden",zIndex:4,pointerEvents:Z?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...a}},[x,N,g,b,R,Z,a]),Ae=h.useCallback(()=>{const E=s.current;if(!E)return;const P=E.getContext("2d");if(!P)return;const v=g,O=b,B=Math.max(1,window.devicePixelRatio||1),oe=Math.max(1,Math.round(v*B)),re=Math.max(1,Math.round(O*B));(E.width!==oe||E.height!==re)&&(E.width=oe,E.height=re),P.setTransform(1,0,0,1,0,0),P.clearRect(0,0,E.width,E.height),P.setTransform(B,0,0,B,0,0),P.fillStyle=F,P.fillRect(0,0,v,O);const be=u.current;be&&P.drawImage(be,0,0,v,O),P.strokeStyle=Y,P.lineWidth=_,P.strokeRect(_*.5,_*.5,v-_,O-_);const he=e.current,se=he?.getViewBounds?.(),G=he?.getViewCorners?.(),J=wt(se)?se:wt(c.current)?c.current:null;if(!J)return;c.current=J;const K=v/Math.max(1,t.width),L=O/Math.max(1,t.height),fe=Array.isArray(G)&&G.length>=4&&G.every(U=>Array.isArray(U)&&U.length>=2&&Number.isFinite(U[0])&&Number.isFinite(U[1]))?G:null;if(fe){P.beginPath();for(let U=0;U<fe.length;U+=1){const de=fe[U],Ee=ee(de[0]*K,0,v),_e=ee(de[1]*L,0,O);U===0?P.moveTo(Ee,_e):P.lineTo(Ee,_e)}P.closePath(),P.fillStyle=z,P.fill(),P.strokeStyle=T,P.lineWidth=1.5,P.stroke();return}const ae=ee(J[0]*K,0,v),ue=ee(J[1]*L,0,O),j=ee(J[2]*K,0,v),ve=ee(J[3]*L,0,O),Re=Math.max(1,j-ae),Ie=Math.max(1,ve-ue);P.fillStyle=z,P.fillRect(ae,ue,Re,Ie),P.strokeStyle=T,P.lineWidth=1.5,P.strokeRect(ae+.5,ue+.5,Math.max(1,Re-1),Math.max(1,Ie-1))},[g,b,F,Y,_,e,t.width,t.height,z,T]),$=h.useCallback(()=>{m.current||(m.current=!0,p.current=requestAnimationFrame(()=>{m.current=!1,p.current=null,Ae()}))},[Ae]),Ce=h.useCallback((E,P)=>{const v=s.current;if(!v)return null;const O=v.getBoundingClientRect();if(!O.width||!O.height)return null;const B=ee((E-O.left)/O.width,0,1),oe=ee((P-O.top)/O.height,0,1);return[B*t.width,oe*t.height]},[t.width,t.height]),Le=h.useCallback((E,P)=>{const v=e.current;if(!v)return;if(v.setViewCenter){v.setViewCenter(E,P),$();return}const O=v.getViewBounds?.(),B=wt(O)?O:wt(c.current)?c.current:null;if(!B)return;const oe=Math.max(1e-6,B[2]-B[0]),re=Math.max(1e-6,B[3]-B[1]);v.setViewState({offsetX:E-oe*.5,offsetY:P-re*.5}),$()},[e,$]),Ze=h.useCallback(E=>{if(!Z||E.button!==0)return;const P=s.current;if(!P)return;const v=Ce(E.clientX,E.clientY);v&&(E.preventDefault(),E.stopPropagation(),P.setPointerCapture(E.pointerId),f.current={active:!0,pointerId:E.pointerId},Le(v[0],v[1]))},[Z,Ce,Le]),me=h.useCallback(E=>{const P=f.current;if(!P.active||P.pointerId!==E.pointerId)return;const v=Ce(E.clientX,E.clientY);v&&(E.preventDefault(),E.stopPropagation(),Le(v[0],v[1]))},[Ce,Le]),ne=h.useCallback(E=>{const P=f.current;if(!P.active||P.pointerId!==E.pointerId)return;const v=s.current;if(v&&v.hasPointerCapture(E.pointerId))try{v.releasePointerCapture(E.pointerId)}catch{}f.current={active:!1,pointerId:null},$()},[$]);return h.useEffect(()=>{let E=!1;u.current=null,$();const P=0,v=2**(t.maxTierZoom-P),O=Math.ceil(t.width/v),B=Math.ceil(t.height/v),oe=Math.max(1,Math.ceil(O/t.tileSize)),re=Math.max(1,Math.ceil(B/t.tileSize)),be=oe*re;if(!te||be>W)return;const he=document.createElement("canvas");he.width=Math.max(1,Math.round(g)),he.height=Math.max(1,Math.round(b));const se=he.getContext("2d");if(!se)return;se.fillStyle=F,se.fillRect(0,0,he.width,he.height);const G=[];for(let J=0;J<re;J+=1)for(let K=0;K<oe;K+=1){const L=K*t.tileSize*v,fe=J*t.tileSize*v,ae=Math.min((K+1)*t.tileSize,O)*v,ue=Math.min((J+1)*t.tileSize,B)*v;G.push({url:en(t,P,K,J),bounds:[L,fe,ae,ue]})}return Promise.allSettled(G.map(async J=>{const K=!!n,L=await fetch(J.url,{headers:K?{Authorization:n}:void 0});if(!L.ok)throw new Error(`HTTP ${L.status}`);const fe=await createImageBitmap(await L.blob());return{tile:J,bitmap:fe}})).then(J=>{if(E){for(const fe of J)fe.status==="fulfilled"&&fe.value.bitmap.close();return}const K=he.width/Math.max(1,t.width),L=he.height/Math.max(1,t.height);for(const fe of J){if(fe.status!=="fulfilled")continue;const{tile:{bounds:ae},bitmap:ue}=fe.value,j=ae[0]*K,ve=ae[1]*L,Re=Math.max(1,(ae[2]-ae[0])*K),Ie=Math.max(1,(ae[3]-ae[1])*L);se.drawImage(ue,j,ve,Re,Ie),ue.close()}u.current=he,$()}),()=>{E=!0}},[t,n,g,b,F,te,W,$]),h.useEffect(()=>{$()},[$]),h.useEffect(()=>{if(i)return i.current=$,()=>{i.current===$&&(i.current=null)}},[i,$]),h.useEffect(()=>()=>{f.current={active:!1,pointerId:null},p.current!==null&&(cancelAnimationFrame(p.current),p.current=null),m.current=!1},[]),Me.jsx("canvas",{ref:s,className:o,style:Pe,onPointerDown:Ze,onPointerMove:me,onPointerUp:ne,onPointerCancel:ne,onContextMenu:E=>{E.preventDefault()},onWheel:E=>{E.preventDefault(),E.stopPropagation()}})}function Zi({imageWidth:t,imageHeight:e,tiles:n,viewState:r,className:i,style:o}){const a=h.useRef(null),s=h.useRef(null),u=h.useMemo(()=>({width:"100%",height:"100%",display:"block",...o}),[o]);return h.useEffect(()=>{const c=a.current;if(!c)return;const f=new Yn({canvas:c,imageWidth:t,imageHeight:e,initialViewState:r});return s.current=f,f.setTiles(n),()=>{f.destroy(),s.current=null}},[t,e]),h.useEffect(()=>{const c=s.current;c&&c.setTiles(n)},[n]),h.useEffect(()=>{const c=s.current;!c||!r||c.setViewState(r)},[r]),Me.jsx("canvas",{ref:a,className:i,style:u})}function nr(t){const e=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0,e))}function st(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return null;const n=at(e??[]);if(n.length===0){const b={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return t.fillModes instanceof Uint8Array&&(b.fillModes=new Uint8Array(0)),t.ids instanceof Uint32Array&&(b.ids=new Uint32Array(0)),b}const r=nr(t),i=t.positions,o=t.paletteIndices,a=t.fillModes instanceof Uint8Array&&t.fillModes.length>=r?t.fillModes:null,s=t.ids instanceof Uint32Array&&t.ids.length>=r?t.ids:null,u=new Float32Array(r*2),c=new Uint16Array(r),f=a?new Uint8Array(r):null,p=s?new Uint32Array(r):null;let m=0;for(let b=0;b<r;b+=1){const x=i[b*2],R=i[b*2+1];Pt(x,R,n)&&(u[m*2]=x,u[m*2+1]=R,c[m]=o[b],f&&(f[m]=a[b]),p&&(p[m]=s[b]),m+=1)}const g={count:m,positions:u.subarray(0,m*2),paletteIndices:c.subarray(0,m)};return f&&(g.fillModes=f.subarray(0,m)),p&&(g.ids=p.subarray(0,m)),g}function rr(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return new Uint32Array(0);const n=at(e??[]);if(n.length===0)return new Uint32Array(0);const r=nr(t);if(r===0)return new Uint32Array(0);const i=t.positions,o=new Uint32Array(r);let a=0;for(let s=0;s<r;s+=1){const u=i[s*2],c=i[s*2+1];Pt(u,c,n)&&(o[a]=s,a+=1)}return o.subarray(0,a)}let Mt=null;const Ki=`
32
+ `;class On{constructor(e){M(this,"canvas");M(this,"gl");M(this,"camera",new Tr);M(this,"imageWidth");M(this,"imageHeight");M(this,"clearColor");M(this,"program");M(this,"vao");M(this,"quadBuffer");M(this,"uCameraLocation");M(this,"uBoundsLocation");M(this,"uTextureLocation");M(this,"resizeObserver");M(this,"tiles",[]);M(this,"frameId",null);M(this,"loadVersion",0);M(this,"destroyed",!1);M(this,"fitted",!1);M(this,"controlledViewState",!1);this.canvas=e.canvas,this.imageWidth=Math.max(1,e.imageWidth),this.imageHeight=Math.max(1,e.imageHeight),this.clearColor=e.clearColor??[.03,.05,.08,1],this.gl=Er(this.canvas),this.program=Rr(this.gl,Pr,Cr);const n=this.gl.createVertexArray(),r=this.gl.createBuffer();if(!n||!r)throw new Error("Failed to create WebGL buffers.");this.vao=n,this.quadBuffer=r,this.gl.bindVertexArray(this.vao),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.quadBuffer);const i=new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]);this.gl.bufferData(this.gl.ARRAY_BUFFER,i,this.gl.STATIC_DRAW);const o=this.gl.getAttribLocation(this.program,"aUnit"),a=this.gl.getAttribLocation(this.program,"aUv");if(o<0||a<0)throw new Error("Failed to get attribute locations.");const s=4*Float32Array.BYTES_PER_ELEMENT;this.gl.enableVertexAttribArray(o),this.gl.vertexAttribPointer(o,2,this.gl.FLOAT,!1,s,0),this.gl.enableVertexAttribArray(a),this.gl.vertexAttribPointer(a,2,this.gl.FLOAT,!1,s,2*Float32Array.BYTES_PER_ELEMENT),this.gl.bindVertexArray(null),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null),this.uCameraLocation=Lt(this.gl,this.program,"uCamera"),this.uBoundsLocation=Lt(this.gl,this.program,"uBounds"),this.uTextureLocation=Lt(this.gl,this.program,"uTexture"),e.initialViewState&&(this.controlledViewState=!0,this.camera.setViewState(e.initialViewState)),this.resizeObserver=new ResizeObserver(()=>{this.resize()}),this.resizeObserver.observe(this.canvas),this.resize()}async setTiles(e){if(this.destroyed)return;const n=++this.loadVersion,r=await Promise.all(e.map(async i=>await this.loadTile(i,n)));if(this.destroyed||n!==this.loadVersion){for(const i of r)i&&this.gl.deleteTexture(i.texture);return}this.disposeTiles(this.tiles),this.tiles=r.filter(i=>i!==null),this.requestRender()}setViewState(e){this.controlledViewState=!0,this.camera.setViewState(e),this.requestRender()}getViewState(){return this.camera.getViewState()}destroy(){this.destroyed||(this.destroyed=!0,this.loadVersion+=1,this.frameId!==null&&(cancelAnimationFrame(this.frameId),this.frameId=null),this.resizeObserver.disconnect(),this.disposeTiles(this.tiles),this.tiles=[],this.gl.deleteBuffer(this.quadBuffer),this.gl.deleteVertexArray(this.vao),this.gl.deleteProgram(this.program))}async loadTile(e,n){try{const r=await fetch(e.url);if(!r.ok)throw new Error(`Tile fetch failed: ${r.status} ${r.statusText}`);const i=await r.blob(),o=await createImageBitmap(i);if(this.destroyed||n!==this.loadVersion)return o.close(),null;const a=this.gl.createTexture();if(!a)throw o.close(),new Error("Failed to create tile texture.");return this.gl.bindTexture(this.gl.TEXTURE_2D,a),this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,1),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,o),this.gl.bindTexture(this.gl.TEXTURE_2D,null),o.close(),{id:e.id,bounds:e.bounds,texture:a}}catch(r){return console.error(`[M1TileRenderer] tile load failed: ${e.id}`,r),null}}resize(){if(this.destroyed)return;const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),a=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==a)&&(this.canvas.width=o,this.canvas.height=a),this.camera.setViewport(n,r),this.gl.viewport(0,0,this.canvas.width,this.canvas.height),!this.fitted&&!this.controlledViewState&&(this.fitToImage(),this.fitted=!0),this.requestRender()}fitToImage(){const e=this.camera.getViewportSize(),n=Math.min(e.width/this.imageWidth,e.height/this.imageHeight),r=Number.isFinite(n)&&n>0?n:1,i=e.width/r,o=e.height/r,a=(this.imageWidth-i)*.5,s=(this.imageHeight-o)*.5;this.camera.setViewState({zoom:r,offsetX:a,offsetY:s})}requestRender(){this.frameId!==null||this.destroyed||(this.frameId=requestAnimationFrame(()=>{this.frameId=null,this.render()}))}render(){if(!this.destroyed){this.gl.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.useProgram(this.program),this.gl.bindVertexArray(this.vao),this.gl.uniformMatrix3fv(this.uCameraLocation,!1,this.camera.getMatrix()),this.gl.uniform1i(this.uTextureLocation,0);for(const e of this.tiles)this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,e.texture),this.gl.uniform4f(this.uBoundsLocation,e.bounds[0],e.bounds[1],e.bounds[2],e.bounds[3]),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4);this.gl.bindTexture(this.gl.TEXTURE_2D,null),this.gl.bindVertexArray(null)}}disposeTiles(e){for(const n of e)this.gl.deleteTexture(n.texture)}}const Ir=.1,vr=4e6,_r=4096,Ur=64,Fr=1,Br=4,Vn=1e-6,Lr=24;function Tt(t,e,n){return Math.max(e,Math.min(n,t))}function Le(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function zr(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const n of t){if(!Array.isArray(n)||n.length<2)continue;const r=Number(n[0]),i=Number(n[1]);if(!Number.isFinite(r)||!Number.isFinite(i))continue;const o=e[e.length-1];o&&Math.abs(o[0]-r)<1e-9&&Math.abs(o[1]-i)<1e-9||e.push([r,i])}return e}function Nr(t,e,n){if(e<=Vn||n<8)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return Le(r)}function zt(t,e){if(!t.length)return[];let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,u]of t)s<n&&(n=s),s>i&&(i=s),u<r&&(r=u),u>o&&(o=u);if(!Number.isFinite(n)||!Number.isFinite(r))return[];const a=Math.max(e,1);return Le([[n-a,r-a],[i+a,r-a],[i+a,o+a],[n-a,o+a]])}function kr(t,e){let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[s,u]of t)s<n&&(n=s),s>i&&(i=s),u<r&&(r=u),u>o&&(o=u);const a=Math.max(e,1);return[n-a,r-a,i+a,o+a]}function Dr(t,e,n){const r=Math.max(Ir,Number(n.minRasterStep)||0),i=Math.max(32768,Math.floor(n.maxRasterPixels||vr)),o=Math.max(256,Math.floor(n.maxRasterSize||_r)),a=Math.max(.001,t[2]-t[0]),s=Math.max(.001,t[3]-t[1]);let u=Math.max(r,Number.EPSILON),c=3,h=Math.ceil(a/u)+c*2+1,b=Math.ceil(s/u)+c*2+1;for(;(h>o||b>o||h*b>i)&&(u*=1.15,h=Math.ceil(a/u)+c*2+1,b=Math.ceil(s/u)+c*2+1,!(u>Math.max(a,s))););return h=Math.max(8,h),b=Math.max(8,b),{minX:t[0],minY:t[1],step:u,padding:c,width:h,height:b}}function Xr(t,e){if(typeof OffscreenCanvas<"u"){const r=new OffscreenCanvas(t,e).getContext("2d",{willReadFrequently:!0});if(r)return r}if(typeof document<"u"){const n=document.createElement("canvas");return n.width=t,n.height=e,n.getContext("2d",{willReadFrequently:!0})}return null}function Wr(t,e){return[(t[0]-e.minX)/e.step+e.padding,(t[1]-e.minY)/e.step+e.padding]}function Yr(t,e,n){const r=Xr(n.width,n.height);if(!r)return new Uint8Array(0);r.clearRect(0,0,n.width,n.height),r.fillStyle="#ffffff",r.strokeStyle="#ffffff",r.lineCap="round",r.lineJoin="round",r.lineWidth=e*2/n.step;const i=t.map(s=>Wr(s,n));if(i.length<=1){const s=i[0];if(!s)return new Uint8Array(0);r.beginPath(),r.arc(s[0],s[1],e/n.step,0,Math.PI*2),r.fill()}else{r.beginPath(),r.moveTo(i[0][0],i[0][1]);for(let s=1;s<i.length;s+=1)r.lineTo(i[s][0],i[s][1]);r.stroke()}const o=r.getImageData(0,0,n.width,n.height),a=new Uint8Array(n.width*n.height);for(let s=0;s<a.length;s+=1)a[s]=o.data[s*4+3]>=Lr?1:0;return a}function Or(t,e,n){const r=[],i=e+1,o=(s,u)=>u*i+s,a=(s,u)=>s>=0&&u>=0&&s<e&&u<n&&t[u*e+s]>0;for(let s=0;s<n;s+=1)for(let u=0;u<e;u+=1)a(u,s)&&(a(u,s-1)||r.push({start:o(u,s),end:o(u+1,s),dir:0}),a(u+1,s)||r.push({start:o(u+1,s),end:o(u+1,s+1),dir:1}),a(u,s+1)||r.push({start:o(u+1,s+1),end:o(u,s+1),dir:2}),a(u-1,s)||r.push({start:o(u,s+1),end:o(u,s),dir:3}));return r}function Vr(t,e){const n=(e-t+4)%4;return n===1?0:n===0?1:n===3?2:3}function Gr(t){if(!t.length)return[];const e=new Map;for(let i=0;i<t.length;i+=1){const o=e.get(t[i].start);o?o.push(i):e.set(t[i].start,[i])}const n=new Uint8Array(t.length),r=[];for(let i=0;i<t.length;i+=1){if(n[i])continue;const o=t[i],a=o.start;let s=o.end,u=o.dir;const c=[o.start,o.end];n[i]=1;let h=0;const b=t.length*3;for(;s!==a&&h<b;){const m=e.get(s);if(!m||m.length===0)break;let g=-1,y=1/0;for(const E of m){if(n[E])continue;const _=t[E],X=Vr(u,_.dir);X<y&&(y=X,g=E)}if(g<0)break;n[g]=1;const x=t[g];s=x.end,u=x.dir,c.push(s),h+=1}c.length>=4&&c[0]===c[c.length-1]&&r.push(c)}return r}function qr(t,e,n){const r=e+1,i=[];for(const o of t){const a=o%r,s=Math.floor(o/r);i.push([n.minX+(a-n.padding)*n.step,n.minY+(s-n.padding)*n.step])}return Le(i)}function Hr(t){if(t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function $r(t,e=1e-9){const n=Le(t);if(n.length<5)return n;const r=[n[0]];for(let i=1;i<n.length-1;i+=1){const o=r[r.length-1],a=n[i],s=n[i+1],u=(a[0]-o[0])*(s[1]-a[1])-(a[1]-o[1])*(s[0]-a[0]);Math.abs(u)<=e||r.push(a)}return r.push(r[0]),Le(r)}function Zr(t,e,n){const r=n[0]-e[0],i=n[1]-e[1],o=r*r+i*i;if(o<=1e-12){const b=t[0]-e[0],m=t[1]-e[1];return b*b+m*m}const a=Tt(((t[0]-e[0])*r+(t[1]-e[1])*i)/o,0,1),s=e[0]+r*a,u=e[1]+i*a,c=t[0]-s,h=t[1]-u;return c*c+h*h}function Kr(t,e){if(t.length<=2||e<=0)return t.slice();const n=new Uint8Array(t.length);n[0]=1,n[t.length-1]=1;const r=e*e,i=[[0,t.length-1]];for(;i.length>0;){const a=i.pop();if(!a)break;const[s,u]=a;if(u-s<=1)continue;let c=0,h=-1;for(let b=s+1;b<u;b+=1){const m=Zr(t[b],t[s],t[u]);m>c&&(c=m,h=b)}h>=0&&c>r&&(n[h]=1,i.push([s,h],[h,u]))}const o=[];for(let a=0;a<t.length;a+=1)n[a]&&o.push(t[a]);return o}function jr(t,e){const n=Le(t);if(n.length<5||e<=0)return n;const r=n.slice(0,-1),i=Kr(r,e);return i.length<3?n:Le(i)}function Jr(t,e){let n=Le(t);if(e<=0||n.length<5)return n;for(let r=0;r<e;r+=1){const i=n.slice(0,-1);if(i.length<3)break;const o=[];for(let a=0;a<i.length;a+=1){const s=i[a],u=i[(a+1)%i.length];o.push([s[0]*.75+u[0]*.25,s[1]*.75+u[1]*.25],[s[0]*.25+u[0]*.75,s[1]*.25+u[1]*.75])}n=Le(o)}return n}function nt(t,e){return e?Le(t.map(([n,r])=>[Tt(n,e[0],e[2]),Tt(r,e[1],e[3])])):t}function Qr(t,e){const n=zr(t),r=Math.max(Vn,Number(e.radius)||0);if(n.length===0||!Number.isFinite(r))return[];const i=Math.max(12,Math.floor(e.circleSides||Ur));if(n.length===1)return nt(Nr(n[0],r,i),e.clipBounds);const o=kr(n,r),a=Dr(o,r,e),s=Yr(n,r,a);if(!s.length)return nt(zt(n,r),e.clipBounds);const u=Or(s,a.width,a.height),c=Gr(u);if(!c.length)return nt(zt(n,r),e.clipBounds);let h=[],b=0;for(const x of c){const E=qr(x,a.width,a),_=Math.abs(Hr(E));_<=b||(b=_,h=E)}if(!h.length)return nt(zt(n,r),e.clipBounds);const m=typeof e.simplifyTolerance=="number"&&Number.isFinite(e.simplifyTolerance)?Math.max(0,e.simplifyTolerance):a.step*.2,g=typeof e.smoothingPasses=="number"&&Number.isFinite(e.smoothingPasses)?Math.round(Tt(e.smoothingPasses,0,Br)):Fr,y=jr(Jr($r(h,a.step*.001),g),m);return nt(y,e.clipBounds)}function Rn(t){return typeof t=="number"&&Number.isFinite(t)}function ei(t){return Array.isArray(t)&&t.length>=2&&Rn(t[0])&&Rn(t[1])}function Gn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>ei(e))}function qn(t){return Array.isArray(t)&&t.length>0&&t.every(e=>Gn(e))}function ti(t){return Array.isArray(t)&&t.length>0&&t.every(e=>qn(e))}function ni(t){if(!Array.isArray(t)||t.length<3)return[];const e=[];for(const i of t){if(!Array.isArray(i)||i.length<2)continue;const o=Number(i[0]),a=Number(i[1]);if(!Number.isFinite(o)||!Number.isFinite(a))continue;const s=e[e.length-1];s&&s[0]===o&&s[1]===a||e.push([o,a])}if(e.length<3)return[];const n=e[0],r=e[e.length-1];return(n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e.length>=4?e:[]}function Wt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return e*.5}function Nt(t){if(!Array.isArray(t)||t.length===0)return[];const e=[];for(const o of t){const a=ni(o);a.length>=4&&e.push(a)}if(e.length===0)return[];if(e.length===1)return[e[0]];let n=0,r=0;for(let o=0;o<e.length;o+=1){const a=Math.abs(Wt(e[o]));a<=r||(r=a,n=o)}const i=[e[n]];for(let o=0;o<e.length;o+=1)o!==n&&i.push(e[o]);return i}function Hn(t){if(!t)return[];if(Gn(t)){const e=Nt([t]);return e.length>0?[e]:[]}if(qn(t)){const e=Nt(t);return e.length>0?[e]:[]}if(ti(t)){const e=[];for(const n of t){const r=Nt(n);r.length>0&&e.push(r)}return e}return[]}function En(t,e,n){let r=!1;for(let i=0,o=n.length-1;i<n.length;o=i,i+=1){const a=n[i][0],s=n[i][1],u=n[o][0],c=n[o][1];s>e!=c>e&&t<(u-a)*(e-s)/(c-s||Number.EPSILON)+a&&(r=!r)}return r}function ut(t){const e=[];for(const n of t??[]){const r=Hn(n);for(const i of r){const o=i[0];if(!o||o.length<4)continue;let a=1/0,s=1/0,u=-1/0,c=-1/0;for(const[b,m]of o)b<a&&(a=b),b>u&&(u=b),m<s&&(s=m),m>c&&(c=m);if(!Number.isFinite(a)||!Number.isFinite(s)||!Number.isFinite(u)||!Number.isFinite(c))continue;let h=Math.abs(Wt(o));for(let b=1;b<i.length;b+=1)h-=Math.abs(Wt(i[b]));e.push({outer:o,holes:i.slice(1),minX:a,minY:s,maxX:u,maxY:c,area:Math.max(1e-6,h)})}}return e}function jt(t,e,n){if(t<n.minX||t>n.maxX||e<n.minY||e>n.maxY||!En(t,e,n.outer))return!1;for(const r of n.holes)if(En(t,e,r))return!1;return!0}function Pt(t,e,n){for(const r of n)if(jt(t,e,r))return!0;return!1}const Jt=[160,160,160,255];function Q(t,e,n){return Math.max(e,Math.min(n,t))}function Qt(t,e,n){const r=Number(t),i=Number(e),o=Number(n);return!Number.isFinite(r)||r<=0?1:!Number.isFinite(i)||!Number.isFinite(o)?r:Math.pow(2,i-o)*r}function ri(t,e,n){let i=100*Qt(t,e,n);if(Number(t)){let o="μm";return i>1e3&&(i/=1e3,o="mm"),`${i.toPrecision(3)} ${o}`}return`${Math.round(i*1e3)/1e3} pixels`}function ii(t,e){return!t&&!e?!0:!t||!e?!1:Math.abs((t.zoom??0)-(e.zoom??0))<1e-6&&Math.abs((t.offsetX??0)-(e.offsetX??0))<1e-6&&Math.abs((t.offsetY??0)-(e.offsetY??0))<1e-6&&Math.abs((t.rotationDeg??0)-(e.rotationDeg??0))<1e-6}function oi(t){const e=String(t??"").trim();if(!e)return"";if(/^bearer\s+/i.test(e)){const n=e.replace(/^bearer\s+/i,"").trim();return n?`Bearer ${n}`:""}return`Bearer ${e}`}function $n(t){const n=String(t??"").trim().match(/^#?([0-9a-fA-F]{6})$/);if(!n)return[...Jt];const r=Number.parseInt(n[1],16);return[r>>16&255,r>>8&255,r&255,255]}function si(t){const e=[[...Jt]],n=new Map;for(const i of t??[]){const o=String(i?.termId??"");!o||n.has(o)||(n.set(o,e.length),e.push($n(i?.termColor)))}const r=new Uint8Array(e.length*4);for(let i=0;i<e.length;i+=1)r[i*4]=e[i][0],r[i*4+1]=e[i][1],r[i*4+2]=e[i][2],r[i*4+3]=e[i][3];return{colors:r,termToPaletteIndex:n}}function Tn(t,e,n){const r=t.createShader(t.VERTEX_SHADER),i=t.createShader(t.FRAGMENT_SHADER);if(!r||!i)throw new Error("Shader allocation failed");if(t.shaderSource(r,e),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(r)||"vertex compile failed");if(t.shaderSource(i,n),t.compileShader(i),!t.getShaderParameter(i,t.COMPILE_STATUS))throw new Error(t.getShaderInfoLog(i)||"fragment compile failed");const o=t.createProgram();if(!o)throw new Error("Program allocation failed");if(t.attachShader(o,r),t.attachShader(o,i),t.linkProgram(o),t.deleteShader(r),t.deleteShader(i),!t.getProgramParameter(o,t.LINK_STATUS))throw new Error(t.getProgramInfoLog(o)||"program link failed");return o}const ai="rgba(255, 77, 79, 0.16)",ui=3,li=2,Zn=96,ci=1,Pn=[],Ct=[],Cn=1e3,Kn=2,jn=2,fi=4096,hi=.2,di=1.12,mi=.89,gi=32,pi="#000000",bi=.1,yi="#FFCF00",wi="#FF0000",Mi=1.5,In=[2,2],Si=1,xi=.25,Ai=4,Ri=1,Ei=0,Ti=4,Pi=.05,Ci=256,vn=1.5,Ve={color:"#ff4d4f",width:2,lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},Ii={color:"#4cc9f0",width:2,lineDash:[10,8],lineJoin:"round",lineCap:"round",shadowColor:"rgba(0, 0, 0, 0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0},Ie={fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:12,fontWeight:500,textColor:"#ffffff",backgroundColor:"rgba(8, 14, 22, 0.88)",borderColor:"rgba(255, 77, 79, 0.85)",borderWidth:1,paddingX:6,paddingY:4,offsetY:10,borderRadius:3};function ke(t,e,n){return Math.max(e,Math.min(n,t))}function bt(t){return t==="stamp-rectangle"||t==="stamp-circle"||t==="stamp-rectangle-4096px"||t==="stamp-rectangle-2mm2"||t==="stamp-circle-2mm2"||t==="stamp-circle-hpf-0.2mm2"}function ot(t,e){return typeof t!="number"||!Number.isFinite(t)||t<=0?e:t}function vi(t){return{rectangleAreaMm2:ot(t?.rectangleAreaMm2,Kn),circleAreaMm2:ot(t?.circleAreaMm2,jn),rectanglePixelSize:ot(t?.rectanglePixelSize,fi)}}function _i(t,e){return typeof t!="number"||!Number.isFinite(t)?e:ke(t,0,1)}function Ui(t){if(!Array.isArray(t))return In;const e=t.filter(n=>Number.isFinite(n)&&n>=0);return e.length>0?e:In}function Fi(t){return typeof t!="number"||!Number.isFinite(t)?Si:ke(t,xi,Ai)}function Bi(t){return typeof t!="number"||!Number.isFinite(t)?Ri:Math.round(ke(t,Ei,Ti))}function Li(t){const e=ot(t?.radius,gi),n=ot(t?.cursorLineWidth,Mi),r=Fi(t?.edgeDetail),i=Bi(t?.edgeSmoothing);return{radius:e,edgeDetail:r,edgeSmoothing:i,clickSelectRoi:t?.clickSelectRoi===!0,fillColor:t?.fillColor||pi,fillOpacity:_i(t?.fillOpacity,bi),cursorColor:t?.cursorColor||yi,cursorActiveColor:t?.cursorActiveColor||wi,cursorLineWidth:n,cursorLineDash:Ui(t?.cursorLineDash)}}function zi(t){return t*Cn*Cn}function _n(t,e){return!t||!Number.isFinite(e)||e<=0?[]:Be([[t[0]-e,t[1]-e],[t[0]+e,t[1]-e],[t[0]+e,t[1]+e],[t[0]-e,t[1]+e]])}function Ni(t,e,n=Zn){if(!t||!Number.isFinite(e)||e<=0)return[];const r=[];for(let i=0;i<=n;i+=1){const o=i/n*Math.PI*2;r.push([t[0]+Math.cos(o)*e,t[1]+Math.sin(o)*e])}return Be(r)}function Be(t){if(!Array.isArray(t)||t.length<3)return[];const e=t.map(([i,o])=>[i,o]),n=e[0],r=e[e.length-1];return!n||!r?[]:((n[0]!==r[0]||n[1]!==r[1])&&e.push([n[0],n[1]]),e)}function Yt(t,e){return!t||!e?[]:Be([[t[0],t[1]],[e[0],t[1]],[e[0],e[1]],[t[0],e[1]]])}function Ot(t,e,n=Zn){if(!t||!e)return[];const r=(t[0]+e[0])*.5,i=(t[1]+e[1])*.5,o=Math.hypot(e[0]-t[0],e[1]-t[1])*.5;if(o<1)return[];const a=[];for(let s=0;s<=n;s+=1){const u=s/n*Math.PI*2;a.push([r+Math.cos(u)*o,i+Math.sin(u)*o])}return Be(a)}function Vt(t){if(!Array.isArray(t)||t.length<4)return 0;let e=0;for(let n=0;n<t.length-1;n+=1){const r=t[n],i=t[n+1];e+=r[0]*i[1]-i[0]*r[1]}return Math.abs(e*.5)}function Un(t){if(!Array.isArray(t)||t.length===0)return[0,0,0,0];let e=1/0,n=1/0,r=-1/0,i=-1/0;for(const[o,a]of t)o<e&&(e=o),o>r&&(r=o),a<n&&(n=a),a>i&&(i=a);return[e,n,r,i]}function Fn(t){return Array.isArray(t)&&t.length>=4&&Vt(t)>ci}function Gt(t,e,n=!1){if(e.length!==0){t.moveTo(e[0][0],e[0][1]);for(let r=1;r<e.length;r+=1)t.lineTo(e[r][0],e[r][1]);n&&t.closePath()}}function Ge(t,e,n,r=!1,i=!1){e.length!==0&&(t.beginPath(),Gt(t,e,r),i&&r&&(t.fillStyle=ai,t.fill()),t.strokeStyle=n.color,t.lineWidth=n.width,t.lineJoin=n.lineJoin,t.lineCap=n.lineCap,t.shadowColor=n.shadowColor,t.shadowBlur=n.shadowBlur,t.shadowOffsetX=n.shadowOffsetX,t.shadowOffsetY=n.shadowOffsetY,t.setLineDash(n.lineDash),t.stroke(),t.setLineDash(Ct),t.shadowColor="rgba(0, 0, 0, 0)",t.shadowBlur=0,t.shadowOffsetX=0,t.shadowOffsetY=0)}function Jn(t){const e=Array.isArray(t?.lineDash)?t.lineDash.filter(a=>Number.isFinite(a)&&a>=0):Ct,n=typeof t?.width=="number"&&Number.isFinite(t.width)?Math.max(0,t.width):Ve.width,r=typeof t?.shadowBlur=="number"&&Number.isFinite(t.shadowBlur)?Math.max(0,t.shadowBlur):Ve.shadowBlur,i=typeof t?.shadowOffsetX=="number"&&Number.isFinite(t.shadowOffsetX)?t.shadowOffsetX:Ve.shadowOffsetX,o=typeof t?.shadowOffsetY=="number"&&Number.isFinite(t.shadowOffsetY)?t.shadowOffsetY:Ve.shadowOffsetY;return{color:t?.color||Ve.color,width:n,lineDash:e.length?e:Ct,lineJoin:t?.lineJoin||Ve.lineJoin,lineCap:t?.lineCap||Ve.lineCap,shadowColor:t?.shadowColor||Ve.shadowColor,shadowBlur:r,shadowOffsetX:i,shadowOffsetY:o}}function rt(t,e){return e?Jn({color:e.color??t.color,width:e.width??t.width,lineDash:e.lineDash??t.lineDash,lineJoin:e.lineJoin??t.lineJoin,lineCap:e.lineCap??t.lineCap,shadowColor:e.shadowColor??t.shadowColor,shadowBlur:e.shadowBlur??t.shadowBlur,shadowOffsetX:e.shadowOffsetX??t.shadowOffsetX,shadowOffsetY:e.shadowOffsetY??t.shadowOffsetY}):t}function Bn(t,e){return t==null||e===null||e===void 0?!1:String(t)===String(e)}function ki(t){const e=t[0];return Array.isArray(e)&&Array.isArray(e[0])}function Ln(t){return typeof t=="number"&&Number.isFinite(t)}function Di(t){return Array.isArray(t)&&t.length>=2&&Ln(t[0])&&Ln(t[1])}function Xi(t){return Array.isArray(t)&&t.length>=2&&t.every(e=>Di(e))}function Qn(t,e){if(!(!Array.isArray(t)||t.length===0)){if(Xi(t)){e.push(t.map(([n,r])=>[n,r]));return}for(const n of t)Qn(n,e)}}function zn(t,e){const n=[];Qn(t,n);const r=[];for(const i of n){if(i.length<2)continue;const o=e?Be(i):i;o.length>=(e?4:2)&&r.push(o)}return r}function Wi(t,e,n,r){if(!(e.length<4||n.length===0)){t.save(),t.beginPath(),Gt(t,e,!0);for(const i of n)i.length<4||Gt(t,i,!0);t.fillStyle=r,t.fill("evenodd"),t.restore()}}function Yi(t){const e=typeof t?.paddingX=="number"&&Number.isFinite(t.paddingX)?Math.max(0,t.paddingX):Ie.paddingX,n=typeof t?.paddingY=="number"&&Number.isFinite(t.paddingY)?Math.max(0,t.paddingY):Ie.paddingY,r=typeof t?.fontSize=="number"&&Number.isFinite(t.fontSize)?Math.max(8,t.fontSize):Ie.fontSize,i=typeof t?.borderWidth=="number"&&Number.isFinite(t.borderWidth)?Math.max(0,t.borderWidth):Ie.borderWidth,o=typeof t?.offsetY=="number"&&Number.isFinite(t.offsetY)?t.offsetY:Ie.offsetY,a=typeof t?.borderRadius=="number"&&Number.isFinite(t.borderRadius)?Math.max(0,t.borderRadius):Ie.borderRadius;return{fontFamily:t?.fontFamily||Ie.fontFamily,fontSize:r,fontWeight:t?.fontWeight||Ie.fontWeight,textColor:t?.textColor||Ie.textColor,backgroundColor:t?.backgroundColor||Ie.backgroundColor,borderColor:t?.borderColor||Ie.borderColor,borderWidth:i,paddingX:e,paddingY:n,offsetY:o,borderRadius:a}}function Oi(t,e,n,r,i,o){const a=Math.max(0,Math.min(o,r*.5,i*.5));t.beginPath(),t.moveTo(e+a,n),t.lineTo(e+r-a,n),t.quadraticCurveTo(e+r,n,e+r,n+a),t.lineTo(e+r,n+i-a),t.quadraticCurveTo(e+r,n+i,e+r-a,n+i),t.lineTo(e+a,n+i),t.quadraticCurveTo(e,n+i,e,n+i-a),t.lineTo(e,n+a),t.quadraticCurveTo(e,n,e+a,n),t.closePath()}function Vi(t){if(!t.length)return null;let e=1/0;for(const i of t)i[1]<e&&(e=i[1]);if(!Number.isFinite(e))return null;let n=1/0,r=-1/0;for(const i of t)Math.abs(i[1]-e)>.5||(i[0]<n&&(n=i[0]),i[0]>r&&(r=i[0]));return!Number.isFinite(n)||!Number.isFinite(r)?null:[(n+r)*.5,e]}function Gi(t){let e=null;for(const n of t){const r=Vi(n.outer);r&&(!e||r[1]<e[1]||r[1]===e[1]&&r[0]<e[0])&&(e=r)}return e}function Nn(t){const e=Hn(t);if(e.length===0)return[];const n=[];for(const r of e){const i=r[0];if(!i||i.length<4)continue;const o=i.map(([s,u])=>[s,u]),a=[];for(let s=1;s<r.length;s+=1){const u=r[s];!u||u.length<4||a.push(u.map(([c,h])=>[c,h]))}n.push({outer:o,holes:a})}return n}function qi(t,e,n,r,i,o){const a=e.trim();if(!a)return;t.save(),t.font=`${o.fontWeight} ${o.fontSize}px ${o.fontFamily}`,t.textAlign="center",t.textBaseline="middle";const u=t.measureText(a).width+o.paddingX*2,c=o.fontSize+o.paddingY*2,h=ke(n[0],u*.5+1,r-u*.5-1),b=ke(n[1]-o.offsetY,c*.5+1,i-c*.5-1),m=h-u*.5,g=b-c*.5;t.fillStyle=o.backgroundColor,t.strokeStyle=o.borderColor,t.lineWidth=o.borderWidth,Oi(t,m,g,u,c,o.borderRadius),t.fill(),o.borderWidth>0&&t.stroke(),t.fillStyle=o.textColor,t.fillText(a,h,b+.5),t.restore()}function yt(t,e,n){return[ke(t[0],0,e),ke(t[1],0,n)]}function it(t){if(!Array.isArray(t)||t.length<2)return null;const e=Number(t[0]),n=Number(t[1]);return!Number.isFinite(e)||!Number.isFinite(n)?null:[e,n]}function er({tool:t,imageWidth:e,imageHeight:n,imageMpp:r,imageZoom:i,stampOptions:o,brushOptions:a,projectorRef:s,onBrushTap:u,onDrawComplete:c,onPatchComplete:h,enabled:b,viewStateSignal:m,persistedRegions:g,patchRegions:y,persistedPolygons:x,regionStrokeStyle:E,regionStrokeHoverStyle:_,regionStrokeActiveStyle:X,patchStrokeStyle:F,resolveRegionStrokeStyle:W,overlayShapes:P,hoveredRegionId:z=null,activeRegionId:Z=null,regionLabelStyle:ee,invalidateRef:N,className:ve,style:Te}){const $=d.useRef(null),_e=d.useRef(!1),ze=d.useRef(new Map),Ke=d.useRef(t),be=d.useRef({isDrawing:!1,pointerId:null,start:null,current:null,cursor:null,cursorScreen:null,points:[],screenPoints:[],stampCenter:null}),ne=b??t!=="cursor",T=d.useMemo(()=>g&&g.length>0?g:!x||x.length===0?Pn:x.map((l,f)=>({id:f,coordinates:l})),[g,x]),C=d.useMemo(()=>y??Pn,[y]),I=d.useMemo(()=>{const l=[];for(let f=0;f<T.length;f+=1){const p=T[f],S=Nn(p.coordinates);S.length!==0&&l.push({region:p,regionIndex:f,regionKey:p.id??f,polygons:S})}return l},[T]),Y=d.useMemo(()=>{const l=[];for(let f=0;f<C.length;f+=1){const p=C[f],S=Nn(p.coordinates);S.length!==0&&l.push({region:p,regionIndex:f,regionKey:p.id??f,polygons:S})}return l},[C]),L=d.useMemo(()=>Jn(E),[E]),ie=d.useMemo(()=>rt(L,_),[L,_]),re=d.useMemo(()=>rt(L,X),[L,X]),we=d.useMemo(()=>rt(Ii,F),[F]),fe=d.useMemo(()=>Yi(ee),[ee]),oe=d.useMemo(()=>vi(o),[o]),V=d.useMemo(()=>Li(a),[a]),J=d.useMemo(()=>({position:"absolute",inset:0,zIndex:2,width:"100%",height:"100%",display:"block",touchAction:"none",pointerEvents:ne?"auto":"none",cursor:ne?t==="brush"?"none":"crosshair":"default",...Te}),[ne,t,Te]),K=d.useCallback(()=>{const l=$.current;if(!l)return;const f=l.getBoundingClientRect(),p=Math.max(1,window.devicePixelRatio||1),S=Math.max(1,Math.round(f.width*p)),A=Math.max(1,Math.round(f.height*p));(l.width!==S||l.height!==A)&&(l.width=S,l.height=A)},[]),D=d.useCallback(l=>{const f=s.current;if(!f||l.length===0)return[];const p=new Array(l.length);for(let S=0;S<l.length;S+=1){const A=it(f.worldToScreen(l[S][0],l[S][1]));if(!A)return[];p[S]=A}return p},[s]),ce=d.useCallback(l=>{const f=s.current,p=$.current;if(!f||!p)return null;const S=p.getBoundingClientRect(),A=it(f.screenToWorld(S.left+l[0],S.top+l[1]));return A?yt(A,e,n):null},[s,e,n]),se=d.useCallback(l=>{if(!Number.isFinite(l)||l<=0)return 0;const f=typeof r=="number"&&Number.isFinite(r)&&r>0?r:1,p=typeof i=="number"&&Number.isFinite(i)?i:0,S=s.current?.getViewState?.().zoom,A=typeof S=="number"&&Number.isFinite(S)&&S>0?S:1,B=p+Math.log2(A),O=Math.max(1e-9,Qt(f,p,B));return l/O/A},[r,i,s]),ae=d.useCallback((l,f)=>{if(!f)return[];let p=0;if(l==="stamp-rectangle-4096px"){const B=oe.rectanglePixelSize*.5;return _n(f,B).map(H=>yt(H,e,n))}if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"?p=l==="stamp-rectangle-2mm2"?Kn:oe.rectangleAreaMm2:(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2")&&(p=l==="stamp-circle-hpf-0.2mm2"?hi:l==="stamp-circle-2mm2"?jn:oe.circleAreaMm2),!Number.isFinite(p)||p<=0)return[];const S=zi(p);let A=[];if(l==="stamp-rectangle"||l==="stamp-rectangle-2mm2"){const B=se(Math.sqrt(S)*.5);A=_n(f,B)}else if(l==="stamp-circle"||l==="stamp-circle-2mm2"||l==="stamp-circle-hpf-0.2mm2"){const B=se(Math.sqrt(S/Math.PI));A=Ni(f,B)}return A.length?A.map(B=>yt(B,e,n)):[]},[se,e,n,oe]),j=d.useCallback(()=>{const l=be.current;return bt(t)?ae(t,l.stampCenter):t==="brush"?[]:l.isDrawing?t==="freehand"?l.points:t==="rectangle"?Yt(l.start,l.current):t==="circular"?Ot(l.start,l.current):[]:[]},[t,ae]),Ue=d.useCallback(l=>{const f=be.current;if(!f.isDrawing||f.screenPoints.length===0)return;const p=f.screenPoints;if(p.length===0)return;const S=V.radius;if(!(!Number.isFinite(S)||S<=0)){if(l.save(),l.globalAlpha=V.fillOpacity,l.fillStyle=V.fillColor,l.strokeStyle=V.fillColor,l.lineCap="round",l.lineJoin="round",l.lineWidth=S*2,p.length===1)l.beginPath(),l.arc(p[0][0],p[0][1],S,0,Math.PI*2),l.fill();else{l.beginPath(),l.moveTo(p[0][0],p[0][1]);for(let A=1;A<p.length;A+=1)l.lineTo(p[A][0],p[A][1]);l.stroke()}l.restore()}},[V]),Pe=d.useCallback(l=>{const f=be.current,p=f.cursor;if(!p)return;const S=f.cursorScreen??it(s.current?.worldToScreen(p[0],p[1])??[]);if(!S)return;const A=V.radius;!Number.isFinite(A)||A<=0||(l.save(),l.beginPath(),l.arc(S[0],S[1],A,0,Math.PI*2),l.strokeStyle=f.isDrawing?V.cursorActiveColor:V.cursorColor,l.lineWidth=V.cursorLineWidth,l.setLineDash(V.cursorLineDash),l.stroke(),l.setLineDash(Ct),l.restore())},[s,V]),Fe=d.useCallback(()=>{K();const l=$.current;if(!l)return;const f=l.getContext("2d");if(!f)return;const p=Math.max(1,window.devicePixelRatio||1),S=l.width/p,A=l.height/p;if(f.setTransform(1,0,0,1,0,0),f.clearRect(0,0,l.width,l.height),f.setTransform(p,0,0,p,0,0),I.length>0)for(const B of I){const{region:O,polygons:H,regionIndex:G,regionKey:he}=B,Xe=Bn(Z,he)?"active":Bn(z,he)?"hover":"default";let de=Xe==="active"?re:Xe==="hover"?ie:L;if(W){const te=W({region:O,regionId:he,regionIndex:G,state:Xe});de=rt(de,te||void 0)}for(const te of H){const me=D(te.outer);me.length>=4&&Ge(f,me,de,!0,!1);for(const Me of te.holes){const Se=D(Me);Se.length>=4&&Ge(f,Se,de,!0,!1)}}}if(Y.length>0)for(const B of Y)for(const O of B.polygons){const H=D(O.outer);H.length>=4&&Ge(f,H,we,!0,!1);for(const G of O.holes){const he=D(G);he.length>=4&&Ge(f,he,we,!0,!1)}}if(Array.isArray(P)&&P.length>0){const B=!!globalThis.__OPEN_PLANT_DEBUG_OVERLAY__,O=D(Be([[0,0],[e,0],[e,n],[0,n]]));for(let H=0;H<P.length;H+=1){const G=P[H];if(!G?.coordinates?.length||G.visible===!1)continue;const he=G.closed??ki(G.coordinates),Xe=zn(G.coordinates,he);if(G.invertedFill?.fillColor){const te=[],me=zn(G.coordinates,!0);for(const Me of me){const Se=D(Me);Se.length>=4&&te.push(Se)}if(B){const Me=String(G.id??H),Se=`${O.length}|${me.length}|${te.length}|${G.invertedFill.fillColor}`;ze.current.get(Me)!==Se&&(ze.current.set(Me,Se),console.debug("[open-plant] invertedFill",{id:G.id??H,outerRingPoints:O.length,sourceRingCount:me.length,holeRingCount:te.length,fillColor:G.invertedFill.fillColor}))}Wi(f,O,te,G.invertedFill.fillColor)}if(Xe.length===0)continue;const de=rt(L,G.stroke??G.strokeStyle);for(const te of Xe){const me=D(te);me.length<2||Ge(f,me,de,he,G.fill??!1)}}}if(ne)if(t==="brush")Ue(f),Pe(f);else{const B=j();if(B.length>0)if(t==="freehand"){const O=D(B);O.length>=2&&Ge(f,O,L,!1,!1),O.length>=3&&Ge(f,D(Be(B)),L,!0,!0)}else{const O=D(B);O.length>=4&&Ge(f,O,L,!0,!0)}}if(I.length>0)for(const B of I){if(!B.region.label)continue;const O=Gi(B.polygons);if(!O)continue;const H=it(s.current?.worldToScreen(O[0],O[1])??[]);H&&qi(f,B.region.label,H,S,A,fe)}},[ne,t,j,Ue,Pe,K,D,e,n,s,I,P,z,Z,L,ie,re,Y,we,W,fe]),U=d.useCallback(()=>{_e.current||(_e.current=!0,requestAnimationFrame(()=>{_e.current=!1,Fe()}))},[Fe]),ge=d.useCallback((l=!1)=>{const f=be.current,p=$.current;if(p&&f.pointerId!==null&&p.hasPointerCapture(f.pointerId))try{p.releasePointerCapture(f.pointerId)}catch{}f.isDrawing=!1,f.pointerId=null,f.start=null,f.current=null,f.points=[],f.screenPoints=[],f.stampCenter=null,l||(f.cursor=null,f.cursorScreen=null)},[]),Ce=d.useCallback(l=>{const f=s.current;if(!f||e<=0||n<=0)return null;const p=it(f.screenToWorld(l.clientX,l.clientY));return p?yt(p,e,n):null},[s,e,n]),ye=d.useCallback(l=>{const f=$.current;if(!f)return null;const p=f.getBoundingClientRect(),S=ke(l.clientX-p.left,0,p.width),A=ke(l.clientY-p.top,0,p.height);return!Number.isFinite(S)||!Number.isFinite(A)?null:[S,A]},[]),Qe=d.useCallback(()=>{const l=be.current;if(!l.isDrawing){ge(!0),U();return}let f=[];if(t==="freehand")l.points.length>=ui&&(f=Be(l.points));else if(t==="rectangle")f=Yt(l.start,l.current);else if(t==="circular")f=Ot(l.start,l.current);else if(t==="brush"){const p=l.points[l.points.length-1]??l.current??l.start;if(V.clickSelectRoi&&p&&l.points.length<=1&&u?.(p)){ge(!0),U();return}const S=V.edgeDetail,A=Math.max(Pi,V.radius*2/(Ci*S)),B=l.screenPoints.length>0?l.screenPoints:D(l.points),O=Qr(B,{radius:V.radius,minRasterStep:A,circleSides:Math.max(24,Math.round(64*S)),simplifyTolerance:A*.25,smoothingPasses:V.edgeSmoothing}),H=[];for(const G of O){const he=ce(G);he&&H.push(he)}f=Be(H)}(t==="freehand"||t==="rectangle"||t==="circular"||t==="brush")&&Fn(f)&&c&&c({tool:t,intent:t==="brush"?"brush":"roi",coordinates:f,bbox:Un(f),areaPx:Vt(f)}),ge(!0),U()},[t,c,ge,U,D,ce,V.radius,V.edgeDetail,V.edgeSmoothing,V.clickSelectRoi,u]),De=d.useCallback((l,f)=>{const p=ae(l,f);if(!Fn(p))return;const S=l==="stamp-rectangle-4096px"?"patch":"roi",A={tool:l,intent:S,coordinates:p,bbox:Un(p),areaPx:Vt(p)};c?.(A),S==="patch"&&h&&h(A)},[ae,c,h]),pe=d.useCallback((l,f,p)=>{const S=vn*vn,A=l.screenPoints[l.screenPoints.length-1];if(!A){l.points.push(f),l.screenPoints.push(p),l.current=f;return}const B=p[0]-A[0],O=p[1]-A[1];B*B+O*O>=S?(l.points.push(f),l.screenPoints.push(p)):(l.points[l.points.length-1]=f,l.screenPoints[l.screenPoints.length-1]=p),l.current=f},[]),It=d.useCallback(l=>{if(!ne||t==="cursor"||l.button!==0)return;const f=Ce(l);if(!f)return;const p=t==="brush"?ye(l):null;if(t==="brush"&&!p)return;if(l.preventDefault(),l.stopPropagation(),bt(t)){const B=be.current;B.stampCenter=f,De(t,f),U();return}const S=$.current;S&&S.setPointerCapture(l.pointerId);const A=be.current;A.isDrawing=!0,A.pointerId=l.pointerId,A.start=f,A.current=f,A.cursor=f,A.cursorScreen=p,A.points=t==="freehand"||t==="brush"?[f]:[],A.screenPoints=t==="brush"&&p?[p]:[],U()},[ne,t,Ce,ye,De,U]),lt=d.useCallback(l=>{if(!ne||t==="cursor")return;const f=Ce(l);if(!f)return;if(bt(t)){const S=be.current;S.stampCenter=f,l.preventDefault(),l.stopPropagation(),U();return}const p=be.current;if(t==="brush"){const S=ye(l);if(!S)return;if(p.cursor=f,p.cursorScreen=S,!p.isDrawing||p.pointerId!==l.pointerId){U();return}l.preventDefault(),l.stopPropagation(),pe(p,f,S),U();return}if(!(!p.isDrawing||p.pointerId!==l.pointerId)){if(l.preventDefault(),l.stopPropagation(),t==="freehand"){const S=s.current,A=Math.max(1e-6,S?.getViewState?.().zoom??1),B=li/A,O=B*B,H=p.points[p.points.length-1];if(!H)p.points.push(f);else{const G=f[0]-H[0],he=f[1]-H[1];G*G+he*he>=O&&p.points.push(f)}}else p.current=f;U()}},[ne,t,Ce,ye,U,s,pe]),et=d.useCallback(l=>{const f=be.current;if(!f.isDrawing||f.pointerId!==l.pointerId)return;l.preventDefault(),l.stopPropagation();const p=Ce(l),S=t==="brush"?ye(l):null;p&&(f.cursor=p,t==="brush"?S&&(f.cursorScreen=S,pe(f,p,S)):f.current=p);const A=$.current;if(A&&A.hasPointerCapture(l.pointerId))try{A.releasePointerCapture(l.pointerId)}catch{}Qe()},[Qe,Ce,ye,t,pe]),ue=d.useCallback(()=>{const l=be.current;let f=!1;t==="brush"&&!l.isDrawing&&l.cursor&&(l.cursor=null,l.cursorScreen=null,f=!0),bt(t)&&l.stampCenter&&(l.stampCenter=null,f=!0),f&&U()},[t,U]);return d.useEffect(()=>{K(),U();const l=$.current;if(!l)return;const f=new ResizeObserver(()=>{K(),U()});return f.observe(l),()=>{f.disconnect()}},[K,U]),d.useEffect(()=>{ne||ge(),U()},[ne,U,ge]),d.useEffect(()=>{Ke.current!==t&&(Ke.current=t,ge(),U())},[t,ge,U]),d.useEffect(()=>{U()},[m,T,P,U]),d.useEffect(()=>{if(N)return N.current=U,()=>{N.current===U&&(N.current=null)}},[N,U]),d.useEffect(()=>{if(!ne)return;const l=f=>{f.key==="Escape"&&(ge(),U())};return window.addEventListener("keydown",l),()=>{window.removeEventListener("keydown",l)}},[ne,ge,U]),Ae.jsx("canvas",{ref:$,className:ve,style:J,onPointerDown:It,onPointerMove:lt,onPointerUp:et,onPointerCancel:et,onPointerLeave:ue,onContextMenu:l=>{ne&&l.preventDefault()},onWheel:l=>{if(!ne)return;const f=$.current,p=s.current;if(!f||typeof p?.zoomBy!="function")return;l.preventDefault(),l.stopPropagation();const S=f.getBoundingClientRect(),A=l.clientX-S.left,B=l.clientY-S.top;p.zoomBy(l.deltaY<0?di:mi,A,B),U()}})}function kn(t){return String(t??"").replace(/\/+$/,"")}function tr(t){const e=String(t??"");return e.startsWith("/")?e:`/${e}`}function Hi(t){const e=kn(t);if(!e)return"";if(/\/TileGroup\d+$/i.test(e))return e;let n=null;try{n=new URL(e)}catch{n=null}if(n){const r=`${n.protocol}//${n.host}`,i=kn(n.pathname||"");return/\/ims$/i.test(i)?`${r}${i}`:/\/tiles$/i.test(i)?`${r}${i}`:`${r}${i}/tiles`}return/\/ims$/i.test(e)?"/ims":/\/tiles$/i.test(e)?`${e}`:`${e}/tiles`}function $i(t,e){const n=t?.imsInfo||{},r=!!t?.imsInfo,i=Number(n.width??t?.width??0),o=Number(n.height??t?.height??0),a=Number(n.tileSize??t?.tileSize??0),s=Number(n.zoom??t?.zoom??0),u=String(n.path??t?.path??""),c=Number(n.mpp??t?.mpp??0);if(!i||!o||!a||!u)throw new Error("이미지 메타데이터가 불완전합니다. width/height/tileSize/path 확인 필요");const h=Array.isArray(t?.terms)?t.terms.map(y=>({termId:String(y?.termId??""),termName:String(y?.termName??""),termColor:String(y?.termColor??"")})):[],b=tr(u),m=Hi(e),g=r?(y,x,E)=>`${m}${b}/${y}/${E}_${x}.webp`:void 0;return{id:t?._id||"unknown",name:t?.name||"unknown",width:i,height:o,mpp:Number.isFinite(c)&&c>0?c:void 0,tileSize:a,maxTierZoom:Number.isFinite(s)?Math.max(0,Math.floor(s)):0,tilePath:u,tileBaseUrl:e,terms:h,tileUrlBuilder:g}}function en(t,e,n,r){if(t.tileUrlBuilder)return t.tileUrlBuilder(e,n,r);const i=tr(t.tilePath);return`${t.tileBaseUrl}${i}/${e}/${r}_${n}.webp`}const xe={width:220,height:140,margin:16,position:"bottom-right",borderRadius:10,borderWidth:1.5,backgroundColor:"rgba(4, 10, 18, 0.88)",borderColor:"rgba(230, 244, 255, 0.35)",viewportStrokeColor:"rgba(255, 106, 61, 0.95)",viewportFillColor:"rgba(255, 106, 61, 0.2)",interactive:!0,showThumbnail:!0,maxThumbnailTiles:16};function Je(t,e,n=1){return typeof t!="number"||!Number.isFinite(t)?e:Math.max(n,t)}function wt(t){return Array.isArray(t)&&t.length===4&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(t[2])&&Number.isFinite(t[3])}function nr({source:t,projectorRef:e,authToken:n="",options:r,invalidateRef:i,className:o,style:a}){const s=d.useRef(null),u=d.useRef(null),c=d.useRef(null),h=d.useRef({active:!1,pointerId:null}),b=d.useRef(null),m=d.useRef(!1),g=Je(r?.width,xe.width,64),y=Je(r?.height,xe.height,48),x=Je(r?.margin,xe.margin,0),E=Je(r?.borderRadius,xe.borderRadius,0),_=Je(r?.borderWidth,xe.borderWidth,0),X=Math.max(1,Math.round(Je(r?.maxThumbnailTiles,xe.maxThumbnailTiles,1))),F=r?.backgroundColor||xe.backgroundColor,W=r?.borderColor||xe.borderColor,P=r?.viewportStrokeColor||xe.viewportStrokeColor,z=r?.viewportFillColor||xe.viewportFillColor,Z=r?.interactive??xe.interactive,ee=r?.showThumbnail??xe.showThumbnail,N=r?.position||xe.position,ve=d.useMemo(()=>{const T={};return N==="top-left"||N==="bottom-left"?T.left=x:T.right=x,N==="top-left"||N==="top-right"?T.top=x:T.bottom=x,{position:"absolute",...T,width:g,height:y,borderRadius:E,overflow:"hidden",zIndex:4,pointerEvents:Z?"auto":"none",touchAction:"none",boxShadow:"0 10px 22px rgba(0, 0, 0, 0.3)",...a}},[x,N,g,y,E,Z,a]),Te=d.useCallback(()=>{const T=s.current;if(!T)return;const C=T.getContext("2d");if(!C)return;const I=g,Y=y,L=Math.max(1,window.devicePixelRatio||1),ie=Math.max(1,Math.round(I*L)),re=Math.max(1,Math.round(Y*L));(T.width!==ie||T.height!==re)&&(T.width=ie,T.height=re),C.setTransform(1,0,0,1,0,0),C.clearRect(0,0,T.width,T.height),C.setTransform(L,0,0,L,0,0),C.fillStyle=F,C.fillRect(0,0,I,Y);const we=u.current;we&&C.drawImage(we,0,0,I,Y),C.strokeStyle=W,C.lineWidth=_,C.strokeRect(_*.5,_*.5,I-_,Y-_);const fe=e.current,oe=fe?.getViewBounds?.(),V=fe?.getViewCorners?.(),J=wt(oe)?oe:wt(c.current)?c.current:null;if(!J)return;c.current=J;const K=I/Math.max(1,t.width),D=Y/Math.max(1,t.height),ce=Array.isArray(V)&&V.length>=4&&V.every(U=>Array.isArray(U)&&U.length>=2&&Number.isFinite(U[0])&&Number.isFinite(U[1]))?V:null;if(ce){C.beginPath();for(let U=0;U<ce.length;U+=1){const ge=ce[U],Ce=Q(ge[0]*K,0,I),ye=Q(ge[1]*D,0,Y);U===0?C.moveTo(Ce,ye):C.lineTo(Ce,ye)}C.closePath(),C.fillStyle=z,C.fill(),C.strokeStyle=P,C.lineWidth=1.5,C.stroke();return}const se=Q(J[0]*K,0,I),ae=Q(J[1]*D,0,Y),j=Q(J[2]*K,0,I),Ue=Q(J[3]*D,0,Y),Pe=Math.max(1,j-se),Fe=Math.max(1,Ue-ae);C.fillStyle=z,C.fillRect(se,ae,Pe,Fe),C.strokeStyle=P,C.lineWidth=1.5,C.strokeRect(se+.5,ae+.5,Math.max(1,Pe-1),Math.max(1,Fe-1))},[g,y,F,W,_,e,t.width,t.height,z,P]),$=d.useCallback(()=>{m.current||(m.current=!0,b.current=requestAnimationFrame(()=>{m.current=!1,b.current=null,Te()}))},[Te]),_e=d.useCallback((T,C)=>{const I=s.current;if(!I)return null;const Y=I.getBoundingClientRect();if(!Y.width||!Y.height)return null;const L=Q((T-Y.left)/Y.width,0,1),ie=Q((C-Y.top)/Y.height,0,1);return[L*t.width,ie*t.height]},[t.width,t.height]),ze=d.useCallback((T,C)=>{const I=e.current;if(!I)return;if(I.setViewCenter){I.setViewCenter(T,C),$();return}const Y=I.getViewBounds?.(),L=wt(Y)?Y:wt(c.current)?c.current:null;if(!L)return;const ie=Math.max(1e-6,L[2]-L[0]),re=Math.max(1e-6,L[3]-L[1]);I.setViewState({offsetX:T-ie*.5,offsetY:C-re*.5}),$()},[e,$]),Ke=d.useCallback(T=>{if(!Z||T.button!==0)return;const C=s.current;if(!C)return;const I=_e(T.clientX,T.clientY);I&&(T.preventDefault(),T.stopPropagation(),C.setPointerCapture(T.pointerId),h.current={active:!0,pointerId:T.pointerId},ze(I[0],I[1]))},[Z,_e,ze]),be=d.useCallback(T=>{const C=h.current;if(!C.active||C.pointerId!==T.pointerId)return;const I=_e(T.clientX,T.clientY);I&&(T.preventDefault(),T.stopPropagation(),ze(I[0],I[1]))},[_e,ze]),ne=d.useCallback(T=>{const C=h.current;if(!C.active||C.pointerId!==T.pointerId)return;const I=s.current;if(I&&I.hasPointerCapture(T.pointerId))try{I.releasePointerCapture(T.pointerId)}catch{}h.current={active:!1,pointerId:null},$()},[$]);return d.useEffect(()=>{let T=!1;u.current=null,$();const C=0,I=2**(t.maxTierZoom-C),Y=Math.ceil(t.width/I),L=Math.ceil(t.height/I),ie=Math.max(1,Math.ceil(Y/t.tileSize)),re=Math.max(1,Math.ceil(L/t.tileSize)),we=ie*re;if(!ee||we>X)return;const fe=document.createElement("canvas");fe.width=Math.max(1,Math.round(g)),fe.height=Math.max(1,Math.round(y));const oe=fe.getContext("2d");if(!oe)return;oe.fillStyle=F,oe.fillRect(0,0,fe.width,fe.height);const V=[];for(let J=0;J<re;J+=1)for(let K=0;K<ie;K+=1){const D=K*t.tileSize*I,ce=J*t.tileSize*I,se=Math.min((K+1)*t.tileSize,Y)*I,ae=Math.min((J+1)*t.tileSize,L)*I;V.push({url:en(t,C,K,J),bounds:[D,ce,se,ae]})}return Promise.allSettled(V.map(async J=>{const K=!!n,D=await fetch(J.url,{headers:K?{Authorization:n}:void 0});if(!D.ok)throw new Error(`HTTP ${D.status}`);const ce=await createImageBitmap(await D.blob());return{tile:J,bitmap:ce}})).then(J=>{if(T){for(const ce of J)ce.status==="fulfilled"&&ce.value.bitmap.close();return}const K=fe.width/Math.max(1,t.width),D=fe.height/Math.max(1,t.height);for(const ce of J){if(ce.status!=="fulfilled")continue;const{tile:{bounds:se},bitmap:ae}=ce.value,j=se[0]*K,Ue=se[1]*D,Pe=Math.max(1,(se[2]-se[0])*K),Fe=Math.max(1,(se[3]-se[1])*D);oe.drawImage(ae,j,Ue,Pe,Fe),ae.close()}u.current=fe,$()}),()=>{T=!0}},[t,n,g,y,F,ee,X,$]),d.useEffect(()=>{$()},[$]),d.useEffect(()=>{if(i)return i.current=$,()=>{i.current===$&&(i.current=null)}},[i,$]),d.useEffect(()=>()=>{h.current={active:!1,pointerId:null},b.current!==null&&(cancelAnimationFrame(b.current),b.current=null),m.current=!1},[]),Ae.jsx("canvas",{ref:s,className:o,style:ve,onPointerDown:Ke,onPointerMove:be,onPointerUp:ne,onPointerCancel:ne,onContextMenu:T=>{T.preventDefault()},onWheel:T=>{T.preventDefault(),T.stopPropagation()}})}function Zi({imageWidth:t,imageHeight:e,tiles:n,viewState:r,className:i,style:o}){const a=d.useRef(null),s=d.useRef(null),u=d.useMemo(()=>({width:"100%",height:"100%",display:"block",...o}),[o]);return d.useEffect(()=>{const c=a.current;if(!c)return;const h=new On({canvas:c,imageWidth:t,imageHeight:e,initialViewState:r});return s.current=h,h.setTiles(n),()=>{h.destroy(),s.current=null}},[t,e]),d.useEffect(()=>{const c=s.current;c&&c.setTiles(n)},[n]),d.useEffect(()=>{const c=s.current;!c||!r||c.setViewState(r)},[r]),Ae.jsx("canvas",{ref:a,className:i,style:u})}function rr(t){const e=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0,e))}function at(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return null;const n=ut(e??[]);if(n.length===0){const y={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return t.fillModes instanceof Uint8Array&&(y.fillModes=new Uint8Array(0)),t.ids instanceof Uint32Array&&(y.ids=new Uint32Array(0)),y}const r=rr(t),i=t.positions,o=t.paletteIndices,a=t.fillModes instanceof Uint8Array&&t.fillModes.length>=r?t.fillModes:null,s=t.ids instanceof Uint32Array&&t.ids.length>=r?t.ids:null,u=new Float32Array(r*2),c=new Uint16Array(r),h=a?new Uint8Array(r):null,b=s?new Uint32Array(r):null;let m=0;for(let y=0;y<r;y+=1){const x=i[y*2],E=i[y*2+1];Pt(x,E,n)&&(u[m*2]=x,u[m*2+1]=E,c[m]=o[y],h&&(h[m]=a[y]),b&&(b[m]=s[y]),m+=1)}const g={count:m,positions:u.subarray(0,m*2),paletteIndices:c.subarray(0,m)};return h&&(g.fillModes=h.subarray(0,m)),b&&(g.ids=b.subarray(0,m)),g}function ir(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return new Uint32Array(0);const n=ut(e??[]);if(n.length===0)return new Uint32Array(0);const r=rr(t);if(r===0)return new Uint32Array(0);const i=t.positions,o=new Uint32Array(r);let a=0;for(let s=0;s<r;s+=1){const u=i[s*2],c=i[s*2+1];Pt(u,c,n)&&(o[a]=s,a+=1)}return o.subarray(0,a)}let Mt=null;const Ki=`
33
33
  struct Params {
34
34
  pointCount: u32,
35
35
  boundsCount: u32,
@@ -60,7 +60,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
60
60
  }
61
61
  outputMask[i] = inside;
62
62
  }
63
- `;function ji(){if(typeof navigator>"u")return!1;const t=navigator;return typeof t.gpu=="object"&&t.gpu!==null}function ir(){if(!ji())return null;const e=navigator.gpu;if(!e||typeof e!="object")return null;const n=e;return typeof n.requestAdapter!="function"?null:n}const St=globalThis.GPUShaderStage?.COMPUTE??4,kt=globalThis.GPUBufferUsage?.STORAGE??128,xt=globalThis.GPUBufferUsage?.COPY_DST??8,Ji=globalThis.GPUBufferUsage?.COPY_SRC??4,Qi=globalThis.GPUBufferUsage?.UNIFORM??64,eo=globalThis.GPUBufferUsage?.MAP_READ??1,to=globalThis.GPUMapMode?.READ??1;async function no(){const t=ir();if(!t)return{supported:!1,features:[]};const e=await t.requestAdapter();return e?{supported:!0,adapterName:e.info?.description??e.info?.vendor??"unknown",features:Array.from(e.features),limits:{maxStorageBufferBindingSize:Number(e.limits.maxStorageBufferBindingSize),maxComputeInvocationsPerWorkgroup:Number(e.limits.maxComputeInvocationsPerWorkgroup),maxComputeWorkgroupSizeX:Number(e.limits.maxComputeWorkgroupSizeX)}}:{supported:!1,features:[]}}async function ro(){return Mt||(Mt=(async()=>{const t=ir();if(!t)return null;const e=await t.requestAdapter();if(!e)return null;const n=await e.requestDevice(),r=n.createBindGroupLayout({entries:[{binding:0,visibility:St,buffer:{type:"read-only-storage"}},{binding:1,visibility:St,buffer:{type:"read-only-storage"}},{binding:2,visibility:St,buffer:{type:"storage"}},{binding:3,visibility:St,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Ki}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),Mt)}function At(t,e){return Math.ceil(t/e)*e}async function or(t,e,n){const r=await ro();if(!r)return null;const i=Math.max(0,Math.floor(e)),o=Math.max(0,Math.floor(n.length/4));if(i===0||o===0)return new Uint32Array(0);const a=Math.min(i,Math.floor(t.length/2));if(a===0)return new Uint32Array(0);const s=a*2*Float32Array.BYTES_PER_ELEMENT,u=o*4*Float32Array.BYTES_PER_ELEMENT,c=a*Uint32Array.BYTES_PER_ELEMENT,f=Number(r.device.limits.maxStorageBufferBindingSize);if(s>f||u>f||c>f)return null;const p=r.device.createBuffer({size:At(s,4),usage:kt|xt}),m=r.device.createBuffer({size:At(u,4),usage:kt|xt}),g=r.device.createBuffer({size:At(c,4),usage:kt|Ji}),b=r.device.createBuffer({size:16,usage:Qi|xt}),x=r.device.createBuffer({size:At(c,4),usage:xt|eo});r.device.queue.writeBuffer(p,0,t.buffer,t.byteOffset,s),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,u),r.device.queue.writeBuffer(b,0,new Uint32Array([a,o,0,0]));const R=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:p}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:g}},{binding:3,resource:{buffer:b}}]}),_=r.device.createCommandEncoder(),W=_.beginComputePass();W.setPipeline(r.pipeline),W.setBindGroup(0,R),W.dispatchWorkgroups(Math.ceil(a/256)),W.end(),_.copyBufferToBuffer(g,0,x,0,c),r.device.queue.submit([_.finish()]),await x.mapAsync(to);const F=x.getMappedRange(),Y=new Uint32Array(F.slice(0));return x.unmap(),p.destroy(),m.destroy(),g.destroy(),b.destroy(),x.destroy(),Y}function ze(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}async function sr(t,e,n={}){const r=ze(),i=n.bridgeToDraw===!0;if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=at(e??[]);if(o.length===0){const T={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return t.fillModes instanceof Uint8Array&&(T.fillModes=new Uint8Array(0)),t.ids instanceof Uint32Array&&(T.ids=new Uint32Array(0)),{data:T,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const a=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,s=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,a)),u=t.fillModes instanceof Uint8Array&&t.fillModes.length>=s?t.fillModes:null,c=t.ids instanceof Uint32Array&&t.ids.length>=s?t.ids:null;if(s===0){const T={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return u&&(T.fillModes=new Uint8Array(0)),c&&(T.ids=new Uint32Array(0)),{data:T,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const f=new Float32Array(o.length*4);for(let T=0;T<o.length;T+=1){const z=T*4,Z=o[T];f[z]=Z.minX,f[z+1]=Z.minY,f[z+2]=Z.maxX,f[z+3]=Z.maxY}let p=null,m=!1;try{p=await or(t.positions,s,f),m=!!p}catch{p=null,m=!1}if(!p)return{data:st(t,e),meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!1,candidateCount:s,bridgedToDraw:!1}};let g=0;for(let T=0;T<s;T+=1)p[T]===1&&(g+=1);const b=new Uint32Array(g);if(g>0){let T=0;for(let z=0;z<s;z+=1)p[z]===1&&(b[T]=z,T+=1)}if(g===0){if(i){const z={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:new Uint32Array(0)};return u&&(z.fillModes=u.subarray(0,s)),c&&(z.ids=c.subarray(0,s)),{data:z,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}const T={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return u&&(T.fillModes=new Uint8Array(0)),c&&(T.ids=new Uint32Array(0)),{data:T,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const T=new Uint32Array(g);let z=0;for(let te=0;te<g;te+=1){const N=b[te]??0,Pe=t.positions[N*2],Ae=t.positions[N*2+1];Pt(Pe,Ae,o)&&(T[z]=N,z+=1)}const Z={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:T.subarray(0,z)};return u&&(Z.fillModes=u.subarray(0,s)),c&&(Z.ids=c.subarray(0,s)),{data:Z,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!0}}}const x=new Float32Array(g*2),R=new Uint16Array(g),_=u?new Uint8Array(g):null,W=c?new Uint32Array(g):null;let F=0;for(let T=0;T<g;T+=1){const z=b[T]??0,Z=t.positions[z*2],te=t.positions[z*2+1];Pt(Z,te,o)&&(x[F*2]=Z,x[F*2+1]=te,R[F]=t.paletteIndices[z],_&&(_[F]=u[z]),W&&(W[F]=c[z]),F+=1)}const Y={count:F,positions:x.subarray(0,F*2),paletteIndices:R.subarray(0,F)};return _&&(Y.fillModes=_.subarray(0,F)),W&&(Y.ids=W.subarray(0,F)),{data:Y,meta:{mode:"hybrid-webgpu",durationMs:ze()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!1}}}let Se=null,qt=!0,ar=1;const qe=new Map;function Ge(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function ur(){if(!qt)return null;if(Se)return Se;try{const t=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-BDVQwN2T.js").href:new URL("assets/roi-clip-worker-BDVQwN2T.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:Bt&&Bt.tagName.toUpperCase()==="SCRIPT"&&Bt.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return t.addEventListener("message",tn),t.addEventListener("error",nn),Se=t,t}catch{return qt=!1,null}}function tn(t){const e=t.data;if(!e)return;const n=qe.get(e.id);if(!n)return;if(qe.delete(e.id),e.type==="roi-clip-failure"){n.reject(new Error(e.error||"worker clip failed"));return}if(e.type==="roi-clip-index-success"){if(n.kind!=="index"){n.reject(new Error("worker response mismatch: expected point data result"));return}const c=Math.max(0,Math.floor(e.count)),f=new Uint32Array(e.indices).subarray(0,c);n.resolve({indices:f,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:Ge()-n.startMs}});return}if(n.kind!=="data"){n.reject(new Error("worker response mismatch: expected index result"));return}const r=Math.max(0,Math.floor(e.count)),i=new Float32Array(e.positions),o=new Uint16Array(e.paletteIndices),a=e.fillModes?new Uint8Array(e.fillModes):null,s=e.ids?new Uint32Array(e.ids):null,u={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};a&&(u.fillModes=a.subarray(0,r)),s&&(u.ids=s.subarray(0,r)),n.resolve({data:u,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:Ge()-n.startMs}})}function nn(){qt=!1,Se&&(Se.removeEventListener("message",tn),Se.removeEventListener("error",nn),Se.terminate(),Se=null);for(const[,t]of qe)t.reject(new Error("worker crashed"));qe.clear()}function io(){if(Se){Se.removeEventListener("message",tn),Se.removeEventListener("error",nn),Se.terminate(),Se=null;for(const[,t]of qe)t.reject(new Error("worker terminated"));qe.clear()}}async function lr(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=ur();if(!n){const p=Ge();return{data:st(t,e),meta:{mode:"sync",durationMs:Ge()-p}}}const r=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r)),o=t.positions.slice(0,i*2),a=t.paletteIndices.slice(0,i),s=t.fillModes instanceof Uint8Array&&t.fillModes.length>=i?t.fillModes.slice(0,i):null,u=t.ids instanceof Uint32Array&&t.ids.length>=i?t.ids.slice(0,i):null,c=ar++,f=Ge();return new Promise((p,m)=>{qe.set(c,{kind:"data",resolve:p,reject:m,startMs:f});const g={type:"roi-clip-request",id:c,count:i,positions:o.buffer,paletteIndices:a.buffer,fillModes:s?.buffer,ids:u?.buffer,polygons:e??[]},b=[o.buffer,a.buffer];s&&b.push(s.buffer),u&&b.push(u.buffer),n.postMessage(g,b)})}async function oo(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=ur();if(!n){const u=Ge();return{indices:rr(t,e),meta:{mode:"sync",durationMs:Ge()-u}}}const r=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r)),o=t.positions.slice(0,i*2),a=ar++,s=Ge();return new Promise((u,c)=>{qe.set(a,{kind:"index",resolve:u,reject:c,startMs:s});const f={type:"roi-clip-index-request",id:a,count:i,positions:o.buffer,polygons:e??[]};n.postMessage(f,[o.buffer])})}function so(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=at([r?.coordinates]);if(i.length===0)continue;let o=0;for(const a of i)o+=a.area;e.push({regionId:r.id??n,regionIndex:n,polygons:i,area:Math.max(1e-6,o)})}return e}function ao(t,e){if(Array.isArray(e)){const n=e[t];if(typeof n=="string"&&n.length>0)return n}if(e instanceof Map){const n=e.get(t);if(typeof n=="string"&&n.length>0)return n}return String(t)}function cr(t,e,n={}){const r=Math.max(0,Math.min(Math.floor(t?.count??0),Math.floor((t?.positions?.length??0)/2),t?.paletteIndices?.length??0,t?.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER));let i=null;if(t?.drawIndices instanceof Uint32Array){const m=t.drawIndices;let g=m.length;for(let b=0;b<m.length;b+=1)m[b]<r||(g-=1);if(g===m.length)i=m;else if(g>0){const b=new Uint32Array(g);let x=0;for(let R=0;R<m.length;R+=1){const _=m[R];_>=r||(b[x]=_,x+=1)}i=b}else i=new Uint32Array(0)}const o=i?i.length:r,a=so(e??[]);if(!t||o===0||a.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const s=new Map,u=new Map;let c=0;for(let m=0;m<o;m+=1){const g=i?i[m]:m,b=t.positions[g*2],x=t.positions[g*2+1];let R=null;for(const F of a){let Y=!1;for(const T of F.polygons)if(jt(b,x,T)){Y=!0;break}Y&&(!R||F.area<R.area)&&(R=F)}if(!R)continue;c+=1;const _=t.paletteIndices[g]??0,W=s.get(R.regionIndex)??new Map;W.set(_,(W.get(_)??0)+1),s.set(R.regionIndex,W),u.set(R.regionIndex,(u.get(R.regionIndex)??0)+1)}const f=n.includeEmptyRegions??!1,p=[];for(const m of a){const g=u.get(m.regionIndex)??0;if(!f&&g<=0)continue;const b=s.get(m.regionIndex)??new Map,x=Array.from(b.entries()).map(([R,_])=>({termId:ao(R,n.paletteIndexToTermId),paletteIndex:R,count:_})).sort((R,_)=>_.count-R.count||R.paletteIndex-_.paletteIndex);p.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:g,termCounts:x})}return{groups:p,inputPointCount:o,pointsInsideAnyRegion:c,unmatchedPointCount:Math.max(0,o-c)}}function Rt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function uo(t,e){if(!e)return!1;try{const r=new URL(t,typeof window<"u"?window.location.href:void 0).hostname.toLowerCase();if(r.includes("amazonaws.com")||r.startsWith("s3.")||r.includes(".s3."))return!1}catch{}return!0}class fr{constructor(e){M(this,"maxConcurrency");M(this,"maxRetries");M(this,"retryBaseDelayMs");M(this,"retryMaxDelayMs");M(this,"onTileLoad");M(this,"onTileError");M(this,"onStateChange");M(this,"authToken");M(this,"destroyed",!1);M(this,"queue",[]);M(this,"queuedByKey",new Map);M(this,"inflight",new Map);M(this,"visibleKeys",new Set);M(this,"timerId",null);M(this,"abortedCount",0);M(this,"retryCount",0);M(this,"failedCount",0);this.maxConcurrency=Math.max(1,Math.floor(e.maxConcurrency??12)),this.maxRetries=Math.max(0,Math.floor(e.maxRetries??2)),this.retryBaseDelayMs=Math.max(10,Math.floor(e.retryBaseDelayMs??120)),this.retryMaxDelayMs=Math.max(this.retryBaseDelayMs,Math.floor(e.retryMaxDelayMs??1200)),this.authToken=e.authToken??"",this.onTileLoad=e.onTileLoad,this.onTileError=e.onTileError,this.onStateChange=e.onStateChange}setAuthToken(e){this.authToken=String(e??"")}schedule(e){if(this.destroyed)return;const n=new Set;for(const r of e)n.add(r.key);this.visibleKeys=n,this.dropInvisibleQueued(n),this.abortInvisibleInflight(n);for(const r of e){if(this.inflight.has(r.key)){const a=this.inflight.get(r.key);a&&(a.tile=r);continue}const i=this.queuedByKey.get(r.key);if(i){i.tile=r;continue}const o={tile:r,attempt:0,readyAt:Rt()};this.queue.push(o),this.queuedByKey.set(r.key,o)}this.sortQueue(),this.pump(),this.emitStateChange()}clear(){this.clearPumpTimer(),this.visibleKeys.clear(),this.queue=[],this.queuedByKey.clear();for(const[,e]of this.inflight)e.controller.abort();this.inflight.clear(),this.emitStateChange()}destroy(){this.destroyed||(this.destroyed=!0,this.clear())}getInflightCount(){return this.inflight.size}getSnapshot(){return{inflight:this.inflight.size,queued:this.queue.length,aborted:this.abortedCount,retries:this.retryCount,failed:this.failedCount}}dropInvisibleQueued(e){if(this.queue.length===0)return;const n=[];for(const r of this.queue){if(!e.has(r.tile.key)){this.queuedByKey.delete(r.tile.key);continue}n.push(r)}this.queue=n}abortInvisibleInflight(e){for(const[n,r]of this.inflight)e.has(n)||(this.inflight.delete(n),this.abortedCount+=1,r.controller.abort())}sortQueue(){this.queue.sort((e,n)=>e.readyAt!==n.readyAt?e.readyAt-n.readyAt:e.tile.distance2!==n.tile.distance2?e.tile.distance2-n.tile.distance2:e.tile.tier!==n.tile.tier?n.tile.tier-e.tile.tier:e.tile.key.localeCompare(n.tile.key))}pump(){if(this.destroyed)return;for(this.clearPumpTimer();this.inflight.size<this.maxConcurrency;){const r=this.takeNextReadyQueueItem();if(!r)break;this.startFetch(r)}if(this.inflight.size>=this.maxConcurrency||this.queue.length===0)return;const e=this.queue[0]?.readyAt;if(typeof e!="number")return;const n=Math.max(0,e-Rt());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const e=Rt(),n=this.queue[0];return!n||n.readyAt>e?null:(this.queue.shift(),this.queuedByKey.delete(n.tile.key),n)}startFetch(e){const n=new AbortController,r={tile:e.tile,attempt:e.attempt,controller:n};this.inflight.set(e.tile.key,r),this.emitStateChange();const i=uo(e.tile.url,this.authToken);fetch(e.tile.url,{signal:n.signal,headers:i?{Authorization:this.authToken}:void 0}).then(o=>{if(!o.ok)throw new Error(`HTTP ${o.status}`);return o.blob()}).then(o=>createImageBitmap(o)).then(o=>{if(this.destroyed||n.signal.aborted){o.close();return}if(!this.visibleKeys.has(e.tile.key)){o.close();return}this.onTileLoad(e.tile,o)}).catch(o=>{if(n.signal.aborted||this.destroyed)return;if(e.attempt<this.maxRetries&&this.visibleKeys.has(e.tile.key)){this.retryCount+=1;const s=e.attempt+1,u=this.getRetryDelay(s),c={tile:e.tile,attempt:s,readyAt:Rt()+u},f=this.queuedByKey.get(e.tile.key);f?(f.tile=c.tile,f.readyAt=Math.min(f.readyAt,c.readyAt),f.attempt=Math.max(f.attempt,c.attempt)):(this.queue.push(c),this.queuedByKey.set(c.tile.key,c)),this.sortQueue();return}this.failedCount+=1,this.onTileError?.(e.tile,o,e.attempt+1)}).finally(()=>{this.inflight.delete(e.tile.key),this.pump(),this.emitStateChange()})}getRetryDelay(e){const n=Math.max(0,e-1),r=Math.min(this.retryMaxDelayMs,this.retryBaseDelayMs*2**n),i=.85+Math.random()*.3;return Math.round(r*i)}clearPumpTimer(){this.timerId!==null&&(window.clearTimeout(this.timerId),this.timerId=null)}emitStateChange(){this.onStateChange?.(this.getSnapshot())}}const kn=.35,Ht=.5,lo=256,$t=[{zoom:1,size:2.8},{zoom:2,size:3.4},{zoom:3,size:4.2},{zoom:4,size:5.3},{zoom:5,size:6.8},{zoom:6,size:8.4},{zoom:7,size:9.8},{zoom:8,size:11.2},{zoom:9,size:14},{zoom:10,size:17.5},{zoom:11,size:22},{zoom:12,size:28}];class co{constructor(){M(this,"viewportWidth",1);M(this,"viewportHeight",1);M(this,"viewState",{zoom:1,offsetX:0,offsetY:0,rotationDeg:0})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewport(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){typeof e.zoom=="number"&&(this.viewState.zoom=Math.max(1e-4,e.zoom)),typeof e.offsetX=="number"&&(this.viewState.offsetX=e.offsetX),typeof e.offsetY=="number"&&(this.viewState.offsetY=e.offsetY),typeof e.rotationDeg=="number"&&Number.isFinite(e.rotationDeg)&&(this.viewState.rotationDeg=e.rotationDeg)}getViewState(){return{...this.viewState}}getCenter(){const e=Math.max(1e-6,this.viewState.zoom);return[this.viewState.offsetX+this.viewportWidth/(2*e),this.viewState.offsetY+this.viewportHeight/(2*e)]}setCenter(e,n){const r=Math.max(1e-6,this.viewState.zoom);this.viewState.offsetX=e-this.viewportWidth/(2*r),this.viewState.offsetY=n-this.viewportHeight/(2*r)}screenToWorld(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,a]=this.getCenter(),s=(e-this.viewportWidth*.5)/i,u=(n-this.viewportHeight*.5)/i,c=ot(r.rotationDeg),f=Math.cos(c),p=Math.sin(c);return[o+s*f-u*p,a+s*p+u*f]}worldToScreen(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,a]=this.getCenter(),s=e-o,u=n-a,c=ot(r.rotationDeg),f=Math.cos(c),p=Math.sin(c),m=s*f+u*p,g=-s*p+u*f;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+g*i]}getViewCorners(){const e=this.viewportWidth,n=this.viewportHeight;return[this.screenToWorld(0,0),this.screenToWorld(e,0),this.screenToWorld(e,n),this.screenToWorld(0,n)]}getMatrix(){const e=Math.max(1e-6,this.viewState.zoom),[n,r]=this.getCenter(),i=ot(this.viewState.rotationDeg),o=Math.cos(i),a=Math.sin(i),s=2*e*o/this.viewportWidth,u=2*e*a/this.viewportWidth,c=2*e*a/this.viewportHeight,f=-2*e*o/this.viewportHeight,p=-(s*n+u*r),m=-(c*n+f*r);return new Float32Array([s,c,0,u,f,0,p,m,1])}}function ot(t){return t*Math.PI/180}function Dn(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Ve(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Et(t,e){return!t||!e?t===e:t.buffer===e.buffer&&t.byteOffset===e.byteOffset&&t.byteLength===e.byteLength}function Zt(t){return t.map(e=>({zoom:e.zoom,size:e.size}))}function Xn(t){if(!t)return Zt($t);const e=new Map;for(const[n,r]of Object.entries(t)){const i=Number(n),o=Number(r);!Number.isFinite(i)||!Number.isFinite(o)||o<=0||e.set(i,o)}return e.size===0?Zt($t):Array.from(e.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function fo(t,e){if(t===e)return!0;if(t.length!==e.length)return!1;for(let n=0;n<t.length;n+=1)if(t[n].zoom!==e[n].zoom||t[n].size!==e[n].size)return!1;return!0}function ho(t,e){if(!Number.isFinite(t))return e[0]?.size??Ht;if(e.length===0)return Ht;if(e.length===1||t<=e[0].zoom)return e[0].size;for(let a=1;a<e.length;a+=1){const s=e[a-1],u=e[a];if(t>u.zoom)continue;const c=Math.max(1e-6,u.zoom-s.zoom),f=ee((t-s.zoom)/c,0,1);return s.size+(u.size-s.size)*f}const n=e[e.length-1],r=e[e.length-2],i=Math.max(1e-6,n.zoom-r.zoom),o=(n.size-r.size)/i;return n.size+(t-n.zoom)*o}const mo=.1,go=5;function Wn(t){return typeof t!="number"||!Number.isFinite(t)?1:ee(t,mo,go)}class hr{constructor(e,n,r={}){M(this,"canvas");M(this,"source");M(this,"gl");M(this,"camera",new co);M(this,"onViewStateChange");M(this,"onStats");M(this,"onTileError");M(this,"onContextLost");M(this,"onContextRestored");M(this,"resizeObserver");M(this,"tileProgram");M(this,"pointProgram");M(this,"tileScheduler");M(this,"authToken");M(this,"destroyed",!1);M(this,"contextLost",!1);M(this,"frame",null);M(this,"frameSerial",0);M(this,"dragging",!1);M(this,"interactionMode","none");M(this,"rotateLastAngleRad",null);M(this,"pointerId",null);M(this,"lastPointerX",0);M(this,"lastPointerY",0);M(this,"interactionLocked",!1);M(this,"ctrlDragRotate",!0);M(this,"rotationDragSensitivityDegPerPixel",.35);M(this,"maxCacheTiles");M(this,"fitZoom",1);M(this,"minZoom",1e-6);M(this,"maxZoom",1);M(this,"currentTier",0);M(this,"pointCount",0);M(this,"usePointIndices",!1);M(this,"pointBuffersDirty",!0);M(this,"pointPaletteSize",1);M(this,"pointSizeStops",Zt($t));M(this,"pointStrokeScale",1);M(this,"lastPointData",null);M(this,"lastPointPalette",null);M(this,"zeroFillModes",new Uint8Array(0));M(this,"cache",new Map);M(this,"boundPointerDown");M(this,"boundPointerMove");M(this,"boundPointerUp");M(this,"boundWheel");M(this,"boundDoubleClick");M(this,"boundContextMenu");M(this,"boundContextLost");M(this,"boundContextRestored");this.canvas=e,this.source=n,this.onViewStateChange=r.onViewStateChange,this.onStats=r.onStats,this.onTileError=r.onTileError,this.onContextLost=r.onContextLost,this.onContextRestored=r.onContextRestored,this.authToken=r.authToken??"",this.maxCacheTiles=Math.max(32,Math.floor(r.maxCacheTiles??320)),this.ctrlDragRotate=r.ctrlDragRotate??!0,this.rotationDragSensitivityDegPerPixel=typeof r.rotationDragSensitivityDegPerPixel=="number"&&Number.isFinite(r.rotationDragSensitivityDegPerPixel)?Math.max(0,r.rotationDragSensitivityDegPerPixel):kn,this.pointSizeStops=Xn(r.pointSizeByZoom),this.pointStrokeScale=Wn(r.pointStrokeScale);const i=e.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"});if(!i)throw new Error("WebGL2 not supported");this.gl=i,this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.tileScheduler=new fr({authToken:this.authToken,maxConcurrency:r.tileScheduler?.maxConcurrency??12,maxRetries:r.tileScheduler?.maxRetries??2,retryBaseDelayMs:r.tileScheduler?.retryBaseDelayMs??120,retryMaxDelayMs:r.tileScheduler?.retryMaxDelayMs??1200,onTileLoad:(o,a)=>this.handleTileLoaded(o,a),onTileError:(o,a,s)=>{this.onTileError?.({tile:o,error:a,attemptCount:s}),console.warn("tile load failed",o.url,a)}}),this.resizeObserver=new ResizeObserver(()=>this.resize()),this.resizeObserver.observe(e),this.boundPointerDown=o=>this.onPointerDown(o),this.boundPointerMove=o=>this.onPointerMove(o),this.boundPointerUp=o=>this.onPointerUp(o),this.boundWheel=o=>this.onWheel(o),this.boundDoubleClick=o=>this.onDoubleClick(o),this.boundContextMenu=o=>this.onContextMenu(o),this.boundContextLost=o=>this.onWebGlContextLost(o),this.boundContextRestored=o=>this.onWebGlContextRestored(o),e.addEventListener("pointerdown",this.boundPointerDown),e.addEventListener("pointermove",this.boundPointerMove),e.addEventListener("pointerup",this.boundPointerUp),e.addEventListener("pointercancel",this.boundPointerUp),e.addEventListener("wheel",this.boundWheel,{passive:!1}),e.addEventListener("dblclick",this.boundDoubleClick),e.addEventListener("contextmenu",this.boundContextMenu),e.addEventListener("webglcontextlost",this.boundContextLost),e.addEventListener("webglcontextrestored",this.boundContextRestored),this.fitToImage(),this.resize()}setAuthToken(e){this.authToken=String(e??""),this.tileScheduler.setAuthToken(this.authToken)}setViewState(e){const n={...e};typeof n.zoom=="number"&&(n.zoom=ee(n.zoom,this.minZoom,this.maxZoom)),this.camera.setViewState(n),this.clampViewState(),this.emitViewState(),this.requestRender()}getViewState(){return this.camera.getViewState()}setPointPalette(e){if(!e||e.length===0){this.lastPointPalette=null;return}if(this.lastPointPalette=new Uint8Array(e),this.contextLost||this.gl.isContextLost())return;const n=this.gl,r=Math.max(1,Math.floor(this.lastPointPalette.length/4));this.pointPaletteSize=r,n.bindTexture(n.TEXTURE_2D,this.pointProgram.paletteTexture),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,r,1,0,n.RGBA,n.UNSIGNED_BYTE,this.lastPointPalette),n.bindTexture(n.TEXTURE_2D,null),this.requestRender()}setPointData(e){if(!e||!e.count||!e.positions||!e.paletteIndices){this.lastPointData=null,this.pointCount=0,this.usePointIndices=!1,this.requestRender();return}const n=e.fillModes instanceof Uint8Array?e.fillModes:null,r=n!==null,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r?n.length:Number.MAX_SAFE_INTEGER)),o=e.positions.subarray(0,i*2),a=e.paletteIndices.subarray(0,i),s=r?n.subarray(0,i):void 0,u=e.drawIndices instanceof Uint32Array,c=u?this.sanitizeDrawIndices(e.drawIndices,i):null,f=this.lastPointData,p=f?.fillModes instanceof Uint8Array;let m=this.pointBuffersDirty||!f||f.count!==i||!Et(f.positions,o)||!Et(f.paletteIndices,a)||p!==r||r&&(!f?.fillModes||!Et(f.fillModes,s)),g=this.pointBuffersDirty||u&&(!f?.drawIndices||!Et(f.drawIndices,c))||!u&&!!f?.drawIndices;if(this.lastPointData={count:i,positions:o,paletteIndices:a,fillModes:s,drawIndices:u?c??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const b=this.gl;m&&(b.bindBuffer(b.ARRAY_BUFFER,this.pointProgram.posBuffer),b.bufferData(b.ARRAY_BUFFER,this.lastPointData.positions,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,this.pointProgram.termBuffer),b.bufferData(b.ARRAY_BUFFER,this.lastPointData.paletteIndices,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,this.pointProgram.fillModeBuffer),b.bufferData(b.ARRAY_BUFFER,this.lastPointData.fillModes??this.getZeroFillModes(i),b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,null)),u&&g&&(b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,c??new Uint32Array(0),b.DYNAMIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=u,this.pointCount=u?c?.length??0:this.lastPointData.count,(m||g)&&(this.pointBuffersDirty=!1),this.requestRender()}sanitizeDrawIndices(e,n){if(n<=0||e.length===0)return new Uint32Array(0);let r=e.length;for(let a=0;a<e.length;a+=1)e[a]<n||(r-=1);if(r===e.length)return e;if(r<=0)return new Uint32Array(0);const i=new Uint32Array(r);let o=0;for(let a=0;a<e.length;a+=1){const s=e[a];s>=n||(i[o]=s,o+=1)}return i}getZeroFillModes(e){return e<=0?new Uint8Array(0):(this.zeroFillModes.length<e&&(this.zeroFillModes=new Uint8Array(e)),this.zeroFillModes.subarray(0,e))}setInteractionLock(e){const n=!!e;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(e){const n=Xn(e);fo(this.pointSizeStops,n)||(this.pointSizeStops=n,this.requestRender())}setPointStrokeScale(e){const n=Wn(e);this.pointStrokeScale!==n&&(this.pointStrokeScale=n,this.requestRender())}cancelDrag(){if(this.pointerId!==null&&this.canvas.hasPointerCapture(this.pointerId))try{this.canvas.releasePointerCapture(this.pointerId)}catch{}this.dragging=!1,this.interactionMode="none",this.rotateLastAngleRad=null,this.pointerId=null,this.canvas.classList.remove("dragging")}getPointerAngleRad(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left-r.width*.5,o=n-r.top-r.height*.5;return Math.atan2(o,i)}screenToWorld(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left,o=n-r.top;return this.camera.screenToWorld(i,o)}worldToScreen(e,n){return this.camera.worldToScreen(e,n)}setViewCenter(e,n){!Number.isFinite(e)||!Number.isFinite(n)||(this.camera.setCenter(e,n),this.clampViewState(),this.emitViewState(),this.requestRender())}getViewCorners(){return this.camera.getViewCorners()}resetRotation(){const e=this.camera.getViewState();Math.abs(e.rotationDeg)<1e-6||(this.camera.setViewState({rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender())}getPointSizeByZoom(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e),r=ho(n,this.pointSizeStops);return ee(r,Ht,lo)}fitToImage(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||1),r=Math.max(1,e.height||1),i=Math.min(n/this.source.width,r/this.source.height),o=Number.isFinite(i)&&i>0?i:1;this.fitZoom=o,this.minZoom=Math.max(this.fitZoom*.5,1e-6),this.maxZoom=Math.max(1,this.fitZoom*8),this.minZoom>this.maxZoom&&(this.minZoom=this.maxZoom);const a=n/o,s=r/o;this.camera.setViewState({zoom:ee(o,this.minZoom,this.maxZoom),offsetX:(this.source.width-a)*.5,offsetY:(this.source.height-s)*.5,rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender()}zoomBy(e,n,r){const i=this.camera.getViewState(),o=ee(i.zoom*e,this.minZoom,this.maxZoom);if(o===i.zoom)return;const[a,s]=this.camera.screenToWorld(n,r);this.camera.setViewState({zoom:o});const u=this.camera.getViewport(),c=n-u.width*.5,f=r-u.height*.5,p=ot(this.camera.getViewState().rotationDeg),m=Math.cos(p),g=Math.sin(p),b=c/o*m-f/o*g,x=c/o*g+f/o*m;this.camera.setCenter(a-b,s-x),this.clampViewState(),this.emitViewState(),this.requestRender()}clampViewState(){const e=this.getViewBounds(),n=Math.max(1e-6,e[2]-e[0]),r=Math.max(1e-6,e[3]-e[1]),i=n*.2,o=r*.2,[a,s]=this.camera.getCenter(),u=n*.5,c=r*.5,f=u-i,p=this.source.width-u+i,m=c-o,g=this.source.height-c+o,b=f<=p?ee(a,f,p):this.source.width*.5,x=m<=g?ee(s,m,g):this.source.height*.5;this.camera.setCenter(b,x)}emitViewState(){this.onViewStateChange?.(this.camera.getViewState())}selectTier(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e);return ee(Math.floor(n),0,this.source.maxTierZoom)}getViewBounds(){const e=this.camera.getViewCorners();let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,s]of e)a<n&&(n=a),a>i&&(i=a),s<r&&(r=s),s>o&&(o=s);return[n,r,i,o]}intersectsBounds(e,n){return!(e[2]<=n[0]||e[0]>=n[2]||e[3]<=n[1]||e[1]>=n[3])}getVisibleTiles(){const e=this.selectTier();this.currentTier=e;const n=this.getViewBounds(),r=Math.pow(2,this.source.maxTierZoom-e),i=Math.ceil(this.source.width/r),o=Math.ceil(this.source.height/r),a=Math.max(1,Math.ceil(i/this.source.tileSize)),s=Math.max(1,Math.ceil(o/this.source.tileSize)),u=n[0],c=n[1],f=n[2],p=n[3],m=ee(Math.floor(u/r/this.source.tileSize),0,a-1),g=ee(Math.floor((f-1)/r/this.source.tileSize),0,a-1),b=ee(Math.floor(c/r/this.source.tileSize),0,s-1),x=ee(Math.floor((p-1)/r/this.source.tileSize),0,s-1);if(m>g||b>x)return[];const R=(u+f)*.5/r/this.source.tileSize,_=(c+p)*.5/r/this.source.tileSize,W=[];for(let F=b;F<=x;F+=1)for(let Y=m;Y<=g;Y+=1){const T=Y*this.source.tileSize*r,z=F*this.source.tileSize*r,Z=Math.min((Y+1)*this.source.tileSize,i)*r,te=Math.min((F+1)*this.source.tileSize,o)*r,N=Y-R,Pe=F-_;W.push({key:`${e}/${Y}/${F}`,tier:e,x:Y,y:F,bounds:[T,z,Z,te],distance2:N*N+Pe*Pe,url:en(this.source,e,Y,F)})}return W.sort((F,Y)=>F.distance2-Y.distance2),W}trimCache(){if(this.cache.size<=this.maxCacheTiles)return;const e=Array.from(this.cache.entries());e.sort((r,i)=>r[1].lastUsed-i[1].lastUsed);const n=this.cache.size-this.maxCacheTiles;for(let r=0;r<n;r+=1){const[i,o]=e[r];this.gl.deleteTexture(o.texture),this.cache.delete(i)}}render(){if(this.destroyed||this.contextLost||this.gl.isContextLost())return;const e=Dn();this.frameSerial+=1;const n=this.gl,r=this.tileProgram,i=this.pointProgram;n.clearColor(.03,.06,.1,1),n.clear(n.COLOR_BUFFER_BIT);const o=this.getVisibleTiles(),a=this.getViewBounds(),s=new Set(o.map(m=>m.key));n.useProgram(r.program),n.bindVertexArray(r.vao),n.uniformMatrix3fv(r.uCamera,!1,this.camera.getMatrix()),n.uniform1i(r.uTexture,0);const u=[];for(const[,m]of this.cache)s.has(m.key)||this.intersectsBounds(m.bounds,a)&&u.push(m);u.sort((m,g)=>m.tier-g.tier);for(const m of u)m.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,m.texture),n.uniform4f(r.uBounds,m.bounds[0],m.bounds[1],m.bounds[2],m.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4);let c=0;const f=[];for(const m of o){const g=this.cache.get(m.key);if(!g){f.push(m);continue}g.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,g.texture),n.uniform4f(r.uBounds,g.bounds[0],g.bounds[1],g.bounds[2],g.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),c+=1}this.tileScheduler.schedule(f),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let p=0;if(this.pointCount>0&&(n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),n.useProgram(i.program),n.bindVertexArray(i.vao),n.uniformMatrix3fv(i.uCamera,!1,this.camera.getMatrix()),n.uniform1f(i.uPointSize,this.getPointSizeByZoom()),n.uniform1f(i.uPointStrokeScale,this.pointStrokeScale),n.uniform1f(i.uPaletteSize,this.pointPaletteSize),n.uniform1i(i.uPalette,1),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,i.paletteTexture),this.usePointIndices?n.drawElements(n.POINTS,this.pointCount,n.UNSIGNED_INT,0):n.drawArrays(n.POINTS,0,this.pointCount),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null),p=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),g=c,b=f.length,x=u.length+c+(p>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:c,points:p,fallback:u.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:g,cacheMisses:b,drawCalls:x,frameMs:Dn()-e})}}requestRender(){this.frame!==null||this.destroyed||this.contextLost||this.gl.isContextLost()||(this.frame=requestAnimationFrame(()=>{this.frame=null,this.render()}))}resize(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),a=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==a)&&(this.canvas.width=o,this.canvas.height=a),this.camera.setViewport(n,r),this.gl.viewport(0,0,o,a),this.requestRender()}onPointerDown(e){if(this.interactionLocked)return;const n=this.ctrlDragRotate&&(e.ctrlKey||e.metaKey);(e.button===0||n&&e.button===2)&&(n&&e.preventDefault(),this.dragging=!0,this.interactionMode=n?"rotate":"pan",this.pointerId=e.pointerId,this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.rotateLastAngleRad=this.interactionMode==="rotate"?this.getPointerAngleRad(e.clientX,e.clientY):null,this.canvas.classList.add("dragging"),this.canvas.setPointerCapture(e.pointerId))}onPointerMove(e){if(this.interactionLocked||!this.dragging||e.pointerId!==this.pointerId)return;const n=e.clientX-this.lastPointerX,r=e.clientY-this.lastPointerY;if(this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.interactionMode==="rotate"){const i=this.getPointerAngleRad(e.clientX,e.clientY),o=this.rotateLastAngleRad;if(this.rotateLastAngleRad=i,o!==null){const a=i-o,s=Math.atan2(Math.sin(a),Math.cos(a)),u=this.rotationDragSensitivityDegPerPixel/kn,c=this.camera.getViewState();this.camera.setViewState({rotationDeg:c.rotationDeg-s*180/Math.PI*u})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),a=ot(i.rotationDeg),s=Math.cos(a),u=Math.sin(a),c=(n*s-r*u)/o,f=(n*u+r*s)/o;this.camera.setViewState({offsetX:i.offsetX-c,offsetY:i.offsetY-f})}this.clampViewState(),this.emitViewState(),this.requestRender()}onPointerUp(e){this.interactionLocked||e.pointerId===this.pointerId&&this.cancelDrag()}onWheel(e){if(this.interactionLocked){e.preventDefault();return}e.preventDefault();const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top,o=e.deltaY<0?1.12:.89;this.zoomBy(o,r,i)}onDoubleClick(e){if(this.interactionLocked)return;const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top;this.zoomBy(e.shiftKey?.8:1.25,r,i)}onContextMenu(e){(this.dragging||e.ctrlKey||e.metaKey)&&e.preventDefault()}onWebGlContextLost(e){e.preventDefault(),!(this.destroyed||this.contextLost)&&(this.contextLost=!0,this.pointBuffersDirty=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelDrag(),this.tileScheduler.clear(),this.cache.clear(),this.onContextLost?.())}onWebGlContextRestored(e){this.destroyed||(this.contextLost=!1,this.cache.clear(),this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.pointBuffersDirty=!0,this.lastPointPalette&&this.lastPointPalette.length>0&&this.setPointPalette(this.lastPointPalette),this.lastPointData?this.setPointData(this.lastPointData):this.pointCount=0,this.resize(),this.requestRender(),this.onContextRestored?.())}destroy(){if(!this.destroyed){if(this.destroyed=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.resizeObserver.disconnect(),this.canvas.removeEventListener("pointerdown",this.boundPointerDown),this.canvas.removeEventListener("pointermove",this.boundPointerMove),this.canvas.removeEventListener("pointerup",this.boundPointerUp),this.canvas.removeEventListener("pointercancel",this.boundPointerUp),this.canvas.removeEventListener("wheel",this.boundWheel),this.canvas.removeEventListener("dblclick",this.boundDoubleClick),this.canvas.removeEventListener("contextmenu",this.boundContextMenu),this.canvas.removeEventListener("webglcontextlost",this.boundContextLost),this.canvas.removeEventListener("webglcontextrestored",this.boundContextRestored),this.cancelDrag(),this.tileScheduler.destroy(),!this.contextLost&&!this.gl.isContextLost()){for(const[,e]of this.cache)this.gl.deleteTexture(e.texture);this.gl.deleteBuffer(this.tileProgram.vbo),this.gl.deleteVertexArray(this.tileProgram.vao),this.gl.deleteProgram(this.tileProgram.program),this.gl.deleteBuffer(this.pointProgram.posBuffer),this.gl.deleteBuffer(this.pointProgram.termBuffer),this.gl.deleteBuffer(this.pointProgram.fillModeBuffer),this.gl.deleteBuffer(this.pointProgram.indexBuffer),this.gl.deleteTexture(this.pointProgram.paletteTexture),this.gl.deleteVertexArray(this.pointProgram.vao),this.gl.deleteProgram(this.pointProgram.program)}this.cache.clear()}}initTileProgram(){const e=this.gl,i=Tn(e,`#version 300 es
63
+ `;function ji(){if(typeof navigator>"u")return!1;const t=navigator;return typeof t.gpu=="object"&&t.gpu!==null}function or(){if(!ji())return null;const e=navigator.gpu;if(!e||typeof e!="object")return null;const n=e;return typeof n.requestAdapter!="function"?null:n}const St=globalThis.GPUShaderStage?.COMPUTE??4,kt=globalThis.GPUBufferUsage?.STORAGE??128,xt=globalThis.GPUBufferUsage?.COPY_DST??8,Ji=globalThis.GPUBufferUsage?.COPY_SRC??4,Qi=globalThis.GPUBufferUsage?.UNIFORM??64,eo=globalThis.GPUBufferUsage?.MAP_READ??1,to=globalThis.GPUMapMode?.READ??1;async function no(){const t=or();if(!t)return{supported:!1,features:[]};const e=await t.requestAdapter();return e?{supported:!0,adapterName:e.info?.description??e.info?.vendor??"unknown",features:Array.from(e.features),limits:{maxStorageBufferBindingSize:Number(e.limits.maxStorageBufferBindingSize),maxComputeInvocationsPerWorkgroup:Number(e.limits.maxComputeInvocationsPerWorkgroup),maxComputeWorkgroupSizeX:Number(e.limits.maxComputeWorkgroupSizeX)}}:{supported:!1,features:[]}}async function ro(){return Mt||(Mt=(async()=>{const t=or();if(!t)return null;const e=await t.requestAdapter();if(!e)return null;const n=await e.requestDevice(),r=n.createBindGroupLayout({entries:[{binding:0,visibility:St,buffer:{type:"read-only-storage"}},{binding:1,visibility:St,buffer:{type:"read-only-storage"}},{binding:2,visibility:St,buffer:{type:"storage"}},{binding:3,visibility:St,buffer:{type:"uniform"}}]}),i=n.createComputePipeline({layout:n.createPipelineLayout({bindGroupLayouts:[r]}),compute:{module:n.createShaderModule({code:Ki}),entryPoint:"main"}});return{device:n,pipeline:i,bindGroupLayout:r}})(),Mt)}function At(t,e){return Math.ceil(t/e)*e}async function sr(t,e,n){const r=await ro();if(!r)return null;const i=Math.max(0,Math.floor(e)),o=Math.max(0,Math.floor(n.length/4));if(i===0||o===0)return new Uint32Array(0);const a=Math.min(i,Math.floor(t.length/2));if(a===0)return new Uint32Array(0);const s=a*2*Float32Array.BYTES_PER_ELEMENT,u=o*4*Float32Array.BYTES_PER_ELEMENT,c=a*Uint32Array.BYTES_PER_ELEMENT,h=Number(r.device.limits.maxStorageBufferBindingSize);if(s>h||u>h||c>h)return null;const b=r.device.createBuffer({size:At(s,4),usage:kt|xt}),m=r.device.createBuffer({size:At(u,4),usage:kt|xt}),g=r.device.createBuffer({size:At(c,4),usage:kt|Ji}),y=r.device.createBuffer({size:16,usage:Qi|xt}),x=r.device.createBuffer({size:At(c,4),usage:xt|eo});r.device.queue.writeBuffer(b,0,t.buffer,t.byteOffset,s),r.device.queue.writeBuffer(m,0,n.buffer,n.byteOffset,u),r.device.queue.writeBuffer(y,0,new Uint32Array([a,o,0,0]));const E=r.device.createBindGroup({layout:r.bindGroupLayout,entries:[{binding:0,resource:{buffer:b}},{binding:1,resource:{buffer:m}},{binding:2,resource:{buffer:g}},{binding:3,resource:{buffer:y}}]}),_=r.device.createCommandEncoder(),X=_.beginComputePass();X.setPipeline(r.pipeline),X.setBindGroup(0,E),X.dispatchWorkgroups(Math.ceil(a/256)),X.end(),_.copyBufferToBuffer(g,0,x,0,c),r.device.queue.submit([_.finish()]),await x.mapAsync(to);const F=x.getMappedRange(),W=new Uint32Array(F.slice(0));return x.unmap(),b.destroy(),m.destroy(),g.destroy(),y.destroy(),x.destroy(),W}function Ne(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}async function ar(t,e,n={}){const r=Ne(),i=n.bridgeToDraw===!0;if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}};const o=ut(e??[]);if(o.length===0){const P={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return t.fillModes instanceof Uint8Array&&(P.fillModes=new Uint8Array(0)),t.ids instanceof Uint32Array&&(P.ids=new Uint32Array(0)),{data:P,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const a=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,s=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,a)),u=t.fillModes instanceof Uint8Array&&t.fillModes.length>=s?t.fillModes:null,c=t.ids instanceof Uint32Array&&t.ids.length>=s?t.ids:null;if(s===0){const P={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return u&&(P.fillModes=new Uint8Array(0)),c&&(P.ids=new Uint32Array(0)),{data:P,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!1,candidateCount:0,bridgedToDraw:!1}}}const h=new Float32Array(o.length*4);for(let P=0;P<o.length;P+=1){const z=P*4,Z=o[P];h[z]=Z.minX,h[z+1]=Z.minY,h[z+2]=Z.maxX,h[z+3]=Z.maxY}let b=null,m=!1;try{b=await sr(t.positions,s,h),m=!!b}catch{b=null,m=!1}if(!b)return{data:at(t,e),meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!1,candidateCount:s,bridgedToDraw:!1}};let g=0;for(let P=0;P<s;P+=1)b[P]===1&&(g+=1);const y=new Uint32Array(g);if(g>0){let P=0;for(let z=0;z<s;z+=1)b[z]===1&&(y[P]=z,P+=1)}if(g===0){if(i){const z={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:new Uint32Array(0)};return u&&(z.fillModes=u.subarray(0,s)),c&&(z.ids=c.subarray(0,s)),{data:z,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!0}}}const P={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)};return u&&(P.fillModes=new Uint8Array(0)),c&&(P.ids=new Uint32Array(0)),{data:P,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!0,candidateCount:0,bridgedToDraw:!1}}}if(i){const P=new Uint32Array(g);let z=0;for(let ee=0;ee<g;ee+=1){const N=y[ee]??0,ve=t.positions[N*2],Te=t.positions[N*2+1];Pt(ve,Te,o)&&(P[z]=N,z+=1)}const Z={count:s,positions:t.positions.subarray(0,s*2),paletteIndices:t.paletteIndices.subarray(0,s),drawIndices:P.subarray(0,z)};return u&&(Z.fillModes=u.subarray(0,s)),c&&(Z.ids=c.subarray(0,s)),{data:Z,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!0}}}const x=new Float32Array(g*2),E=new Uint16Array(g),_=u?new Uint8Array(g):null,X=c?new Uint32Array(g):null;let F=0;for(let P=0;P<g;P+=1){const z=y[P]??0,Z=t.positions[z*2],ee=t.positions[z*2+1];Pt(Z,ee,o)&&(x[F*2]=Z,x[F*2+1]=ee,E[F]=t.paletteIndices[z],_&&(_[F]=u[z]),X&&(X[F]=c[z]),F+=1)}const W={count:F,positions:x.subarray(0,F*2),paletteIndices:E.subarray(0,F)};return _&&(W.fillModes=_.subarray(0,F)),X&&(W.ids=X.subarray(0,F)),{data:W,meta:{mode:"hybrid-webgpu",durationMs:Ne()-r,usedWebGpu:!0,candidateCount:g,bridgedToDraw:!1}}}let Re=null,qt=!0,ur=1;const $e=new Map;function He(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function lr(){if(!qt)return null;if(Re)return Re;try{const t=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/roi-clip-worker-BDVQwN2T.js").href:new URL("assets/roi-clip-worker-BDVQwN2T.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:Bt&&Bt.tagName.toUpperCase()==="SCRIPT"&&Bt.src||new URL("index.cjs",document.baseURI).href),{type:"module"});return t.addEventListener("message",tn),t.addEventListener("error",nn),Re=t,t}catch{return qt=!1,null}}function tn(t){const e=t.data;if(!e)return;const n=$e.get(e.id);if(!n)return;if($e.delete(e.id),e.type==="roi-clip-failure"){n.reject(new Error(e.error||"worker clip failed"));return}if(e.type==="roi-clip-index-success"){if(n.kind!=="index"){n.reject(new Error("worker response mismatch: expected point data result"));return}const c=Math.max(0,Math.floor(e.count)),h=new Uint32Array(e.indices).subarray(0,c);n.resolve({indices:h,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:He()-n.startMs}});return}if(n.kind!=="data"){n.reject(new Error("worker response mismatch: expected index result"));return}const r=Math.max(0,Math.floor(e.count)),i=new Float32Array(e.positions),o=new Uint16Array(e.paletteIndices),a=e.fillModes?new Uint8Array(e.fillModes):null,s=e.ids?new Uint32Array(e.ids):null,u={count:r,positions:i.subarray(0,r*2),paletteIndices:o.subarray(0,r)};a&&(u.fillModes=a.subarray(0,r)),s&&(u.ids=s.subarray(0,r)),n.resolve({data:u,meta:{mode:"worker",durationMs:Number.isFinite(e.durationMs)?e.durationMs:He()-n.startMs}})}function nn(){qt=!1,Re&&(Re.removeEventListener("message",tn),Re.removeEventListener("error",nn),Re.terminate(),Re=null);for(const[,t]of $e)t.reject(new Error("worker crashed"));$e.clear()}function io(){if(Re){Re.removeEventListener("message",tn),Re.removeEventListener("error",nn),Re.terminate(),Re=null;for(const[,t]of $e)t.reject(new Error("worker terminated"));$e.clear()}}async function cr(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{data:null,meta:{mode:"worker",durationMs:0}};const n=lr();if(!n){const b=He();return{data:at(t,e),meta:{mode:"sync",durationMs:He()-b}}}const r=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r)),o=t.positions.slice(0,i*2),a=t.paletteIndices.slice(0,i),s=t.fillModes instanceof Uint8Array&&t.fillModes.length>=i?t.fillModes.slice(0,i):null,u=t.ids instanceof Uint32Array&&t.ids.length>=i?t.ids.slice(0,i):null,c=ur++,h=He();return new Promise((b,m)=>{$e.set(c,{kind:"data",resolve:b,reject:m,startMs:h});const g={type:"roi-clip-request",id:c,count:i,positions:o.buffer,paletteIndices:a.buffer,fillModes:s?.buffer,ids:u?.buffer,polygons:e??[]},y=[o.buffer,a.buffer];s&&y.push(s.buffer),u&&y.push(u.buffer),n.postMessage(g,y)})}async function oo(t,e){if(!t||!t.count||!t.positions||!t.paletteIndices)return{indices:new Uint32Array(0),meta:{mode:"worker",durationMs:0}};const n=lr();if(!n){const u=He();return{indices:ir(t,e),meta:{mode:"sync",durationMs:He()-u}}}const r=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER,i=Math.max(0,Math.min(t.count,Math.floor(t.positions.length/2),t.paletteIndices.length,r)),o=t.positions.slice(0,i*2),a=ur++,s=He();return new Promise((u,c)=>{$e.set(a,{kind:"index",resolve:u,reject:c,startMs:s});const h={type:"roi-clip-index-request",id:a,count:i,positions:o.buffer,polygons:e??[]};n.postMessage(h,[o.buffer])})}function so(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=ut([r?.coordinates]);if(i.length===0)continue;let o=0;for(const a of i)o+=a.area;e.push({regionId:r.id??n,regionIndex:n,polygons:i,area:Math.max(1e-6,o)})}return e}function ao(t,e){if(Array.isArray(e)){const n=e[t];if(typeof n=="string"&&n.length>0)return n}if(e instanceof Map){const n=e.get(t);if(typeof n=="string"&&n.length>0)return n}return String(t)}function fr(t,e,n={}){const r=Math.max(0,Math.min(Math.floor(t?.count??0),Math.floor((t?.positions?.length??0)/2),t?.paletteIndices?.length??0,t?.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER));let i=null;if(t?.drawIndices instanceof Uint32Array){const m=t.drawIndices;let g=m.length;for(let y=0;y<m.length;y+=1)m[y]<r||(g-=1);if(g===m.length)i=m;else if(g>0){const y=new Uint32Array(g);let x=0;for(let E=0;E<m.length;E+=1){const _=m[E];_>=r||(y[x]=_,x+=1)}i=y}else i=new Uint32Array(0)}const o=i?i.length:r,a=so(e??[]);if(!t||o===0||a.length===0)return{groups:[],inputPointCount:o,pointsInsideAnyRegion:0,unmatchedPointCount:o};const s=new Map,u=new Map;let c=0;for(let m=0;m<o;m+=1){const g=i?i[m]:m,y=t.positions[g*2],x=t.positions[g*2+1];let E=null;for(const F of a){let W=!1;for(const P of F.polygons)if(jt(y,x,P)){W=!0;break}W&&(!E||F.area<E.area)&&(E=F)}if(!E)continue;c+=1;const _=t.paletteIndices[g]??0,X=s.get(E.regionIndex)??new Map;X.set(_,(X.get(_)??0)+1),s.set(E.regionIndex,X),u.set(E.regionIndex,(u.get(E.regionIndex)??0)+1)}const h=n.includeEmptyRegions??!1,b=[];for(const m of a){const g=u.get(m.regionIndex)??0;if(!h&&g<=0)continue;const y=s.get(m.regionIndex)??new Map,x=Array.from(y.entries()).map(([E,_])=>({termId:ao(E,n.paletteIndexToTermId),paletteIndex:E,count:_})).sort((E,_)=>_.count-E.count||E.paletteIndex-_.paletteIndex);b.push({regionId:m.regionId,regionIndex:m.regionIndex,totalCount:g,termCounts:x})}return{groups:b,inputPointCount:o,pointsInsideAnyRegion:c,unmatchedPointCount:Math.max(0,o-c)}}function Rt(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function uo(t,e){if(!e)return!1;try{const r=new URL(t,typeof window<"u"?window.location.href:void 0).hostname.toLowerCase();if(r.includes("amazonaws.com")||r.startsWith("s3.")||r.includes(".s3."))return!1}catch{}return!0}class hr{constructor(e){M(this,"maxConcurrency");M(this,"maxRetries");M(this,"retryBaseDelayMs");M(this,"retryMaxDelayMs");M(this,"onTileLoad");M(this,"onTileError");M(this,"onStateChange");M(this,"authToken");M(this,"destroyed",!1);M(this,"queue",[]);M(this,"queuedByKey",new Map);M(this,"inflight",new Map);M(this,"visibleKeys",new Set);M(this,"timerId",null);M(this,"abortedCount",0);M(this,"retryCount",0);M(this,"failedCount",0);this.maxConcurrency=Math.max(1,Math.floor(e.maxConcurrency??12)),this.maxRetries=Math.max(0,Math.floor(e.maxRetries??2)),this.retryBaseDelayMs=Math.max(10,Math.floor(e.retryBaseDelayMs??120)),this.retryMaxDelayMs=Math.max(this.retryBaseDelayMs,Math.floor(e.retryMaxDelayMs??1200)),this.authToken=e.authToken??"",this.onTileLoad=e.onTileLoad,this.onTileError=e.onTileError,this.onStateChange=e.onStateChange}setAuthToken(e){this.authToken=String(e??"")}schedule(e){if(this.destroyed)return;const n=new Set;for(const r of e)n.add(r.key);this.visibleKeys=n,this.dropInvisibleQueued(n),this.abortInvisibleInflight(n);for(const r of e){if(this.inflight.has(r.key)){const a=this.inflight.get(r.key);a&&(a.tile=r);continue}const i=this.queuedByKey.get(r.key);if(i){i.tile=r;continue}const o={tile:r,attempt:0,readyAt:Rt()};this.queue.push(o),this.queuedByKey.set(r.key,o)}this.sortQueue(),this.pump(),this.emitStateChange()}clear(){this.clearPumpTimer(),this.visibleKeys.clear(),this.queue=[],this.queuedByKey.clear();for(const[,e]of this.inflight)e.controller.abort();this.inflight.clear(),this.emitStateChange()}destroy(){this.destroyed||(this.destroyed=!0,this.clear())}getInflightCount(){return this.inflight.size}getSnapshot(){return{inflight:this.inflight.size,queued:this.queue.length,aborted:this.abortedCount,retries:this.retryCount,failed:this.failedCount}}dropInvisibleQueued(e){if(this.queue.length===0)return;const n=[];for(const r of this.queue){if(!e.has(r.tile.key)){this.queuedByKey.delete(r.tile.key);continue}n.push(r)}this.queue=n}abortInvisibleInflight(e){for(const[n,r]of this.inflight)e.has(n)||(this.inflight.delete(n),this.abortedCount+=1,r.controller.abort())}sortQueue(){this.queue.sort((e,n)=>e.readyAt!==n.readyAt?e.readyAt-n.readyAt:e.tile.distance2!==n.tile.distance2?e.tile.distance2-n.tile.distance2:e.tile.tier!==n.tile.tier?n.tile.tier-e.tile.tier:e.tile.key.localeCompare(n.tile.key))}pump(){if(this.destroyed)return;for(this.clearPumpTimer();this.inflight.size<this.maxConcurrency;){const r=this.takeNextReadyQueueItem();if(!r)break;this.startFetch(r)}if(this.inflight.size>=this.maxConcurrency||this.queue.length===0)return;const e=this.queue[0]?.readyAt;if(typeof e!="number")return;const n=Math.max(0,e-Rt());this.timerId=window.setTimeout(()=>{this.timerId=null,this.pump()},n)}takeNextReadyQueueItem(){if(this.queue.length===0)return null;const e=Rt(),n=this.queue[0];return!n||n.readyAt>e?null:(this.queue.shift(),this.queuedByKey.delete(n.tile.key),n)}startFetch(e){const n=new AbortController,r={tile:e.tile,attempt:e.attempt,controller:n};this.inflight.set(e.tile.key,r),this.emitStateChange();const i=uo(e.tile.url,this.authToken);fetch(e.tile.url,{signal:n.signal,headers:i?{Authorization:this.authToken}:void 0}).then(o=>{if(!o.ok)throw new Error(`HTTP ${o.status}`);return o.blob()}).then(o=>createImageBitmap(o)).then(o=>{if(this.destroyed||n.signal.aborted){o.close();return}if(!this.visibleKeys.has(e.tile.key)){o.close();return}this.onTileLoad(e.tile,o)}).catch(o=>{if(n.signal.aborted||this.destroyed)return;if(e.attempt<this.maxRetries&&this.visibleKeys.has(e.tile.key)){this.retryCount+=1;const s=e.attempt+1,u=this.getRetryDelay(s),c={tile:e.tile,attempt:s,readyAt:Rt()+u},h=this.queuedByKey.get(e.tile.key);h?(h.tile=c.tile,h.readyAt=Math.min(h.readyAt,c.readyAt),h.attempt=Math.max(h.attempt,c.attempt)):(this.queue.push(c),this.queuedByKey.set(c.tile.key,c)),this.sortQueue();return}this.failedCount+=1,this.onTileError?.(e.tile,o,e.attempt+1)}).finally(()=>{this.inflight.delete(e.tile.key),this.pump(),this.emitStateChange()})}getRetryDelay(e){const n=Math.max(0,e-1),r=Math.min(this.retryMaxDelayMs,this.retryBaseDelayMs*2**n),i=.85+Math.random()*.3;return Math.round(r*i)}clearPumpTimer(){this.timerId!==null&&(window.clearTimeout(this.timerId),this.timerId=null)}emitStateChange(){this.onStateChange?.(this.getSnapshot())}}const Dn=.35,Ht=.5,lo=256,$t=[{zoom:1,size:2.8},{zoom:2,size:3.4},{zoom:3,size:4.2},{zoom:4,size:5.3},{zoom:5,size:6.8},{zoom:6,size:8.4},{zoom:7,size:9.8},{zoom:8,size:11.2},{zoom:9,size:14},{zoom:10,size:17.5},{zoom:11,size:22},{zoom:12,size:28}];class co{constructor(){M(this,"viewportWidth",1);M(this,"viewportHeight",1);M(this,"viewState",{zoom:1,offsetX:0,offsetY:0,rotationDeg:0})}setViewport(e,n){this.viewportWidth=Math.max(1,e),this.viewportHeight=Math.max(1,n)}getViewport(){return{width:this.viewportWidth,height:this.viewportHeight}}setViewState(e){typeof e.zoom=="number"&&(this.viewState.zoom=Math.max(1e-4,e.zoom)),typeof e.offsetX=="number"&&(this.viewState.offsetX=e.offsetX),typeof e.offsetY=="number"&&(this.viewState.offsetY=e.offsetY),typeof e.rotationDeg=="number"&&Number.isFinite(e.rotationDeg)&&(this.viewState.rotationDeg=e.rotationDeg)}getViewState(){return{...this.viewState}}getCenter(){const e=Math.max(1e-6,this.viewState.zoom);return[this.viewState.offsetX+this.viewportWidth/(2*e),this.viewState.offsetY+this.viewportHeight/(2*e)]}setCenter(e,n){const r=Math.max(1e-6,this.viewState.zoom);this.viewState.offsetX=e-this.viewportWidth/(2*r),this.viewState.offsetY=n-this.viewportHeight/(2*r)}screenToWorld(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,a]=this.getCenter(),s=(e-this.viewportWidth*.5)/i,u=(n-this.viewportHeight*.5)/i,c=st(r.rotationDeg),h=Math.cos(c),b=Math.sin(c);return[o+s*h-u*b,a+s*b+u*h]}worldToScreen(e,n){const r=this.viewState,i=Math.max(1e-6,r.zoom),[o,a]=this.getCenter(),s=e-o,u=n-a,c=st(r.rotationDeg),h=Math.cos(c),b=Math.sin(c),m=s*h+u*b,g=-s*b+u*h;return[this.viewportWidth*.5+m*i,this.viewportHeight*.5+g*i]}getViewCorners(){const e=this.viewportWidth,n=this.viewportHeight;return[this.screenToWorld(0,0),this.screenToWorld(e,0),this.screenToWorld(e,n),this.screenToWorld(0,n)]}getMatrix(){const e=Math.max(1e-6,this.viewState.zoom),[n,r]=this.getCenter(),i=st(this.viewState.rotationDeg),o=Math.cos(i),a=Math.sin(i),s=2*e*o/this.viewportWidth,u=2*e*a/this.viewportWidth,c=2*e*a/this.viewportHeight,h=-2*e*o/this.viewportHeight,b=-(s*n+u*r),m=-(c*n+h*r);return new Float32Array([s,c,0,u,h,0,b,m,1])}}function st(t){return t*Math.PI/180}function Xn(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function qe(t,e,n){const r=t.getUniformLocation(e,n);if(!r)throw new Error(`uniform location lookup failed: ${n}`);return r}function Et(t,e){return!t||!e?t===e:t.buffer===e.buffer&&t.byteOffset===e.byteOffset&&t.byteLength===e.byteLength}function Zt(t){return t.map(e=>({zoom:e.zoom,size:e.size}))}function Wn(t){if(!t)return Zt($t);const e=new Map;for(const[n,r]of Object.entries(t)){const i=Number(n),o=Number(r);!Number.isFinite(i)||!Number.isFinite(o)||o<=0||e.set(i,o)}return e.size===0?Zt($t):Array.from(e.entries()).sort((n,r)=>n[0]-r[0]).map(([n,r])=>({zoom:n,size:r}))}function fo(t,e){if(t===e)return!0;if(t.length!==e.length)return!1;for(let n=0;n<t.length;n+=1)if(t[n].zoom!==e[n].zoom||t[n].size!==e[n].size)return!1;return!0}function ho(t,e){if(!Number.isFinite(t))return e[0]?.size??Ht;if(e.length===0)return Ht;if(e.length===1||t<=e[0].zoom)return e[0].size;for(let a=1;a<e.length;a+=1){const s=e[a-1],u=e[a];if(t>u.zoom)continue;const c=Math.max(1e-6,u.zoom-s.zoom),h=Q((t-s.zoom)/c,0,1);return s.size+(u.size-s.size)*h}const n=e[e.length-1],r=e[e.length-2],i=Math.max(1e-6,n.zoom-r.zoom),o=(n.size-r.size)/i;return n.size+(t-n.zoom)*o}const mo=.1,go=5;function Yn(t){return typeof t!="number"||!Number.isFinite(t)?1:Q(t,mo,go)}class dr{constructor(e,n,r={}){M(this,"canvas");M(this,"source");M(this,"gl");M(this,"camera",new co);M(this,"onViewStateChange");M(this,"onStats");M(this,"onTileError");M(this,"onContextLost");M(this,"onContextRestored");M(this,"resizeObserver");M(this,"tileProgram");M(this,"pointProgram");M(this,"tileScheduler");M(this,"authToken");M(this,"destroyed",!1);M(this,"contextLost",!1);M(this,"frame",null);M(this,"frameSerial",0);M(this,"dragging",!1);M(this,"interactionMode","none");M(this,"rotateLastAngleRad",null);M(this,"pointerId",null);M(this,"lastPointerX",0);M(this,"lastPointerY",0);M(this,"interactionLocked",!1);M(this,"ctrlDragRotate",!0);M(this,"rotationDragSensitivityDegPerPixel",.35);M(this,"maxCacheTiles");M(this,"fitZoom",1);M(this,"minZoom",1e-6);M(this,"maxZoom",1);M(this,"currentTier",0);M(this,"pointCount",0);M(this,"usePointIndices",!1);M(this,"pointBuffersDirty",!0);M(this,"pointPaletteSize",1);M(this,"pointSizeStops",Zt($t));M(this,"pointStrokeScale",1);M(this,"lastPointData",null);M(this,"lastPointPalette",null);M(this,"zeroFillModes",new Uint8Array(0));M(this,"cache",new Map);M(this,"boundPointerDown");M(this,"boundPointerMove");M(this,"boundPointerUp");M(this,"boundWheel");M(this,"boundDoubleClick");M(this,"boundContextMenu");M(this,"boundContextLost");M(this,"boundContextRestored");this.canvas=e,this.source=n,this.onViewStateChange=r.onViewStateChange,this.onStats=r.onStats,this.onTileError=r.onTileError,this.onContextLost=r.onContextLost,this.onContextRestored=r.onContextRestored,this.authToken=r.authToken??"",this.maxCacheTiles=Math.max(32,Math.floor(r.maxCacheTiles??320)),this.ctrlDragRotate=r.ctrlDragRotate??!0,this.rotationDragSensitivityDegPerPixel=typeof r.rotationDragSensitivityDegPerPixel=="number"&&Number.isFinite(r.rotationDragSensitivityDegPerPixel)?Math.max(0,r.rotationDragSensitivityDegPerPixel):Dn,this.pointSizeStops=Wn(r.pointSizeByZoom),this.pointStrokeScale=Yn(r.pointStrokeScale);const i=e.getContext("webgl2",{alpha:!1,antialias:!1,depth:!1,stencil:!1,powerPreference:"high-performance"});if(!i)throw new Error("WebGL2 not supported");this.gl=i,this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.tileScheduler=new hr({authToken:this.authToken,maxConcurrency:r.tileScheduler?.maxConcurrency??12,maxRetries:r.tileScheduler?.maxRetries??2,retryBaseDelayMs:r.tileScheduler?.retryBaseDelayMs??120,retryMaxDelayMs:r.tileScheduler?.retryMaxDelayMs??1200,onTileLoad:(o,a)=>this.handleTileLoaded(o,a),onTileError:(o,a,s)=>{this.onTileError?.({tile:o,error:a,attemptCount:s}),console.warn("tile load failed",o.url,a)}}),this.resizeObserver=new ResizeObserver(()=>this.resize()),this.resizeObserver.observe(e),this.boundPointerDown=o=>this.onPointerDown(o),this.boundPointerMove=o=>this.onPointerMove(o),this.boundPointerUp=o=>this.onPointerUp(o),this.boundWheel=o=>this.onWheel(o),this.boundDoubleClick=o=>this.onDoubleClick(o),this.boundContextMenu=o=>this.onContextMenu(o),this.boundContextLost=o=>this.onWebGlContextLost(o),this.boundContextRestored=o=>this.onWebGlContextRestored(o),e.addEventListener("pointerdown",this.boundPointerDown),e.addEventListener("pointermove",this.boundPointerMove),e.addEventListener("pointerup",this.boundPointerUp),e.addEventListener("pointercancel",this.boundPointerUp),e.addEventListener("wheel",this.boundWheel,{passive:!1}),e.addEventListener("dblclick",this.boundDoubleClick),e.addEventListener("contextmenu",this.boundContextMenu),e.addEventListener("webglcontextlost",this.boundContextLost),e.addEventListener("webglcontextrestored",this.boundContextRestored),this.fitToImage(),this.resize()}setAuthToken(e){this.authToken=String(e??""),this.tileScheduler.setAuthToken(this.authToken)}setViewState(e){const n={...e};typeof n.zoom=="number"&&(n.zoom=Q(n.zoom,this.minZoom,this.maxZoom)),this.camera.setViewState(n),this.clampViewState(),this.emitViewState(),this.requestRender()}getViewState(){return this.camera.getViewState()}setPointPalette(e){if(!e||e.length===0){this.lastPointPalette=null;return}if(this.lastPointPalette=new Uint8Array(e),this.contextLost||this.gl.isContextLost())return;const n=this.gl,r=Math.max(1,Math.floor(this.lastPointPalette.length/4));this.pointPaletteSize=r,n.bindTexture(n.TEXTURE_2D,this.pointProgram.paletteTexture),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,r,1,0,n.RGBA,n.UNSIGNED_BYTE,this.lastPointPalette),n.bindTexture(n.TEXTURE_2D,null),this.requestRender()}setPointData(e){if(!e||!e.count||!e.positions||!e.paletteIndices){this.lastPointData=null,this.pointCount=0,this.usePointIndices=!1,this.requestRender();return}const n=e.fillModes instanceof Uint8Array?e.fillModes:null,r=n!==null,i=Math.max(0,Math.min(e.count,Math.floor(e.positions.length/2),e.paletteIndices.length,r?n.length:Number.MAX_SAFE_INTEGER)),o=e.positions.subarray(0,i*2),a=e.paletteIndices.subarray(0,i),s=r?n.subarray(0,i):void 0,u=e.drawIndices instanceof Uint32Array,c=u?this.sanitizeDrawIndices(e.drawIndices,i):null,h=this.lastPointData,b=h?.fillModes instanceof Uint8Array;let m=this.pointBuffersDirty||!h||h.count!==i||!Et(h.positions,o)||!Et(h.paletteIndices,a)||b!==r||r&&(!h?.fillModes||!Et(h.fillModes,s)),g=this.pointBuffersDirty||u&&(!h?.drawIndices||!Et(h.drawIndices,c))||!u&&!!h?.drawIndices;if(this.lastPointData={count:i,positions:o,paletteIndices:a,fillModes:s,drawIndices:u?c??void 0:void 0},this.contextLost||this.gl.isContextLost())return;const y=this.gl;m&&(y.bindBuffer(y.ARRAY_BUFFER,this.pointProgram.posBuffer),y.bufferData(y.ARRAY_BUFFER,this.lastPointData.positions,y.STATIC_DRAW),y.bindBuffer(y.ARRAY_BUFFER,this.pointProgram.termBuffer),y.bufferData(y.ARRAY_BUFFER,this.lastPointData.paletteIndices,y.STATIC_DRAW),y.bindBuffer(y.ARRAY_BUFFER,this.pointProgram.fillModeBuffer),y.bufferData(y.ARRAY_BUFFER,this.lastPointData.fillModes??this.getZeroFillModes(i),y.STATIC_DRAW),y.bindBuffer(y.ARRAY_BUFFER,null)),u&&g&&(y.bindBuffer(y.ELEMENT_ARRAY_BUFFER,this.pointProgram.indexBuffer),y.bufferData(y.ELEMENT_ARRAY_BUFFER,c??new Uint32Array(0),y.DYNAMIC_DRAW),y.bindBuffer(y.ELEMENT_ARRAY_BUFFER,null)),this.usePointIndices=u,this.pointCount=u?c?.length??0:this.lastPointData.count,(m||g)&&(this.pointBuffersDirty=!1),this.requestRender()}sanitizeDrawIndices(e,n){if(n<=0||e.length===0)return new Uint32Array(0);let r=e.length;for(let a=0;a<e.length;a+=1)e[a]<n||(r-=1);if(r===e.length)return e;if(r<=0)return new Uint32Array(0);const i=new Uint32Array(r);let o=0;for(let a=0;a<e.length;a+=1){const s=e[a];s>=n||(i[o]=s,o+=1)}return i}getZeroFillModes(e){return e<=0?new Uint8Array(0):(this.zeroFillModes.length<e&&(this.zeroFillModes=new Uint8Array(e)),this.zeroFillModes.subarray(0,e))}setInteractionLock(e){const n=!!e;this.interactionLocked!==n&&(this.interactionLocked=n,n&&this.cancelDrag())}setPointSizeByZoom(e){const n=Wn(e);fo(this.pointSizeStops,n)||(this.pointSizeStops=n,this.requestRender())}setPointStrokeScale(e){const n=Yn(e);this.pointStrokeScale!==n&&(this.pointStrokeScale=n,this.requestRender())}cancelDrag(){if(this.pointerId!==null&&this.canvas.hasPointerCapture(this.pointerId))try{this.canvas.releasePointerCapture(this.pointerId)}catch{}this.dragging=!1,this.interactionMode="none",this.rotateLastAngleRad=null,this.pointerId=null,this.canvas.classList.remove("dragging")}getPointerAngleRad(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left-r.width*.5,o=n-r.top-r.height*.5;return Math.atan2(o,i)}screenToWorld(e,n){const r=this.canvas.getBoundingClientRect(),i=e-r.left,o=n-r.top;return this.camera.screenToWorld(i,o)}worldToScreen(e,n){return this.camera.worldToScreen(e,n)}setViewCenter(e,n){!Number.isFinite(e)||!Number.isFinite(n)||(this.camera.setCenter(e,n),this.clampViewState(),this.emitViewState(),this.requestRender())}getViewCorners(){return this.camera.getViewCorners()}resetRotation(){const e=this.camera.getViewState();Math.abs(e.rotationDeg)<1e-6||(this.camera.setViewState({rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender())}getPointSizeByZoom(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e),r=ho(n,this.pointSizeStops);return Q(r,Ht,lo)}fitToImage(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||1),r=Math.max(1,e.height||1),i=Math.min(n/this.source.width,r/this.source.height),o=Number.isFinite(i)&&i>0?i:1;this.fitZoom=o,this.minZoom=Math.max(this.fitZoom*.5,1e-6),this.maxZoom=Math.max(1,this.fitZoom*8),this.minZoom>this.maxZoom&&(this.minZoom=this.maxZoom);const a=n/o,s=r/o;this.camera.setViewState({zoom:Q(o,this.minZoom,this.maxZoom),offsetX:(this.source.width-a)*.5,offsetY:(this.source.height-s)*.5,rotationDeg:0}),this.clampViewState(),this.emitViewState(),this.requestRender()}zoomBy(e,n,r){const i=this.camera.getViewState(),o=Q(i.zoom*e,this.minZoom,this.maxZoom);if(o===i.zoom)return;const[a,s]=this.camera.screenToWorld(n,r);this.camera.setViewState({zoom:o});const u=this.camera.getViewport(),c=n-u.width*.5,h=r-u.height*.5,b=st(this.camera.getViewState().rotationDeg),m=Math.cos(b),g=Math.sin(b),y=c/o*m-h/o*g,x=c/o*g+h/o*m;this.camera.setCenter(a-y,s-x),this.clampViewState(),this.emitViewState(),this.requestRender()}clampViewState(){const e=this.getViewBounds(),n=Math.max(1e-6,e[2]-e[0]),r=Math.max(1e-6,e[3]-e[1]),i=n*.2,o=r*.2,[a,s]=this.camera.getCenter(),u=n*.5,c=r*.5,h=u-i,b=this.source.width-u+i,m=c-o,g=this.source.height-c+o,y=h<=b?Q(a,h,b):this.source.width*.5,x=m<=g?Q(s,m,g):this.source.height*.5;this.camera.setCenter(y,x)}emitViewState(){this.onViewStateChange?.(this.camera.getViewState())}selectTier(){const e=Math.max(1e-6,this.camera.getViewState().zoom),n=this.source.maxTierZoom+Math.log2(e);return Q(Math.floor(n),0,this.source.maxTierZoom)}getViewBounds(){const e=this.camera.getViewCorners();let n=1/0,r=1/0,i=-1/0,o=-1/0;for(const[a,s]of e)a<n&&(n=a),a>i&&(i=a),s<r&&(r=s),s>o&&(o=s);return[n,r,i,o]}intersectsBounds(e,n){return!(e[2]<=n[0]||e[0]>=n[2]||e[3]<=n[1]||e[1]>=n[3])}getVisibleTiles(){const e=this.selectTier();this.currentTier=e;const n=this.getViewBounds(),r=Math.pow(2,this.source.maxTierZoom-e),i=Math.ceil(this.source.width/r),o=Math.ceil(this.source.height/r),a=Math.max(1,Math.ceil(i/this.source.tileSize)),s=Math.max(1,Math.ceil(o/this.source.tileSize)),u=n[0],c=n[1],h=n[2],b=n[3],m=Q(Math.floor(u/r/this.source.tileSize),0,a-1),g=Q(Math.floor((h-1)/r/this.source.tileSize),0,a-1),y=Q(Math.floor(c/r/this.source.tileSize),0,s-1),x=Q(Math.floor((b-1)/r/this.source.tileSize),0,s-1);if(m>g||y>x)return[];const E=(u+h)*.5/r/this.source.tileSize,_=(c+b)*.5/r/this.source.tileSize,X=[];for(let F=y;F<=x;F+=1)for(let W=m;W<=g;W+=1){const P=W*this.source.tileSize*r,z=F*this.source.tileSize*r,Z=Math.min((W+1)*this.source.tileSize,i)*r,ee=Math.min((F+1)*this.source.tileSize,o)*r,N=W-E,ve=F-_;X.push({key:`${e}/${W}/${F}`,tier:e,x:W,y:F,bounds:[P,z,Z,ee],distance2:N*N+ve*ve,url:en(this.source,e,W,F)})}return X.sort((F,W)=>F.distance2-W.distance2),X}trimCache(){if(this.cache.size<=this.maxCacheTiles)return;const e=Array.from(this.cache.entries());e.sort((r,i)=>r[1].lastUsed-i[1].lastUsed);const n=this.cache.size-this.maxCacheTiles;for(let r=0;r<n;r+=1){const[i,o]=e[r];this.gl.deleteTexture(o.texture),this.cache.delete(i)}}render(){if(this.destroyed||this.contextLost||this.gl.isContextLost())return;const e=Xn();this.frameSerial+=1;const n=this.gl,r=this.tileProgram,i=this.pointProgram;n.clearColor(.03,.06,.1,1),n.clear(n.COLOR_BUFFER_BIT);const o=this.getVisibleTiles(),a=this.getViewBounds(),s=new Set(o.map(m=>m.key));n.useProgram(r.program),n.bindVertexArray(r.vao),n.uniformMatrix3fv(r.uCamera,!1,this.camera.getMatrix()),n.uniform1i(r.uTexture,0);const u=[];for(const[,m]of this.cache)s.has(m.key)||this.intersectsBounds(m.bounds,a)&&u.push(m);u.sort((m,g)=>m.tier-g.tier);for(const m of u)m.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,m.texture),n.uniform4f(r.uBounds,m.bounds[0],m.bounds[1],m.bounds[2],m.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4);let c=0;const h=[];for(const m of o){const g=this.cache.get(m.key);if(!g){h.push(m);continue}g.lastUsed=this.frameSerial,n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,g.texture),n.uniform4f(r.uBounds,g.bounds[0],g.bounds[1],g.bounds[2],g.bounds[3]),n.drawArrays(n.TRIANGLE_STRIP,0,4),c+=1}this.tileScheduler.schedule(h),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null);let b=0;if(this.pointCount>0&&(n.enable(n.BLEND),n.blendFunc(n.ONE,n.ONE_MINUS_SRC_ALPHA),n.useProgram(i.program),n.bindVertexArray(i.vao),n.uniformMatrix3fv(i.uCamera,!1,this.camera.getMatrix()),n.uniform1f(i.uPointSize,this.getPointSizeByZoom()),n.uniform1f(i.uPointStrokeScale,this.pointStrokeScale),n.uniform1f(i.uPaletteSize,this.pointPaletteSize),n.uniform1i(i.uPalette,1),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,i.paletteTexture),this.usePointIndices?n.drawElements(n.POINTS,this.pointCount,n.UNSIGNED_INT,0):n.drawArrays(n.POINTS,0,this.pointCount),n.bindTexture(n.TEXTURE_2D,null),n.bindVertexArray(null),b=this.pointCount),this.onStats){const m=this.tileScheduler.getSnapshot(),g=c,y=h.length,x=u.length+c+(b>0?1:0);this.onStats({tier:this.currentTier,visible:o.length,rendered:c,points:b,fallback:u.length,cache:this.cache.size,inflight:m.inflight,queued:m.queued,retries:m.retries,failed:m.failed,aborted:m.aborted,cacheHits:g,cacheMisses:y,drawCalls:x,frameMs:Xn()-e})}}requestRender(){this.frame!==null||this.destroyed||this.contextLost||this.gl.isContextLost()||(this.frame=requestAnimationFrame(()=>{this.frame=null,this.render()}))}resize(){const e=this.canvas.getBoundingClientRect(),n=Math.max(1,e.width||this.canvas.clientWidth||1),r=Math.max(1,e.height||this.canvas.clientHeight||1),i=Math.max(1,window.devicePixelRatio||1),o=Math.max(1,Math.round(n*i)),a=Math.max(1,Math.round(r*i));(this.canvas.width!==o||this.canvas.height!==a)&&(this.canvas.width=o,this.canvas.height=a),this.camera.setViewport(n,r),this.gl.viewport(0,0,o,a),this.requestRender()}onPointerDown(e){if(this.interactionLocked)return;const n=this.ctrlDragRotate&&(e.ctrlKey||e.metaKey);(e.button===0||n&&e.button===2)&&(n&&e.preventDefault(),this.dragging=!0,this.interactionMode=n?"rotate":"pan",this.pointerId=e.pointerId,this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.rotateLastAngleRad=this.interactionMode==="rotate"?this.getPointerAngleRad(e.clientX,e.clientY):null,this.canvas.classList.add("dragging"),this.canvas.setPointerCapture(e.pointerId))}onPointerMove(e){if(this.interactionLocked||!this.dragging||e.pointerId!==this.pointerId)return;const n=e.clientX-this.lastPointerX,r=e.clientY-this.lastPointerY;if(this.lastPointerX=e.clientX,this.lastPointerY=e.clientY,this.interactionMode==="rotate"){const i=this.getPointerAngleRad(e.clientX,e.clientY),o=this.rotateLastAngleRad;if(this.rotateLastAngleRad=i,o!==null){const a=i-o,s=Math.atan2(Math.sin(a),Math.cos(a)),u=this.rotationDragSensitivityDegPerPixel/Dn,c=this.camera.getViewState();this.camera.setViewState({rotationDeg:c.rotationDeg-s*180/Math.PI*u})}}else{const i=this.camera.getViewState(),o=Math.max(1e-6,i.zoom),a=st(i.rotationDeg),s=Math.cos(a),u=Math.sin(a),c=(n*s-r*u)/o,h=(n*u+r*s)/o;this.camera.setViewState({offsetX:i.offsetX-c,offsetY:i.offsetY-h})}this.clampViewState(),this.emitViewState(),this.requestRender()}onPointerUp(e){this.interactionLocked||e.pointerId===this.pointerId&&this.cancelDrag()}onWheel(e){if(this.interactionLocked){e.preventDefault();return}e.preventDefault();const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top,o=e.deltaY<0?1.12:.89;this.zoomBy(o,r,i)}onDoubleClick(e){if(this.interactionLocked)return;const n=this.canvas.getBoundingClientRect(),r=e.clientX-n.left,i=e.clientY-n.top;this.zoomBy(e.shiftKey?.8:1.25,r,i)}onContextMenu(e){(this.dragging||e.ctrlKey||e.metaKey)&&e.preventDefault()}onWebGlContextLost(e){e.preventDefault(),!(this.destroyed||this.contextLost)&&(this.contextLost=!0,this.pointBuffersDirty=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.cancelDrag(),this.tileScheduler.clear(),this.cache.clear(),this.onContextLost?.())}onWebGlContextRestored(e){this.destroyed||(this.contextLost=!1,this.cache.clear(),this.tileProgram=this.initTileProgram(),this.pointProgram=this.initPointProgram(),this.pointBuffersDirty=!0,this.lastPointPalette&&this.lastPointPalette.length>0&&this.setPointPalette(this.lastPointPalette),this.lastPointData?this.setPointData(this.lastPointData):this.pointCount=0,this.resize(),this.requestRender(),this.onContextRestored?.())}destroy(){if(!this.destroyed){if(this.destroyed=!0,this.frame!==null&&(cancelAnimationFrame(this.frame),this.frame=null),this.resizeObserver.disconnect(),this.canvas.removeEventListener("pointerdown",this.boundPointerDown),this.canvas.removeEventListener("pointermove",this.boundPointerMove),this.canvas.removeEventListener("pointerup",this.boundPointerUp),this.canvas.removeEventListener("pointercancel",this.boundPointerUp),this.canvas.removeEventListener("wheel",this.boundWheel),this.canvas.removeEventListener("dblclick",this.boundDoubleClick),this.canvas.removeEventListener("contextmenu",this.boundContextMenu),this.canvas.removeEventListener("webglcontextlost",this.boundContextLost),this.canvas.removeEventListener("webglcontextrestored",this.boundContextRestored),this.cancelDrag(),this.tileScheduler.destroy(),!this.contextLost&&!this.gl.isContextLost()){for(const[,e]of this.cache)this.gl.deleteTexture(e.texture);this.gl.deleteBuffer(this.tileProgram.vbo),this.gl.deleteVertexArray(this.tileProgram.vao),this.gl.deleteProgram(this.tileProgram.program),this.gl.deleteBuffer(this.pointProgram.posBuffer),this.gl.deleteBuffer(this.pointProgram.termBuffer),this.gl.deleteBuffer(this.pointProgram.fillModeBuffer),this.gl.deleteBuffer(this.pointProgram.indexBuffer),this.gl.deleteTexture(this.pointProgram.paletteTexture),this.gl.deleteVertexArray(this.pointProgram.vao),this.gl.deleteProgram(this.pointProgram.program)}this.cache.clear()}}initTileProgram(){const e=this.gl,i=Tn(e,`#version 300 es
64
64
  precision highp float;
65
65
  in vec2 aUnit;
66
66
  in vec2 aUv;
@@ -82,7 +82,7 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
82
82
  out vec4 outColor;
83
83
  void main() {
84
84
  outColor = texture(uTexture, vUv);
85
- }`),o=Ve(e,i,"uCamera"),a=Ve(e,i,"uBounds"),s=Ve(e,i,"uTexture"),u=e.createVertexArray(),c=e.createBuffer();if(!u||!c)throw new Error("buffer allocation failed");e.bindVertexArray(u),e.bindBuffer(e.ARRAY_BUFFER,c),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]),e.STATIC_DRAW);const f=e.getAttribLocation(i,"aUnit"),p=e.getAttribLocation(i,"aUv");if(f<0||p<0)throw new Error("tile attribute lookup failed");return e.enableVertexAttribArray(f),e.enableVertexAttribArray(p),e.vertexAttribPointer(f,2,e.FLOAT,!1,16,0),e.vertexAttribPointer(p,2,e.FLOAT,!1,16,8),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),{program:i,vao:u,vbo:c,uCamera:o,uBounds:a,uTexture:s}}initPointProgram(){const e=this.gl,i=Tn(e,`#version 300 es
85
+ }`),o=qe(e,i,"uCamera"),a=qe(e,i,"uBounds"),s=qe(e,i,"uTexture"),u=e.createVertexArray(),c=e.createBuffer();if(!u||!c)throw new Error("buffer allocation failed");e.bindVertexArray(u),e.bindBuffer(e.ARRAY_BUFFER,c),e.bufferData(e.ARRAY_BUFFER,new Float32Array([0,0,0,0,1,0,1,0,0,1,0,1,1,1,1,1]),e.STATIC_DRAW);const h=e.getAttribLocation(i,"aUnit"),b=e.getAttribLocation(i,"aUv");if(h<0||b<0)throw new Error("tile attribute lookup failed");return e.enableVertexAttribArray(h),e.enableVertexAttribArray(b),e.vertexAttribPointer(h,2,e.FLOAT,!1,16,0),e.vertexAttribPointer(b,2,e.FLOAT,!1,16,8),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),{program:i,vao:u,vbo:c,uCamera:o,uBounds:a,uTexture:s}}initPointProgram(){const e=this.gl,i=Tn(e,`#version 300 es
86
86
  precision highp float;
87
87
  in vec2 aPosition;
88
88
  in uint aTerm;
@@ -131,6 +131,6 @@ fn main(@builtin(global_invocation_id) gid: vec3<u32>) {
131
131
  if (alpha <= 0.001) discard;
132
132
 
133
133
  outColor = vec4(color.rgb * alpha, alpha);
134
- }`),o=Ve(e,i,"uCamera"),a=Ve(e,i,"uPointSize"),s=Ve(e,i,"uPointStrokeScale"),u=Ve(e,i,"uPalette"),c=Ve(e,i,"uPaletteSize"),f=e.createVertexArray(),p=e.createBuffer(),m=e.createBuffer(),g=e.createBuffer(),b=e.createBuffer(),x=e.createTexture();if(!f||!p||!m||!g||!b||!x)throw new Error("point buffer allocation failed");e.bindVertexArray(f),e.bindBuffer(e.ARRAY_BUFFER,p),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const R=e.getAttribLocation(i,"aPosition");if(R<0)throw new Error("point position attribute not found");e.enableVertexAttribArray(R),e.vertexAttribPointer(R,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,m),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const _=e.getAttribLocation(i,"aTerm");if(_<0)throw new Error("point term attribute not found");e.enableVertexAttribArray(_),e.vertexAttribIPointer(_,1,e.UNSIGNED_SHORT,0,0),e.bindBuffer(e.ARRAY_BUFFER,g),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const W=e.getAttribLocation(i,"aFillMode");if(W<0)throw new Error("point fill mode attribute not found");return e.enableVertexAttribArray(W),e.vertexAttribIPointer(W,1,e.UNSIGNED_BYTE,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,b),e.bufferData(e.ELEMENT_ARRAY_BUFFER,0,e.DYNAMIC_DRAW),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null),e.bindTexture(e.TEXTURE_2D,x),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([160,160,160,255])),e.bindTexture(e.TEXTURE_2D,null),{program:i,vao:f,posBuffer:p,termBuffer:m,fillModeBuffer:g,indexBuffer:b,paletteTexture:x,uCamera:o,uPointSize:a,uPointStrokeScale:s,uPalette:u,uPaletteSize:c}}handleTileLoaded(e,n){if(this.destroyed||this.contextLost||this.gl.isContextLost()){n.close();return}if(this.cache.has(e.key)){n.close();return}const r=this.createTextureFromBitmap(n);n.close(),r&&(this.cache.set(e.key,{key:e.key,texture:r,bounds:e.bounds,tier:e.tier,lastUsed:this.frameSerial}),this.trimCache(),this.requestRender())}createTextureFromBitmap(e){if(this.contextLost||this.gl.isContextLost())return null;const n=this.gl,r=n.createTexture();return r?(n.bindTexture(n.TEXTURE_2D,r),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,1),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,e),n.bindTexture(n.TEXTURE_2D,null),r):null}}const Dt=[],po=[],bo={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},yo=.65,wo=4,Mo=24,So=1024,xo=4;function Ao(t){const e=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0,e))}function Ro(t,e){if(!(t instanceof Uint32Array)||e<=0||t.length===0)return null;let n=!1;for(let o=0;o<t.length;o+=1)if(!(t[o]<e)){n=!0;break}if(!n)return t;const r=new Uint32Array(t.length);let i=0;for(let o=0;o<t.length;o+=1){const a=t[o];a>=e||(r[i]=a,i+=1)}return r.subarray(0,i)}function Eo(t,e){if(!t||e<=0)return 256;const n=Math.max(1,t.width*t.height),i=Math.sqrt(n/Math.max(1,e))*xo;return Math.max(Mo,Math.min(So,i))}function To(t,e){if(!t||!t.positions||!t.paletteIndices)return null;const n=Ao(t);if(n<=0)return null;const r=t.positions.subarray(0,n*2),i=t.ids instanceof Uint32Array&&t.ids.length>=n?t.ids.subarray(0,n):null,o=Ro(t.drawIndices,n),a=o?o.length:n;if(a===0)return null;const s=Eo(e,a),u=new Map,c=f=>{const p=r[f*2],m=r[f*2+1];if(!Number.isFinite(p)||!Number.isFinite(m))return;const g=Math.floor(p/s),b=Math.floor(m/s);let x=u.get(g);x||(x=new Map,u.set(g,x));const R=x.get(b);R?R.push(f):x.set(b,[f])};if(o)for(let f=0;f<o.length;f+=1)c(o[f]??0);else for(let f=0;f<n;f+=1)c(f);return u.size===0?null:{cellSize:s,safeCount:n,positions:r,ids:i,buckets:u}}function Kt(t,e){return t.id??e}function Po(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=at([r?.coordinates]);i.length!==0&&e.push({region:r,regionIndex:n,regionId:Kt(r,n),polygons:i})}return e}function Xt(t,e){const n=t[0],r=t[1];for(let i=e.length-1;i>=0;i-=1){const o=e[i];for(const a of o.polygons)if(jt(n,r,a))return{region:o.region,regionIndex:o.regionIndex,regionId:o.regionId}}return null}function Co({source:t,viewState:e,onViewStateChange:n,onStats:r,onTileError:i,onContextLost:o,onContextRestored:a,debugOverlay:s=!1,debugOverlayStyle:u,fitNonce:c=0,rotationResetNonce:f=0,authToken:p="",ctrlDragRotate:m=!0,pointData:g=null,pointPalette:b=null,pointSizeByZoom:x,pointStrokeScale:R,roiRegions:_,roiPolygons:W,clipPointsToRois:F=!1,clipMode:Y="worker",onClipStats:T,onRoiPointGroups:z,roiPaletteIndexToTermId:Z,interactionLock:te=!1,drawTool:N="cursor",stampOptions:Pe,brushOptions:Ae,regionStrokeStyle:$,regionStrokeHoverStyle:Ce,regionStrokeActiveStyle:Le,patchStrokeStyle:Ze,resolveRegionStrokeStyle:me,overlayShapes:ne,customLayers:E,patchRegions:P,regionLabelStyle:v,onPointerWorldMove:O,onPointHover:B,onPointClick:oe,onRegionHover:re,onRegionClick:be,onActiveRegionChange:he,getCellByCoordinatesRef:se,onDrawComplete:G,onPatchComplete:J,showOverviewMap:K=!1,overviewMapOptions:L,className:fe,style:ae}){const ue=h.useRef(null),j=h.useRef(null),ve=h.useRef(null),Re=h.useRef(null),Ie=h.useRef(n),U=h.useRef(r),de=h.useRef(s),[Ee,_e]=h.useState(!0),[Je,Ue]=h.useState(null),[ye,vt]=h.useState(null),[Qe,ut]=h.useState(null),[l,d]=h.useState(null),w=h.useRef(null),S=h.useRef(null),C=h.useRef(null),k=h.useRef(0),X=_??Dt,H=P??Dt,V=W??po,ie=(E?.length??0)>0,Ne=h.useMemo(()=>({position:"relative",width:"100%",height:"100%",...ae}),[ae]),ke=h.useMemo(()=>({position:"absolute",top:8,left:8,zIndex:7,margin:0,padding:"8px 10px",maxWidth:"min(420px, 80%)",pointerEvents:"none",whiteSpace:"pre-wrap",lineHeight:1.35,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:11,color:"#cde6ff",background:"rgba(6, 12, 20, 0.82)",border:"1px solid rgba(173, 216, 255, 0.28)",borderRadius:8,boxShadow:"0 8px 22px rgba(0,0,0,0.35)",...u}),[u]),Q=h.useMemo(()=>X.length>0?X:V.length===0?Dt:V.map((y,A)=>({id:A,coordinates:y})),[X,V]),le=h.useMemo(()=>Po(Q),[Q]),pe=h.useMemo(()=>Q.map(y=>y.coordinates),[Q]),[ge,lt]=h.useState(g);h.useEffect(()=>{const y=++k.current;let A=!1;if(!F)return lt(g),()=>{A=!0};if(!g||!g.count||!g.positions||!g.paletteIndices)return lt(null),()=>{A=!0};if(pe.length===0)return lt(bo),T?.({mode:Y,durationMs:0,inputCount:g.count,outputCount:0,polygonCount:0}),()=>{A=!0};const I=(D,ce)=>{if(A||y!==k.current)return;const ht=D?.drawIndices?D.drawIndices.length:D?.count??0;lt(D),T?.({mode:ce.mode,durationMs:ce.durationMs,inputCount:g.count,outputCount:ht,polygonCount:pe.length,usedWebGpu:ce.usedWebGpu,candidateCount:ce.candidateCount,bridgedToDraw:ce.bridgedToDraw})};return(async()=>{if(Y==="sync"){const D=performance.now(),ce=st(g,pe);I(ce,{mode:"sync",durationMs:performance.now()-D});return}if(Y==="hybrid-webgpu"){const D=await sr(g,pe,{bridgeToDraw:!0});I(D.data,{mode:D.meta.mode,durationMs:D.meta.durationMs,usedWebGpu:D.meta.usedWebGpu,candidateCount:D.meta.candidateCount,bridgedToDraw:D.meta.bridgedToDraw});return}try{const D=await lr(g,pe);I(D.data,{mode:D.meta.mode,durationMs:D.meta.durationMs})}catch{const D=performance.now(),ce=st(g,pe);I(ce,{mode:"sync",durationMs:performance.now()-D})}})(),()=>{A=!0}},[F,Y,g,pe,T]);const rn=!!(B||oe||se),xe=h.useMemo(()=>rn?To(ge,t):null,[rn,ge,t]),He=h.useCallback(y=>{const A=j.current;if(!A||!xe)return null;const I=Number(y[0]),q=Number(y[1]);if(!Number.isFinite(I)||!Number.isFinite(q))return null;const D=Math.max(1e-6,A.getViewState().zoom),ce=A.getPointSizeByZoom(),et=Math.max(wo,ce*yo)/D;if(!Number.isFinite(et)||et<=0)return null;const It=xe.cellSize,hn=Math.floor(I/It),dn=Math.floor(q/It),dt=Math.max(1,Math.ceil(et/It)),wr=et*et;let mt=-1,mn=wr,gn=0,pn=0;for(let _t=hn-dt;_t<=hn+dt;_t+=1){const bn=xe.buckets.get(_t);if(bn)for(let Ut=dn-dt;Ut<=dn+dt;Ut+=1){const gt=bn.get(Ut);if(!(!gt||gt.length===0))for(let Ft=0;Ft<gt.length;Ft+=1){const pt=gt[Ft];if(pt>=xe.safeCount)continue;const yn=xe.positions[pt*2],wn=xe.positions[pt*2+1],Mn=yn-I,Sn=wn-q,xn=Mn*Mn+Sn*Sn;xn>mn||(mn=xn,mt=pt,gn=yn,pn=wn)}}}if(mt<0)return null;const Mr=xe.ids?Number(xe.ids[mt]):null;return{index:mt,id:Mr,coordinate:[I,q],pointCoordinate:[gn,pn]}},[xe]),Ke=h.useCallback((y,A)=>{if(!B)return;const I=y?.index??null,q=y?.id??null;S.current===I&&C.current===q||(S.current=I,C.current=q,B({index:I,id:q,coordinate:A,pointCoordinate:y?.pointCoordinate??null}))},[B]),ct=h.useCallback((y,A)=>{if(!oe)return;const I=He(y);I&&oe({...I,button:A})},[oe,He]);h.useMemo(()=>{const y=Number(L?.width??220);return Number.isFinite(y)?Math.max(64,y):220},[L?.width]);const on=h.useMemo(()=>{const y=Number(L?.height??140);return Number.isFinite(y)?Math.max(48,y):140},[L?.height]),De=h.useMemo(()=>{const y=Number(L?.margin??16);return Number.isFinite(y)?Math.max(0,y):16},[L?.margin]),ft=L?.position||"bottom-right";h.useEffect(()=>{if(se)return se.current=He,()=>{se.current===He&&(se.current=null)}},[se,He]);const Xe=h.useCallback(y=>{vt(A=>String(A)===String(y)?A:(he?.(y),y))},[he]);h.useEffect(()=>{Ie.current=n},[n]),h.useEffect(()=>{U.current=r},[r]),h.useEffect(()=>{de.current=s,s||d(null)},[s]);const sn=h.useCallback(y=>{U.current?.(y),de.current&&d(y)},[]),dr=h.useMemo(()=>l?[`tier ${l.tier} | frame ${l.frameMs?.toFixed(2)??"-"} ms | drawCalls ${l.drawCalls??"-"}`,`tiles visible ${l.visible} | rendered ${l.rendered} | fallback ${l.fallback}`,`cache size ${l.cache} | hit ${l.cacheHits??"-"} | miss ${l.cacheMisses??"-"}`,`queue inflight ${l.inflight} | queued ${l.queued??"-"} | retries ${l.retries??"-"} | failed ${l.failed??"-"} | aborted ${l.aborted??"-"}`,`points ${l.points}`].join(`
135
- `):"stats: waiting for first frame...",[l]);h.useEffect(()=>{!(ye===null?!0:Q.some((q,D)=>String(Kt(q,D))===String(ye)))&&ye!==null&&Xe(null);const A=w.current;!(A===null?!0:Q.some((q,D)=>String(Kt(q,D))===String(A)))&&A!==null&&(w.current=null,Ue(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[Q,ye,re,Xe]),h.useEffect(()=>{const y=S.current;y!==null&&(xe&&y<xe.safeCount||(S.current=null,C.current=null,B?.({index:null,id:null,coordinate:null,pointCoordinate:null})))},[xe,B]);const an=h.useCallback(y=>{ie&&ut(y);const A=Ie.current;A&&A(y),ve.current?.(),Re.current?.()},[ie]);h.useEffect(()=>{if(!K){_e(!1);return}_e(!0)},[K,t?.id]),h.useEffect(()=>{N!=="cursor"&&w.current!==null&&(w.current=null,Ue(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[N,re]),h.useEffect(()=>{N!=="cursor"&&S.current!==null&&(S.current=null,C.current=null,B?.({index:null,id:null,coordinate:null,pointCoordinate:null}))},[N,B]);const We=h.useCallback((y,A)=>{const I=j.current;if(!I)return null;const q=I.screenToWorld(y,A);if(!Array.isArray(q)||q.length<2)return null;const D=Number(q[0]),ce=Number(q[1]);return!Number.isFinite(D)||!Number.isFinite(ce)?null:[D,ce]},[]),un=h.useCallback((y,A)=>{const I=j.current;if(!I)return null;const q=I.worldToScreen(y,A);if(!Array.isArray(q)||q.length<2)return null;const D=Number(q[0]),ce=Number(q[1]);return!Number.isFinite(D)||!Number.isFinite(ce)?null:[D,ce]},[]),ln=h.useCallback(()=>{j.current?.requestRender(),ve.current?.(),Re.current?.()},[]),cn=h.useMemo(()=>Qe??j.current?.getViewState()??null,[Qe]),fn=h.useMemo(()=>{if(!t)return null;const y=cn;return y?{source:t,viewState:y,drawTool:N,interactionLock:te,worldToScreen:un,screenToWorld:We,requestRedraw:ln}:null},[t,cn,N,te,un,We,ln]),mr=h.useCallback(y=>{const A=y.target===ue.current,I=We(y.clientX,y.clientY);if(O){const ht=!!I&&I[0]>=0&&I[1]>=0&&!!t&&I[0]<=t.width&&I[1]<=t.height;O({coordinate:I,clientX:y.clientX,clientY:y.clientY,insideImage:ht})}if(N!=="cursor")return;if(!A){Ke(null,null),w.current!==null&&(w.current=null,Ue(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}));return}if(!I){Ke(null,null);return}if(B&&Ke(He(I),I),!le.length)return;const q=Xt(I,le),D=q?.regionId??null,ce=w.current;String(ce)!==String(D)&&(w.current=D,Ue(D),re?.({region:q?.region??null,regionId:D,regionIndex:q?.regionIndex??-1,coordinate:I}))},[N,le,We,re,O,t,Ke,He,B]),gr=h.useCallback(()=>{O?.({coordinate:null,clientX:-1,clientY:-1,insideImage:!1}),Ke(null,null),w.current!==null&&(w.current=null,Ue(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[re,O,Ke]),pr=h.useCallback(y=>{if(N!=="cursor"||y.target!==ue.current)return;const A=We(y.clientX,y.clientY);if(!A)return;if(ct(A,y.button),!le.length){Xe(null);return}const I=Xt(A,le);if(!I){Xe(null);return}const q=ye!==null&&String(ye)===String(I.regionId)?null:I.regionId;Xe(q),be?.({region:I.region,regionId:I.regionId,regionIndex:I.regionIndex,coordinate:A})},[N,le,We,be,ye,Xe,ct]),br=h.useCallback(y=>{if(N!=="brush"||Ae?.clickSelectRoi!==!0||!le.length)return!1;const A=Xt(y,le);if(!A)return!1;const I=ye!==null&&String(ye)===String(A.regionId)?null:A.regionId;return Xe(I),be?.({region:A.region,regionId:A.regionId,regionIndex:A.regionIndex,coordinate:y}),!0},[N,Ae?.clickSelectRoi,le,ye,Xe,be]),yr=h.useCallback(y=>{if(!oe||N!=="cursor"||y.target!==ue.current)return;y.preventDefault();const A=We(y.clientX,y.clientY);A&&ct(A,y.button)},[N,We,ct,oe]);return h.useEffect(()=>{const y=ue.current;if(!y||!t)return;const A=new hr(y,t,{onViewStateChange:an,onStats:sn,onTileError:i,onContextLost:o,onContextRestored:a,authToken:p,ctrlDragRotate:m,pointSizeByZoom:x,pointStrokeScale:R});return j.current=A,e&&A.setViewState(e),A.setInteractionLock(te),ie&&ut(A.getViewState()),()=>{A.destroy(),j.current=null}},[t,sn,i,o,a,p,m,x,R,an,ie]),h.useEffect(()=>{const y=j.current;!y||!e||y.setViewState(e)},[e]),h.useEffect(()=>{const y=j.current;y&&y.fitToImage()},[c]),h.useEffect(()=>{const y=j.current;y&&y.resetRotation()},[f]),h.useEffect(()=>{const y=j.current;!y||!b||y.setPointPalette(b)},[b]),h.useEffect(()=>{const y=j.current;y&&y.setPointSizeByZoom(x)},[x]),h.useEffect(()=>{const y=j.current;y&&y.setPointStrokeScale(R)},[R]),h.useEffect(()=>{const y=j.current;y&&y.setPointData(ge)},[ge]),h.useEffect(()=>{if(!z)return;const A=cr(F?ge:g,Q,{paletteIndexToTermId:Z,includeEmptyRegions:!0});z(A)},[z,F,g,ge,Q,Z]),h.useEffect(()=>{const y=j.current;y&&y.setInteractionLock(te)},[te]),Me.jsxs("div",{className:fe,style:Ne,onPointerMove:mr,onPointerLeave:gr,onClick:pr,onContextMenu:yr,children:[Me.jsx("canvas",{ref:ue,className:"wsi-render-canvas",style:{position:"absolute",inset:0,zIndex:1,width:"100%",height:"100%",display:"block",touchAction:"none",cursor:N==="cursor"&&Je!==null?"pointer":te?"crosshair":"grab"}}),t&&fn&&Array.isArray(E)&&E.length>0?E.map((y,A)=>Me.jsx("div",{className:y.className,style:{position:"absolute",inset:0,zIndex:y.zIndex??3,pointerEvents:y.pointerEvents??"none",...y.style},children:y.render(fn)},y.id??A)):null,t?Me.jsx(Qn,{tool:N,enabled:N!=="cursor",imageWidth:t.width,imageHeight:t.height,imageMpp:t.mpp,imageZoom:t.maxTierZoom,stampOptions:Pe,brushOptions:Ae,projectorRef:j,onBrushTap:br,viewStateSignal:e,persistedRegions:Q,patchRegions:H,regionStrokeStyle:$,regionStrokeHoverStyle:Ce,regionStrokeActiveStyle:Le,patchStrokeStyle:Ze,resolveRegionStrokeStyle:me,overlayShapes:ne,hoveredRegionId:Je,activeRegionId:ye,regionLabelStyle:v,invalidateRef:ve,onDrawComplete:G,onPatchComplete:J}):null,s?Me.jsx("pre",{"data-open-plant-debug-overlay":!0,style:ke,children:dr}):null,t&&K?Ee?Me.jsxs(Me.Fragment,{children:[Me.jsx(tr,{source:t,projectorRef:j,authToken:p,options:L,invalidateRef:Re}),Me.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:()=>_e(!1),style:{position:"absolute",zIndex:6,...ft.includes("left")?{left:De}:{right:De},...ft.includes("top")?{top:De+on+8}:{bottom:De+on+8},width:20,height:20,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(8, 14, 22, 0.9)",color:"#fff",fontSize:13,lineHeight:1,cursor:"pointer",padding:0},children:"×"})]}):Me.jsx("button",{type:"button","aria-label":"Show overview map",onClick:()=>_e(!0),style:{position:"absolute",zIndex:6,...ft.includes("left")?{left:De}:{right:De},...ft.includes("top")?{top:De}:{bottom:De},height:24,minWidth:40,borderRadius:999,border:"1px solid rgba(255,255,255,0.45)",background:"rgba(8, 14, 22, 0.9)",color:"#dff8ff",fontSize:11,fontWeight:700,cursor:"pointer",padding:"0 8px"},children:"Map"}):null]})}exports.DEFAULT_POINT_COLOR=Jt;exports.DrawLayer=Qn;exports.M1TileRenderer=Yn;exports.OverviewMap=tr;exports.TileScheduler=fr;exports.TileViewerCanvas=Zi;exports.WsiTileRenderer=hr;exports.WsiViewerCanvas=Co;exports.buildTermPalette=oi;exports.calcScaleLength=ni;exports.calcScaleResolution=Qt;exports.clamp=ee;exports.closeRing=Fe;exports.computeRoiPointGroups=cr;exports.createCircle=Ot;exports.createRectangle=Yt;exports.filterPointDataByPolygons=st;exports.filterPointDataByPolygonsHybrid=sr;exports.filterPointDataByPolygonsInWorker=lr;exports.filterPointIndicesByPolygons=rr;exports.filterPointIndicesByPolygonsInWorker=oo;exports.getWebGpuCapabilities=no;exports.hexToRgba=Hn;exports.isSameViewState=ri;exports.normalizeImageInfo=$i;exports.prefilterPointsByBoundsWebGpu=or;exports.terminateRoiClipWorker=io;exports.toBearerToken=ii;exports.toTileUrl=en;
134
+ }`),o=qe(e,i,"uCamera"),a=qe(e,i,"uPointSize"),s=qe(e,i,"uPointStrokeScale"),u=qe(e,i,"uPalette"),c=qe(e,i,"uPaletteSize"),h=e.createVertexArray(),b=e.createBuffer(),m=e.createBuffer(),g=e.createBuffer(),y=e.createBuffer(),x=e.createTexture();if(!h||!b||!m||!g||!y||!x)throw new Error("point buffer allocation failed");e.bindVertexArray(h),e.bindBuffer(e.ARRAY_BUFFER,b),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const E=e.getAttribLocation(i,"aPosition");if(E<0)throw new Error("point position attribute not found");e.enableVertexAttribArray(E),e.vertexAttribPointer(E,2,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,m),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const _=e.getAttribLocation(i,"aTerm");if(_<0)throw new Error("point term attribute not found");e.enableVertexAttribArray(_),e.vertexAttribIPointer(_,1,e.UNSIGNED_SHORT,0,0),e.bindBuffer(e.ARRAY_BUFFER,g),e.bufferData(e.ARRAY_BUFFER,0,e.DYNAMIC_DRAW);const X=e.getAttribLocation(i,"aFillMode");if(X<0)throw new Error("point fill mode attribute not found");return e.enableVertexAttribArray(X),e.vertexAttribIPointer(X,1,e.UNSIGNED_BYTE,0,0),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,y),e.bufferData(e.ELEMENT_ARRAY_BUFFER,0,e.DYNAMIC_DRAW),e.bindVertexArray(null),e.bindBuffer(e.ARRAY_BUFFER,null),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null),e.bindTexture(e.TEXTURE_2D,x),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([160,160,160,255])),e.bindTexture(e.TEXTURE_2D,null),{program:i,vao:h,posBuffer:b,termBuffer:m,fillModeBuffer:g,indexBuffer:y,paletteTexture:x,uCamera:o,uPointSize:a,uPointStrokeScale:s,uPalette:u,uPaletteSize:c}}handleTileLoaded(e,n){if(this.destroyed||this.contextLost||this.gl.isContextLost()){n.close();return}if(this.cache.has(e.key)){n.close();return}const r=this.createTextureFromBitmap(n);n.close(),r&&(this.cache.set(e.key,{key:e.key,texture:r,bounds:e.bounds,tier:e.tier,lastUsed:this.frameSerial}),this.trimCache(),this.requestRender())}createTextureFromBitmap(e){if(this.contextLost||this.gl.isContextLost())return null;const n=this.gl,r=n.createTexture();return r?(n.bindTexture(n.TEXTURE_2D,r),n.pixelStorei(n.UNPACK_FLIP_Y_WEBGL,1),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,e),n.bindTexture(n.TEXTURE_2D,null),r):null}}const Dt=[],po=[],bo={count:0,positions:new Float32Array(0),paletteIndices:new Uint16Array(0)},yo=.65,wo=4,Mo=24,So=1024,xo=4;function Ao(t){const e=t.fillModes instanceof Uint8Array?t.fillModes.length:Number.MAX_SAFE_INTEGER;return Math.max(0,Math.min(Math.floor(t.count??0),Math.floor((t.positions?.length??0)/2),t.paletteIndices?.length??0,e))}function Ro(t,e){if(!(t instanceof Uint32Array)||e<=0||t.length===0)return null;let n=!1;for(let o=0;o<t.length;o+=1)if(!(t[o]<e)){n=!0;break}if(!n)return t;const r=new Uint32Array(t.length);let i=0;for(let o=0;o<t.length;o+=1){const a=t[o];a>=e||(r[i]=a,i+=1)}return r.subarray(0,i)}function Eo(t,e){if(!t||e<=0)return 256;const n=Math.max(1,t.width*t.height),i=Math.sqrt(n/Math.max(1,e))*xo;return Math.max(Mo,Math.min(So,i))}function To(t,e){if(!t||!t.positions||!t.paletteIndices)return null;const n=Ao(t);if(n<=0)return null;const r=t.positions.subarray(0,n*2),i=t.ids instanceof Uint32Array&&t.ids.length>=n?t.ids.subarray(0,n):null,o=Ro(t.drawIndices,n),a=o?o.length:n;if(a===0)return null;const s=Eo(e,a),u=new Map,c=h=>{const b=r[h*2],m=r[h*2+1];if(!Number.isFinite(b)||!Number.isFinite(m))return;const g=Math.floor(b/s),y=Math.floor(m/s);let x=u.get(g);x||(x=new Map,u.set(g,x));const E=x.get(y);E?E.push(h):x.set(y,[h])};if(o)for(let h=0;h<o.length;h+=1)c(o[h]??0);else for(let h=0;h<n;h+=1)c(h);return u.size===0?null:{cellSize:s,safeCount:n,positions:r,ids:i,buckets:u}}function Kt(t,e){return t.id??e}function Po(t){const e=[];for(let n=0;n<t.length;n+=1){const r=t[n],i=ut([r?.coordinates]);i.length!==0&&e.push({region:r,regionIndex:n,regionId:Kt(r,n),polygons:i})}return e}function Xt(t,e){const n=t[0],r=t[1];for(let i=e.length-1;i>=0;i-=1){const o=e[i];for(const a of o.polygons)if(jt(n,r,a))return{region:o.region,regionIndex:o.regionIndex,regionId:o.regionId}}return null}function Co({source:t,viewState:e,onViewStateChange:n,onStats:r,onTileError:i,onContextLost:o,onContextRestored:a,debugOverlay:s=!1,debugOverlayStyle:u,fitNonce:c=0,rotationResetNonce:h=0,authToken:b="",ctrlDragRotate:m=!0,pointData:g=null,pointPalette:y=null,pointSizeByZoom:x,pointStrokeScale:E,roiRegions:_,roiPolygons:X,clipPointsToRois:F=!1,clipMode:W="worker",onClipStats:P,onRoiPointGroups:z,roiPaletteIndexToTermId:Z,interactionLock:ee=!1,drawTool:N="cursor",stampOptions:ve,brushOptions:Te,regionStrokeStyle:$,regionStrokeHoverStyle:_e,regionStrokeActiveStyle:ze,patchStrokeStyle:Ke,resolveRegionStrokeStyle:be,overlayShapes:ne,customLayers:T,patchRegions:C,regionLabelStyle:I,onPointerWorldMove:Y,onPointHover:L,onPointClick:ie,onRegionHover:re,onRegionClick:we,onActiveRegionChange:fe,getCellByCoordinatesRef:oe,onDrawComplete:V,onPatchComplete:J,showOverviewMap:K=!1,overviewMapOptions:D,className:ce,style:se}){const ae=d.useRef(null),j=d.useRef(null),Ue=d.useRef(null),Pe=d.useRef(null),Fe=d.useRef(n),U=d.useRef(r),ge=d.useRef(s),[Ce,ye]=d.useState(!0),[Qe,De]=d.useState(null),[pe,It]=d.useState(null),[lt,et]=d.useState(null),[ue,l]=d.useState(null),f=d.useRef(null),p=d.useRef(null),S=d.useRef(null),A=d.useRef(0),B=_??Dt,O=C??Dt,H=X??po,G=(T?.length??0)>0,he=d.useMemo(()=>({position:"relative",width:"100%",height:"100%",...se}),[se]),Xe=d.useMemo(()=>({position:"absolute",top:8,left:8,zIndex:7,margin:0,padding:"8px 10px",maxWidth:"min(420px, 80%)",pointerEvents:"none",whiteSpace:"pre-wrap",lineHeight:1.35,fontFamily:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",fontSize:11,color:"#cde6ff",background:"rgba(6, 12, 20, 0.82)",border:"1px solid rgba(173, 216, 255, 0.28)",borderRadius:8,boxShadow:"0 8px 22px rgba(0,0,0,0.35)",...u}),[u]),de=d.useMemo(()=>B.length>0?B:H.length===0?Dt:H.map((w,R)=>({id:R,coordinates:w})),[B,H]),te=d.useMemo(()=>Po(de),[de]),me=d.useMemo(()=>de.map(w=>w.coordinates),[de]),[Me,Se]=d.useState(g);d.useEffect(()=>{const w=++A.current;let R=!1;if(!F)return Se(g),()=>{R=!0};if(!g||!g.count||!g.positions||!g.paletteIndices)return Se(null),()=>{R=!0};if(me.length===0)return Se(bo),P?.({mode:W,durationMs:0,inputCount:g.count,outputCount:0,polygonCount:0}),()=>{R=!0};const v=(k,le)=>{if(R||w!==A.current)return;const ht=k?.drawIndices?k.drawIndices.length:k?.count??0;Se(k),P?.({mode:le.mode,durationMs:le.durationMs,inputCount:g.count,outputCount:ht,polygonCount:me.length,usedWebGpu:le.usedWebGpu,candidateCount:le.candidateCount,bridgedToDraw:le.bridgedToDraw})};return(async()=>{if(W==="sync"){const k=performance.now(),le=at(g,me);v(le,{mode:"sync",durationMs:performance.now()-k});return}if(W==="hybrid-webgpu"){const k=await ar(g,me,{bridgeToDraw:!0});v(k.data,{mode:k.meta.mode,durationMs:k.meta.durationMs,usedWebGpu:k.meta.usedWebGpu,candidateCount:k.meta.candidateCount,bridgedToDraw:k.meta.bridgedToDraw});return}try{const k=await cr(g,me);v(k.data,{mode:k.meta.mode,durationMs:k.meta.durationMs})}catch{const k=performance.now(),le=at(g,me);v(le,{mode:"sync",durationMs:performance.now()-k})}})(),()=>{R=!0}},[F,W,g,me,P]);const rn=!!(L||ie||oe),Ee=d.useMemo(()=>rn?To(Me,t):null,[rn,Me,t]),Ze=d.useCallback(w=>{const R=j.current;if(!R||!Ee)return null;const v=Number(w[0]),q=Number(w[1]);if(!Number.isFinite(v)||!Number.isFinite(q))return null;const k=Math.max(1e-6,R.getViewState().zoom),le=R.getPointSizeByZoom(),tt=Math.max(wo,le*yo)/k;if(!Number.isFinite(tt)||tt<=0)return null;const vt=Ee.cellSize,hn=Math.floor(v/vt),dn=Math.floor(q/vt),dt=Math.max(1,Math.ceil(tt/vt)),Mr=tt*tt;let mt=-1,mn=Mr,gn=0,pn=0;for(let _t=hn-dt;_t<=hn+dt;_t+=1){const bn=Ee.buckets.get(_t);if(bn)for(let Ut=dn-dt;Ut<=dn+dt;Ut+=1){const gt=bn.get(Ut);if(!(!gt||gt.length===0))for(let Ft=0;Ft<gt.length;Ft+=1){const pt=gt[Ft];if(pt>=Ee.safeCount)continue;const yn=Ee.positions[pt*2],wn=Ee.positions[pt*2+1],Mn=yn-v,Sn=wn-q,xn=Mn*Mn+Sn*Sn;xn>mn||(mn=xn,mt=pt,gn=yn,pn=wn)}}}if(mt<0)return null;const Sr=Ee.ids?Number(Ee.ids[mt]):null;return{index:mt,id:Sr,coordinate:[v,q],pointCoordinate:[gn,pn]}},[Ee]),je=d.useCallback((w,R)=>{if(!L)return;const v=w?.index??null,q=w?.id??null;p.current===v&&S.current===q||(p.current=v,S.current=q,L({index:v,id:q,coordinate:R,pointCoordinate:w?.pointCoordinate??null}))},[L]),ct=d.useCallback((w,R)=>{if(!ie)return;const v=Ze(w);v&&ie({...v,button:R})},[ie,Ze]);d.useMemo(()=>{const w=Number(D?.width??220);return Number.isFinite(w)?Math.max(64,w):220},[D?.width]);const on=d.useMemo(()=>{const w=Number(D?.height??140);return Number.isFinite(w)?Math.max(48,w):140},[D?.height]),We=d.useMemo(()=>{const w=Number(D?.margin??16);return Number.isFinite(w)?Math.max(0,w):16},[D?.margin]),ft=D?.position||"bottom-right";d.useEffect(()=>{if(oe)return oe.current=Ze,()=>{oe.current===Ze&&(oe.current=null)}},[oe,Ze]);const Ye=d.useCallback(w=>{It(R=>String(R)===String(w)?R:(fe?.(w),w))},[fe]);d.useEffect(()=>{Fe.current=n},[n]),d.useEffect(()=>{U.current=r},[r]),d.useEffect(()=>{ge.current=s,s||l(null)},[s]);const sn=d.useCallback(w=>{U.current?.(w),ge.current&&l(w)},[]),mr=d.useMemo(()=>ue?[`tier ${ue.tier} | frame ${ue.frameMs?.toFixed(2)??"-"} ms | drawCalls ${ue.drawCalls??"-"}`,`tiles visible ${ue.visible} | rendered ${ue.rendered} | fallback ${ue.fallback}`,`cache size ${ue.cache} | hit ${ue.cacheHits??"-"} | miss ${ue.cacheMisses??"-"}`,`queue inflight ${ue.inflight} | queued ${ue.queued??"-"} | retries ${ue.retries??"-"} | failed ${ue.failed??"-"} | aborted ${ue.aborted??"-"}`,`points ${ue.points}`].join(`
135
+ `):"stats: waiting for first frame...",[ue]);d.useEffect(()=>{!(pe===null?!0:de.some((q,k)=>String(Kt(q,k))===String(pe)))&&pe!==null&&Ye(null);const R=f.current;!(R===null?!0:de.some((q,k)=>String(Kt(q,k))===String(R)))&&R!==null&&(f.current=null,De(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[de,pe,re,Ye]),d.useEffect(()=>{const w=p.current;w!==null&&(Ee&&w<Ee.safeCount||(p.current=null,S.current=null,L?.({index:null,id:null,coordinate:null,pointCoordinate:null})))},[Ee,L]);const an=d.useCallback(w=>{G&&et(w);const R=Fe.current;R&&R(w),Ue.current?.(),Pe.current?.()},[G]);d.useEffect(()=>{if(!K){ye(!1);return}ye(!0)},[K,t?.id]),d.useEffect(()=>{N!=="cursor"&&f.current!==null&&(f.current=null,De(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[N,re]),d.useEffect(()=>{N!=="cursor"&&p.current!==null&&(p.current=null,S.current=null,L?.({index:null,id:null,coordinate:null,pointCoordinate:null}))},[N,L]);const Oe=d.useCallback((w,R)=>{const v=j.current;if(!v)return null;const q=v.screenToWorld(w,R);if(!Array.isArray(q)||q.length<2)return null;const k=Number(q[0]),le=Number(q[1]);return!Number.isFinite(k)||!Number.isFinite(le)?null:[k,le]},[]),un=d.useCallback((w,R)=>{const v=j.current;if(!v)return null;const q=v.worldToScreen(w,R);if(!Array.isArray(q)||q.length<2)return null;const k=Number(q[0]),le=Number(q[1]);return!Number.isFinite(k)||!Number.isFinite(le)?null:[k,le]},[]),ln=d.useCallback(()=>{j.current?.requestRender(),Ue.current?.(),Pe.current?.()},[]),cn=d.useMemo(()=>lt??j.current?.getViewState()??null,[lt]),fn=d.useMemo(()=>{if(!t)return null;const w=cn;return w?{source:t,viewState:w,drawTool:N,interactionLock:ee,worldToScreen:un,screenToWorld:Oe,requestRedraw:ln}:null},[t,cn,N,ee,un,Oe,ln]),gr=d.useCallback(w=>{const R=w.target===ae.current,v=Oe(w.clientX,w.clientY);if(Y){const ht=!!v&&v[0]>=0&&v[1]>=0&&!!t&&v[0]<=t.width&&v[1]<=t.height;Y({coordinate:v,clientX:w.clientX,clientY:w.clientY,insideImage:ht})}if(N!=="cursor")return;if(!R){je(null,null),f.current!==null&&(f.current=null,De(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}));return}if(!v){je(null,null);return}if(L&&je(Ze(v),v),!te.length)return;const q=Xt(v,te),k=q?.regionId??null,le=f.current;String(le)!==String(k)&&(f.current=k,De(k),re?.({region:q?.region??null,regionId:k,regionIndex:q?.regionIndex??-1,coordinate:v}))},[N,te,Oe,re,Y,t,je,Ze,L]),pr=d.useCallback(()=>{Y?.({coordinate:null,clientX:-1,clientY:-1,insideImage:!1}),je(null,null),f.current!==null&&(f.current=null,De(null),re?.({region:null,regionId:null,regionIndex:-1,coordinate:null}))},[re,Y,je]),br=d.useCallback(w=>{if(N!=="cursor"||w.target!==ae.current)return;const R=Oe(w.clientX,w.clientY);if(!R)return;if(ct(R,w.button),!te.length){Ye(null);return}const v=Xt(R,te);if(!v){Ye(null);return}const q=pe!==null&&String(pe)===String(v.regionId)?null:v.regionId;Ye(q),we?.({region:v.region,regionId:v.regionId,regionIndex:v.regionIndex,coordinate:R})},[N,te,Oe,we,pe,Ye,ct]),yr=d.useCallback(w=>{if(N!=="brush"||Te?.clickSelectRoi!==!0||!te.length)return!1;const R=Xt(w,te);if(!R)return!1;const v=pe!==null&&String(pe)===String(R.regionId)?null:R.regionId;return Ye(v),we?.({region:R.region,regionId:R.regionId,regionIndex:R.regionIndex,coordinate:w}),!0},[N,Te?.clickSelectRoi,te,pe,Ye,we]),wr=d.useCallback(w=>{if(!ie||N!=="cursor"||w.target!==ae.current)return;w.preventDefault();const R=Oe(w.clientX,w.clientY);R&&ct(R,w.button)},[N,Oe,ct,ie]);return d.useEffect(()=>{const w=ae.current;if(!w||!t)return;const R=new dr(w,t,{onViewStateChange:an,onStats:sn,onTileError:i,onContextLost:o,onContextRestored:a,authToken:b,ctrlDragRotate:m,pointSizeByZoom:x,pointStrokeScale:E});return j.current=R,e&&R.setViewState(e),R.setInteractionLock(ee),G&&et(R.getViewState()),()=>{R.destroy(),j.current=null}},[t,sn,i,o,a,b,m,x,E,an,G]),d.useEffect(()=>{const w=j.current;!w||!e||w.setViewState(e)},[e]),d.useEffect(()=>{const w=j.current;w&&w.fitToImage()},[c]),d.useEffect(()=>{const w=j.current;w&&w.resetRotation()},[h]),d.useEffect(()=>{const w=j.current;!w||!y||w.setPointPalette(y)},[y]),d.useEffect(()=>{const w=j.current;w&&w.setPointSizeByZoom(x)},[x]),d.useEffect(()=>{const w=j.current;w&&w.setPointStrokeScale(E)},[E]),d.useEffect(()=>{const w=j.current;w&&w.setPointData(Me)},[Me]),d.useEffect(()=>{if(!z)return;const R=fr(F?Me:g,de,{paletteIndexToTermId:Z,includeEmptyRegions:!0});z(R)},[z,F,g,Me,de,Z]),d.useEffect(()=>{const w=j.current;w&&w.setInteractionLock(ee)},[ee]),Ae.jsxs("div",{className:ce,style:he,onPointerMove:gr,onPointerLeave:pr,onClick:br,onContextMenu:wr,children:[Ae.jsx("canvas",{ref:ae,className:"wsi-render-canvas",style:{position:"absolute",inset:0,zIndex:1,width:"100%",height:"100%",display:"block",touchAction:"none",cursor:N==="cursor"&&Qe!==null?"pointer":ee?"crosshair":"grab"}}),t&&fn&&Array.isArray(T)&&T.length>0?T.map((w,R)=>Ae.jsx("div",{className:w.className,style:{position:"absolute",inset:0,zIndex:w.zIndex??3,pointerEvents:w.pointerEvents??"none",...w.style},children:w.render(fn)},w.id??R)):null,t?Ae.jsx(er,{tool:N,enabled:N!=="cursor",imageWidth:t.width,imageHeight:t.height,imageMpp:t.mpp,imageZoom:t.maxTierZoom,stampOptions:ve,brushOptions:Te,projectorRef:j,onBrushTap:yr,viewStateSignal:e,persistedRegions:de,patchRegions:O,regionStrokeStyle:$,regionStrokeHoverStyle:_e,regionStrokeActiveStyle:ze,patchStrokeStyle:Ke,resolveRegionStrokeStyle:be,overlayShapes:ne,hoveredRegionId:Qe,activeRegionId:pe,regionLabelStyle:I,invalidateRef:Ue,onDrawComplete:V,onPatchComplete:J}):null,s?Ae.jsx("pre",{"data-open-plant-debug-overlay":!0,style:Xe,children:mr}):null,t&&K?Ce?Ae.jsxs(Ae.Fragment,{children:[Ae.jsx(nr,{source:t,projectorRef:j,authToken:b,options:D,invalidateRef:Pe}),Ae.jsx("button",{type:"button","aria-label":"Hide overview map",onClick:()=>ye(!1),style:{position:"absolute",zIndex:6,...ft.includes("left")?{left:We}:{right:We},...ft.includes("top")?{top:We+on+8}:{bottom:We+on+8},width:20,height:20,borderRadius:999,border:"1px solid rgba(255,255,255,0.4)",background:"rgba(8, 14, 22, 0.9)",color:"#fff",fontSize:13,lineHeight:1,cursor:"pointer",padding:0},children:"×"})]}):Ae.jsx("button",{type:"button","aria-label":"Show overview map",onClick:()=>ye(!0),style:{position:"absolute",zIndex:6,...ft.includes("left")?{left:We}:{right:We},...ft.includes("top")?{top:We}:{bottom:We},height:24,minWidth:40,borderRadius:999,border:"1px solid rgba(255,255,255,0.45)",background:"rgba(8, 14, 22, 0.9)",color:"#dff8ff",fontSize:11,fontWeight:700,cursor:"pointer",padding:"0 8px"},children:"Map"}):null]})}exports.DEFAULT_POINT_COLOR=Jt;exports.DrawLayer=er;exports.M1TileRenderer=On;exports.OverviewMap=nr;exports.TileScheduler=hr;exports.TileViewerCanvas=Zi;exports.WsiTileRenderer=dr;exports.WsiViewerCanvas=Co;exports.buildTermPalette=si;exports.calcScaleLength=ri;exports.calcScaleResolution=Qt;exports.clamp=Q;exports.closeRing=Be;exports.computeRoiPointGroups=fr;exports.createCircle=Ot;exports.createRectangle=Yt;exports.filterPointDataByPolygons=at;exports.filterPointDataByPolygonsHybrid=ar;exports.filterPointDataByPolygonsInWorker=cr;exports.filterPointIndicesByPolygons=ir;exports.filterPointIndicesByPolygonsInWorker=oo;exports.getWebGpuCapabilities=no;exports.hexToRgba=$n;exports.isSameViewState=ii;exports.normalizeImageInfo=$i;exports.prefilterPointsByBoundsWebGpu=sr;exports.terminateRoiClipWorker=io;exports.toBearerToken=oi;exports.toTileUrl=en;
136
136
  //# sourceMappingURL=index.cjs.map