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