@tileflow/core 0.1.0-alpha.46 → 0.1.0-alpha.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -162,8 +162,9 @@ Theme controllers also provide module/label emphasis, eased numeric `expr.global
162
162
  and fixed-size dynamic RGBA images with state refresh and restoration across theme changes.
163
163
  `getRouteInks()` supplies route colours; `createTileflowLineProgress` animates drawing routes.
164
164
  `createTileflowGroundLayers` places them under 3D buildings, optionally showing occluded stretches
165
- faintly. Themes declare `lighting.sun` and `lighting.ambient`; `getSun()` returns the displayed,
166
- blended sun for application 3D layers. `setSun()` accepts a direction or a date and location.
165
+ faintly. Themes declare `lighting.sun` and `lighting.ambient`; `getSun()` returns the displayed
166
+ sun. `setSun()` accepts angles or a date and location. Transitions
167
+ mix 3D directions (angular fallback for opposite vectors) and OKLab light colours.
167
168
 
168
169
  `createTileflowBuildings3D` enables worker-meshed buildings rising at zoom 15–15.3, scene sun,
169
170
  cast/contact shadows and 0.8 m rounded corners; effects are independently overridable. Its
@@ -247,15 +248,16 @@ package uses this contract for its mounted Map; it is not yet published.
247
248
 
248
249
  ## Data, terrain, and browser resources
249
250
 
250
- Tileflow World is the hosted primary source. `vectorTiles()` with `openMapTiles()` supports
251
- external local/self-hosted data; hosted eligibility is separate. `hostedTileset()`, `boundaryAreas`
252
- and semantic overlays add named sources. Local PMTiles inputs are tooling-only.
251
+ Tileflow World is the hosted primary source, with an open (CC0)
252
+ [schema](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/reference/tileflow-world-v1.json);
253
+ detail layers load only when drawn. `vectorTiles()` takes that schema or OpenMapTiles
254
+ (`openMapTiles()`). `hostedTileset()`, `boundaryAreas` and overlays add named sources.
253
255
 
254
256
  `bathymetry({vectorLayers: {...}})` declares contour/name layers. `marine: 'nautical'` adds
255
257
  navigation marks, flashing lights, and a "Not for navigation" notice.
256
258
 
257
- World attribution links to Tileflow's source notice, OpenMapTiles, and OpenStreetMap. External
258
- vector data retains the attribution supplied by its owner.
259
+ World attribution credits Tileflow and OpenStreetMap; other vector data keeps its owner's
260
+ attribution.
259
261
 
260
262
  `projection` accepts `mercator` or `globe`. Terrain supports `none`, `hillshade`, `3d`, and an object
261
263
  form for explicit hillshade and contour configuration. Browser-derived contours require a DEM tile
@@ -395,8 +395,8 @@ declare function resolveTileflowSun(preset: TileflowSunPreset, direction?: Reado
395
395
  altitude: number;
396
396
  }>, source?: TileflowSun['source']): TileflowSun;
397
397
  /**
398
- * A preset `t` of the way from `from` to `to`: the azimuth turns the short way round, colours mix
399
- * in OKLab, as theme blends mix paint colours, and numbers linearly.
398
+ * A preset `t` of the way from `from` to `to`: directions mix as unit vectors, colours mix in
399
+ * OKLab, as theme blends mix paint colours, and strengths linearly.
400
400
  */
401
401
  declare function mixTileflowSunPresets(from: TileflowSunPreset, to: TileflowSunPreset, t: number): TileflowSunPreset;
402
402
  /** Reads the sun a compiled style publishes, or undefined when its metadata has none. */
@@ -877,7 +877,7 @@ type TileflowTreeLayers = Readonly<{
877
877
  /** Decorative canopy points in parks and gardens (World's `canopy`). */
878
878
  canopy?: TileflowTileLayer;
879
879
  /**
880
- * World's `traffic_control`: its hedges, lines and areas of `subclass=hedge`, stand as clipped
880
+ * World's `traffic_control`: its hedges, lines and areas of `type=hedge`, stand as clipped
881
881
  * pieces along each line and round each area. Other barriers are left out.
882
882
  */
883
883
  hedges?: TileflowTileLayer;
package/dist/3d.d.ts CHANGED
@@ -1 +1 @@
1
- export { C as TileflowCameraOptions, u as TileflowMap3D, D as TileflowMap3DMap, t as TileflowMap3DOptions, ab as createTileflowMap3D } from './3d-EHN80Dhw.js';
1
+ export { C as TileflowCameraOptions, u as TileflowMap3D, D as TileflowMap3DMap, t as TileflowMap3DOptions, ab as createTileflowMap3D } from './3d-CyOz9GmH.js';
package/dist/3d.js CHANGED
@@ -668,7 +668,7 @@ function record2(value) {
668
668
  var tileflowBuildingsMetadataKey = "tileflow:buildings";
669
669
  var tileflowDefaultBuildings3DDesign = Object.freeze({
670
670
  source: "tileflow",
671
- layers: Object.freeze({ building: "building", places: "poi" }),
671
+ layers: Object.freeze({ building: "building", places: "poi_label" }),
672
672
  color: "#d8d0c0",
673
673
  edges: 0,
674
674
  edgeRadius: 0.8,
@@ -789,7 +789,7 @@ var tileflowDefaultSunPreset = Object.freeze({
789
789
  var degrees = Math.PI / 180;
790
790
  function normalizeTileflowAzimuth(azimuth) {
791
791
  const turned = azimuth % 360;
792
- return turned < 0 ? turned + 360 : turned === 0 ? 0 : turned;
792
+ return turned < 0 ? (turned + 360) % 360 : turned === 0 ? 0 : turned;
793
793
  }
794
794
  function tileflowSunDirection(azimuth, altitude) {
795
795
  const a = azimuth * degrees;
@@ -1892,12 +1892,17 @@ function meshTileflowBuildings(layer, options) {
1892
1892
  for (const [featureIndex, feature] of layer.features.entries()) {
1893
1893
  if (feature.type !== "Polygon" || features.length >= 65535) continue;
1894
1894
  const properties = feature.properties;
1895
- const hidden = properties.hide_3d;
1896
- if (hidden === true || hidden === 1 || hidden === "1" || hidden === "true") continue;
1897
- const height = Math.min(6e3, positive(properties.render_height) ?? fallback);
1898
- const base = Math.min(height, positive(properties.render_min_height) ?? 0);
1899
- const tone = tones[String(properties.building_tone ?? "")] ?? 0;
1900
- const group = classGroups[String(properties.class ?? "")] ?? 0;
1895
+ if (drawnByParts(properties)) continue;
1896
+ const height = Math.min(
1897
+ 6e3,
1898
+ positive(properties.height) ?? positive(properties.render_height) ?? fallback
1899
+ );
1900
+ const base = Math.min(
1901
+ height,
1902
+ positive(properties.min_height) ?? positive(properties.render_min_height) ?? 0
1903
+ );
1904
+ const tone = tones[String(properties.tone ?? "")] ?? 0;
1905
+ const group = classGroups[String(properties.use ?? properties.class ?? "")] ?? 0;
1901
1906
  const use = uses.get(featureIndex) ?? 0;
1902
1907
  const index = features.length;
1903
1908
  let used = false;
@@ -2323,8 +2328,7 @@ function nightUsesOf(layer, options) {
2323
2328
  const shapes = [];
2324
2329
  for (const [index, feature] of layer.features.entries()) {
2325
2330
  if (feature.type !== "Polygon") continue;
2326
- const hidden = feature.properties.hide_3d;
2327
- if (hidden === true || hidden === 1 || hidden === "1" || hidden === "true") continue;
2331
+ if (drawnByParts(feature.properties)) continue;
2328
2332
  const box = [Infinity, Infinity, -Infinity, -Infinity];
2329
2333
  for (const ring of feature.geometry)
2330
2334
  for (let at = 0; at + 1 < ring.length; at += 2) {
@@ -2339,7 +2343,7 @@ function nightUsesOf(layer, options) {
2339
2343
  for (const place of places.features) {
2340
2344
  if (place.type !== "Point") continue;
2341
2345
  const properties = place.properties;
2342
- const use = placeNightUses[String(properties.type ?? "")] ?? placeNightUses[String(properties.subclass ?? "")] ?? placeNightUses[String(properties.class ?? "")];
2346
+ const use = placeNightUses[String(properties.type ?? "")] ?? placeNightUses[String(properties.class ?? "")];
2343
2347
  if (!use) continue;
2344
2348
  for (const points of place.geometry)
2345
2349
  for (let at = 0; at + 1 < points.length; at += 2) {
@@ -2469,8 +2473,17 @@ function hash(value) {
2469
2473
  const s = Math.sin(value * 12.9898 + 78.233) * 43758.5453;
2470
2474
  return s - Math.floor(s);
2471
2475
  }
2476
+ function drawnByParts(properties) {
2477
+ const hidden = properties.hide_3d;
2478
+ return properties.extrude === false || hidden === true || hidden === 1 || hidden === "1" || hidden === "true";
2479
+ }
2472
2480
 
2473
2481
  // src/scene-3d-shaders.ts
2482
+ var tileflowAmbientLight = `
2483
+ vec3 ambientLight(vec3 sky, vec3 normal) {
2484
+ float up = clamp(normal.z, -1.0, 1.0);
2485
+ return sky * (0.96 + 0.04 * up);
2486
+ }`;
2474
2487
  var tileflowShadowLookup = `
