@tileflow/core 0.1.0-alpha.37 → 0.1.0-alpha.38

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.
@@ -0,0 +1 @@
1
+ "use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=jn(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=wt(e,n,r,t)),e.length>80*t){a=e[0],l=e[1];let c=a,f=l;for(let d=t;d<o;d+=t){let g=e[d],m=e[d+1];g<a&&(a=g),m<l&&(l=m),g>c&&(c=g),m>f&&(f=m)}u=Math.max(c-a,f-l),u=u!==0?32767/u:0}return un(r,s,a,l,u),s}function jn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Ue(r,r.next)&&(Oe(r),r=r.next),r}function ge(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Ue(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Oe(i),i=i.prev,o=!0):(t||i!==n)&&(i=i.next,o=!t);while(o||i!==n);return n}function un(e,n,t,i,o){o&&At(e,t,i,o);let r=e,s=!1;for(;e.prev!==e.next;){let a=e.prev,l=e.next;if(Q(a,e,l)<0&&(o?yt(e,t,i,o):pt(e))){n.push(a.i,e.i,l.i),Oe(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=bt(e,n),r=e,s=!0;continue}gt(e,n,t,i,o);break}}}function pt(e){let n=e.prev,t=e,i=e.next,o=n.x,r=t.x,s=i.x,a=n.y,l=t.y,u=i.y,c=Math.min(o,r,s),f=Math.min(a,l,u),d=Math.max(o,r,s),g=Math.max(a,l,u),m=i.next;for(;m!==n;){if(m.x>=c&&m.x<=d&&m.y>=f&&m.y<=g&&!(o===m.x&&a===m.y)&&Ke(o,a,r,l,s,u,m.x,m.y)&&Q(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function yt(e,n,t,i){let o=e.prev,r=e,s=e.next,a=o.x,l=r.x,u=s.x,c=o.y,f=r.y,d=s.y,g=Math.min(a,l,u),m=Math.min(c,f,d),p=Math.max(a,l,u),h=Math.max(c,f,d),A=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=A;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=F;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function bt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Nn(o,t,t.next,r,!1)&&Ce(o,r)&&Ce(r,o)&&(n.push(o.i,t.i,r.i),Oe(t),Oe(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function gt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&_t(r,s)){let a=Vn(r,s);r=ge(r,r.next),a=ge(a,a.next),un(r,n,t,i,o),un(a,n,t,i,o);return}s=s.next}r=r.next}while(r!==e)}var cn=!1;function wt(e,n,t,i){let o=[];for(let r=0,s=n.length;r<s;r++){let a=n[r]*i,l=r<s-1?n[r+1]*i:e.length,u=jn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(xt),Mt(e.length/i,n.length),zn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Tt(o[r],t);return cn=!1,ge(t)}function xt(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Tt(e,n){let t=vt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return zn(t,o.next),ge(i,i.next),ge(t,t.next)}var Dn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function Mt(e,n){let t=Math.ceil((e+2*n)/Dn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function zn(e,n){let t=e;do{let i=Je++;fn[i]=t;let o=t.x,r=t.y,s=t.x,a=t.y,l=0;do{let c=t.next;t.z=i,c.x<o&&(o=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y),t=c}while(++l<Dn&&t!==n);dn[i]=t;let u=i*4;X[u]=o,X[u+1]=r,X[u+2]=s,X[u+3]=a}while(t!==n)}function kt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function En(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function vt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Ue(e,t))return t;for(let d=0,g=0;d<Je;d++,g+=4){if(o<X[g+1]||o>X[g+3]||X[g]>i||X[g+2]<=r)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t){if(Ue(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let p=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(p<=i&&p>r&&(r=p,s=t.x<t.next.x?t:t.next,p===i))return s}}t=t.next}while(t!==m)}if(!s)return null;let a=s.x,l=s.y,u=Math.min(o,l),c=Math.max(o,l),f=1/0;for(let d=0,g=0;d<Je;d++,g+=4){if(X[g+2]<a||X[g]>i||X[g+3]<u||X[g+1]>c)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ce(t,e)||t.y===o&&t.next.y===o&&t.next.x>i)&&(p<f||p===f&&(t.x>s.x||t.x===s.x&&Rt(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function Rt(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=new Uint32Array(0),_e=new Uint32Array(0),Le=new Uint32Array(256);function At(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),ie[r++]=o,o=o.next;while(o!==e);Ft(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function Ft(e){if(e<=32){for(let n=1;n<e;n++){let t=ie[n],i=t.z,o=n-1;for(;o>=0&&ie[o].z>i;)ie[o+1]=ie[o],o--;ie[o+1]=t}return}be.length<e&&(be=new Uint32Array(e),_e=new Uint32Array(e),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,_e,0),Xe(e,ve,_e,ie,be,8),Xe(e,ie,be,ve,_e,16),Xe(e,ve,_e,ie,be,24)}function Xe(e,n,t,i,o,r){Le.fill(0);for(let a=0;a<e;a++)Le[t[a]>>>r&255]++;let s=0;for(let a=0;a<256;a++){let l=Le[a];Le[a]=s,s+=l}for(let a=0;a<e;a++){let l=t[a],u=Le[l>>>r&255]++;i[u]=n[a],o[u]=l}}function mn(e,n,t,i,o){return e=(e-t)*o|0,n=(n-i)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function St(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ke(e,n,t,i,o,r,s,a){return(o-s)*(n-a)>=(e-s)*(r-a)&&(e-s)*(i-a)>=(t-s)*(n-a)&&(t-s)*(r-a)>=(o-s)*(i-a)}function _t(e,n){let t=Ue(e,n)&&Q(e.prev,e,e.next)>0&&Q(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ce(e,n)&&Ce(n,e)&&(Q(e.prev,e,n.prev)!==0||Q(e,n.prev,n)!==0))&&!Lt(e,n)&&(t||Bt(e,n))}function Q(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Ue(e,n){return e.x===n.x&&e.y===n.y}function Nn(e,n,t,i,o=!0){let r=Q(e,n,t),s=Q(e,n,i),a=Q(t,i,e),l=Q(t,i,n);return(r>0&&s<0||r<0&&s>0)&&(a>0&&l<0||a<0&&l>0)?!0:o?!!(r===0&&Ye(e,t,n)||s===0&&Ye(e,i,n)||a===0&&Ye(t,e,i)||l===0&&Ye(t,n,i)):!1}function Ye(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Lt(e,n){let t=Math.min(e.x,n.x),i=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),s=e;do{let a=s.next;if(s.x>i&&a.x>i||s.x<t&&a.x<t||s.y>r&&a.y>r||s.y<o&&a.y<o){s=a;continue}if(s.i!==e.i&&a.i!==e.i&&s.i!==n.i&&a.i!==n.i&&Nn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ce(e,n){return Q(e.prev,e,e.next)<0?Q(e,n,e.next)>=0&&Q(e,e.prev,n)>=0:Q(e,n,e.prev)<0||Q(e,e.next,n)<0}function Bt(e,n){let t=e,i=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let s=t.next;t.y>r!=s.y>r&&o<(s.x-t.x)*(r-t.y)/(s.y-t.y)+t.x&&(i=!i),t=s}while(t!==e);return i}function Vn(e,n){let t=hn(e.i,e.x,e.y),i=hn(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,i.next=t,t.prev=i,r.next=i,i.prev=r,i}function In(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Oe(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),cn&&kt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ut(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ct=.7,Ot=Math.tan(Math.PI/6),Pt=Math.tan(35*Math.PI/180),Et=Math.tan(Math.PI/18),Ee=.65,Ie=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Nt(e,s))return;let l=Dt(e);if(!l||Math.abs(pn(e))<Ct*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=Hn(t.roof_direction),m=g===void 0?void 0:[Math.sin(g*Math.PI/180),-Math.cos(g*Math.PI/180)];(m!==void 0?Math.abs(m[0]*u[0]+m[1]*u[1])>Math.abs(m[0]*c[0]+m[1]*c[1]):t.roof_orientation==="across")&&a!=="skillion"&&([u,c,f,d]=[c,u,d,f]);let h=jt(a,f,d,m&&[Gn(m,u),Gn(m,c)]);if(!h)return;let A=Math.max(0,o-i),F=Hn(t.roof_height),k,M;if(F!==void 0&&F>0)M=o,k=Math.max(i+Math.min(2,A/2),o-F);else{let y=Math.min(It(a,d),A*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[C,E]=l.centre,O=(y,b)=>{let x=(y-C)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[C+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],N=(y,b)=>{let x=1/0;for(let[T,S,v]of h)x=Math.min(x,T*y+S*b+v);return Math.max(0,x)},K=(y,b)=>k+B*N(...O(y,b)),G=[];for(let y=0;y+1<n.length;y+=2)G.push(...O(n[y],n[y+1]));pn(G)<0&&Vt(G);let z=1.01,Y=[-f*z,-d*z,f*z,-d*z,f*z,d*z,-f*z,d*z],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let D=b[0]-Z[0],H=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(D)+Math.abs(H)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=$n(x,D,H,W),x.length<6)break}if(x.length<6)continue;let T=G,S=x.length/2;for(let P=0;P<S&&T.length>=6;P+=1){let[Z,D]=[x[P*2],x[P*2+1]],[H,W]=[x[(P+1)%S*2],x[(P+1)%S*2+1]];T=$n(T,W-D,Z-H,-(W-D)*Z-(Z-H)*D)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let v=[];for(let P=0;P<T.length;P+=2)v.push(...I(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let U=B*b[0],V=B*b[1],R=U*u[0]+V*c[0],_=U*u[1]+V*c[1],j=Math.hypot(R,_,1);w.push({ring:v,triangles:L,normal:[-R/j,-_/j]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[S,v]=O(y,b),[L,U]=O(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let _=R+1;_<h.length;_+=1){let j=(ae,$)=>(h[R][0]-h[_][0])*ae+(h[R][1]-h[_][1])*$+(h[R][2]-h[_][2]),P=j(S,v),Z=j(L,U);if(P===Z||P*Z>0)continue;let D=P/(P-Z);if(D<=1e-4||D>=1-1e-4)continue;let H=S+(L-S)*D,W=v+(U-v)*D;h[R][0]*H+h[R][1]*W+h[R][2]<=N(H,W)+1e-6&&V.push(D)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,_)=>R-_)}}}function It(e,n){switch(e){case"skillion":return 2*n*Et;case"pyramidal":return n*Pt;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Ot}}function jt(e,n,t,i){let o=n,r=t,s=[[0,-1/r,1],[0,1/r,1]],a=u=>u.flatMap(c=>[1,-1].flatMap(f=>{let d=c==="v"?r:o,g=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function $n(e,n,t,i){let o=e.length/2,r=[];for(let s=0;s<o;s+=1){let a=e[s*2],l=e[s*2+1],u=e[(s+1)%o*2],c=e[(s+1)%o*2+1],f=n*a+t*l+i,d=n*u+t*c+i;if(f<=0&&r.push(a,l),f<0&&d>0||f>0&&d<0){let g=f/(f-d);r.push(a+(u-a)*g,l+(c-l)*g)}}return r}function Dt(e){let n=zt(e);if(n.length<3)return;let t,i=1/0;for(let o=0;o<n.length;o+=1){let[r,s]=n[o],[a,l]=n[(o+1)%n.length],u=Math.hypot(a-r,l-s);if(u===0)continue;let c=[(a-r)/u,(l-s)/u],f=[-c[1],c[0]],[d,g,m,p]=[1/0,-1/0,1/0,-1/0];for(let[A,F]of n){let k=A*c[0]+F*c[1],M=A*f[0]+F*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let A=(d+g)/2,F=(m+p)/2;t={centre:[A*c[0]+F*f[0],A*c[1]+F*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function zt(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,s)=>r[0]-s[0]||r[1]-s[1]);let t=(r,s,a)=>(s[0]-r[0])*(a[1]-r[1])-(s[1]-r[1])*(a[0]-r[0]),i=[];for(let r of n){for(;i.length>=2&&t(i.at(-2),i.at(-1),r)<=0;)i.pop();i.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...i.slice(0,-1),...o.slice(0,-1)]}function Nt(e,n){let[t,i,o,r]=[1/0,-1/0,1/0,-1/0];for(let a=0;a+1<e.length;a+=2)t=Math.min(t,e[a]),i=Math.max(i,e[a]),o=Math.min(o,e[a+1]),r=Math.max(r,e[a+1]);let s=e.length/2;for(let a=0;a<s;a+=1){let l=e[a*2],u=e[a*2+1],c=e[(a+1)%s*2],f=e[(a+1)%s*2+1];if(t<0&&l===t&&c===t||i>n&&l===i&&c===i||o<0&&u===o&&f===o||r>n&&u===r&&f===r)return!0}return!1}function pn(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n/2}function Vt(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function Gn(e,n){return e[0]*n[0]+e[1]*n[1]}function Hn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var jr=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),zr=Object.freeze([1,1,4,1,3]),Nr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Gt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=$t(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function $t(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Gt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Ht={commercial:1,active:2,destination:3},Zt={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},Wt={dining:1,entertainment:2,nightlife:3},bn={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},Xt=6,Yt=.5,Jt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=er(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let C=B.properties,E=C.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let O=Math.min(6e3,Jn(C.render_height)??o),I=Math.min(O,Jn(C.render_min_height)??0),N=Ht[String(C.building_tone??"")]??0,K=Zt[String(C.class??"")]??0,G=d.get(M)??0,z=u.length,Y=!1;for(let w of nr(B.geometry,t)){let y=w.map(rr).filter(_=>_.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=tr(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Jt/i)))continue;let T={cell:Math.min(7,Math.max(0,Math.floor(x/1024)))*8+Math.min(7,Math.max(0,Math.floor(b/1024))),bounds:[1/0,1/0,-1/0,-1/0,O+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let _ of y)for(let j=0;j<_.length;j+=2)T.bounds[0]=Math.min(T.bounds[0],_[j]-1),T.bounds[1]=Math.min(T.bounds[1],_[j+1]-1),T.bounds[2]=Math.max(T.bounds[2],_[j]+1),T.bounds[3]=Math.max(T.bounds[3],_[j+1]+1);Y=!0,f=Math.max(f,O);let S=Number.isSafeInteger(B.id),v=gn(S?B.id*.0731:b*.0731+x*.19137+z*1.618),L=!S&&y[0].some(_=>_<=0||_>=ue)?gn(O*7.31+I*3.17+N):v,U={base:I,top:O,jitter:L,seed:v,tone:N,group:K,use:G,cx:b,cy:x,index:z},V=y.map((_,j)=>qt(_,j,r,n.cornerAngle));y=V.map(({ring:_})=>_);let R=w.length===1&&y.length===1?Zn(w[0],y[0],C,I,O,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),Qt(R,U,s,a)):Kt(y,U,s,a);for(let[_,j]of y.entries()){let P=qe(j)>0,Z=_===0?P?-1:1:P?1:-1,D=j.length/2,H=$=>{let J=($%D+D)%D;return[j[J*2],j[J*2+1]]},W=$=>{let[J,re]=H($-1),[ne,te]=H($),[le,de]=H($+1);if(we(J,re,ne,te)||we(ne,te,le,de))return!1;let me=Math.hypot(ne-J,te-re),ce=Math.hypot(le-ne,de-te);if(!me||!ce)return!1;let De=-(te-re)/me*Z,ze=(ne-J)/me*Z;return(De*(le-ne)+ze*(de-te))/ce>Yt},se=($,J)=>R?R.heightAt($,J):O,ae=0;for(let $=0;$<D;$+=1){let[J,re]=H($),[ne,te]=H($+1),le=Math.hypot(ne-J,te-re);if(le===0||we(J,re,ne,te))continue;let de=-(te-re)/le*Z,me=(ne-J)/le*Z,ce=V[_].normals[$]??[de,me],De=V[_].normals[($+1)%D]??[de,me],ze=oe=>{let Ae=ce[0]+(De[0]-ce[0])*oe,Fe=ce[1]+(De[1]-ce[1])*oe,ye=Math.hypot(Ae,Fe)||1;return[Ae/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let Ae=oe===0,Fe=oe+2===he.length,ye=J+(ne-J)*he[oe],Ne=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],$e=re+(te-re)*he[oe+1],Se=Math.hypot(Ve-ye,$e-Ne)/ue*n.tileMetres,Ge=(Ae&&W($)?1:0)|(Fe&&W($+1)?2:0)|(_>0?4:0),He=(Ae&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Se,Ze=ze(he[oe]),We=ze(he[oe+1]),Cn=se(ye,Ne),On=se(Ve,$e),ke=s.write(U,ye,Ne,0,Ze[0],Ze[1],1,ae,Ge,Se,0,He,Cn);s.write(U,Ve,$e,0,We[0],We[1],1,an,Ge,Se,1,He,On),s.write(U,ye,Ne,1,Ze[0],Ze[1],1,ae,Ge,Se,0,He,Cn),s.write(U,Ve,$e,1,We[0],We[1],1,an,Ge,Se,1,He,On),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(C)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,A=a.values(),F=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let C=0;C<5;C+=1)B.bounds[C]=C<2?Math.min(B.bounds[C],M.bounds[C]):Math.max(B.bounds[C],M.bounds[C]);g.set(A.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(F.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function Kt(e,n,t,i){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let s=(l,u)=>{let c=r.findIndex((p,h)=>l>=p&&l<r[h+1]),[f,d]=[r[c],r[c+1]-1];if(u<f||u>d)return!1;let[g,m]=l<u?[l,u]:[u,l];return m-g!==1&&!(g===f&&m===d)?!1:!we(o[l*2],o[l*2+1],o[u*2],o[u*2+1])},a=Pe(o,r.slice(1,-1),2);for(let l=0;l+2<a.length;l+=3){let u=[a[l],a[l+1],a[l+2]],c=0;for(let f=0;f<3;f+=1)s(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries())i.push(t.write(n,o[d*2],o[d*2+1],1,0,0,0,0,0,0,f,c))}}function Qt(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function qt(e,n,t,i=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=qe(e)>0,s=n===0?r?-1:1:r?1:-1,a=[],l=[],u=(c,f,d)=>{c=Re(c),f=Re(f),!(a.at(-2)===c&&a.at(-1)===f)&&(a.push(c,f),l.push(d))};for(let c=0;c<o;c+=1){let f=(c+o-1)%o,d=(c+1)%o,[g,m]=[e[f*2],e[f*2+1]],[p,h]=[e[c*2],e[c*2+1]],[A,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(A-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,A,F)){u(p,h);continue}let[B,C]=[(p-g)/k,(h-m)/k],[E,O]=[(A-p)/M,(F-h)/M],I=Math.atan2(B*O-C*E,B*E+C*O);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let N=Math.tan(Math.abs(I)/2),K=Math.min(t*N,k*.2,M*.2),G=K/N;if(G<1){u(p,h);continue}let[z,Y]=[-C*s,B*s],[w,y]=[p-B*K-z*G,h-C*K-Y*G],b=Math.atan2(Y,z),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let S=b+I*T/x,v=[Math.cos(S),Math.sin(S)];u(w+v[0]*G,y+v[1]*G,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let A=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(A).set(new Uint8Array(this.#e)),this.#e=A,this.#n=new DataView(A)}let p=this.#n,h=this.count*m;return p.setUint16(h,Re(t),!0),p.setUint16(h+2,Re(i),!0),p.setUint16(h+4,Math.min(65535,Math.round(n.base*10)),!0),p.setUint16(h+6,Math.min(65535,Math.max(0,Math.round(g*10))),!0),p.setInt8(h+8,Math.round(r*127)),p.setInt8(h+9,Math.round(s*127)),p.setUint8(h+10,o),p.setUint8(h+11,a),p.setUint16(h+12,Math.round(l*10)%65536,!0),p.setUint8(h+14,Math.round(n.jitter*255)),p.setUint8(h+15,Math.round(n.seed*255)),p.setUint16(h+16,Re(n.cx),!0),p.setUint16(h+18,Re(n.cy),!0),p.setUint8(h+20,n.tone+4*n.group),p.setUint8(h+21,n.use),p.setUint8(h+22,u),p.setUint8(h+23,Math.min(255,Math.round(c))),p.setUint16(h+24,n.index,!0),p.setUint8(h+26,f),p.setUint8(h+27,d),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*pe))}},Qe=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function er(e,n){let t=new Map;if(e.features.some(a=>a.properties.night_use!==void 0)){for(let[a,l]of e.features.entries()){let u=Wt[String(l.properties.night_use??"")];u&&t.set(a,u)}return t}let i=n.places;if(!i||i.features.length===0)return t;let o=Xt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let F of r){let[k,M,B,C]=F.box;if(d<k-o||d>B+o||g<M-o||g>C+o)continue;let E=!1;for(let O of F.rings)for(let I=0,N=O.length-2;I+1<O.length;N=I,I+=2){let K=O[N],G=O[N+1],z=O[I],Y=O[I+1];Y>g!=G>g&&d<(K-z)*(g-Y)/(G-Y)+z&&(E=!E);let w=z-K,y=Y-G,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-G)*y)/b)):0,T=Math.hypot(d-K-x*w,g-G-x*y);T<h&&(h=T,p=F.index)}if(E){m=F.index;break}}let A=m??p;A!==void 0&&t.set(A,Math.max(t.get(A)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Jn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function nr(e,n){let t=[],i;for(let o of e){let r=[];for(let a=0;a+1<o.length;a+=2){let l=o[a]*n,u=o[a+1]*n;r.length&&l===r.at(-2)&&u===r.at(-1)||r.push(l,u)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let s=Math.sign(qe(r));s&&(i??=s,s===i||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function qe(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n}function tr(e){let n=0,t=0,i=e.length/2;for(let o=0;o<i;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/i,t/i]}function xn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function we(e,n,t,i){let o=ue;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&i<=0||n>=o&&i>=o}function rr(e){let n=ue,t=[...e],i=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,s]of i){let a=[],l=t.length/2;for(let u=0;u<l;u+=1){let c=[t[u*2],t[u*2+1]],f=[t[(u+1)%l*2],t[(u+1)%l*2+1]],d=s(c[o]),g=s(f[o]);if(d&&a.push(c[0],c[1]),d!==g){let m=(r-c[o])/(f[o]-c[o]);a.push(c[0]+(f[0]-c[0])*m,c[1]+(f[1]-c[1])*m)}}if(t=a,t.length<6)return[]}return t}function gn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}function Qn(e){let n=(e.indices.length-e.wallsFrom)/6,t=new Uint8Array(n*16);for(let i=0;i<n;i+=1){let o=e.wallsFrom+i*6,r=e.indices[o]*pe,s=e.indices[o+1]*pe;t.set(e.vertices.subarray(r,r+4),i*16),t.set(e.vertices.subarray(s,s+4),i*16+4),t.set(e.vertices.subarray(r+4,r+8),i*16+8),t[i*16+12]=e.vertices[r+14],t[i*16+13]=e.vertices[r+27]}return t}function qn(e){let n=e.vertices.length/pe;return{mesh:{...e.groups?{groups:e.groups}:{},wallsFrom:e.wallsFrom,top:e.top,features:e.features,vertexCount:n,indexCount:e.indices.length},data:{vertices:e.vertices,indices:n<=65536?Uint16Array.from(e.indices):e.indices,contact:Qn(e)}}}function et({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=or(e);return n?[Math.min(1,Math.max(0,n[0]/255)),Math.min(1,Math.max(0,n[1]/255)),Math.min(1,Math.max(0,n[2]/255)),Math.min(1,Math.max(0,n[3]))]:null}function or(e){let n=e.trim().toLowerCase(),t=/^#([\da-f]{3,8})$/u.exec(n)?.[1];if(t&&[3,4,6,8].includes(t.length)){let A=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[A[0],A[1],A[2],A.length>3?A[3]/255:1]}let i=/^(rgba?|hsla?)\(([^)]+)\)$/u.exec(n);if(!i)return null;let o=i[2].split(/[\s,/]+/u).filter(Boolean);if(o.length<3||o.length>4)return null;let r=o[3]===void 0?1:en(o[3],1);if(i[1].startsWith("rgb")){let[h,A,F]=o.slice(0,3).map(k=>en(k,255));return[h,A,F,r].some(k=>k===null)?null:[h,A,F,r]}let s=Number.parseFloat(o[0]),a=en(o[1],1),l=en(o[2],1);if(!Number.isFinite(s)||a===null||l===null||r===null)return null;let u=(1-Math.abs(2*l-1))*a,c=(s%360+360)%360/60,f=u*(1-Math.abs(c%2-1)),[d,g,m]=c<1?[u,f,0]:c<2?[f,u,0]:c<3?[0,u,f]:c<4?[0,f,u]:c<5?[f,0,u]:[u,0,f],p=l-u/2;return[(d+p)*255,(g+p)*255,(m+p)*255,r]}function en(e,n){let t=e.endsWith("%"),i=Number.parseFloat(e);return Number.isFinite(i)?t?i/100*n:i:null}var fe=8192,Mn=12,ir={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},minor:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},sr={motorway:{spacing:45,kerb:14},trunk:{spacing:40,kerb:12},service:{spacing:38,kerb:4},path:{spacing:28,kerb:1.5},track:{spacing:40,kerb:2.5}},ar={spacing:30,kerb:0},lr=12,ur=18,cr=9,fr={sodium:"#ffa64d",high_pressure_sodium:"#ffa64d",low_pressure_sodium:"#ff9326",led:"#fff1db",mercury:"#e3ecff",metal_halide:"#f4f4ff",fluorescent:"#eef9ff",electric:"#ffd59a",incandescent:"#ffd59a",halogen:"#ffe3b0",gas:"#ffd28a",gaslight:"#ffd28a"},dr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},mr=new Set(["wall","wall_mounted","wall_bracket"]),hr=new Set(["suspended","cable","catenary","wire"]);function ot(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(ur),r=new nn(cr),s=e.streetFurniture;if(s){let m=fe/s.extent;for(let p of s.features){let h=p.properties;if(p.type!=="Point"||h.subclass!=="street_lamp")continue;let A=pr(h),F=yr(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,A*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let C=0;C+1<B.length;C+=2){let E=B[C]*m,O=B[C+1]*m;if(!tt(E,O))continue;i.write(E,O,A,M,!0,F);let I=rt(E,O,n.tileMetres);o.add(...I),r.add(...I)}}}let a=i.count;if(t==="none")return i.done(a);let l=e.transportation,u=0;if(l){let m=n.tileMetres/l.extent;for(let p of l.features)if(!(p.type!=="LineString"||!nt(p.properties,"streets")))for(let h of p.geometry)u+=br(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=lr,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,A)=>{let F=fe/m.extent,k=[];for(let N=0;N+1<p.length;N+=2)k.push(p[N]*F,p[N+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,C=Rn(k[0]*.013+k[1]*.029+A)*h.spacing,E=0,O=C,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let N=2;N<k.length;N+=2){let K=k[N-2],G=k[N-1],z=k[N],Y=k[N+1],w=Math.hypot(z-K,Y-G)*M;if(w!==0){for(;O<=E+w;){let y=(O-E)/w,b=-(Y-G)/(w/M)*I,x=(z-K)/(w/M)*I,T=K+(z-K)*y+b*B,S=G+(Y-G)*y+x*B;if(O+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!tt(T,S))continue;let v=rt(T,S,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,S,7,15,!1))}E+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=nt(m.properties,f);if(p)for(let h of m.geometry)d(l,h,p,1)}let g=e.sidewalks;if(g){for(let m of g.features)if(!(m.type==="Point"||!kn(m.properties.lit)))for(let p of m.geometry)d(g,p,ar,2)}return i.done(a)}function nt(e,n){if(e.brunnel==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=String(e.subclass??""),r=i==="path"&&(o==="pedestrian"||o==="living_street")?"pedestrian":i,s=ir[r];if(s&&(n==="streets"||kn(t)))return s;let a=sr[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function pr(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return mr.has(t)?4.5:hr.has(t)?7.5:7}function yr(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(dr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=fr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function tt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function rt(e,n,t){return[e/fe*t,n/fe*t]}function br(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var eo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"transportation",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Me=["round","open","tall","conifer","columnar","palm"];var lt=Object.freeze({height:"height",diameterCrown:"diameter_crown",circumference:"circumference",genus:"genus",species:"species",leafType:"leaf_type",taxon:"taxon",canopyRank:"rank",canopyClearance:"clearance_px_z15",canopyCover:"cover_pct",canopyHeight:"height_m",subclass:"subclass",hedge:"hedge"}),_n=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,it={round:{height:[6,12],crown:[.66,.9]},open:{height:[5,10],crown:[.8,1.05]},tall:{height:[9,17],crown:[.48,.68]},conifer:{height:[7,16],crown:[.46,.66]},columnar:{height:[9,18],crown:[.22,.36]},palm:{height:[12,20],crown:[.42,.55]}};var on=[2,45],An=[1,25],gr=1.2,wr=1.5,xr=1.3,Tr=1,Mr=[.3,10],kr=new Set(["acoelorrhaphe","adonidia","archontophoenix","areca","arecastrum","bismarckia","brahea","butia","caryota","chamaedorea","chamaerops","coccothrinax","cocos","dypsis","elaeis","howea","jubaea","licuala","livistona","phoenix","pritchardia","ptychosperma","rhapis","roystonea","sabal","serenoa","syagrus","thrinax","trachycarpus","veitchia","washingtonia","wodyetia"]),vr=new Set(["cupressus","calocedrus","thuja"]),Rr=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),st=Object.freeze({...Object.fromEntries(["acacia","albizia","arbutus","bursera","ceratonia","delonix","ficus","gleditsia","jacaranda","olea","quercus","robinia","schinus","sophora","styphnolobium","tamarix"].map(e=>[e,"open"])),...Object.fromEntries(["betula","celtis","fraxinus","ginkgo","liquidambar","liriodendron","magnolia","platanus","populus","pyrus","ulmus","zelkova"].map(e=>[e,"tall"])),...Object.fromEntries(["acer","aesculus","carpinus","castanea","catalpa","cercis","citrus","fagus","lagerstroemia","malus","melia","morus","prunus","sorbus","tilia"].map(e=>[e,"round"]))});function at(e,n={}){let t={...lt,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=Fn(e[t.genus])??Fn(e[t.species])??(o.endsWith("aceae")?void 0:Fn(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&kr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&vr.has(r))return"columnar";if(i.includes("needle")||r&&Rr.has(r))return"conifer";if(r&&st[r])return st[r];if(i.includes("broad"))return"broadleaf"}function Fn(e){return typeof e!="string"?void 0:e.trim().split(/\s+/u)[0]?.toLowerCase()||void 0}function ut(e,n){let t={...lt,...n.fields},i=n.unknownForms??_n,o=n.regions??[],{tile:r,tileMetres:s}=n,a=s/2**(15-r.z)/512,l=[],u=0,c=0,f=(w,y)=>{if(o.length===0)return i;let[b,x]=Fr(r,w/q,y/q);for(let T of o){let[S,v,L,U]=T.bounds;if(x>=v&&x<=U&&(S<=L?b>=S&&b<=L:b>=S||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=it[w],S=Sn(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=Sn(T.height,ee(y,1))),v===void 0&&(v=L/S),L===void 0&&(L=v*S),{height:Te(v,on),crown:Te(L,An)}},g=(w,y,b,x,T,S)=>{let v=je(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Ar(f(w,y)),ee(v,3)):b,U=x===void 0&&T===void 0&&S!==void 0?d(L,v,Sn(it[L].height,Te(S/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...U,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=at(b,t),T=xe(b[t.height],on),S=xe(b[t.diameterCrown],An),v=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let U=0;U+1<L.length;U+=2){let V=L[U],R=L[U+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,S,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=at(x,t),S=xe(x[t.height],on),v=xe(x[t.diameterCrown],An);for(let L of b.geometry){let U=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[_,j,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],D=Math.hypot(P-_,Z-j);for(;U<=V+D;){let H=D>0?(U-V)/D:0,W=_+(P-_)*H,se=j+(Z-j)*H;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,S,v,void 0),U+=y}V+=D}}}}let h=e.canopy;if(h){let w=q/h.extent;for(let y of h.features){if(y.type!=="Point")continue;let b=y.properties,x=Te(Math.floor(Number(b[t.canopyRank]??8)),[0,rn-1]),T=Math.max(4,Number(b[t.canopyClearance]??8))*a,S=Number(b[t.canopyCover]??30),v=S>=60?3:S>=30?2:1;for(let L of y.geometry)for(let U=0;U+1<L.length;U+=2){let V=L[U],R=L[U+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let _=V*w,j=R*w,P=je(r.x*q+_,r.y*q+j,11),Z=f(_,j),D=xe(b[t.canopyHeight],on),H=Te(Math.min(T*(v===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(H*.5,T-H/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<v;ae+=1){let $=je(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee($,1):W,ne=_+Math.cos(J)*re/(s/q),te=j+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee($,3)),de=H*(.85+ee($,2)*.3),me=D===void 0?void 0:D*(.85+ee($,6)*.25),ce=d(le,$,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee($,4),shade:ee($,5),form:Me.indexOf(le),rank:x,seed:ee($,7),canopy:1}),c+=1}}}}let A=[],F=e.hedges;if(F){let w=q/F.extent,y=gr/(s/F.extent);for(let b of F.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?Tr:0,T=(xe(b.properties[t.height],Mr)??xr)+x;for(let S of b.geometry){let v=y/2,L=0;for(let U=0;U+3<S.length;U+=2){let[V,R,_,j]=[S[U],S[U+1],S[U+2],S[U+3]],P=Math.hypot(_-V,j-R),Z=(Math.atan2(R-j,_-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let D=P>0?(v-L)/P:0,H=V+(_-V)*D,W=R+(j-R)*D;if(H>=0&&W>=0&&H<F.extent&&W<F.extent){let se=je(r.x*q+H*w,r.y*q+W*w,17);A.push({x:H*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),C=l.map((w,y)=>y);C.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),O=new DataView(E.buffer),I=0,N=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...N(),variants:Array.from({length:k(y)},N)}])),G=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};C.forEach((w,y)=>{let b=l[w],x=y*tn;O.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),O.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),O.setUint16(x+4,Math.round(b.height*10),!0),O.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];G(T,y,b.rank),G(T.variants[B[w]],y,b.rank)});let z=new Uint8Array(A.length*tn),Y=new DataView(z.buffer);return A.forEach((w,y)=>{let b=y*tn;Y.setUint16(b,Math.min(q-1,Math.round(w.x)),!0),Y.setUint16(b+2,Math.min(q-1,Math.round(w.y)),!0),Y.setUint16(b+4,Math.round(w.height*10),!0),Y.setUint16(b+6,Math.round(wr*10),!0),z[b+8]=Math.round(w.turn*256)&255,z[b+9]=Math.floor(w.shade*256)&255,z[b+12]=Math.floor(w.seed*256)&255,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:z,tallest:I,mapped:u,canopy:c}}function Ar(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:_n}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(_n,n);let i=n*t;for(let o of Me){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function xe(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?Te(t,n):void 0}function Te(e,[n,t]){return Math.min(t,Math.max(n,e))}function Sn([e,n],t){return e+(n-e)*t}function Fr(e,n,t){let i=2**e.z,o=(e.x+n)/i*360-180,r=Math.atan(Math.sinh(Math.PI*(1-2*(e.y+t)/i)))*180/Math.PI;return[o,r]}function je(e,n,t){let i=(Math.imul(Math.floor(e)|0,668265261)^Math.imul(Math.floor(n)|0,374761393)^Math.imul(t,2654435761))>>>0;return i=Math.imul(i^i>>>15,2246822507)>>>0,i=Math.imul(i^i>>>13,3266489909)>>>0,(i^i>>>16)>>>0}function ee(e,n){return je(e,n,20973)/4294967296}var Sr=[void 0,"Point","LineString","Polygon"];function ct(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Bn(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=_r(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function _r(e,n){let t,i=4096,o=[],r=[],s=[];for(;e.more();){let[a,l]=e.tag();if(a===1?t=e.string():a===2?s.push(e.message()):a===3?o.push(e.string()):a===4?r.push(Ur(e.message())):a===5?i=e.varint():e.skip(l),t!==void 0&&n&&!n.has(t))return}if(!(t===void 0||n&&!n.has(t)))return{name:t,layer:Object.freeze({extent:i,features:Object.freeze(s.flatMap(a=>{let l=Lr(a,o,r);return l?[l]:[]}))})}}function Lr(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Sr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Br(s,o))})}function Br(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Cr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Cr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function ft(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function dt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Kn(r,{...e.options,...s?{places:s}:{}});return a&&qn(a)}if(e.kind==="trees"){let r=n(e.layers.tree),s=n(e.layers.canopy),a=n(e.layers.hedge);if(!r&&!s&&!a)return;let l=ut({...r?{trees:r}:{},...s?{canopy:s}:{},...a?{hedges:a}:{}},e.options);return l.trees.length>0||l.hedges.length>0?l:void 0}let t=n(e.layers.streetFurniture),i=n(e.layers.transportation),o=n(e.layers.sidewalk);return ot({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function mt(e,n){if(!n)return[];if(e==="buildings")return et(n);if(e==="trees"){let{trees:t,hedges:i}=n;return[t.buffer,i.buffer].filter((o,r,s)=>s.indexOf(o)===r)}return[n.lamps.buffer]}function ht(e=16){let n=new Map;return{read(t,i,o){let r=n.get(t);for(n.delete(t),r??={bytes:i,layers:new Map},n.set(t,r);n.size>e;)n.delete(n.keys().next().value);let s=o.filter(l=>!r.layers.has(l));if(s.length>0){let l=ct(r.bytes,{layers:s});for(let u of s)r.layers.set(u,l[u])}let a=r.layers;return l=>l===void 0?void 0:a.get(l)}}}var Un=globalThis,Or=ht();Un.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=dt(t,Or.read(e,n,ft(t)));Un.postMessage({result:i},mt(t.kind,i))}catch(i){Un.postMessage({error:String(i)})}};})();
@@ -65,12 +65,15 @@ state on the map.
65
65
  ## Requests and cache
66
66
 
67
67
  - **One request per tile.** However many reads wait for a tile, it is requested once. A read whose
68
- signal aborts stops waiting, but the request finishes for the cache and the other reads.
68
+ signal aborts stops waiting. Once every read waiting for a request has stopped, a request still
69
+ waiting its turn is dropped; one already sent finishes for the cache, or stops when `cacheSize`
70
+ is 0.
69
71
  - **Cache.** The reader keeps up to `cacheSize` decoded tiles (128 by default), the most recently
70
72
  read first. It remembers a tile the source does not have (404 or 204) as absent, and does not
71
73
  remember errors. `clear()` forgets everything.
72
74
  - **Concurrency.** At most `concurrency` requests (6 by default) run at once; the rest wait their
73
- turn.
75
+ turn, lowest `priority` first (a read option, 0 by default). `readArea` reads the tiles nearest
76
+ its centre first.
74
77
  - **Requests.** `transformRequest` rewrites each request as a MapLibre map's option does. Pass the
75
78
  map's own so tile reads follow the same rules. The browser's HTTP cache applies as for any
76
79
  request.
@@ -259,3 +259,11 @@ data; passes placed beside a moved target follow it. Operations sharing a placem
259
259
  declaration order, the first lowest. For symbols, a higher layer is also placed first in MapLibre