2475
2488
  uniform highp sampler2DShadow u_shadow_map;
2476
2489
  uniform float u_shadow;
@@ -2896,6 +2909,7 @@ uniform float u_edge_width; // their width, in the drawing buffer's pixels
2896
2909
  uniform vec3 u_edge_colour; // the application's colour for them
2897
2910
  uniform float u_edge_own; // how much of them takes the application's colour, from 0 to 1
2898
2911
  ${nightLight}
2912
+ ${tileflowAmbientLight}
2899
2913
  ${tileflowShadowLookup}
2900
2914
  ${tileflowHazeFragment}
2901
2915
  out vec4 fragColor;
@@ -2940,11 +2954,10 @@ vec3 styleColour(vec3 colour, vec3 normal) {
2940
2954
  }
2941
2955
 
2942
2956
  // A surface's light over the light a sunlit roof takes, in the map's colours: a sunlit roof keeps
2943
- // its colour, a wall turned to a low sun glows, and shade takes the sky's colour. A wall sees half
2944
- // the sky; broad daylight fill keeps facades luminous, while night has little bounced light.
2957
+ // its colour, a wall turned to a low sun glows, and shade takes the sky's colour.
2945
2958
  vec3 shade(vec3 normal, float lit) {
2946
2959
  float facing = dot(normal, u_sun_dir);
2947
- vec3 sky = u_sky_light * mix(mix(0.92, 0.5, u_night), 1.0, normal.z);
2960
+ vec3 sky = ambientLight(u_sky_light, normal);
2948
2961
  vec3 light = sky + u_sun_light * max(facing, 0.0) * (1.0 - u_shadow * (1.0 - lit));
2949
2962
  vec3 roof = u_sky_light + u_sun_light * max(u_sun_dir.z, 0.0);
2950
2963
  return min(pow(light / max(roof, vec3(1e-4)), vec3(1.0 / 2.2)), vec3(1.7));
@@ -3300,7 +3313,7 @@ var streets = {
3300
3313
  primary: { spacing: 30, kerb: 10 },
3301
3314
  secondary: { spacing: 32, kerb: 8.5 },
3302
3315
  tertiary: { spacing: 34, kerb: 7 },
3303
- minor: { spacing: 36, kerb: 5.5 },
3316
+ street: { spacing: 36, kerb: 5.5 },
3304
3317
  pedestrian: { spacing: 26, kerb: 3 }
3305
3318
  };
3306
3319
  var litOnly = {
@@ -3351,7 +3364,7 @@ function placeTileflowStreetLights(layers, options) {
3351
3364
  const scale = extent / furniture.extent;
3352
3365
  for (const feature of furniture.features) {
3353
3366
  const properties = feature.properties;
3354
- if (feature.type !== "Point" || properties.subclass !== "street_lamp") continue;
3367
+ if (feature.type !== "Point" || properties.type !== "street_lamp") continue;
3355
3368
  const height = lampHeight(properties);
3356
3369
  const colour = lampColour(properties);
3357
3370
  const count = Math.max(1, Math.min(4, Number(properties.light_count) || 1));
@@ -3432,12 +3445,10 @@ function placeTileflowStreetLights(layers, options) {
3432
3445
  return writer.done(mapped);
3433
3446
  }
3434
3447
  function streetRule(properties, mode) {
3435
- if (properties.brunnel === "tunnel" || properties.covered === true) return void 0;
3448
+ if (properties.structure === "tunnel" || properties.covered === true) return void 0;
3436
3449
  const lit = properties.lit;
3437
3450
  if (lit === false || lit === "no") return void 0;
3438
- const featureClass = String(properties.class ?? "");
3439
- const subclass = String(properties.subclass ?? "");
3440
- const kind = featureClass === "path" && (subclass === "pedestrian" || subclass === "living_street") ? "pedestrian" : featureClass;
3451
+ const kind = String(properties.class ?? "");
3441
3452
  const rule = streets[kind];
3442
3453
  if (rule && (mode === "streets" || isLit(lit))) return rule;
3443
3454
  const litRule = litOnly[kind];
@@ -3549,7 +3560,7 @@ var tileflowDefaultStreetLightsDesign = Object.freeze({
3549
3560
  source: "tileflow",
3550
3561
  layers: Object.freeze({
3551
3562
  streetFurniture: "street_furniture",
3552
- transportation: "transportation",
3563
+ transportation: "road",
3553
3564
  sidewalk: "sidewalk"
3554
3565
  }),
3555
3566
  estimate: "lit",
@@ -3594,7 +3605,8 @@ var tileflowWorldTreeFields = Object.freeze({
3594
3605
  canopyClearance: "clearance_px_z15",
3595
3606
  canopyCover: "cover_pct",
3596
3607
  canopyHeight: "height_m",
3597
- subclass: "subclass",
3608
+ // The barrier kind: World's `type`.
3609
+ subclass: "type",
3598
3610
  hedge: "hedge"
3599
3611
  });
3600
3612
  var tileflowDefaultUnknownTreeForms = Object.freeze({
@@ -4424,7 +4436,7 @@ function browserWorker() {
4424
4436
  if (typeof Worker === "undefined" || false)
4425
4437
  return;
4426
4438
  const url = URL.createObjectURL(
4427
- new Blob(['"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=In(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(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 In(e,n,t,i,o){let r=null;if(o===Ct(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=En(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=En(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ue(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))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ue(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&&_t(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?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ue(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(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 bt(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),_=mn(p,h,n,t,i),v=e.prevZ;for(;v&&v.z>=A;){if(v.x>=g&&v.x<=p&&v.y>=m&&v.y<=h&&v!==s&&!(a===v.x&&c===v.y)&&Ke(a,c,l,f,u,d,v.x,v.y)&&Q(v.prev,v,v.next)>=0)return!1;v=v.prevZ}let M=e.nextZ;for(;M&&M.z<=_;){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 gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Dn(o,t,t.next,r,!1)&&Ce(o,r)&&Ce(r,o)&&(n.push(o.i,t.i,r.i),Ue(t),Ue(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(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 xt(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=In(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),vt(e.length/i,n.length),Nn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,ge(t)}function Tt(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 Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return Nn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function vt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Nn(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<jn&&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 zn(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(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=zn(d);do{if(t.prev.next===t){if(Oe(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=zn(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&&At(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function At(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ke=[],be=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function _t(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),ke.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),Se=new Uint32Array(e),ke=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ke,Se,0),Xe(e,ke,Se,ie,be,8),Xe(e,ie,be,ke,Se,16),Xe(e,ke,Se,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 Lt(e,n){let t=Oe(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))&&!Bt(e,n)&&(t||Ot(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 Oe(e,n){return e.x===n.x&&e.y===n.y}function Dn(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 Bt(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&&Dn(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 Ot(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 En(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 Ue(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 Ct(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 Ut=.7,Pt=Math.tan(Math.PI/6),zt=Math.tan(35*Math.PI/180),Et=Math.tan(Math.PI/18),ze=.65,Ee=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Nt(e);if(!l||Math.abs(pn(e))<Ut*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=Gn(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&&[$n(m,u),$n(m,c)]);if(!h)return;let A=Math.max(0,o-i),_=Gn(t.roof_height),v,M;if(_!==void 0&&_>0)M=o,v=Math.max(i+Math.min(2,A/2),o-_);else{let y=Math.min(It(a,d),A*.6,30);t.height_source==="height"?(M=o,v=o-y):(v=o,M=o+y)}let B=M-v;if(!(B>=.3))return;let[C,z]=l.centre,U=(y,b)=>{let x=(y-C)*r,T=(b-z)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},E=(y,b)=>[C+(y*u[0]+b*c[0])/r,z+(y*u[1]+b*c[1])/r],D=(y,b)=>{let x=1/0;for(let[T,F,k]of h)x=Math.min(x,T*y+F*b+k);return Math.max(0,x)},K=(y,b)=>v+B*D(...U(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...U(n[y],n[y+1]));pn($)<0&&Ht($);let N=1.01,Y=[-f*N,-d*N,f*N,-d*N,f*N,d*N,-f*N,d*N],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let j=b[0]-Z[0],G=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(j)+Math.abs(G)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=Hn(x,j,G,W),x.length<6)break}if(x.length<6)continue;let T=$,F=x.length/2;for(let P=0;P<F&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%F*2],x[(P+1)%F*2+1]];T=Hn(T,W-j,Z-G,-(W-j)*Z-(Z-G)*j)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let k=[];for(let P=0;P<T.length;P+=2)k.push(...E(T[P],T[P+1]));let L=Pe(k);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],I=Math.hypot(R,S,1);w.push({ring:k,triangles:L,normal:[-R/I,-S/I]})}if(w.length!==0)return{eaves:v,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[F,k]=U(y,b),[L,O]=U(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let I=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=I(F,k),Z=I(L,O);if(P===Z||P*Z>0)continue;let j=P/(P-Z);if(j<=1e-4||j>=1-1e-4)continue;let G=F+(L-F)*j,W=k+(O-k)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=D(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function It(e,n){switch(e){case"skillion":return 2*n*Et;case"pyramidal":return n*zt;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}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=ze/(Ee*r)*f,m=(1-ze)/((1-Ee)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),ze/(Ee*r)*d],[...p(m),ze+(1-ze)/((1-Ee)*r)*(d-Ee*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 Hn(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 Nt(e){let n=Dt(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,_]of n){let v=A*c[0]+_*c[1],M=A*f[0]+_*f[1];d=Math.min(d,v),g=Math.max(g,v),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,_=(m+p)/2;t={centre:[A*c[0]+_*f[0],A*c[1]+_*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 Dt(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 Vt(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 Ht(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 $n(e,n){return e[0]*n[0]+e[1]*n[1]}function Gn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var $t=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Nr=Object.freeze(Object.keys($t));var Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6});var Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024,parts:16});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)&&Zt(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=Gt(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 Gt(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 Zt(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,Wt={commercial:1,active:2,destination:3},Xt={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]))},Yt={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]))},Jt=6,Kt=.5,Qt=.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.5,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=tr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let C=B.properties,z=C.hide_3d;if(z===!0||z===1||z==="1"||z==="true")continue;let U=Math.min(6e3,Jn(C.render_height)??o),E=Math.min(U,Jn(C.render_min_height)??0),D=Wt[String(C.building_tone??"")]??0,K=Xt[String(C.class??"")]??0,$=d.get(M)??0,N=u.length,Y=!1;for(let w of rr(B.geometry,t)){let y=w.map(ir).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=or(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Qt/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,U+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let I=0;I<S.length;I+=2)T.bounds[0]=Math.min(T.bounds[0],S[I]-1),T.bounds[1]=Math.min(T.bounds[1],S[I+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[I]+1),T.bounds[3]=Math.max(T.bounds[3],S[I+1]+1);Y=!0,f=Math.max(f,U);let F=Number.isSafeInteger(B.id),k=gn(F?B.id*.0731:b*.0731+x*.19137+N*1.618),L=!F&&y[0].some(S=>S<=0||S>=ue)?gn(U*7.31+E*3.17+D):k,O={base:E,top:U,jitter:L,seed:k,tone:D,group:K,use:$,cx:b,cy:x,index:N},V=y.map((S,I)=>nr(S,I,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],C,E,U,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),er(R,O,s,a)):qt(y,O,s,a);for(let[S,I]of y.entries()){let P=qe(I)>0,Z=S===0?P?-1:1:P?1:-1,j=I.length/2,G=H=>{let J=(H%j+j)%j;return[I[J*2],I[J*2+1]]},W=H=>{let[J,re]=G(H-1),[ne,te]=G(H),[le,de]=G(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 je=-(te-re)/me*Z,Ne=(ne-J)/me*Z;return(je*(le-ne)+Ne*(de-te))/ce>Kt},se=(H,J)=>R?R.heightAt(H,J):U,ae=0;for(let H=0;H<j;H+=1){let[J,re]=G(H),[ne,te]=G(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[S].normals[H]??[de,me],je=V[S].normals[(H+1)%j]??[de,me],Ne=oe=>{let Ae=ce[0]+(je[0]-ce[0])*oe,_e=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(Ae,_e)||1;return[Ae/ye,_e/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,_e=oe+2===he.length,ye=J+(ne-J)*he[oe],De=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Fe=Math.hypot(Ve-ye,He-De)/ue*n.tileMetres,$e=(Ae&&W(H)?1:0)|(_e&&W(H+1)?2:0)|(S>0?4:0),Ge=(Ae&&xn(J,re)?1:0)|(_e&&xn(ne,te)?2:0),an=ae+Fe,Ze=Ne(he[oe]),We=Ne(he[oe+1]),Cn=se(ye,De),Un=se(Ve,He),ve=s.write(O,ye,De,0,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Cn);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Fe,1,Ge,Un),s.write(O,ye,De,1,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Cn),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Fe,1,Ge,Un),l.push(ve,ve+1,ve+2,ve+1,ve+3,ve+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(),_=l.values();c.sort((M,B)=>M.cell-B.cell);let v=-1;for(let M of c){M.cell!==v&&(v=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(_.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 qt(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 er(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 nr(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,_]=[e[d*2],e[d*2+1]],v=Math.hypot(p-g,h-m),M=Math.hypot(A-p,_-h);if(!v||!M||xn(p,h)||we(g,m,p,h)||we(p,h,A,_)){u(p,h);continue}let[B,C]=[(p-g)/v,(h-m)/v],[z,U]=[(A-p)/M,(_-h)/M],E=Math.atan2(B*U-C*z,B*z+C*U);if(E*s>=-.08||Math.abs(E)>Math.PI*.85){u(p,h);continue}let D=Math.tan(Math.abs(E)/2),K=Math.min(t*D,v*.2,M*.2),$=K/D;if($<1){u(p,h);continue}let[N,Y]=[-C*s,B*s],[w,y]=[p-B*K-N*$,h-C*K-Y*$],b=Math.atan2(Y,N),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(E)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let F=b+E*T/x,k=[Math.cos(F),Math.sin(F)];u(w+k[0]*$,y+k[1]*$,k)}}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 tr(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=Yt[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=Jt/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 _ of r){let[v,M,B,C]=_.box;if(d<v-o||d>B+o||g<M-o||g>C+o)continue;let z=!1;for(let U of _.rings)for(let E=0,D=U.length-2;E+1<U.length;D=E,E+=2){let K=U[D],$=U[D+1],N=U[E],Y=U[E+1];Y>g!=$>g&&d<(K-N)*(g-Y)/($-Y)+N&&(z=!z);let w=N-K,y=Y-$,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-$)*y)/b)):0,T=Math.hypot(d-K-x*w,g-$-x*y);T<h&&(h=T,p=_.index)}if(z){m=_.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 rr(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 or(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 ir(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)}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\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}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(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 nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=sr(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 sr(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(_=>_+_).join(""):t).match(/../gu).map(_=>Number.parseInt(_,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,_]=o.slice(0,3).map(v=>en(v,255));return[h,A,_,r].some(v=>v===null)?null:[h,A,_,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,ar={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}},lr={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}},ur={spacing:30,kerb:0},cr=12,fr=18,dr=9,mr={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"},hr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},pr=new Set(["wall","wall_mounted","wall_bracket"]),yr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new kn,o=new nn(fr),r=new nn(dr),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=br(h),_=gr(h),v=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,A*1.7*(v>1?1.15:1)));for(let B of p.geometry)for(let C=0;C+1<B.length;C+=2){let z=B[C]*m,U=B[C+1]*m;if(!rt(z,U))continue;i.write(z,U,A,M,!0,_);let E=ot(z,U,n.tileMetres);o.add(...E),r.add(...E)}}}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"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=wr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=cr,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,A)=>{let _=fe/m.extent,v=[];for(let D=0;D+1<p.length;D+=2)v.push(p[D]*_,p[D+1]*_);let M=n.tileMetres/fe,B=h.kerb*.45/M,C=Rn(v[0]*.013+v[1]*.029+A)*h.spacing,z=0,U=C,E=Rn(v[0]+v[1]*3.1)<.5?1:-1;for(let D=2;D<v.length;D+=2){let K=v[D-2],$=v[D-1],N=v[D],Y=v[D+1],w=Math.hypot(N-K,Y-$)*M;if(w!==0){for(;U<=z+w;){let y=(U-z)/w,b=-(Y-$)/(w/M)*E,x=(N-K)/(w/M)*E,T=K+(N-K)*y+b*B,F=$+(Y-$)*y+x*B;if(U+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(E=-E),!rt(T,F))continue;let k=ot(T,F,n.tileMetres);o.near(...k)||r.near(...k)||(r.add(...k),i.write(T,F,7,15,!1))}z+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(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"||!vn(m.properties.lit)))for(let p of m.geometry)d(g,p,ur,2)}return i.done(a)}function tt(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=ar[r];if(s&&(n==="streets"||vn(t)))return s;let a=lr[r];if(a&&vn(t))return a}function vn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function br(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return pr.has(t)?4.5:yr.has(t)?7.5:7}function gr(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(hr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=mr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function wr(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}},kn=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 oo=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 ut=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"}),Sn=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={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],xr=1.2,Tr=1.5,Mr=1.3,vr=1,kr=[.3,10],Rr=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"]),Ar=new Set(["cupressus","calocedrus","thuja"]),_r=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=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 lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=_n(e[t.genus])??_n(e[t.species])??(o.endsWith("aceae")?void 0:_n(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&Rr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Ar.has(r))return"columnar";if(i.includes("needle")||r&&_r.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function _n(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...n.fields},i=n.unknownForms??Sn,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]=Sr(r,w/q,y/q);for(let T of o){let[F,k,L,O]=T.bounds;if(x>=k&&x<=O&&(F<=L?b>=F&&b<=L:b>=F||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],F=Fn(T.crown,ee(y,2)),k=b,L=x;return k===void 0&&L===void 0&&(k=Fn(T.height,ee(y,1))),k===void 0&&(k=L/F),L===void 0&&(L=k*F),{height:Te(k,on),crown:Te(L,An)}},g=(w,y,b,x,T,F)=>{let k=Ie(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(k,3)):b==="broadleaf"?sn(Fr(f(w,y)),ee(k,3)):b,O=x===void 0&&T===void 0&&F!==void 0?d(L,k,Fn(st[L].height,Te(F/3,[0,1]))):d(L,k,x,T);l.push({x:w,y,...O,turn:ee(k,4),shade:ee(k,5),form:Me.indexOf(L),rank:Math.floor(ee(k,6)*rn),seed:ee(k,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=lt(b,t),T=xe(b[t.height],on),F=xe(b[t.diameterCrown],An),k=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,F,k)}}}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=lt(x,t),F=xe(x[t.height],on),k=xe(x[t.diameterCrown],An);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,I,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-I);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=I+(Z-I)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,F,k,void 0),O+=y}V+=j}}}}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,F=Number(b[t.canopyCover]??30),k=F>=60?3:F>=30?2:1;for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let S=V*w,I=R*w,P=Ie(r.x*q+S,r.y*q+I,11),Z=f(S,I),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(k===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(G*.5,T-G/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<k;ae+=1){let H=Ie(P,ae,13),J=se+ae*Math.PI*2/k,re=k===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=I+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee(H,3)),de=G*(.85+ee(H,2)*.3),me=j===void 0?void 0:j*(.85+ee(H,6)*.25),ce=d(le,H,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee(H,4),shade:ee(H,5),form:Me.indexOf(le),rank:x,seed:ee(H,7),canopy:1}),c+=1}}}}let A=[],_=e.hedges;if(_){let w=q/_.extent,y=xr/(s/_.extent);for(let b of _.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?vr:0,T=(xe(b.properties[t.height],kr)??Mr)+x;for(let F of b.geometry){let k=y/2,L=0;for(let O=0;O+3<F.length;O+=2){let[V,R,S,I]=[F[O],F[O+1],F[O+2],F[O+3]],P=Math.hypot(S-V,I-R),Z=(Math.atan2(R-I,S-V)/(Math.PI*2)+1)%1;for(;k<=L+P;){let j=P>0?(k-L)/P:0,G=V+(S-V)*j,W=R+(I-R)*j;if(G>=0&&W>=0&&G<_.extent&&W<_.extent){let se=Ie(r.x*q+G*w,r.y*q+W*w,17);A.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}k+=y}L+=P}}}}let v=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(v(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*v(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 z=new Uint8Array(l.length*tn),U=new DataView(z.buffer),E=0,D=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...D(),variants:Array.from({length:v(y)},D)}])),$=(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;U.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),U.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),U.setUint16(x+4,Math.round(b.height*10),!0),U.setUint16(x+6,Math.round(b.crown*10),!0),z[x+8]=Math.floor(b.turn*256)&255,z[x+9]=Math.floor(b.shade*256)&255,z[x+10]=b.form,z[x+11]=b.rank,z[x+12]=Math.floor(b.seed*256)&255,z[x+13]=b.canopy,z[x+14]=B[w],E=Math.max(E,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let N=new Uint8Array(A.length*tn),Y=new DataView(N.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(Tr*10),!0),N[b+8]=Math.round(w.turn*256)&255,N[b+9]=Math.floor(w.shade*256)&255,N[b+12]=Math.floor(w.seed*256)&255,E=Math.max(E,w.height)}),{trees:z,forms:K,hedges:N,tallest:E,mapped:u,canopy:c}}function Fr(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:Sn}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(Sn,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 Fn([e,n],t){return e+(n-e)*t}function Sr(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 Ie(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 Ie(e,n,20973)/4294967296}var Lr=[void 0,"Point","LineString","Polygon"];function ft(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=Br(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Br(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=Or(a,o,r);return l?[l]:[]}))})}}function Or(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=Lr[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(Cr(s,o))})}function Cr(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 Pr=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 Pr.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 dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(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&&et(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=ct({...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 it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(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 pt(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=ft(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 On=globalThis,zr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,zr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
4439
+ new Blob(['"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=En(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(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 En(e,n,t,i,o){let r=null;if(o===Ct(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=zn(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=zn(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ue(r),r=r.next),r}function be(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ue(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&&Ft(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?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ue(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=be(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(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)&&Je(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 bt(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),F=mn(g,m,n,t,i),_=mn(p,h,n,t,i),M=e.prevZ;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)&&Je(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.prevZ}let T=e.nextZ;for(;T&&T.z<=_;){if(T.x>=g&&T.x<=p&&T.y>=m&&T.y<=h&&T!==s&&!(a===T.x&&c===T.y)&&Je(a,c,l,f,u,d,T.x,T.y)&&Q(T.prev,T,T.next)>=0)return!1;T=T.nextZ}return!0}function gt(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),Ue(t),Ue(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?be(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(r,s)){let a=Dn(r,s);r=be(r,r.next),a=be(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 xt(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=En(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),vt(e.length/i,n.length),jn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,be(t)}function Tt(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 Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Dn(t,e),o=i.next;return jn(t,o.next),be(i,i.next),be(t,t.next)}var In=16,Y=new Float64Array(0),Ye=0,fn=[],dn=[];function vt(e,n){let t=Math.ceil((e+2*n)/In)+n+2;Y.length<t*4&&(Y=new Float64Array(t*4)),Ye=0}function jn(e,n){let t=e;do{let i=Ye++;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<In&&t!==n);dn[i]=t;let u=i*4;Y[u]=o,Y[u+1]=r,Y[u+2]=s,Y[u+3]=a}while(t!==n)}function kt(e,n){let t=e.z*4;n.x<Y[t]&&(Y[t]=n.x),n.y<Y[t+1]&&(Y[t+1]=n.y),n.x>Y[t+2]&&(Y[t+2]=n.x),n.y>Y[t+3]&&(Y[t+3]=n.y)}function Un(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function Pn(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(e,t))return t;for(let d=0,g=0;d<Ye;d++,g+=4){if(o<Y[g+1]||o>Y[g+3]||Y[g]>i||Y[g+2]<=r)continue;let m=Un(d);t=Pn(d);do{if(t.prev.next===t){if(Oe(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<Ye;d++,g+=4){if(Y[g+2]<a||Y[g]>i||Y[g+3]<u||Y[g+1]>c)continue;let m=Un(d);t=Pn(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Je(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&&At(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function At(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var se=[],ke=[],ye=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function Ft(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),se[r++]=o,o=o.next;while(o!==e);_t(r);let s=null;for(let a=0;a<r;a++){let l=se[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,se.fill(null,0,r),ke.fill(null,0,r)}function _t(e){if(e<=32){for(let n=1;n<e;n++){let t=se[n],i=t.z,o=n-1;for(;o>=0&&se[o].z>i;)se[o+1]=se[o],o--;se[o+1]=t}return}ye.length<e&&(ye=new Uint32Array(e),Se=new Uint32Array(e),ke=new Array(e));for(let n=0;n<e;n++)ye[n]=se[n].z;We(e,se,ye,ke,Se,0),We(e,ke,Se,se,ye,8),We(e,se,ye,ke,Se,16),We(e,ke,Se,se,ye,24)}function We(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 Je(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 Lt(e,n){let t=Oe(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))&&!Bt(e,n)&&(t||Ot(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 Oe(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&&Xe(e,t,n)||s===0&&Xe(e,i,n)||a===0&&Xe(t,e,i)||l===0&&Xe(t,n,i)):!1}function Xe(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 Bt(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 Ot(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 Dn(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 zn(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 Ue(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 Ct(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 Ut=.7,Pt=Math.tan(Math.PI/6),zt=Math.tan(35*Math.PI/180),Et=Math.tan(Math.PI/18),ze=.65,Ee=.4;function Gn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Nt(e);if(!l||Math.abs(pn(e))<Ut*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=$n(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&&[Hn(m,u),Hn(m,c)]);if(!h)return;let F=Math.max(0,o-i),_=$n(t.roof_height),M,T;if(_!==void 0&&_>0)T=o,M=Math.max(i+Math.min(2,F/2),o-_);else{let x=Math.min(It(a,d),F*.6,30);t.height_source==="height"?(T=o,M=o-x):(M=o,T=o+x)}let B=T-M;if(!(B>=.3))return;let[L,U]=l.centre,E=(x,y)=>{let w=(x-L)*r,k=(y-U)*r;return[w*u[0]+k*u[1],w*c[0]+k*c[1]]},I=(x,y)=>[L+(x*u[0]+y*c[0])/r,U+(x*u[1]+y*c[1])/r],H=(x,y)=>{let w=1/0;for(let[k,S,R]of h)w=Math.min(w,k*x+S*y+R);return Math.max(0,w)},J=(x,y)=>M+B*H(...E(x,y)),V=[];for(let x=0;x+1<n.length;x+=2)V.push(...E(n[x],n[x+1]));pn(V)<0&&Ht(V);let D=1.01,X=[-f*D,-d*D,f*D,-d*D,f*D,d*D,-f*D,d*D],b=[];for(let[x,y]of h.entries()){let w=X;for(let[C,$]of h.entries()){if(C===x)continue;let j=y[0]-$[0],G=y[1]-$[1],Z=y[2]-$[2];if(Math.abs(j)+Math.abs(G)+Math.abs(Z)<1e-9){C<x&&(w=[]);continue}if(w=Vn(w,j,G,Z),w.length<6)break}if(w.length<6)continue;let k=V,S=w.length/2;for(let C=0;C<S&&k.length>=6;C+=1){let[$,j]=[w[C*2],w[C*2+1]],[G,Z]=[w[(C+1)%S*2],w[(C+1)%S*2+1]];k=Vn(k,Z-j,$-G,-(Z-j)*$-($-G)*j)}if(k.length<6||Math.abs(pn(k))<1e-6)continue;let R=[];for(let C=0;C<k.length;C+=2)R.push(...I(k[C],k[C+1]));let A=Pe(R);if(A.length===0)continue;let P=B*y[0],z=B*y[1],v=P*u[0]+z*c[0],O=P*u[1]+z*c[1],K=Math.hypot(v,O,1);b.push({ring:R,triangles:A,normal:[-v/K,-O/K]})}if(b.length!==0)return{eaves:M,ridge:T,faces:b,heightAt:J,breaks(x,y,w,k){let[S,R]=E(x,y),[A,P]=E(w,k),z=[];for(let v=0;v<h.length;v+=1)for(let O=v+1;O<h.length;O+=1){let K=(W,N)=>(h[v][0]-h[O][0])*W+(h[v][1]-h[O][1])*N+(h[v][2]-h[O][2]),C=K(S,R),$=K(A,P);if(C===$||C*$>0)continue;let j=C/(C-$);if(j<=1e-4||j>=1-1e-4)continue;let G=S+(A-S)*j,Z=R+(P-R)*j;h[v][0]*G+h[v][1]*Z+h[v][2]<=H(G,Z)+1e-6&&z.push(j)}return[...new Set(z.map(v=>Math.round(v*1e6)/1e6))].sort((v,O)=>v-O)}}}function It(e,n){switch(e){case"skillion":return 2*n*Et;case"pyramidal":return n*zt;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}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=ze/(Ee*r)*f,m=(1-ze)/((1-Ee)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),ze/(Ee*r)*d],[...p(m),ze+(1-ze)/((1-Ee)*r)*(d-Ee*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 Vn(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 Nt(e){let n=Dt(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[F,_]of n){let M=F*c[0]+_*c[1],T=F*f[0]+_*f[1];d=Math.min(d,M),g=Math.max(g,M),m=Math.min(m,T),p=Math.max(p,T)}let h=(g-d)*(p-m);if(h<i){i=h;let F=(d+g)/2,_=(m+p)/2;t={centre:[F*c[0]+_*f[0],F*c[1]+_*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 Dt(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 Vt(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 Ht(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 Hn(e,n){return e[0]*n[0]+e[1]*n[1]}function $n(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var $t=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Nr=Object.freeze(Object.keys($t));var Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6});var Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024,parts:16});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 Xn(e,n,t){for(let i of n){let[o,r,s,a]=Wn(i);for(let l of e){let[u,c,f,d]=Wn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Zn(l,i,t)||Zn(i,l,t)))return!0}}return!1}function Zn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Zt(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=Gt(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 Gt(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 Zt(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 Wn(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,he=28,Wt={commercial:1,active:2,destination:3},Xt={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]))},Yt={dining:1,entertainment:2,nightlife:3},Yn={...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]))},Jt=6,Kt=.5,Qt=.5;function Jn(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.5,n.edgeRadius))/i:0,s=new gn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=tr(e,n);for(let[T,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let L=B.properties;if(Kn(L))continue;let U=Math.min(6e3,Ke(L.height)??Ke(L.render_height)??o),E=Math.min(U,Ke(L.min_height)??Ke(L.render_min_height)??0),I=Wt[String(L.tone??"")]??0,H=Xt[String(L.use??L.class??"")]??0,J=d.get(T)??0,V=u.length,D=!1;for(let X of rr(B.geometry,t)){let b=X.map(ir).filter(v=>v.length>=6);if(b.length===0||qe(b[0])===0)continue;let[x,y]=or(b[0]);if(n.masks?.length&&(yn(n.masks,x,y)||Xn(b,n.masks,Qt/i)))continue;let w={cell:Math.min(7,Math.max(0,Math.floor(y/1024)))*8+Math.min(7,Math.max(0,Math.floor(x/1024))),bounds:[1/0,1/0,-1/0,-1/0,U+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let v of b)for(let O=0;O<v.length;O+=2)w.bounds[0]=Math.min(w.bounds[0],v[O]-1),w.bounds[1]=Math.min(w.bounds[1],v[O+1]-1),w.bounds[2]=Math.max(w.bounds[2],v[O]+1),w.bounds[3]=Math.max(w.bounds[3],v[O+1]+1);D=!0,f=Math.max(f,U);let k=Number.isSafeInteger(B.id),S=bn(k?B.id*.0731:x*.0731+y*.19137+V*1.618),R=!k&&b[0].some(v=>v<=0||v>=ue)?bn(U*7.31+E*3.17+I):S,A={base:E,top:U,jitter:R,seed:S,tone:I,group:H,use:J,cx:x,cy:y,index:V},P=b.map((v,O)=>nr(v,O,r,n.cornerAngle));b=P.map(({ring:v})=>v);let z=X.length===1&&b.length===1?Gn(X[0],b[0],L,E,U,i,ue):void 0;z?(f=Math.max(f,z.ridge),w.bounds[4]=Math.max(w.bounds[4],z.ridge+.1),er(z,A,s,a)):qt(b,A,s,a);for(let[v,O]of b.entries()){let K=qe(O)>0,C=v===0?K?-1:1:K?1:-1,$=O.length/2,j=W=>{let N=(W%$+$)%$;return[O[N*2],O[N*2+1]]},G=W=>{let[N,re]=j(W-1),[te,ne]=j(W),[ae,le]=j(W+1);if(ge(N,re,te,ne)||ge(te,ne,ae,le))return!1;let de=Math.hypot(te-N,ne-re),ce=Math.hypot(ae-te,le-ne);if(!de||!ce)return!1;let Me=-(ne-re)/de*C,je=(te-N)/de*C;return(Me*(ae-te)+je*(le-ne))/ce>Kt},Z=(W,N)=>z?z.heightAt(W,N):U,oe=0;for(let W=0;W<$;W+=1){let[N,re]=j(W),[te,ne]=j(W+1),ae=Math.hypot(te-N,ne-re);if(ae===0||ge(N,re,te,ne))continue;let le=-(ne-re)/ae*C,de=(te-N)/ae*C,ce=P[v].normals[W]??[le,de],Me=P[v].normals[(W+1)%$]??[le,de],je=ie=>{let Ae=ce[0]+(Me[0]-ce[0])*ie,Fe=ce[1]+(Me[1]-ce[1])*ie,pe=Math.hypot(Ae,Fe)||1;return[Ae/pe,Fe/pe]},me=[0,...z?z.breaks(N,re,te,ne):[],1];for(let ie=0;ie+1<me.length;ie+=1){let Ae=ie===0,Fe=ie+2===me.length,pe=N+(te-N)*me[ie],Ne=re+(ne-re)*me[ie],De=N+(te-N)*me[ie+1],Ve=re+(ne-re)*me[ie+1],_e=Math.hypot(De-pe,Ve-Ne)/ue*n.tileMetres,He=(Ae&&G(W)?1:0)|(Fe&&G(W+1)?2:0)|(v>0?4:0),$e=(Ae&&wn(N,re)?1:0)|(Fe&&wn(te,ne)?2:0),an=oe+_e,Ge=je(me[ie]),Ze=je(me[ie+1]),On=Z(pe,Ne),Cn=Z(De,Ve),ve=s.write(A,pe,Ne,0,Ge[0],Ge[1],1,oe,He,_e,0,$e,On);s.write(A,De,Ve,0,Ze[0],Ze[1],1,an,He,_e,1,$e,Cn),s.write(A,pe,Ne,1,Ge[0],Ge[1],1,oe,He,_e,0,$e,On),s.write(A,De,Ve,1,Ze[0],Ze[1],1,an,He,_e,1,$e,Cn),l.push(ve,ve+1,ve+2,ve+1,ve+3,ve+2),oe=an}}}w.roofsCount=a.length-w.roofsFrom,w.wallsCount=l.length-w.wallsFrom,c.push(w)}D&&u.push(L)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,F=a.values(),_=l.values();c.sort((T,B)=>T.cell-B.cell);let M=-1;for(let T of c){T.cell!==M&&(M=T.cell,m.push({bounds:[...T.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let L=0;L<5;L+=1)B.bounds[L]=L<2?Math.min(B.bounds[L],T.bounds[L]):Math.max(B.bounds[L],T.bounds[L]);g.set(F.subarray(T.roofsFrom,T.roofsFrom+T.roofsCount),p),g.set(_.subarray(T.wallsFrom,T.wallsFrom+T.wallsCount),h),p+=T.roofsCount,h+=T.wallsCount,B.roofsCount+=T.roofsCount,B.wallsCount+=T.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function qt(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:!ge(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 er(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:!ge(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 nr(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]],[F,_]=[e[d*2],e[d*2+1]],M=Math.hypot(p-g,h-m),T=Math.hypot(F-p,_-h);if(!M||!T||wn(p,h)||ge(g,m,p,h)||ge(p,h,F,_)){u(p,h);continue}let[B,L]=[(p-g)/M,(h-m)/M],[U,E]=[(F-p)/T,(_-h)/T],I=Math.atan2(B*E-L*U,B*U+L*E);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let H=Math.tan(Math.abs(I)/2),J=Math.min(t*H,M*.2,T*.2),V=J/H;if(V<1){u(p,h);continue}let[D,X]=[-L*s,B*s],[b,x]=[p-B*J-D*V,h-L*J-X*V],y=Math.atan2(X,D),w=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 k=0;k<=w;k+=1){let S=y+I*k/w,R=[Math.cos(S),Math.sin(S)];u(b+R[0]*V,x+R[1]*V,R)}}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 gn=class{#e=new ArrayBuffer(4096*he);#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=he;if((this.count+1)*m>this.#e.byteLength){let F=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(F).set(new Uint8Array(this.#e)),this.#e=F,this.#n=new DataView(F)}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*he))}},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 tr(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=Yt[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=Jt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon"||Kn(l.properties))continue;let u=[1/0,1/0,-1/0,-1/0];for(let c of l.geometry)for(let f=0;f+1<c.length;f+=2)u[0]=Math.min(u[0],c[f]),u[1]=Math.min(u[1],c[f+1]),u[2]=Math.max(u[2],c[f]),u[3]=Math.max(u[3],c[f+1]);r.push({index:a,rings:l.geometry,box:u})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=Yn[String(l.type??"")]??Yn[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 _ of r){let[M,T,B,L]=_.box;if(d<M-o||d>B+o||g<T-o||g>L+o)continue;let U=!1;for(let E of _.rings)for(let I=0,H=E.length-2;I+1<E.length;H=I,I+=2){let J=E[H],V=E[H+1],D=E[I],X=E[I+1];X>g!=V>g&&d<(J-D)*(g-X)/(V-X)+D&&(U=!U);let b=D-J,x=X-V,y=b*b+x*x,w=y?Math.min(1,Math.max(0,((d-J)*b+(g-V)*x)/y)):0,k=Math.hypot(d-J-w*b,g-V-w*x);k<h&&(h=k,p=_.index)}if(U){m=_.index;break}}let F=m??p;F!==void 0&&t.set(F,Math.max(t.get(F)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Ke(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function rr(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 or(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 wn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function ge(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 ir(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 bn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}function Kn(e){let n=e.hide_3d;return e.extrude===!1||n===!0||n===1||n==="1"||n==="true"}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\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]*he,s=e.indices[o+1]*he;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}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(e){let n=e.vertices.length/he;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 nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function xn(e){let n=sr(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 sr(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 F=(t.length<=4?[...t].map(_=>_+_).join(""):t).match(/../gu).map(_=>Number.parseInt(_,16));return[F[0],F[1],F[2],F.length>3?F[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,F,_]=o.slice(0,3).map(M=>en(M,255));return[h,F,_,r].some(M=>M===null)?null:[h,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,Tn=12,ar={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},street:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},lr={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}},ur={spacing:30,kerb:0},cr=12,fr=18,dr=9,mr={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"},hr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},pr=new Set(["wall","wall_mounted","wall_bracket"]),yr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(fr),r=new nn(dr),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.type!=="street_lamp")continue;let F=br(h),_=gr(h),M=Math.max(1,Math.min(4,Number(h.light_count)||1)),T=Math.min(24,Math.max(5,F*1.7*(M>1?1.15:1)));for(let B of p.geometry)for(let L=0;L+1<B.length;L+=2){let U=B[L]*m,E=B[L+1]*m;if(!rt(U,E))continue;i.write(U,E,F,T,!0,_);let I=ot(U,E,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"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=wr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=cr,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,F)=>{let _=fe/m.extent,M=[];for(let H=0;H+1<p.length;H+=2)M.push(p[H]*_,p[H+1]*_);let T=n.tileMetres/fe,B=h.kerb*.45/T,L=kn(M[0]*.013+M[1]*.029+F)*h.spacing,U=0,E=L,I=kn(M[0]+M[1]*3.1)<.5?1:-1;for(let H=2;H<M.length;H+=2){let J=M[H-2],V=M[H-1],D=M[H],X=M[H+1],b=Math.hypot(D-J,X-V)*T;if(b!==0){for(;E<=U+b;){let x=(E-U)/b,y=-(X-V)/(b/T)*I,w=(D-J)/(b/T)*I,k=J+(D-J)*x+y*B,S=V+(X-V)*x+w*B;if(E+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(k,S))continue;let R=ot(k,S,n.tileMetres);o.near(...R)||r.near(...R)||(r.add(...R),i.write(k,S,7,15,!1))}U+=b}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(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"||!Mn(m.properties.lit)))for(let p of m.geometry)d(g,p,ur,2)}return i.done(a)}function tt(e,n){if(e.structure==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=ar[i];if(o&&(n==="streets"||Mn(t)))return o;let r=lr[i];if(r&&Mn(t))return r}function Mn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function br(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return pr.has(t)?4.5:yr.has(t)?7.5:7}function gr(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=xn(hr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=mr[t];if(!i)return;let o=xn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function wr(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*Tn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Tn;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(kn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Tn)),mapped:n,estimated:this.count-n}}};function kn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var oo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"road",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Te=["round","open","tall","conifer","columnar","palm"];var ut=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:"type",hedge:"hedge"}),_n=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={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],Rn=[1,25],xr=1.2,Tr=1.5,Mr=1.3,vr=1,kr=[.3,10],Rr=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"]),Ar=new Set(["cupressus","calocedrus","thuja"]),Fr=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=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 lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=An(e[t.genus])??An(e[t.species])??(o.endsWith("aceae")?void 0:An(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&Rr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Ar.has(r))return"columnar";if(i.includes("needle")||r&&Fr.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function An(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...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=(b,x)=>{if(o.length===0)return i;let[y,w]=Sr(r,b/q,x/q);for(let k of o){let[S,R,A,P]=k.bounds;if(w>=R&&w<=P&&(S<=A?y>=S&&y<=A:y>=S||y<=A))return k.unknownForms}return i},d=(b,x,y,w)=>{let k=st[b],S=Fn(k.crown,ee(x,2)),R=y,A=w;return R===void 0&&A===void 0&&(R=Fn(k.height,ee(x,1))),R===void 0&&(R=A/S),A===void 0&&(A=R*S),{height:xe(R,on),crown:xe(A,Rn)}},g=(b,x,y,w,k,S)=>{let R=Ie(r.x*q+b,r.y*q+x,7),A=y===void 0?sn(f(b,x),ee(R,3)):y==="broadleaf"?sn(_r(f(b,x)),ee(R,3)):y,P=w===void 0&&k===void 0&&S!==void 0?d(A,R,Fn(st[A].height,xe(S/3,[0,1]))):d(A,R,w,k);l.push({x:b,y:x,...P,turn:ee(R,4),shade:ee(R,5),form:Te.indexOf(A),rank:Math.floor(ee(R,6)*rn),seed:ee(R,7),canopy:0}),u+=1},m=e.trees;if(m){let b=q/m.extent;for(let x of m.features){if(x.type!=="Point")continue;let y=x.properties,w=lt(y,t),k=we(y[t.height],on),S=we(y[t.diameterCrown],Rn),R=we(y[t.circumference],[.1,12]);for(let A of x.geometry)for(let P=0;P+1<A.length;P+=2){let z=A[P],v=A[P+1];z<0||v<0||z>=m.extent||v>=m.extent||g(z*b,v*b,w,k,S,R)}}}let p=e.trees;if(p){let b=q/p.extent,x=(n.rowSpacing??8)/(s/p.extent);for(let y of p.features){if(y.type!=="LineString")continue;let w=y.properties,k=lt(w,t),S=we(w[t.height],on),R=we(w[t.diameterCrown],Rn);for(let A of y.geometry){let P=x/2,z=0;for(let v=0;v+3<A.length;v+=2){let[O,K,C,$]=[A[v],A[v+1],A[v+2],A[v+3]],j=Math.hypot(C-O,$-K);for(;P<=z+j;){let G=j>0?(P-z)/j:0,Z=O+(C-O)*G,oe=K+($-K)*G;Z>=0&&oe>=0&&Z<p.extent&&oe<p.extent&&g(Z*b,oe*b,k,S,R,void 0),P+=x}z+=j}}}}let h=e.canopy;if(h){let b=q/h.extent;for(let x of h.features){if(x.type!=="Point")continue;let y=x.properties,w=xe(Math.floor(Number(y[t.canopyRank]??8)),[0,rn-1]),k=Math.max(4,Number(y[t.canopyClearance]??8))*a,S=Number(y[t.canopyCover]??30),R=S>=60?3:S>=30?2:1;for(let A of x.geometry)for(let P=0;P+1<A.length;P+=2){let z=A[P],v=A[P+1];if(z<0||v<0||z>=h.extent||v>=h.extent)continue;let O=z*b,K=v*b,C=Ie(r.x*q+O,r.y*q+K,11),$=f(O,K),j=we(y[t.canopyHeight],on),G=xe(Math.min(k*(R===1?1.3:.95),11)*(.85+ee(C,1)*.25),[3,12]),Z=Math.max(0,Math.min(G*.5,k-G/2)),oe=ee(C,2)*Math.PI*2;for(let W=0;W<R;W+=1){let N=Ie(C,W,13),re=oe+W*Math.PI*2/R,te=R===1?Z*.3*ee(N,1):Z,ne=O+Math.cos(re)*te/(s/q),ae=K+Math.sin(re)*te/(s/q);if(ne<0||ae<0||ne>=q||ae>=q)continue;let le=sn($,ee(N,3)),de=G*(.85+ee(N,2)*.3),ce=j===void 0?void 0:j*(.85+ee(N,6)*.25),Me=d(le,N,ce,le==="palm"?void 0:de);l.push({x:ne,y:ae,...Me,turn:ee(N,4),shade:ee(N,5),form:Te.indexOf(le),rank:w,seed:ee(N,7),canopy:1}),c+=1}}}}let F=[],_=e.hedges;if(_){let b=q/_.extent,x=xr/(s/_.extent);for(let y of _.features){if(y.type==="Point"||y.properties[t.subclass]!=="hedge")continue;let w=y.properties[t.hedge]==="hedge_bank"?vr:0,k=(we(y.properties[t.height],kr)??Mr)+w;for(let S of y.geometry){let R=x/2,A=0;for(let P=0;P+3<S.length;P+=2){let[z,v,O,K]=[S[P],S[P+1],S[P+2],S[P+3]],C=Math.hypot(O-z,K-v),$=(Math.atan2(v-K,O-z)/(Math.PI*2)+1)%1;for(;R<=A+C;){let j=C>0?(R-A)/C:0,G=z+(O-z)*j,Z=v+(K-v)*j;if(G>=0&&Z>=0&&G<_.extent&&Z<_.extent){let oe=Ie(r.x*q+G*b,r.y*q+Z*b,17);F.push({x:G*b,y:Z*b,height:k,turn:$,shade:ee(oe,5),seed:ee(oe,7)})}R+=x}A+=C}}}}let M=b=>xe(Math.floor(n.variants?.[Te[b]]??1),[1,4]),T=b=>Math.min(M(b.form)-1,Math.floor(ee(Math.floor(b.seed*256),9)*M(b.form))),B=l.map(T),L=l.map((b,x)=>x);L.sort((b,x)=>l[b].form-l[x].form||B[b]-B[x]||l[b].rank-l[x].rank);let U=new Uint8Array(l.length*tn),E=new DataView(U.buffer),I=0,H=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),J=Object.fromEntries(Te.map((b,x)=>[b,{...H(),variants:Array.from({length:M(x)},H)}])),V=(b,x,y)=>{b.count===0&&(b.start=x),b.count+=1;for(let w=y;w<rn;w+=1)b.upTo[w]+=1};L.forEach((b,x)=>{let y=l[b],w=x*tn;E.setUint16(w,Math.min(q-1,Math.round(y.x)),!0),E.setUint16(w+2,Math.min(q-1,Math.round(y.y)),!0),E.setUint16(w+4,Math.round(y.height*10),!0),E.setUint16(w+6,Math.round(y.crown*10),!0),U[w+8]=Math.floor(y.turn*256)&255,U[w+9]=Math.floor(y.shade*256)&255,U[w+10]=y.form,U[w+11]=y.rank,U[w+12]=Math.floor(y.seed*256)&255,U[w+13]=y.canopy,U[w+14]=B[b],I=Math.max(I,y.height);let k=J[Te[y.form]];V(k,x,y.rank),V(k.variants[B[b]],x,y.rank)});let D=new Uint8Array(F.length*tn),X=new DataView(D.buffer);return F.forEach((b,x)=>{let y=x*tn;X.setUint16(y,Math.min(q-1,Math.round(b.x)),!0),X.setUint16(y+2,Math.min(q-1,Math.round(b.y)),!0),X.setUint16(y+4,Math.round(b.height*10),!0),X.setUint16(y+6,Math.round(Tr*10),!0),D[y+8]=Math.round(b.turn*256)&255,D[y+9]=Math.floor(b.shade*256)&255,D[y+12]=Math.floor(b.seed*256)&255,I=Math.max(I,b.height)}),{trees:U,forms:J,hedges:D,tallest:I,mapped:u,canopy:c}}function _r(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 Te)t+=Math.max(0,e[o]??0);if(t<=0)return sn(_n,n);let i=n*t;for(let o of Te){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function we(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?xe(t,n):void 0}function xe(e,[n,t]){return Math.min(t,Math.max(n,e))}function Fn([e,n],t){return e+(n-e)*t}function Sr(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 Ie(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 Ie(e,n,20973)/4294967296}var Lr=[void 0,"Point","LineString","Polygon"];function ft(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Ln(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=Br(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Br(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=Or(a,o,r);return l?[l]:[]}))})}}function Or(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=Lr[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(Cr(s,o))})}function Cr(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+=Sn(e[s++]),r+=Sn(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 Sn=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=Sn(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Pr=new TextDecoder,Ln=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 Pr.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 dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Jn(r,{...e.options,...s?{places:s}:{}});return a&&et(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=ct({...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 it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(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 pt(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=ft(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 Bn=globalThis,zr=pt();Bn.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,zr.read(e,n,dt(t)));Bn.postMessage({result:i},ht(t.kind,i))}catch(i){Bn.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
4428
4440
  );
4429
4441
  try {
4430
4442
  return new Worker(url, { name: "tileflow-tiles" });
@@ -7346,16 +7358,17 @@ uniform vec4 u_role_emission_gradient[7];
7346
7358
  uniform float u_role_emission_power[7];
7347
7359
  uniform float u_opacity;
7348
7360
  out vec4 fragColor;
7361
+ ${tileflowAmbientLight}
7349
7362
  ${tileflowShadowLookup}
7350
7363
  ${tileflowHazeFragment}
7351
7364
  ${modelMaterialSampling}
7352
7365
  ${modelPhysicalLighting}
7353
7366
 
7354
7367
  // The buildings' light: a sunlit roof keeps its colour, a face turned to a low sun glows, and shade
7355
- // takes the sky's colour; a face that looks down sees little sky.
7368
+ // takes the sky's colour. Baked occlusion independently attenuates ambient light in recesses.
7356
7369
  vec3 shade(vec3 normal, float lit, float occlusion) {
7357
7370
  float facing = dot(normal, u_sun_dir);
7358
- vec3 sky = u_sky_light * mix(mix(0.8, 0.5, u_night), 1.0, max(normal.z, -0.4));
7371
+ vec3 sky = ambientLight(u_sky_light, normal);
7359
7372
  sky *= mix(1.0, v_light, u_ambient_occlusion * occlusion);
7360
7373
  vec3 light = sky + u_sun_light * max(facing, 0.0) * (1.0 - u_shadow * (1.0 - lit));
7361
7374
  vec3 roof = u_sky_light + u_sun_light * max(u_sun_dir.z, 0.0);
package/dist/browser.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TileflowSymbolStyle, a as TileflowThemeImageValue, b as TileflowThemeColorValue, c as TileflowMarkerSymbolStyle, d as TileflowAreaStyle, e as TileflowLineStackStyle, f as TileflowLineHatchStyle, g as TileflowIconStyle, h as TileflowLinePaint, i as TileflowThemeNumberValue, j as TileflowNumberStyleValue, k as TileflowCircleStyle, l as TileflowLineStyle, m as TileflowFillStyle, n as TileflowExtrusionStyle, o as TileflowThemeValue, p as TileflowBackgroundStyle, q as TileflowSymbolPlacement, r as TileflowVegetationModuleConfig, s as TileflowTileLayer, t as TileflowMap3DOptions, u as TileflowMap3D, v as TileflowViewMode, w as TileflowBuildings3DChange, x as TileflowSun } from './3d-EHN80Dhw.js';
2
- export { y as TileflowBuildings3D, z as TileflowBuildings3DMap, A as TileflowBuildings3DOptions, B as TileflowBuildings3DThemes, C as TileflowCameraOptions, D as TileflowMap3DMap, E as TileflowStreetLights, F as TileflowStreetLightsMap, G as TileflowStreetLightsOptions, H as TileflowSunPreset, I as TileflowTile, J as TileflowTileAddress, K as TileflowTileAreaRequest, L as TileflowTileFeature, M as TileflowTileGeometryType, N as TileflowTileReader, O as TileflowTileReaderOptions, P as TileflowTileRequestTransform, Q as TileflowTileSourceMap, R as TileflowTreeFields, S as TileflowTreeForm, U as TileflowTreeFormMix, V as TileflowTreeFormRange, W as TileflowTreeLayers, X as TileflowTreePlacement, Y as TileflowTreePlacementOptions, Z as TileflowTreeRange, _ as TileflowTreeRegion, $ as TileflowTrees3D, a0 as TileflowTrees3DChange, a1 as TileflowTrees3DMap, a2 as TileflowTrees3DOptions, a3 as TileflowTrees3DThemes, a4 as TileflowVectorTileDecodeOptions, a5 as TileflowVegetation3D, a6 as TileflowVegetationController, a7 as TileflowVegetationDisplay, a8 as TileflowVegetationOptions, a9 as TileflowVegetationRepresentation, aa as createTileflowBuildings3D, ab as createTileflowMap3D, ac as createTileflowStreetLights, ad as createTileflowTileReader, ae as createTileflowTrees3D, af as createTileflowVegetation, ag as decodeTileflowVectorTile, ah as mixTileflowSunPresets, ai as placeTileflowTrees, aj as readTileflowMapTileSource, ak as readTileflowSunPreset, al as readTileflowVegetation3D, am as readTileflowVegetationDisplay, an as resolveTileflowSun, ao as resolveTileflowVegetationRepresentation, ap as tileflowBuildings3DLayerId, aq as tileflowDefaultSunPreset, ar as tileflowStreetLightsLayerId, as as tileflowStyleSunPreset, at as tileflowSunDirection, au as tileflowSunMetadataKey, av as tileflowSunPosition, aw as tileflowTilePointToLngLat, ax as tileflowTilesForBounds, ay as tileflowTreeBytes, az as tileflowTreeFormOf, aA as tileflowTreeForms, aB as tileflowTrees3DLayerId, aC as tileflowVegetationDisplayMetadataKey, aD as tileflowVegetationMetadataKey } from './3d-EHN80Dhw.js';
1
+ import { T as TileflowSymbolStyle, a as TileflowThemeImageValue, b as TileflowThemeColorValue, c as TileflowMarkerSymbolStyle, d as TileflowAreaStyle, e as TileflowLineStackStyle, f as TileflowLineHatchStyle, g as TileflowIconStyle, h as TileflowLinePaint, i as TileflowThemeNumberValue, j as TileflowNumberStyleValue, k as TileflowCircleStyle, l as TileflowLineStyle, m as TileflowFillStyle, n as TileflowExtrusionStyle, o as TileflowThemeValue, p as TileflowBackgroundStyle, q as TileflowSymbolPlacement, r as TileflowVegetationModuleConfig, s as TileflowTileLayer, t as TileflowMap3DOptions, u as TileflowMap3D, v as TileflowViewMode, w as TileflowBuildings3DChange, x as TileflowSun } from './3d-CyOz9GmH.js';
2
+ export { y as TileflowBuildings3D, z as TileflowBuildings3DMap, A as TileflowBuildings3DOptions, B as TileflowBuildings3DThemes, C as TileflowCameraOptions, D as TileflowMap3DMap, E as TileflowStreetLights, F as TileflowStreetLightsMap, G as TileflowStreetLightsOptions, H as TileflowSunPreset, I as TileflowTile, J as TileflowTileAddress, K as TileflowTileAreaRequest, L as TileflowTileFeature, M as TileflowTileGeometryType, N as TileflowTileReader, O as TileflowTileReaderOptions, P as TileflowTileRequestTransform, Q as TileflowTileSourceMap, R as TileflowTreeFields, S as TileflowTreeForm, U as TileflowTreeFormMix, V as TileflowTreeFormRange, W as TileflowTreeLayers, X as TileflowTreePlacement, Y as TileflowTreePlacementOptions, Z as TileflowTreeRange, _ as TileflowTreeRegion, $ as TileflowTrees3D, a0 as TileflowTrees3DChange, a1 as TileflowTrees3DMap, a2 as TileflowTrees3DOptions, a3 as TileflowTrees3DThemes, a4 as TileflowVectorTileDecodeOptions, a5 as TileflowVegetation3D, a6 as TileflowVegetationController, a7 as TileflowVegetationDisplay, a8 as TileflowVegetationOptions, a9 as TileflowVegetationRepresentation, aa as createTileflowBuildings3D, ab as createTileflowMap3D, ac as createTileflowStreetLights, ad as createTileflowTileReader, ae as createTileflowTrees3D, af as createTileflowVegetation, ag as decodeTileflowVectorTile, ah as mixTileflowSunPresets, ai as placeTileflowTrees, aj as readTileflowMapTileSource, ak as readTileflowSunPreset, al as readTileflowVegetation3D, am as readTileflowVegetationDisplay, an as resolveTileflowSun, ao as resolveTileflowVegetationRepresentation, ap as tileflowBuildings3DLayerId, aq as tileflowDefaultSunPreset, ar as tileflowStreetLightsLayerId, as as tileflowStyleSunPreset, at as tileflowSunDirection, au as tileflowSunMetadataKey, av as tileflowSunPosition, aw as tileflowTilePointToLngLat, ax as tileflowTilesForBounds, ay as tileflowTreeBytes, az as tileflowTreeFormOf, aA as tileflowTreeForms, aB as tileflowTrees3DLayerId, aC as tileflowVegetationDisplayMetadataKey, aD as tileflowVegetationMetadataKey } from './3d-CyOz9GmH.js';
3
3
 
4
4
  type TileflowColor = `#${string}`;
5
5
  type TileflowViewConfig = {
@@ -30,7 +30,7 @@ type TileflowRoadTreatmentStyle = Partial<Record<TileflowRoadStructure, Tileflow
30
30
  enabled?: boolean;
31
31
  widthScale?: TileflowThemeNumberValue;
32
32
  };
33
- type TileflowRoadModifier = 'construction' | 'expressway' | 'indoor' | 'official' | 'ramp' | 'unpaved';
33
+ type TileflowRoadModifier = 'construction' | 'expressway' | 'indoor' | 'ramp' | 'unpaved';
34
34
  type TileflowRoadRestriction = 'access' | 'bicycle' | 'foot' | 'horse' | 'toll';
35
35
  type TileflowMountainBikeScale = '0' | '0+' | '1' | '1+' | '2' | '2+' | '3' | '3+' | '4' | '5' | '6';
36
36
  type TileflowRoadServiceType = 'alley' | 'crossover' | 'driveway' | 'parkingAisle' | 'yard';
@@ -590,7 +590,6 @@ type TileflowBuildingModelPlacementConfig = {
590
590
  heading?: number;
591
591
  };
592
592
  type TileflowBuildingsModuleOptions = {
593
- businessCorridor?: TileflowAreaStyle;
594
593
  extrusion?: TileflowExtrusionStyle;
595
594
  flat?: TileflowAreaStyle;
596
595
  mode?: TileflowBuildingMode;
@@ -614,6 +613,11 @@ type TileflowBarrierStyle = {
614
613
  line?: TileflowLineStyle;
615
614
  };
616
615
  type TileflowLandModuleOptions = {
616
+ /**
617
+ * Activity areas, where shops, food, services and offices concentrate: World's
618
+ * `landuse_overlay` areas of class `activity_area`, with an `activity` level from 1 to 5.
619
+ */
620
+ activityAreas?: TileflowAreaStyle;
617
621
  background?: TileflowBackgroundStyle;
618
622
  /**
619
623
  * Hedges, fences and walls, drawn at the top of the land band with hedges uppermost. A barrier
@@ -1489,7 +1493,8 @@ type TileflowBuildingMesh = Readonly<{
1489
1493
  }>;
1490
1494
  /**
1491
1495
  * Meshes the buildings of one decoded tile layer, or returns undefined when it has none. It reads
1492
- * World's `render_height`, `render_min_height`, `hide_3d`, `building_tone`, `class` and `night_use`.
1496
+ * World's `height`, `min_height`, `extrude`, `tone`, `use` and `night_use`, or OpenMapTiles'
1497
+ * `render_height`, `render_min_height` and `hide_3d`.
1493
1498
  * Vertex layout:
1494
1499
  * 0 position in the tile, 0 to 8192 (uint16 ×2); 4 base and top in decimetres (uint16 ×2); 8 the
1495
1500
  * wall's outward normal (int8 ×2, normalised); 10 raised to the top, part of a wall (uint8 ×2);
@@ -1660,9 +1665,9 @@ type TileflowStreetLightPlacementOptions = Readonly<{
1660
1665
  }>;
1661
1666
  /** A tile's layers the lamps come from, as World names them. */
1662
1667
  type TileflowStreetLightLayers = Readonly<{
1663
- /** Points with `subclass` `street_lamp` (World's `street_furniture`). */
1668
+ /** Points with `type` `street_lamp` (World's `street_furniture`). */
1664
1669
  streetFurniture?: TileflowTileLayer;
1665
- /** Streets by `class`, with `lit` where mapped (World's `transportation`). */
1670
+ /** Streets by `class`, with `lit` where mapped (World's `road`). */
1666
1671
  transportation?: TileflowTileLayer;
1667
1672
  /** Pavements, as lines or areas, with `lit` where mapped (World's `sidewalk`). */
1668
1673
  sidewalks?: TileflowTileLayer;