260
260
  collisions, so placement decides both drawing and precedence. An owner whose layers are all
261
261
  render passes still satisfies other operations' `requirements`.
262
+
263
+ A target exists only in the mode that draws it: buildings draw `buildings.flat.fill` and
264
+ `buildings.flat.outline` in mode `'flat'`, and `buildings.extrusion` in mode `'3d'`. `refine()`
265
+ keeps the inherited render stack, so refining an inherited module's `mode` fails when a pass is
266
+ placed beside, or a refinement targets, the other mode's target; the error names both modes.
267
+ Streets' shadows and its extrusion pass stand beside its flat buildings. To draw native extrusions
268
+ in a map that extends Streets, remove that stack with `refine({mode: '3d', renderStack: reset()})`,
269
+ or declare `buildings({mode: '3d'})` to replace the module.
@@ -16,11 +16,65 @@ the buildings under their footprints.
16
16
 
17
17
  It is a custom WebGL2 layer for MapLibre GL JS, drawn above the map's buildings and below its
18
18
  labels. It needs WebGL2 and the Mercator projection, which MapLibre's globe turns into from about
19
- zoom 12. On every map, buildings and placed models appear automatically from zoom 15,
20
- with opacity rising linearly from 0 at 15 to 1 at 15.25. Zooming back out reverses the fade.
21
- Their height stays unchanged throughout; shadows and contact shading fade with them.
19
+ zoom 12. On every map the city comes in as the camera zooms in: placed models and landmarks first,
20
+ fading in and rising from the ground between zooms 14.2 and 14.6, then the buildings between 15 and
21
+ 15.3. Their shadows and contact shading follow their height. Zooming back out lowers and fades them
22
+ again. With reduced motion (`prefers-reduced-motion`) they keep their height and only fade.
22
23
  `hide()` keeps them hidden at every zoom until `show()` is called.
23
24
 
25
+ A map sets these bands with the buildings module's `threeDimensional.entrance`, each a
26
+ `[from, to]` pair of zooms; a band left out keeps its default:
27
+
28
+ ```ts
29
+ buildings({threeDimensional: {entrance: {buildings: [15.5, 16], models: [14.5, 15]}}});
30
+ ```
31
+
32
+ The renderer reads its tiles from a zoom below its `minzoom`, so a band that starts earlier than
33
+ that comes in from there.
34
+
35
+ ## The map's 3D scene
36
+
37
+ React, Vue and Svelte `Map` components show the 3D scene of every map whose style declares one, by
38
+ default: buildings with Tileflow landmarks and the map's Team building models, 3D trees, and street
39
+ lights where the map enables them. They load the 3D renderers from `@tileflow/core/3d` only when
40
+ the style declares a scene, so a 2D map does not download them. Set `viewMode="2d"` (Vue:
41
+ `view-mode="2d"`) to opt out: no 3D buildings or street lights are mounted, and vegetation follows
42
+ its [display policy](trees-3d.md#visibility-and-representation) for the 2D view. Changing it back to
43
+ `3d` shows the scene on the same map. React Native, image mode, Capture and Static Maps do not draw
44
+ the scene.
45
+
46
+ Applications that build their own MapLibre map mount the same scene with `createTileflowMap3D`.
47
+ It mounts each renderer the style declares, follows theme and style changes, and releases a
48
+ renderer when the style no longer declares it:
49
+
50
+ <!-- docs:check -->
51
+
52
+ ```ts
53
+ import {
54
+ createTileflowMap3D,
55
+ type TileflowMap3DMap,
56
+ type TileflowThemeController,
57
+ } from '@tileflow/core/browser';
58
+
59
+ export function showTheScene(map: TileflowMap3DMap, controller: TileflowThemeController) {
60
+ const scene = createTileflowMap3D({map, controller});
61
+ // Shown on creation; hide() and show() switch the whole scene, dispose() removes it.
62
+ return scene;
63
+ }
64
+ ```
65
+
66
+ `hide()` takes the buildings down and releases the street lights; `show()` brings them back. Both
67
+ take the same transition as the buildings' `show()` and `hide()`. `setVegetation(false)` hides
68
+ every tree and `setVegetation(undefined)` restores the map's default. To load the renderers only
69
+ for maps that need them, call `attachTileflowMap3D({map, controller, load: () =>
70
+ import('@tileflow/core/3d')})` from `@tileflow/core/browser`, as the framework components do; its
71
+ `setViewMode()` and `setVegetation()` apply once the scene mounts.
72
+
73
+ A MapLibre application that loads a compiled `style.json` directly gets no 3D scene: buildings,
74
+ landmarks, models, trees and lights are custom WebGL layers added only by this runtime. Where a map
75
+ draws a plain `fill-extrusion` building pass, the style ships it hidden and grouped under
76
+ `metadata['tileflow:3d-toggle'] = 'building'`; showing those layers gives extruded footprints only.
77
+
24
78
  ## Show the buildings
25
79
 
26
80
  This example assumes an existing MapLibre map showing a Tileflow map whose vector source is called
@@ -194,7 +248,7 @@ longer raised while it stands. Put glTF binaries (`.glb`) in a directory, declar
194
248
  <!-- docs:check -->
195
249
 
196
250
  ```ts
197
- import {defineMap, refine} from '@tileflow/core';
251
+ import {defineMap, fixed, refine} from '@tileflow/core';
198
252
  import {streets, streetsModels} from '@tileflow/maps';
199
253
 
200
254
  export default defineMap({
@@ -210,7 +264,10 @@ export default defineMap({
210
264
  buildings: refine({
211
265
  threeDimensional: {
212
266
  models: [{model: 'eiffel-tower', at: [2.294481, 48.858258], heading: 0}],
213
- modelColors: {surface: '#7a5c45', accent: '#5b4332'},
267
+ modelColors: {
268
+ surface: fixed('#7a5c45', {reason: "The tower's bronze paint"}),
269
+ accent: fixed('#5b4332', {reason: "The tower's bronze paint, in shadow"}),
270
+ },
214
271
  },
215
272
  }),
216
273
  },
@@ -228,7 +285,9 @@ How to prepare a model:
228
285
  `roof` (an exporter's `.001` suffix is ignored); a model whose materials name a tree's parts is a
229
286
  [tree model](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/docs/trees-3d.md)
230
287
  instead. Each part takes its colour from `modelColors`, or from the buildings' colour when the
231
- design gives it none, so the model follows the theme from day to night; vertex colours lighter or
288
+ design gives it none, so the model follows the theme from day to night. Like every visual
289
+ colour, a `modelColors` entry is a theme token such as `token.color('buildings.modelRoof')`, or
290
+ a literal wrapped in `fixed(value, {reason})`; vertex colours lighter or
232
291
  darker than the rest of their part shade it within that colour.
233
292
  - **Architectural roles control lighting.** A material may set
234
293
  `extras.tileflow.lightingRole` to `wall`, `door`, `roof`, `window`, `lamp`, `logo` or
@@ -441,7 +500,8 @@ download.
441
500
 
442
501
  ## Options
443
502
 
444
- The renderer's own options say only how it is delivered: `minzoom` (15 by default, with a 0.25-zoom opacity ramp), `maxTiles`,
503
+ The renderer's own options say only how it is delivered: `minzoom` (15 by default; the default
504
+ entrance bands start from it), `maxTiles`,
445
505
  `beforeId` to place the layer before another one, and `transformRequest` to apply the map's request
446
506
  rules to the tiles it reads.
447
507
 
@@ -451,10 +511,14 @@ During partial opacity, a depth-only geometry pass resolves the nearest surfaces
451
511
  blending, preventing rear walls from bleeding through. At full opacity only the normal geometry
452
512
  pass runs; zoom fading schedules no extra animation frames or per-zoom mesh rebuilds.
453
513
 
454
- The browser bundle prepares building meshes in one worker per renderer and transfers the finished
455
- vertex and index buffers. No worker URL or extra asset hosting is needed. A Content Security Policy
456
- must allow `worker-src blob:` to use this path; if workers are unavailable or blocked, the renderer
457
- falls back to local meshing. The worker is terminated on `dispose()`. Pending tile updates retain
514
+ The browser bundle builds from the tiles' bytes in one worker that the page's 3D buildings, trees
515
+ and street lights share, nearest tiles first: it decodes each tile once for all of them, meshes its
516
+ buildings, keeps their indices to 16 bits when the vertices allow, lays out the walls' contact-band
517
+ segments and transfers the finished arrays. The renderer uploads them to the GPU and keeps no copy;
518
+ a style reloaded in full keeps the uploaded buffers. No worker URL or extra asset hosting is needed.
519
+ A Content Security Policy must allow `worker-src blob:` to use this path; if workers are
520
+ unavailable or blocked, the layers build in the page instead. The worker is terminated when the
521
+ last of those layers is disposed. Tiles the camera has left are not downloaded or built. Pending tile updates retain
458
522
  the previous mesh until their replacement is ready; cancelled and obsolete results are discarded.
459
523
 
460
524
  Mercator rendering batches buildings spatially and skips batches outside the camera. Shadow
@@ -471,11 +535,15 @@ Mercator texel grid stays stable during small pans, including changes of latitud
471
535
  the meshes' physical metre scale. One filtered depth comparison keeps edges sharp.
472
536
  Missing camera capabilities, terrain or a view near the horizon use the full loaded area instead.
473
537
  The depth pass runs again when its focused area, light or casting geometry changes and is reused
474
- when they stay unchanged.
538
+ when they stay unchanged. While the camera moves, the focused area takes a quarter of its span as a
539
+ margin on each side and is kept while it still covers the view at a similar resolution, so the
540
+ depth pass is not drawn on every frame; once the camera stops, it is fitted to the view again.
475
541
 
476
542
  Model ambient visibility and lighting roles retain the existing 16-byte vertex stride. They add
477
543
  no geometry pass or texture. Architectural ground lighting uses a separate one-byte-per-pixel
478
544
  mask and one geometry/composite pair of passes while active; its mask is released when inactive.
545
+ The contact band and the architectural light draw their masks in the layer's prerender, before
546
+ the map's main pass, so the map's framebuffer is never switched while its layers draw.
479
547
  At 1280 × 720 and DPR 1, the mask occupies 921,600 bytes, excluding driver overhead.
480
548
 
481
549
  ## Limits
@@ -160,17 +160,26 @@ texture's marks remain approximately constant in screen pixels across classes, r
160
160
 
161
161
  `classes.pedestrian` styles line-like pedestrian ways. Polygon pedestrian plazas are a distinct
162
162
  geometry and use `areas.pedestrian`, including optional fill opacity, outline color, or sprite
163
- pattern. This prevents plazas from degrading into a thin polygon outline.
163
+ pattern. This prevents plazas from degrading into a thin polygon outline. With a
164
+ `transportationOutline` binding, as in Tileflow World, area outlines stroke only the outer boundary
165
+ of each area, never its holes.
164
166
 
165
167
  Road treatments refine a class without creating another class or exposing source fields.
166
168
  `construction`, `expressway`, `indoor`, `official`, `ramp`, and `unpaved` live under `modifiers`;
167
169
  general, bicycle, foot, horse, and toll restrictions live under `restrictions`; `alley`,
168
170
  `crossover`, `driveway`, `parkingAisle`, and `yard` live under `serviceTypes`; and exact
169
- mountain-bike difficulty values live under `mountainBike`. Treatments reuse
171
+ mountain-bike difficulty values, which apply to paths and tracks, live under `mountainBike`. Treatments reuse
170
172
  surface/tunnel/bridge and casing/fill/shadow paint controls, plus a relative `widthScale`. The
171
173
  compiler emits feature-driven paint expressions inside the existing stable class layers rather
172
174
  than multiplying every possible combination.
173
175
 
176
+ A solid dash, `[1, 0]`, is emitted as no `line-dasharray` at all, so MapLibre draws the line with
177
+ its solid-line shader rather than its dash shader. A treatment's dash that depends on the road
178
+ class is settled for each class layer: a dash for construction paths leaves a motorway's layers
179
+ solid. Roundabout rings state their road widths at each zoom as numbers where the widths allow,
180
+ and name the feature conditions they repeat once with `let`, which keeps their style compact and
181
+ quick to validate.
182
+
174
183
  Road names, shields, and motorway junctions remain label concerns:
175
184
 
176
185
  ```ts
@@ -180,8 +180,8 @@ layer is a protection tint, while urban parks and gardens come from
180
180
  `landcover.class=grass/subclass=park|garden`. The ambiguous legacy `park` class is therefore not
181
181
  a public land-cover target.
182
182
 
183
- Tileflow World V1 makes `bathymetry`, `globallandcover`, `circular_feature`, `sidewalk`, and
184
- `street_furniture` mandatory. Use `tileflowWorldV1Schema()` for that product instead of making raw
183
+ Tileflow World V1 makes `bathymetry`, `globallandcover`, `circular_feature`, `sidewalk`,
184
+ `street_furniture`, and `transportation_outline` mandatory. Use `tileflowWorldV1Schema()` for that product instead of making raw
185
185
  layer names part of a style. Publication tooling calls `validateTileflowWorldV1Tilejson(...)` and
186
186
  fails closed unless each layer occurs exactly once, declares its contracted native zooms, and
187
187
  advertises the typed fields consumed by the maps. This includes bathymetry z0–z9, global land cover
@@ -464,7 +464,10 @@ add `tileflow:sources` plus `tileflow:sourceRequirements` for independent produc
464
464
  Detailed city datasets can bind `sidewalk`, `streetFurniture`, and `circularFeature` source layers
465
465
  through `openMapTiles({layers, fields})`. When present, `roads.sidewalks` owns source-backed
466
466
  pedestrian polygons, `roads.crossings` owns oriented crossing icons, and `roads.roundabouts` owns
467
- metric circular road rings. These bindings are optional: a generic OpenMapTiles source remains
467
+ metric circular road rings. A `transportationOutline` binding names lines that trace the outer
468
+ boundary of each road area; when bound, `roads.areas` outlines stroke those lines instead of the
469
+ area polygons, so the holes of a plaza (tree pits, planting beds) are not stroked. These bindings
470
+ are optional: a generic OpenMapTiles source remains
468
471
  valid and the compiler omits unsupported detail instead of inventing geometry. Crossing icons are
469
472
  explicit because the data contract cannot assume a sprite name. They require positive physical
470
473
  `markings` evidence and reject `crossing=no`; both fields are semantic bindings, so custom schemas
@@ -86,6 +86,10 @@ import {
86
86
  } from '@tileflow/core/browser';
87
87
  ```
88
88
 
89
+ `@tileflow/core/3d` holds only `createTileflowMap3D` and the 3D renderers it mounts, so an
90
+ application can load them with a dynamic import when a style declares a 3D scene; see
91
+ [3D buildings](buildings-3d.md#the-maps-3d-scene). The browser entry exports the same function.
92
+
89
93
  `attachTileflowNotices(map)` renders the notices a compiled style declares, such as Nautical's
90
94
  "Not for navigation", as a compact map control; see
91
95
  [Nautical marks](nautical-marks.md). The browser entry is not re-exported from the root. It is SSR-safe to import, has no MapLibre
@@ -9,6 +9,9 @@ the lights switch on one by one; they go out as day comes.
9
9
  Street lights are off by default in the SDK and in Streets. A compiled map must explicitly set
10
10
  `roads.streetLights.enabled: true` before the renderer or preview will show lamp glows.
11
11
 
12
+ React, Vue and Svelte maps light a map that enables street lights automatically, as part of its
13
+ [3D scene](buildings-3d.md#the-maps-3d-scene); the 2D view has no street lights.
14
+
12
15
  It is a custom WebGL2 layer for MapLibre GL JS, drawn above the map's buildings and below its
13
16
  labels. When `createTileflowBuildings3D` raises the buildings, they hide the lamps behind them. It
14
17
  needs WebGL2 and the Mercator projection, and shines from zoom 14 by default.
@@ -114,7 +117,8 @@ by default, at most 64) bound where and how far the lights shine, `beforeId` pla
114
117
  another one, and `transformRequest` applies the map's request rules to the tiles it reads.
115
118
 
116
119
  Layers that read the same source share each tile's download, so the street lights and the 3D
117
- buildings fetch a tile once between them.
120
+ buildings fetch a tile once between them. The lamps are placed in the worker the page's 3D layers
121
+ share, which decodes each tile once for all of them.
118
122
 
119
123
  ## Limits
120
124
 
package/docs/trees-3d.md CHANGED
@@ -20,7 +20,8 @@ for its models unless an extension explicitly chooses `flat` or `auto`.
20
20
  ## Visibility and representation
21
21
 
22
22
  Use `createTileflowVegetation` for application controls. React, Vue and Svelte mount it automatically
23
- in interactive maps. The map chooses `vegetation.mode` independently of visibility:
23
+ in interactive maps, as part of the map's [3D scene](buildings-3d.md#the-maps-3d-scene). The map
24
+ chooses `vegetation.mode` independently of visibility:
24
25
 
25
26
  | Mode | 2D view | 3D view |
26
27
  | -------------- | ------------------- | ------------------- |
@@ -28,7 +29,8 @@ in interactive maps. The map chooses `vegetation.mode` independently of visibili
28
29
  | `flat` | Flat crowns/circles | Flat crowns/circles |
29
30
  | `auto` | Flat crowns/circles | Model trees |
30
31
 
31
- `viewMode` is explicit application state (`2d` by default), not a pitch threshold. Tilting the camera
32
+ `viewMode` is explicit application state, not a pitch threshold: `2d` by default for
33
+ `createTileflowVegetation`, and `3d` by default in the framework components and `createTileflowMap3D`. Tilting the camera
32
34
  does not change representation. Visibility defaults to `vegetation.visible ?? true`; OFF hides every
33
35
  representation. Turning trees off releases model buffers and tile readers. Controls apply immediately,
34
36
  without a grow/sink animation, and do not change building appearance or lighting.
@@ -70,7 +72,7 @@ export default defineMap({
70
72
  Use `refine({visible: false})` for initially hidden vegetation that can be enabled at runtime.
71
73
  Use `vegetation: disable()` to remove the module entirely; a runtime toggle cannot restore a module
72
74
  that is absent from the compiled map. Browser framework components accept `vegetation={false}` and
73
- `viewMode="3d"` (Vue: `:vegetation="false"`, `view-mode="3d"`). Image mode uses the compiled static
75
+ `viewMode="2d"` (Vue: `:vegetation="false"`, `view-mode="2d"`). Image mode uses the compiled static
74
76
  fallback and does not apply these interactive controls.
75
77
 
76
78
  ## Animate trees with the low-level renderer
@@ -260,7 +262,7 @@ Shadow direction stops lowering at 15° above the horizon; the actual scene ligh
260
262
 
261
263
  ## Options
262
264
 
263
- `minzoom` (15 by default, fading to full coverage at 15.25 like buildings) and `maxTiles` (25 by default, at most 64) bound where and how far trees
265
+ `minzoom` (15 by default, fading to full coverage at 15.25) and `maxTiles` (25 by default, at most 64) bound where and how far trees
264
266
  stand; trees thin out and fade with distance from the map's centre, and near trees take more detail
265
267
  than far ones. `canopySource` names a vector source with canopy points when they are not in the
266
268
  map's World source. `beforeId` places the layer before another one; `transformRequest` applies the
@@ -270,9 +272,12 @@ tile's download.
270
272
  ## Cost
271
273
 
272
274
  A near tree has 60 to 120 triangles and a far one about 20, and each form is one instanced draw per
273
- tile. The shared shadow map concentrates resolution on the view when its public camera methods
275
+ tile. Trees are placed in the worker the page's 3D layers share, which decodes each tile once for
276
+ all of them, nearest tiles first. The shared shadow map concentrates resolution on the view when its public camera methods
274
277
  provide a safe planar fit. It is drawn again when that focused area, the light, visible tree
275
- selection, fading or geometry changes. Unchanged views reuse it. Over the Champ de Mars in Paris,
278
+ selection, fading or geometry changes. Unchanged views reuse it. While the camera moves, the trees'
279
+ shadows follow their selection and fading in steps of a sixteenth of a tile, and exactly again once
280
+ it stops. Over the Champ de Mars in Paris,
276
281
  where OpenStreetMap maps every tree, about 13,000 trees stand in a pitched view at zoom 16.6.
277
282
 
278
283
  ## Limits
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/core",
3
- "version": "0.1.0-alpha.37",
3
+ "version": "0.1.0-alpha.38",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Typed Tileflow config and MapLibre style compiler.",
6
6
  "type": "module",
@@ -35,6 +35,11 @@
35
35
  "import": "./dist/index.js",
36
36
  "default": "./dist/index.js"
37
37
  },
38
+ "./3d": {
39
+ "types": "./dist/3d.d.ts",
40
+ "import": "./dist/3d.js",
41
+ "default": "./dist/3d.js"
42
+ },
38
43
  "./browser": {
39
44
  "types": "./dist/browser.d.ts",
40
45
  "import": "./dist/browser.js",
@@ -1 +0,0 @@
1
- "use strict";(()=>{var Re=new Set,De=!1;function Ue(e,n,t=2){let s=n&&n.length,o=s?n[0]*t:e.length;Re.size&&Re.clear();let r=bn(e,0,o,t,!0),u=[];if(!r||r.next===r.prev)return u;let i=0,l=0,c=0;if(s&&(r=Pn(e,n,r,t)),e.length>80*t){i=e[0],l=e[1];let a=i,f=l;for(let h=t;h<o;h+=t){let m=e[h],b=e[h+1];m<i&&(i=m),b<l&&(l=b),m>a&&(a=m),b>f&&(f=b)}c=Math.max(a-i,f-l),c=c!==0?32767/c:0}return We(r,u,i,l,c),u}function bn(e,n,t,s,o){let r=null;if(o===Xn(e,n,t,s)>0)for(let u=n;u<t;u+=s)r=mn(u/s|0,e[u],e[u+1],r);else for(let u=t-s;u>=n;u-=s)r=mn(u/s|0,e[u],e[u+1],r);return r&&Ae(r,r.next)&&(Te(r),r=r.next),r}function ae(e,n=e){let t=n===e,s=e,o;do o=!1,s!==s.next&&(Re.size===0||!Re.has(s))&&(Ae(s,s.next)||P(s.prev,s,s.next)===0)?((t||s===n)&&(n=s.prev),De=!0,Te(s),s=s.prev,o=!0):(t||s!==n)&&(s=s.next,o=!t);while(o||s!==n);return n}function We(e,n,t,s,o){o&&jn(e,t,s,o);let r=e,u=!1;for(;e.prev!==e.next;){let i=e.prev,l=e.next;if(P(i,e,l)<0&&(o?Bn(e,t,s,o):kn(e))){n.push(i.i,e.i,l.i),Te(e),e=l,r=l;continue}if(e=l,e===r){if(De=!1,e=ae(e),De){r=e;continue}if(!u){e=Fn(e,n),r=e,u=!0;continue}_n(e,n,t,s,o);break}}}function kn(e){let n=e.prev,t=e,s=e.next,o=n.x,r=t.x,u=s.x,i=n.y,l=t.y,c=s.y,a=Math.min(o,r,u),f=Math.min(i,l,c),h=Math.max(o,r,u),m=Math.max(i,l,c),b=s.next;for(;b!==n;){if(b.x>=a&&b.x<=h&&b.y>=f&&b.y<=m&&!(o===b.x&&i===b.y)&&Ne(o,i,r,l,u,c,b.x,b.y)&&P(b.prev,b,b.next)>=0)return!1;b=b.next}return!0}function Bn(e,n,t,s){let o=e.prev,r=e,u=e.next,i=o.x,l=r.x,c=u.x,a=o.y,f=r.y,h=u.y,m=Math.min(i,l,c),b=Math.min(a,f,h),d=Math.max(i,l,c),x=Math.max(a,f,h),U=$e(m,b,n,t,s),k=$e(d,x,n,t,s),M=e.prevZ;for(;M&&M.z>=U;){if(M.x>=m&&M.x<=d&&M.y>=b&&M.y<=x&&M!==u&&!(i===M.x&&a===M.y)&&Ne(i,a,l,f,c,h,M.x,M.y)&&P(M.prev,M,M.next)>=0)return!1;M=M.prevZ}let y=e.nextZ;for(;y&&y.z<=k;){if(y.x>=m&&y.x<=d&&y.y>=b&&y.y<=x&&y!==u&&!(i===y.x&&a===y.y)&&Ne(i,a,l,f,c,h,y.x,y.y)&&P(y.prev,y,y.next)>=0)return!1;y=y.nextZ}return!0}function Fn(e,n){let t=e,s=!1;do{let o=t.prev,r=t.next.next;yn(o,t,t.next,r,!1)&&Ie(o,r)&&Ie(r,o)&&(n.push(o.i,t.i,r.i),Te(t),Te(t.next),t=e=r,s=!0),t=t.next}while(t!==e);return s?ae(t):t}function _n(e,n,t,s,o){let r=e;do{let u=r.next.next;for(;u!==r.prev;){if(r.i!==u.i&&Nn(r,u)){let i=pn(r,u);r=ae(r,r.next),i=ae(i,i.next),We(r,n,t,s,o),We(i,n,t,s,o);return}u=u.next}r=r.next}while(r!==e)}var Ke=!1;function Pn(e,n,t,s){let o=[];for(let r=0,u=n.length;r<u;r++){let i=n[r]*s,l=r<u-1?n[r+1]*s:e.length,c=bn(e,i,l,s,!1);c===c.next&&Re.add(c),o.push(Hn(c))}o.sort(On),zn(e.length/s,n.length),dn(t,t),Ke=!0;for(let r=0;r<o.length;r++)t=Ln(o[r],t);return Ke=!1,ae(t)}function On(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Ln(e,n){let t=Sn(e,n);if(!t)return n;let s=pn(t,e),o=s.next;return dn(t,o.next),ae(s,s.next),ae(t,t.next)}var xn=16,_=new Float64Array(0),He=0,Je=[],Qe=[];function zn(e,n){let t=Math.ceil((e+2*n)/xn)+n+2;_.length<t*4&&(_=new Float64Array(t*4)),He=0}function dn(e,n){let t=e;do{let s=He++;Je[s]=t;let o=t.x,r=t.y,u=t.x,i=t.y,l=0;do{let a=t.next;t.z=s,a.x<o&&(o=a.x),a.x>u&&(u=a.x),a.y<r&&(r=a.y),a.y>i&&(i=a.y),t=a}while(++l<xn&&t!==n);Qe[s]=t;let c=s*4;_[c]=o,_[c+1]=r,_[c+2]=u,_[c+3]=i}while(t!==n)}function Cn(e,n){let t=e.z*4;n.x<_[t]&&(_[t]=n.x),n.y<_[t+1]&&(_[t+1]=n.y),n.x>_[t+2]&&(_[t+2]=n.x),n.y>_[t+3]&&(_[t+3]=n.y)}function fn(e){let n=Qe[e];for(;n.prev.next!==n;)n=n.next;return Qe[e]=n,n}function hn(e){let n=Je[e];for(;n.prev.next!==n;)n=n.next;return Je[e]=n,n}function Sn(e,n){let t=n,s=e.x,o=e.y,r=-1/0,u;if(Ae(e,t))return t;for(let h=0,m=0;h<He;h++,m+=4){if(o<_[m+1]||o>_[m+3]||_[m]>s||_[m+2]<=r)continue;let b=fn(h);t=hn(h);do{if(t.prev.next===t){if(Ae(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let d=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(d<=s&&d>r&&(r=d,u=t.x<t.next.x?t:t.next,d===s))return u}}t=t.next}while(t!==b)}if(!u)return null;let i=u.x,l=u.y,c=Math.min(o,l),a=Math.max(o,l),f=1/0;for(let h=0,m=0;h<He;h++,m+=4){if(_[m+2]<i||_[m]>s||_[m+3]<c||_[m+1]>a)continue;let b=fn(h);t=hn(h);do{if(t.prev.next===t&&s>=t.x&&t.x>=i&&s!==t.x&&Ne(o<l?s:r,o,i,l,o<l?r:s,o,t.x,t.y)){let d=Math.abs(o-t.y)/(s-t.x);(Ie(t,e)||t.y===o&&t.next.y===o&&t.next.x>s)&&(d<f||d===f&&(t.x>u.x||t.x===u.x&&Zn(u,t)))&&(u=t,f=d)}t=t.next}while(t!==b)}return u}function Zn(e,n){return P(e.prev,e,n.prev)<0&&P(n.next,e,e.next)<0}var J=[],de=[],ce=new Uint32Array(0),we=new Uint32Array(0),ve=new Uint32Array(256);function jn(e,n,t,s){let o=e,r=0;do o.z=$e(o.x,o.y,n,t,s),J[r++]=o,o=o.next;while(o!==e);En(r);let u=null;for(let i=0;i<r;i++){let l=J[i];l.prevZ=u,u&&(u.nextZ=l),u=l}u.nextZ=null,J.fill(null,0,r),de.fill(null,0,r)}function En(e){if(e<=32){for(let n=1;n<e;n++){let t=J[n],s=t.z,o=n-1;for(;o>=0&&J[o].z>s;)J[o+1]=J[o],o--;J[o+1]=t}return}ce.length<e&&(ce=new Uint32Array(e),we=new Uint32Array(e),de=new Array(e));for(let n=0;n<e;n++)ce[n]=J[n].z;je(e,J,ce,de,we,0),je(e,de,we,J,ce,8),je(e,J,ce,de,we,16),je(e,de,we,J,ce,24)}function je(e,n,t,s,o,r){ve.fill(0);for(let i=0;i<e;i++)ve[t[i]>>>r&255]++;let u=0;for(let i=0;i<256;i++){let l=ve[i];ve[i]=u,u+=l}for(let i=0;i<e;i++){let l=t[i],c=ve[l>>>r&255]++;s[c]=n[i],o[c]=l}}function $e(e,n,t,s,o){return e=(e-t)*o|0,n=(n-s)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function Hn(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ne(e,n,t,s,o,r,u,i){return(o-u)*(n-i)>=(e-u)*(r-i)&&(e-u)*(s-i)>=(t-u)*(n-i)&&(t-u)*(r-i)>=(o-u)*(s-i)}function Nn(e,n){let t=Ae(e,n)&&P(e.prev,e,e.next)>0&&P(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ie(e,n)&&Ie(n,e)&&(P(e.prev,e,n.prev)!==0||P(e,n.prev,n)!==0))&&!Vn(e,n)&&(t||Yn(e,n))}function P(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Ae(e,n){return e.x===n.x&&e.y===n.y}function yn(e,n,t,s,o=!0){let r=P(e,n,t),u=P(e,n,s),i=P(t,s,e),l=P(t,s,n);return(r>0&&u<0||r<0&&u>0)&&(i>0&&l<0||i<0&&l>0)?!0:o?!!(r===0&&Ee(e,t,n)||u===0&&Ee(e,s,n)||i===0&&Ee(t,e,s)||l===0&&Ee(t,n,s)):!1}function Ee(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Vn(e,n){let t=Math.min(e.x,n.x),s=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),u=e;do{let i=u.next;if(u.x>s&&i.x>s||u.x<t&&i.x<t||u.y>r&&i.y>r||u.y<o&&i.y<o){u=i;continue}if(u.i!==e.i&&i.i!==e.i&&u.i!==n.i&&i.i!==n.i&&yn(u,i,e,n))return!0;u=i}while(u!==e);return!1}function Ie(e,n){return P(e.prev,e,e.next)<0?P(e,n,e.next)>=0&&P(e,e.prev,n)>=0:P(e,n,e.prev)<0||P(e,e.next,n)<0}function Yn(e,n){let t=e,s=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let u=t.next;t.y>r!=u.y>r&&o<(u.x-t.x)*(r-t.y)/(u.y-t.y)+t.x&&(s=!s),t=u}while(t!==e);return s}function pn(e,n){let t=qe(e.i,e.x,e.y),s=qe(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,s.next=t,t.prev=s,r.next=s,s.prev=r,s}function mn(e,n,t,s){let o=qe(e,n,t);return s?(o.next=s.next,o.prev=s,s.next.prev=o,s.next=o):(o.prev=o,o.next=o),o}function Te(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),Ke&&Cn(e.prev,e.next)}function qe(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Xn(e,n,t,s){let o=0;for(let r=n,u=t-s;r<t;r+=s)o+=(e[u]-e[r])*(e[r+1]+e[u+1]),u=r;return o}var Gn=.7,Dn=Math.tan(Math.PI/6),Wn=Math.tan(35*Math.PI/180),Kn=Math.tan(Math.PI/18),ke=.65,Be=.4;function vn(e,n,t,s,o,r,u){let i=String(t.roof_shape??"");if(!i||i==="flat"||i==="sawtooth"||et(e,u))return;let l=$n(e);if(!l||Math.abs(en(e))<Gn*4*l.halfU*l.halfV)return;let c=l.u,a=l.v,f=l.halfU*r,h=l.halfV*r;f<h&&([c,a,f,h]=[a,c,h,f]);let m=wn(t.roof_direction),b=m===void 0?void 0:[Math.sin(m*Math.PI/180),-Math.cos(m*Math.PI/180)];(b!==void 0?Math.abs(b[0]*c[0]+b[1]*c[1])>Math.abs(b[0]*a[0]+b[1]*a[1]):t.roof_orientation==="across")&&i!=="skillion"&&([c,a,f,h]=[a,c,h,f]);let x=Qn(i,f,h,b&&[Mn(b,c),Mn(b,a)]);if(!x)return;let U=Math.max(0,o-s),k=wn(t.roof_height),M,y;if(k!==void 0&&k>0)y=o,M=Math.max(s+Math.min(2,U/2),o-k);else{let p=Math.min(Jn(i,h),U*.6,30);t.height_source==="height"?(y=o,M=o-p):(M=o,y=o+p)}let I=y-M;if(!(I>=.3))return;let[R,V]=l.centre,B=(p,A)=>{let w=(p-R)*r,g=(A-V)*r;return[w*c[0]+g*c[1],w*a[0]+g*a[1]]},j=(p,A)=>[R+(p*c[0]+A*a[0])/r,V+(p*c[1]+A*a[1])/r],Q=(p,A)=>{let w=1/0;for(let[g,N,E]of x)w=Math.min(w,g*p+N*A+E);return Math.max(0,w)},$=(p,A)=>M+I*Q(...B(p,A)),L=[];for(let p=0;p+1<n.length;p+=2)L.push(...B(n[p],n[p+1]));en(L)<0&&nt(L);let z=1.01,q=[-f*z,-h*z,f*z,-h*z,f*z,h*z,-f*z,h*z],Y=[];for(let[p,A]of x.entries()){let w=q;for(let[F,H]of x.entries()){if(F===p)continue;let C=A[0]-H[0],X=A[1]-H[1],ne=A[2]-H[2];if(Math.abs(C)+Math.abs(X)+Math.abs(ne)<1e-9){F<p&&(w=[]);continue}if(w=gn(w,C,X,ne),w.length<6)break}if(w.length<6)continue;let g=L,N=w.length/2;for(let F=0;F<N&&g.length>=6;F+=1){let[H,C]=[w[F*2],w[F*2+1]],[X,ne]=[w[(F+1)%N*2],w[(F+1)%N*2+1]];g=gn(g,ne-C,H-X,-(ne-C)*H-(H-X)*C)}if(g.length<6||Math.abs(en(g))<1e-6)continue;let E=[];for(let F=0;F<g.length;F+=2)E.push(...j(g[F],g[F+1]));let se=Ue(E);if(se.length===0)continue;let ee=I*A[0],oe=I*A[1],T=ee*c[0]+oe*a[0],v=ee*c[1]+oe*a[1],O=Math.hypot(T,v,1);Y.push({ring:E,triangles:se,normal:[-T/O,-v/O]})}if(Y.length!==0)return{eaves:M,ridge:y,faces:Y,heightAt:$,breaks(p,A,w,g){let[N,E]=B(p,A),[se,ee]=B(w,g),oe=[];for(let T=0;T<x.length;T+=1)for(let v=T+1;v<x.length;v+=1){let O=(he,S)=>(x[T][0]-x[v][0])*he+(x[T][1]-x[v][1])*S+(x[T][2]-x[v][2]),F=O(N,E),H=O(se,ee);if(F===H||F*H>0)continue;let C=F/(F-H);if(C<=1e-4||C>=1-1e-4)continue;let X=N+(se-N)*C,ne=E+(ee-E)*C;x[T][0]*X+x[T][1]*ne+x[T][2]<=Q(X,ne)+1e-6&&oe.push(C)}return[...new Set(oe.map(T=>Math.round(T*1e6)/1e6))].sort((T,v)=>T-v)}}}function Jn(e,n){switch(e){case"skillion":return 2*n*Kn;case"pyramidal":return n*Wn;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Dn}}function Qn(e,n,t,s){let o=n,r=t,u=[[0,-1/r,1],[0,1/r,1]],i=c=>c.flatMap(a=>[1,-1].flatMap(f=>{let h=a==="v"?r:o,m=ke/(Be*r)*f,b=(1-ke)/((1-Be)*r)*f,d=x=>a==="v"?[0,-x]:[-x,0];return[[...d(m),ke/(Be*r)*h],[...d(b),ke+(1-ke)/((1-Be)*r)*(h-Be*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return u;case"saltbox":{let c=r/3;return[[0,-1/(r-c),1+c/(r-c)],[0,1/(r+c),1-c/(r+c)]]}case"hipped":return[...u,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...u,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...u,[-1/o,0,1],[1/o,0,1]];case"gambrel":return i(["v"]);case"mansard":return i(["v","u"]);case"skillion":{let[c,a]=s??[0,1],f=Math.abs(c)*o+Math.abs(a)*r;return f>0?[[-c/(2*f),-a/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(c=>{let a=Math.sqrt(1-c*c);return[1,-1].map(f=>[0,-f*c/(r*a),1/a])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(c=>{let a=Math.sqrt(1-c*c);return Array.from({length:12},(f,h)=>{let m=h*Math.PI/6;return[-c*Math.cos(m)/(o*a),-c*Math.sin(m)/(r*a),1/a]})})];default:return}}function gn(e,n,t,s){let o=e.length/2,r=[];for(let u=0;u<o;u+=1){let i=e[u*2],l=e[u*2+1],c=e[(u+1)%o*2],a=e[(u+1)%o*2+1],f=n*i+t*l+s,h=n*c+t*a+s;if(f<=0&&r.push(i,l),f<0&&h>0||f>0&&h<0){let m=f/(f-h);r.push(i+(c-i)*m,l+(a-l)*m)}}return r}function $n(e){let n=qn(e);if(n.length<3)return;let t,s=1/0;for(let o=0;o<n.length;o+=1){let[r,u]=n[o],[i,l]=n[(o+1)%n.length],c=Math.hypot(i-r,l-u);if(c===0)continue;let a=[(i-r)/c,(l-u)/c],f=[-a[1],a[0]],[h,m,b,d]=[1/0,-1/0,1/0,-1/0];for(let[U,k]of n){let M=U*a[0]+k*a[1],y=U*f[0]+k*f[1];h=Math.min(h,M),m=Math.max(m,M),b=Math.min(b,y),d=Math.max(d,y)}let x=(m-h)*(d-b);if(x<s){s=x;let U=(h+m)/2,k=(b+d)/2;t={centre:[U*a[0]+k*f[0],U*a[1]+k*f[1]],u:a,v:f,halfU:(m-h)/2,halfV:(d-b)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function qn(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,u)=>r[0]-u[0]||r[1]-u[1]);let t=(r,u,i)=>(u[0]-r[0])*(i[1]-r[1])-(u[1]-r[1])*(i[0]-r[0]),s=[];for(let r of n){for(;s.length>=2&&t(s.at(-2),s.at(-1),r)<=0;)s.pop();s.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...s.slice(0,-1),...o.slice(0,-1)]}function et(e,n){let[t,s,o,r]=[1/0,-1/0,1/0,-1/0];for(let i=0;i+1<e.length;i+=2)t=Math.min(t,e[i]),s=Math.max(s,e[i]),o=Math.min(o,e[i+1]),r=Math.max(r,e[i+1]);let u=e.length/2;for(let i=0;i<u;i+=1){let l=e[i*2],c=e[i*2+1],a=e[(i+1)%u*2],f=e[(i+1)%u*2+1];if(t<0&&l===t&&a===t||s>n&&l===s&&a===s||o<0&&c===o&&f===o||r>n&&c===r&&f===r)return!0}return!1}function en(e){let n=0,t=e.length/2;for(let s=0;s<t;s+=1){let o=(s+1)%t;n+=e[s*2]*e[o*2+1]-e[o*2]*e[s*2+1]}return n/2}function nt(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function Mn(e,n){return e[0]*n[0]+e[1]*n[1]}function wn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var Mt=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),wt=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),vt=Object.freeze([1,1,4,1,3]),Rt=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});function nn(e,n,t){for(let s of e){let o=!1;for(let r=0,u=s.length-2;r<s.length;u=r,r+=2){let i=s[r],l=s[r+1],c=s[u],a=s[u+1];l>t!=a>t&&n<(c-i)*(t-l)/(a-l)+i&&(o=!o)}if(o)return!0}return!1}function In(e,n,t){for(let s of n){let[o,r,u,i]=An(s);for(let l of e){let[c,a,f,h]=An(l);if(!(c>u-t||f<o+t||a>i-t||h<r+t)&&(Rn(l,s,t)||Rn(s,l,t)))return!0}}return!1}function Rn(e,n,t){let s=(o,r)=>nn([n],o,r)&&ot(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(s(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[u,i,l,c]=[e[r],e[r+1],e[o],e[o+1]],a=[0,1];for(let f=0,h=n.length-2;f<n.length;h=f,f+=2){let m=tt(u,i,l,c,n[h],n[h+1],n[f],n[f+1]);m!==void 0&&a.push(m)}if(a.length!==2){a.sort((f,h)=>f-h);for(let f=1;f<a.length;f+=1){let h=(a[f-1]+a[f])/2;if(s(u+(l-u)*h,i+(c-i)*h))return!0}}}return!1}function tt(e,n,t,s,o,r,u,i){let l=t-e,c=s-n,a=u-o,f=i-r,h=l*f-c*a;if(h===0)return;let m=((o-e)*f-(r-n)*a)/h,b=((o-e)*c-(r-n)*l)/h;return m>0&&m<1&&b>=0&&b<=1?m:void 0}function ot(e,n,t){let s=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[u,i,l,c]=[e[r],e[r+1],e[o],e[o+1]],a=(l-u)**2+(c-i)**2,f=a>0?Math.max(0,Math.min(1,((n-u)*(l-u)+(t-i)*(c-i))/a)):0;s=Math.min(s,Math.hypot(n-(u+(l-u)*f),t-(i+(c-i)*f)))}return s}function An(e){let[n,t,s,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),s=Math.max(s,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,s,o]}var te=8192,tn=28,rt={commercial:1,active:2,destination:3},st={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},it={dining:1,entertainment:2,nightlife:3},on={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},ut=6,lt=.5,ct=.5;function Un(e,n){let t=te/e.extent,s=n.tileMetres/te,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1,n.edgeRadius))/s:0,u=new sn,i=new Ve,l=new Ve,c=[],a=[],f=0,h=mt(e,n);for(let[y,I]of e.features.entries()){if(I.type!=="Polygon"||c.length>=65535)continue;let R=I.properties,V=R.hide_3d;if(V===!0||V===1||V==="1"||V==="true")continue;let B=Math.min(6e3,Tn(R.render_height)??o),j=Math.min(B,Tn(R.render_min_height)??0),Q=rt[String(R.building_tone??"")]??0,$=st[String(R.class??"")]??0,L=h.get(y)??0,z=c.length,q=!1;for(let Y of bt(I.geometry,t)){let p=Y.map(dt).filter(v=>v.length>=6);if(p.length===0||Ye(p[0])===0)continue;let[A,w]=xt(p[0]);if(n.masks?.length&&(nn(n.masks,A,w)||In(p,n.masks,ct/s)))continue;let g={cell:Math.min(7,Math.max(0,Math.floor(w/1024)))*8+Math.min(7,Math.max(0,Math.floor(A/1024))),bounds:[1/0,1/0,-1/0,-1/0,B+.1],roofsFrom:i.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let v of p)for(let O=0;O<v.length;O+=2)g.bounds[0]=Math.min(g.bounds[0],v[O]-1),g.bounds[1]=Math.min(g.bounds[1],v[O+1]-1),g.bounds[2]=Math.max(g.bounds[2],v[O]+1),g.bounds[3]=Math.max(g.bounds[3],v[O+1]+1);q=!0,f=Math.max(f,B);let N=Number.isSafeInteger(I.id),E=rn(N?I.id*.0731:A*.0731+w*.19137+z*1.618),se=!N&&p[0].some(v=>v<=0||v>=te)?rn(B*7.31+j*3.17+Q):E,ee={base:j,top:B,jitter:se,seed:E,tone:Q,group:$,use:L,cx:A,cy:w,index:z},oe=p.map((v,O)=>ht(v,O,r,n.cornerAngle));p=oe.map(({ring:v})=>v);let T=Y.length===1&&p.length===1?vn(Y[0],p[0],R,j,B,s,te):void 0;T?(f=Math.max(f,T.ridge),g.bounds[4]=Math.max(g.bounds[4],T.ridge+.1),ft(T,ee,u,i)):at(p,ee,u,i);for(let[v,O]of p.entries()){let F=Ye(O)>0,H=v===0?F?-1:1:F?1:-1,C=O.length/2,X=S=>{let Z=(S%C+C)%C;return[O[Z*2],O[Z*2+1]]},ne=S=>{let[Z,W]=X(S-1),[G,D]=X(S),[ie,me]=X(S+1);if(fe(Z,W,G,D)||fe(G,D,ie,me))return!1;let be=Math.hypot(G-Z,D-W),ue=Math.hypot(ie-G,me-D);if(!be||!ue)return!1;let Fe=-(D-W)/be*H,_e=(G-Z)/be*H;return(Fe*(ie-G)+_e*(me-D))/ue>lt},Xe=(S,Z)=>T?T.heightAt(S,Z):B,he=0;for(let S=0;S<C;S+=1){let[Z,W]=X(S),[G,D]=X(S+1),ie=Math.hypot(G-Z,D-W);if(ie===0||fe(Z,W,G,D))continue;let me=-(D-W)/ie*H,be=(G-Z)/ie*H,ue=oe[v].normals[S]??[me,be],Fe=oe[v].normals[(S+1)%C]??[me,be],_e=K=>{let pe=ue[0]+(Fe[0]-ue[0])*K,ge=ue[1]+(Fe[1]-ue[1])*K,le=Math.hypot(pe,ge)||1;return[pe/le,ge/le]},re=[0,...T?T.breaks(Z,W,G,D):[],1];for(let K=0;K+1<re.length;K+=1){let pe=K===0,ge=K+2===re.length,le=Z+(G-Z)*re[K],Pe=W+(D-W)*re[K],Oe=Z+(G-Z)*re[K+1],Le=W+(D-W)*re[K+1],Me=Math.hypot(Oe-le,Le-Pe)/te*n.tileMetres,ze=(pe&&ne(S)?1:0)|(ge&&ne(S+1)?2:0)|(v>0?4:0),Ce=(pe&&un(Z,W)?1:0)|(ge&&un(G,D)?2:0),Ge=he+Me,Se=_e(re[K]),Ze=_e(re[K+1]),cn=Xe(le,Pe),an=Xe(Oe,Le),xe=u.write(ee,le,Pe,0,Se[0],Se[1],1,he,ze,Me,0,Ce,cn);u.write(ee,Oe,Le,0,Ze[0],Ze[1],1,Ge,ze,Me,1,Ce,an),u.write(ee,le,Pe,1,Se[0],Se[1],1,he,ze,Me,0,Ce,cn),u.write(ee,Oe,Le,1,Ze[0],Ze[1],1,Ge,ze,Me,1,Ce,an),l.push(xe,xe+1,xe+2,xe+1,xe+3,xe+2),he=Ge}}}g.roofsCount=i.length-g.roofsFrom,g.wallsCount=l.length-g.wallsFrom,a.push(g)}q&&c.push(R)}if(u.count===0)return;let m=new Uint32Array(i.length+l.length),b=[],d=0,x=i.length,U=i.values(),k=l.values();a.sort((y,I)=>y.cell-I.cell);let M=-1;for(let y of a){y.cell!==M&&(M=y.cell,b.push({bounds:[...y.bounds],roofsFrom:d,roofsCount:0,wallsFrom:x,wallsCount:0}));let I=b.at(-1);for(let R=0;R<5;R+=1)I.bounds[R]=R<2?Math.min(I.bounds[R],y.bounds[R]):Math.max(I.bounds[R],y.bounds[R]);m.set(U.subarray(y.roofsFrom,y.roofsFrom+y.roofsCount),d),m.set(k.subarray(y.wallsFrom,y.wallsFrom+y.wallsCount),x),d+=y.roofsCount,x+=y.wallsCount,I.roofsCount+=y.roofsCount,I.wallsCount+=y.wallsCount}return{groups:b,vertices:u.bytes(),indices:m,wallsFrom:i.length,top:f,features:c}}function at(e,n,t,s){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let u=(l,c)=>{let a=r.findIndex((d,x)=>l>=d&&l<r[x+1]),[f,h]=[r[a],r[a+1]-1];if(c<f||c>h)return!1;let[m,b]=l<c?[l,c]:[c,l];return b-m!==1&&!(m===f&&b===h)?!1:!fe(o[l*2],o[l*2+1],o[c*2],o[c*2+1])},i=Ue(o,r.slice(1,-1),2);for(let l=0;l+2<i.length;l+=3){let c=[i[l],i[l+1],i[l+2]],a=0;for(let f=0;f<3;f+=1)u(c[(f+1)%3],c[(f+2)%3])&&(a|=1<<f);for(let[f,h]of c.entries())s.push(t.write(n,o[h*2],o[h*2+1],1,0,0,0,0,0,0,f,a))}}function ft(e,n,t,s){for(let o of e.faces){let r=o.ring,u=r.length/2,i=(l,c)=>{let[a,f]=l<c?[l,c]:[c,l];return f-a!==1&&!(a===0&&f===u-1)?!1:!fe(r[l*2],r[l*2+1],r[c*2],r[c*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let c=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],a=0;for(let f=0;f<3;f+=1)i(c[(f+1)%3],c[(f+2)%3])&&(a|=1<<f);for(let[f,h]of c.entries()){let m=r[h*2],b=r[h*2+1];s.push(t.write(n,m,b,1,o.normal[0],o.normal[1],0,0,0,0,f,a,e.heightAt(m,b)))}}}}function ht(e,n,t,s=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=Ye(e)>0,u=n===0?r?-1:1:r?1:-1,i=[],l=[],c=(a,f,h)=>{a=ye(a),f=ye(f),!(i.at(-2)===a&&i.at(-1)===f)&&(i.push(a,f),l.push(h))};for(let a=0;a<o;a+=1){let f=(a+o-1)%o,h=(a+1)%o,[m,b]=[e[f*2],e[f*2+1]],[d,x]=[e[a*2],e[a*2+1]],[U,k]=[e[h*2],e[h*2+1]],M=Math.hypot(d-m,x-b),y=Math.hypot(U-d,k-x);if(!M||!y||un(d,x)||fe(m,b,d,x)||fe(d,x,U,k)){c(d,x);continue}let[I,R]=[(d-m)/M,(x-b)/M],[V,B]=[(U-d)/y,(k-x)/y],j=Math.atan2(I*B-R*V,I*V+R*B);if(j*u>=-.08||Math.abs(j)>Math.PI*.85){c(d,x);continue}let Q=Math.tan(Math.abs(j)/2),$=Math.min(t*Q,M*.2,y*.2),L=$/Q;if(L<1){c(d,x);continue}let[z,q]=[-R*u,I*u],[Y,p]=[d-I*$-z*L,x-R*$-q*L],A=Math.atan2(q,z),w=Math.max(s<=Math.PI/6?2:1,Math.ceil(Math.abs(j)/Math.max(Math.PI/6,Math.min(Math.PI/3,s))));for(let g=0;g<=w;g+=1){let N=A+j*g/w,E=[Math.cos(N),Math.sin(N)];c(Y+E[0]*L,p+E[1]*L,E)}}return i[0]===i.at(-2)&&i[1]===i.at(-1)&&(i.splice(-2),l.pop()),i.length>=6?{ring:i,normals:l}:{ring:e,normals:[]}}var sn=class{#e=new ArrayBuffer(4096*tn);#n=new DataView(this.#e);count=0;write(n,t,s,o,r,u,i,l,c,a,f=0,h=0,m=n.top){let b=tn;if((this.count+1)*b>this.#e.byteLength){let U=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(U).set(new Uint8Array(this.#e)),this.#e=U,this.#n=new DataView(U)}let d=this.#n,x=this.count*b;return d.setUint16(x,ye(t),!0),d.setUint16(x+2,ye(s),!0),d.setUint16(x+4,Math.min(65535,Math.round(n.base*10)),!0),d.setUint16(x+6,Math.min(65535,Math.max(0,Math.round(m*10))),!0),d.setInt8(x+8,Math.round(r*127)),d.setInt8(x+9,Math.round(u*127)),d.setUint8(x+10,o),d.setUint8(x+11,i),d.setUint16(x+12,Math.round(l*10)%65536,!0),d.setUint8(x+14,Math.round(n.jitter*255)),d.setUint8(x+15,Math.round(n.seed*255)),d.setUint16(x+16,ye(n.cx),!0),d.setUint16(x+18,ye(n.cy),!0),d.setUint8(x+20,n.tone+4*n.group),d.setUint8(x+21,n.use),d.setUint8(x+22,c),d.setUint8(x+23,Math.min(255,Math.round(a))),d.setUint16(x+24,n.index,!0),d.setUint8(x+26,f),d.setUint8(x+27,h),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*tn))}},Ve=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function mt(e,n){let t=new Map;if(e.features.some(i=>i.properties.night_use!==void 0)){for(let[i,l]of e.features.entries()){let c=it[String(l.properties.night_use??"")];c&&t.set(i,c)}return t}let s=n.places;if(!s||s.features.length===0)return t;let o=ut/n.tileMetres*e.extent,r=[];for(let[i,l]of e.features.entries()){if(l.type!=="Polygon")continue;let c=l.properties.hide_3d;if(c===!0||c===1||c==="1"||c==="true")continue;let a=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let h=0;h+1<f.length;h+=2)a[0]=Math.min(a[0],f[h]),a[1]=Math.min(a[1],f[h+1]),a[2]=Math.max(a[2],f[h]),a[3]=Math.max(a[3],f[h+1]);r.push({index:i,rings:l.geometry,box:a})}let u=e.extent/s.extent;for(let i of s.features){if(i.type!=="Point")continue;let l=i.properties,c=on[String(l.type??"")]??on[String(l.subclass??"")]??on[String(l.class??"")];if(c)for(let a of i.geometry)for(let f=0;f+1<a.length;f+=2){let h=a[f]*u,m=a[f+1]*u,b,d,x=o;for(let k of r){let[M,y,I,R]=k.box;if(h<M-o||h>I+o||m<y-o||m>R+o)continue;let V=!1;for(let B of k.rings)for(let j=0,Q=B.length-2;j+1<B.length;Q=j,j+=2){let $=B[Q],L=B[Q+1],z=B[j],q=B[j+1];q>m!=L>m&&h<($-z)*(m-q)/(L-q)+z&&(V=!V);let Y=z-$,p=q-L,A=Y*Y+p*p,w=A?Math.min(1,Math.max(0,((h-$)*Y+(m-L)*p)/A)):0,g=Math.hypot(h-$-w*Y,m-L-w*p);g<x&&(x=g,d=k.index)}if(V){b=k.index;break}}let U=b??d;U!==void 0&&t.set(U,Math.max(t.get(U)??0,c))}}return t}function ye(e){return Math.min(te,Math.max(0,Math.round(e)))}function Tn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function bt(e,n){let t=[],s;for(let o of e){let r=[];for(let i=0;i+1<o.length;i+=2){let l=o[i]*n,c=o[i+1]*n;r.length&&l===r.at(-2)&&c===r.at(-1)||r.push(l,c)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let u=Math.sign(Ye(r));u&&(s??=u,u===s||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function Ye(e){let n=0,t=e.length/2;for(let s=0;s<t;s+=1){let o=(s+1)%t;n+=e[s*2]*e[o*2+1]-e[o*2]*e[s*2+1]}return n}function xt(e){let n=0,t=0,s=e.length/2;for(let o=0;o<s;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/s,t/s]}function un(e,n){return e<=0||n<=0||e>=te||n>=te}function fe(e,n,t,s){let o=te;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&s<=0||n>=o&&s>=o}function dt(e){let n=te,t=[...e],s=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,u]of s){let i=[],l=t.length/2;for(let c=0;c<l;c+=1){let a=[t[c*2],t[c*2+1]],f=[t[(c+1)%l*2],t[(c+1)%l*2+1]],h=u(a[o]),m=u(f[o]);if(h&&i.push(a[0],a[1]),h!==m){let b=(r-a[o])/(f[o]-a[o]);i.push(a[0]+(f[0]-a[0])*b,a[1]+(f[1]-a[1])*b)}}if(t=i,t.length<6)return[]}return t}function rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var ln=globalThis;ln.onmessage=({data:e})=>{try{let n=Un(e.layer,e.options);ln.postMessage({mesh:n},n?[n.vertices.buffer,n.indices.buffer]:[])}catch(n){ln.postMessage({error:String(n)})}};})();