@tileflow/core 0.1.0-alpha.40 → 0.1.0-alpha.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/native.d.ts CHANGED
@@ -362,4 +362,90 @@ declare function planTileflowThemeBlend(styles: readonly MapLibreStyle[], option
362
362
  /** Fills one blend template for a position. Plain values pass through unchanged. */
363
363
  declare function fillTileflowThemeBlendTemplate(template: unknown, position: number): unknown;
364
364
 
365
- export { type TileflowNativeAbortSignal, type TileflowNativeInitialView, type TileflowNativeInitialViewOptions, type TileflowNativeManifestAcquire, type TileflowNativeManifestLoadOptions, type TileflowNativeManifestOperation, type TileflowNativeManifestReader, type TileflowNativeManifestResponse, type TileflowNativeManifestResult, type TileflowNativeNetworkOptions, type TileflowNativeResourceUrlOptions, type TileflowNativeSource, type TileflowNativeSourceController, TileflowNativeSourceError, type TileflowNativeSourceErrorCode, type TileflowNativeSourceErrorField, type TileflowNativeSourceOptions, type TileflowNativeSourceState, TileflowNativeUrlError, type TileflowNativeUrlErrorCode, type TileflowNativeUrlField, type TileflowThemeBlendClock, TileflowThemeBlendError, type TileflowThemeBlendImage, type TileflowThemeBlendOptions, type TileflowThemeBlendPaint, type TileflowThemeBlendPlan, type TileflowThemeBlendSelection, type TileflowThemeBlendSwitch, type TileflowTimeOfDay, type TileflowTimeOfDayVariants, createTileflowNativeSourceController, fillTileflowThemeBlendTemplate, loadTileflowNativeManifest, nearestTileflowBlendTheme, planTileflowThemeBlend, resolveTileflowNativeInitialView, resolveTileflowNativeManifestUrl, resolveTileflowNativeResourceUrl, tileflowNativeManifestLimits, tileflowNativeUrlLimits, tileflowThemeBlendLimits, validateTileflowThemeBlendSelection };
365
+ /**
366
+ * Boundaries families. Each one has its own license, attribution, TileJSON path and style source
367
+ * ID; families are never merged.
368
+ */
369
+ declare const tileflowBoundaryFamilies: Readonly<{
370
+ boundaries: Readonly<{
371
+ attribution: "© OpenStreetMap contributors";
372
+ license: "ODbL-1.0";
373
+ path: "/tiles/boundaries/tiles.json";
374
+ sourceId: "tileflow-boundaries";
375
+ }>;
376
+ }>;
377
+ type TileflowBoundaryFamily = keyof typeof tileflowBoundaryFamilies;
378
+
379
+ /** A value a choropleth can colour: a number for scales, a string for categories. */
380
+ type TileflowBoundaryValue = number | string;
381
+ /** One row of an application's data, keyed by a registry ID or an official code. */
382
+ type TileflowBoundaryRow = Readonly<{
383
+ key: number | string;
384
+ /** `null` leaves the area without a value. */
385
+ value: TileflowBoundaryValue | null;
386
+ }>;
387
+ /** Keys present on every `boundary_area` polygon, usable without the lookup table. */
388
+ type TileflowBoundaryFeatureKey = 'id' | 'iso_3166_1' | 'ref';
389
+ /** Rows joined to areas by one polygon key. */
390
+ type TileflowBoundaryValues = Readonly<{
391
+ joinBy: TileflowBoundaryFeatureKey;
392
+ rows: readonly TileflowBoundaryRow[];
393
+ }>;
394
+
395
+ type FeatureTarget = {
396
+ id?: number | string;
397
+ source: string;
398
+ sourceLayer?: string;
399
+ };
400
+ /** The part of a MapLibre map the controller uses. */
401
+ type TileflowFeatureStateMap = {
402
+ getSource(id: string): unknown;
403
+ getStyle?(): {
404
+ sources?: Record<string, unknown>;
405
+ } | undefined;
406
+ off(type: 'styledata', listener: () => void): unknown;
407
+ on(type: 'styledata', listener: () => void): unknown;
408
+ removeFeatureState(target: FeatureTarget, key?: string): void;
409
+ setFeatureState(target: FeatureTarget & {
410
+ id: number | string;
411
+ }, state: Record<string, unknown>): void;
412
+ };
413
+ type CreateBoundaryFeatureStateOptions = Readonly<{
414
+ /** Defaults to `boundaries`. */
415
+ family?: TileflowBoundaryFamily;
416
+ /** Also set the values on `boundary_label` points, for labels styled by value. */
417
+ labels?: boolean;
418
+ /** Feature-state key; it must match the choropleth's `state`. Defaults to `value`. */
419
+ state?: string;
420
+ }>;
421
+ type TileflowBoundaryFeatureState = Readonly<{
422
+ /** Remove every value this controller set. */
423
+ clear: () => void;
424
+ /** Remove the values and stop following style reloads. */
425
+ dispose: () => void;
426
+ /**
427
+ * Replace the values. Rows must be keyed by the source's feature ID: `id` by default, or `ref`
428
+ * when the map declares `promoteId: 'ref'`. Rows with a `null` value are removed.
429
+ */
430
+ set: (values: TileflowBoundaryValues) => void;
431
+ }>;
432
+ /**
433
+ * Keep Boundaries feature-state in sync with application rows. Values survive a style reload: the
434
+ * controller sets them again once the source is back.
435
+ */
436
+ declare function createBoundaryFeatureState(map: TileflowFeatureStateMap, options?: CreateBoundaryFeatureStateOptions): TileflowBoundaryFeatureState;
437
+
438
+ /** Public selectors only; authority is acquired separately for each protected resource. */
439
+ type TileflowMobileDiscovery = Readonly<{
440
+ version: 1;
441
+ mapId: string;
442
+ deploymentVersion: number;
443
+ representations: Readonly<Partial<Record<'native-v1' | 'webview-v1', Readonly<{
444
+ manifestUrl: string;
445
+ }>>>>;
446
+ }>;
447
+ declare const tileflowMobileDiscoveryMaximumBytes = 4096;
448
+ /** Bind every advertised representation to the exact Hosted origin and Map being requested. */
449
+ declare function parseTileflowMobileDiscovery(value: unknown, discoveryUrl: string): TileflowMobileDiscovery;
450
+
451
+ export { type CreateBoundaryFeatureStateOptions, type TileflowBoundaryFamily, type TileflowBoundaryFeatureState, type TileflowBoundaryRow, type TileflowBoundaryValues, type TileflowFeatureStateMap, type TileflowMobileDiscovery, type TileflowNativeAbortSignal, type TileflowNativeInitialView, type TileflowNativeInitialViewOptions, type TileflowNativeManifestAcquire, type TileflowNativeManifestLoadOptions, type TileflowNativeManifestOperation, type TileflowNativeManifestReader, type TileflowNativeManifestResponse, type TileflowNativeManifestResult, type TileflowNativeNetworkOptions, type TileflowNativeResourceUrlOptions, type TileflowNativeSource, type TileflowNativeSourceController, TileflowNativeSourceError, type TileflowNativeSourceErrorCode, type TileflowNativeSourceErrorField, type TileflowNativeSourceOptions, type TileflowNativeSourceState, TileflowNativeUrlError, type TileflowNativeUrlErrorCode, type TileflowNativeUrlField, type TileflowThemeBlendClock, TileflowThemeBlendError, type TileflowThemeBlendImage, type TileflowThemeBlendOptions, type TileflowThemeBlendPaint, type TileflowThemeBlendPlan, type TileflowThemeBlendSelection, type TileflowThemeBlendSwitch, type TileflowTimeOfDay, type TileflowTimeOfDayVariants, createBoundaryFeatureState, createTileflowNativeSourceController, fillTileflowThemeBlendTemplate, loadTileflowNativeManifest, nearestTileflowBlendTheme, parseTileflowMobileDiscovery, planTileflowThemeBlend, resolveTileflowNativeInitialView, resolveTileflowNativeManifestUrl, resolveTileflowNativeResourceUrl, tileflowBoundaryFamilies, tileflowMobileDiscoveryMaximumBytes, tileflowNativeManifestLimits, tileflowNativeUrlLimits, tileflowThemeBlendLimits, validateTileflowThemeBlendSelection };
package/dist/native.js CHANGED
@@ -5951,18 +5951,211 @@ function snapshotView(input) {
5951
5951
 
5952
5952
  // src/native.ts
5953
5953
  init_theme_blend();
5954
+
5955
+ // src/boundary-areas/schema.ts
5956
+ var tileflowBoundaryClasses = [
5957
+ "country",
5958
+ "dependency",
5959
+ "region",
5960
+ "province_or_county",
5961
+ "municipality",
5962
+ "district",
5963
+ "neighbourhood"
5964
+ ];
5965
+ var tileflowBoundaryClassTiers = ["primary", "secondary"];
5966
+ var tileflowBoundaryAreasV1Schema = Object.freeze({
5967
+ classes: tileflowBoundaryClasses,
5968
+ /** First zoom at which each class appears, by tier. */
5969
+ classMinzoom: Object.freeze({
5970
+ country: Object.freeze({ primary: 0, secondary: 0 }),
5971
+ dependency: Object.freeze({ primary: 0, secondary: 0 }),
5972
+ region: Object.freeze({ primary: 3, secondary: 3 }),
5973
+ province_or_county: Object.freeze({ primary: 6, secondary: 7 }),
5974
+ municipality: Object.freeze({ primary: 8, secondary: 8 }),
5975
+ district: Object.freeze({ primary: 10, secondary: 10 }),
5976
+ neighbourhood: Object.freeze({ primary: 11, secondary: 11 })
5977
+ }),
5978
+ fields: Object.freeze({
5979
+ adminDepth: "admin_depth",
5980
+ adminLevel: "admin_level",
5981
+ class: "class",
5982
+ classTier: "class_tier",
5983
+ iso31661: "iso_3166_1",
5984
+ iso31662: "iso_3166_2",
5985
+ name: "name",
5986
+ nuts: "nuts",
5987
+ ref: "ref",
5988
+ wikidata: "wikidata"
5989
+ }),
5990
+ layers: Object.freeze({ areas: "boundary_area", labels: "boundary_label" }),
5991
+ /** Properties present on `boundary_area` polygons. */
5992
+ areaProperties: Object.freeze([
5993
+ "class",
5994
+ "class_tier",
5995
+ "admin_level",
5996
+ "admin_depth",
5997
+ "ref",
5998
+ "iso_3166_1"
5999
+ ]),
6000
+ maxzoom: 12,
6001
+ minzoom: 0,
6002
+ product: "boundaries-v1",
6003
+ schemaVersion: 1,
6004
+ tiers: tileflowBoundaryClassTiers
6005
+ });
6006
+ var tileflowBoundaryFamilies = Object.freeze({
6007
+ boundaries: Object.freeze({
6008
+ attribution: "\xA9 OpenStreetMap contributors",
6009
+ license: "ODbL-1.0",
6010
+ path: "/tiles/boundaries/tiles.json",
6011
+ sourceId: "tileflow-boundaries"
6012
+ })
6013
+ });
6014
+ function isTileflowBoundaryFamily(value) {
6015
+ return typeof value === "string" && Object.hasOwn(tileflowBoundaryFamilies, value);
6016
+ }
6017
+
6018
+ // src/boundary-areas/feature-state.ts
6019
+ function createBoundaryFeatureState(map2, options = {}) {
6020
+ const family = options.family ?? "boundaries";
6021
+ if (!isTileflowBoundaryFamily(family)) {
6022
+ throw new Error(`Unknown Tileflow Boundaries family: ${String(family)}.`);
6023
+ }
6024
+ const source = tileflowBoundaryFamilies[family].sourceId;
6025
+ const stateKey = options.state?.trim() || "value";
6026
+ const sourceLayers = [
6027
+ tileflowBoundaryAreasV1Schema.layers.areas,
6028
+ ...options.labels ? [tileflowBoundaryAreasV1Schema.layers.labels] : []
6029
+ ];
6030
+ let applied = /* @__PURE__ */ new Map();
6031
+ let disposed = false;
6032
+ const write = (id, value) => {
6033
+ for (const sourceLayer of sourceLayers) {
6034
+ map2.setFeatureState({ id, source, sourceLayer }, { [stateKey]: value });
6035
+ }
6036
+ };
6037
+ const erase = (id) => {
6038
+ for (const sourceLayer of sourceLayers) {
6039
+ map2.removeFeatureState({ id, source, sourceLayer }, stateKey);
6040
+ }
6041
+ };
6042
+ const sourceReady = () => map2.getSource(source) !== void 0;
6043
+ let pendingReload = false;
6044
+ const onStyleData = () => {
6045
+ if (!sourceReady()) {
6046
+ pendingReload = true;
6047
+ return;
6048
+ }
6049
+ if (!pendingReload) return;
6050
+ pendingReload = false;
6051
+ for (const [id, value] of applied) write(id, value);
6052
+ };
6053
+ map2.on("styledata", onStyleData);
6054
+ const assertOpen = () => {
6055
+ if (disposed) throw new Error("This Boundaries feature-state controller was disposed.");
6056
+ };
6057
+ return Object.freeze({
6058
+ clear() {
6059
+ assertOpen();
6060
+ if (sourceReady()) for (const id of applied.keys()) erase(id);
6061
+ applied = /* @__PURE__ */ new Map();
6062
+ },
6063
+ dispose() {
6064
+ if (disposed) return;
6065
+ if (sourceReady()) for (const id of applied.keys()) erase(id);
6066
+ applied = /* @__PURE__ */ new Map();
6067
+ map2.off("styledata", onStyleData);
6068
+ disposed = true;
6069
+ },
6070
+ set(values) {
6071
+ assertOpen();
6072
+ const featureKey = promotedKey(map2, source) ?? "id";
6073
+ if (values.joinBy !== featureKey) {
6074
+ throw new Error(
6075
+ `Boundaries feature-state is keyed by ${featureKey}; join the rows to ${featureKey} first with joinBoundaryRows.`
6076
+ );
6077
+ }
6078
+ const next = /* @__PURE__ */ new Map();
6079
+ for (const row of values.rows) {
6080
+ if (row.value === null) continue;
6081
+ if (featureKey === "id") {
6082
+ if (typeof row.key !== "number" || !Number.isSafeInteger(row.key) || row.key < 0) {
6083
+ throw new Error("Boundaries feature-state rows keyed by id need integer keys.");
6084
+ }
6085
+ } else if (typeof row.key !== "string" || !row.key) {
6086
+ throw new Error("Boundaries feature-state rows keyed by ref need string keys.");
6087
+ }
6088
+ next.set(row.key, row.value);
6089
+ }
6090
+ if (sourceReady()) {
6091
+ for (const id of applied.keys()) if (!next.has(id)) erase(id);
6092
+ for (const [id, value] of next) if (applied.get(id) !== value) write(id, value);
6093
+ } else {
6094
+ pendingReload = true;
6095
+ }
6096
+ applied = next;
6097
+ }
6098
+ });
6099
+ }
6100
+ function promotedKey(map2, source) {
6101
+ const definition = map2.getStyle?.()?.sources?.[source];
6102
+ const promoteId = definition?.promoteId;
6103
+ if (promoteId === void 0) return void 0;
6104
+ const value = typeof promoteId === "string" ? promoteId : promoteId[tileflowBoundaryAreasV1Schema.layers.areas];
6105
+ return value === "ref" ? "ref" : void 0;
6106
+ }
6107
+
6108
+ // src/mobile-discovery.ts
6109
+ var tileflowMobileDiscoveryMaximumBytes = 4096;
6110
+ function parseTileflowMobileDiscovery(value, discoveryUrl) {
6111
+ const fail = () => {
6112
+ throw new Error("Invalid mobile discovery.");
6113
+ };
6114
+ if (typeof discoveryUrl !== "string" || discoveryUrl.length > 2048) return fail();
6115
+ const url = parseNativeUrl(discoveryUrl);
6116
+ const match = /^\/maps\/(map_[A-Za-z0-9_-]{16})\/mobile\/manifest\.json$/u.exec(url.pathname);
6117
+ if (!match || url.protocol !== "https:" || discoveryUrl !== `${url.origin}${url.pathname}`)
6118
+ return fail();
6119
+ const record2 = (candidate) => candidate !== null && typeof candidate === "object" && !Array.isArray(candidate);
6120
+ if (!record2(value) || Object.keys(value).sort().join(",") !== "deploymentVersion,mapId,representations,version")
6121
+ return fail();
6122
+ if (value.version !== 1 || value.mapId !== match[1] || !Number.isSafeInteger(value.deploymentVersion) || Number(value.deploymentVersion) < 1 || !record2(value.representations))
6123
+ return fail();
6124
+ const representations = {};
6125
+ const entries = Object.entries(value.representations);
6126
+ if (!entries.length || entries.length > 2) fail();
6127
+ for (const [profile, representation] of entries) {
6128
+ if (profile !== "native-v1" && profile !== "webview-v1") return fail();
6129
+ if (!record2(representation) || Object.keys(representation).join(",") !== "manifestUrl")
6130
+ return fail();
6131
+ const path = profile === "native-v1" ? "native" : "mobile/webview-v1";
6132
+ const expected = `${url.origin}/maps/${value.mapId}/${path}/manifest.json`;
6133
+ if (representation.manifestUrl !== expected) fail();
6134
+ representations[profile] = Object.freeze({ manifestUrl: expected });
6135
+ }
6136
+ return Object.freeze({
6137
+ version: 1,
6138
+ mapId: value.mapId,
6139
+ deploymentVersion: Number(value.deploymentVersion),
6140
+ representations: Object.freeze(representations)
6141
+ });
6142
+ }
5954
6143
  export {
5955
6144
  TileflowNativeSourceError,
5956
6145
  TileflowNativeUrlError,
5957
6146
  TileflowThemeBlendError,
6147
+ createBoundaryFeatureState,
5958
6148
  createTileflowNativeSourceController,
5959
6149
  fillTileflowThemeBlendTemplate,
5960
6150
  loadTileflowNativeManifest,
5961
6151
  nearestTileflowBlendTheme,
6152
+ parseTileflowMobileDiscovery,
5962
6153
  planTileflowThemeBlend,
5963
6154
  resolveTileflowNativeInitialView,
5964
6155
  resolveTileflowNativeManifestUrl,
5965
6156
  resolveTileflowNativeResourceUrl,
6157
+ tileflowBoundaryFamilies,
6158
+ tileflowMobileDiscoveryMaximumBytes,
5966
6159
  tileflowNativeManifestLimits,
5967
6160
  tileflowNativeUrlLimits,
5968
6161
  tileflowThemeBlendLimits,
package/dist/runtime.d.ts CHANGED
@@ -1 +1 @@
1
- export { C as TileflowAnalytics, a2 as TileflowManifestFetchOptions, a3 as TileflowManifestLoadOptions, a4 as TileflowMapMode, a5 as TileflowMapModeOptions, ai as TileflowResolvedRuntimeTheme, aG as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aH as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aI as TileflowRuntimeSource, aJ as TileflowRuntimeSourceValidation, aK as TileflowRuntimeStyle, aL as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aM as TileflowRuntimeViewOptions, aN as TileflowSessionController, aO as TileflowSessionGrantResponse, aR as TileflowStyleFontFace, ba as TileflowThemeBlendSelection, bh as TileflowThemeSelection, e as TileflowTimeOfDay, f as TileflowTimeOfDayVariants, bp as assertValidTileflowRuntimeSource, bq as clearTileflowManifestCache, bs as createTileflowSessionController, bt as createTileflowSessionId, bu as defaultTileflowManifestUrl, bv as defaultTileflowRuntimeView, bx as getTileflowAnalyticsApiUrl, by as getTileflowStyleFontFaces, bz as inferTileflowAnalyticsFromStyleUrl, bA as isTileflowTimeOfDay, bB as loadTileflowManifest, bC as mergeTileflowAnalytics, bD as nearestTileflowBlendTheme, bE as normalizeTileflowRuntimeCenter, bF as normalizeTileflowStaticImageSize, c2 as normalizeTileflowSurfaceId, bG as normalizeTileflowUrl, bH as resolveTileflowAnalyticsRequestUrl, bI as resolveTileflowManifestMap, bJ as resolveTileflowMapMode, bK as resolveTileflowRuntimeStyle, bL as resolveTileflowRuntimeTheme, bM as resolveTileflowRuntimeThemeBlend, bN as resolveTileflowRuntimeView, bO as resolveTileflowStaticImageUrl, bP as shouldLoadTileflowManifest, bQ as startTileflowSession, bS as tileflowStyleFontFaceLimits, bT as tileflowStyleFontFacesMetadataKey, bU as tileflowThemeBlendLimits, bW as tileflowTimesOfDay, bY as validateTileflowRuntimeSource, bZ as validateTileflowThemeBlendSelection, b_ as validateTileflowThemeSelection } from './manifest-types-DnhSJjCM.js';
1
+ export { C as TileflowAnalytics, a2 as TileflowManifestFetchOptions, a3 as TileflowManifestLoadOptions, a4 as TileflowMapMode, a5 as TileflowMapModeOptions, ai as TileflowResolvedRuntimeTheme, aG as TileflowRuntimeCenterLike, a as TileflowRuntimeColorScheme, T as TileflowRuntimeManifest, aH as TileflowRuntimeManifestMap, b as TileflowRuntimeManifestMapEntry, c as TileflowRuntimeManifestTheme, aI as TileflowRuntimeSource, aJ as TileflowRuntimeSourceValidation, aK as TileflowRuntimeStyle, aL as TileflowRuntimeStyleOptions, d as TileflowRuntimeSystemThemes, aM as TileflowRuntimeViewOptions, aN as TileflowSessionController, aO as TileflowSessionGrantResponse, aR as TileflowStyleFontFace, ba as TileflowThemeBlendSelection, bh as TileflowThemeSelection, e as TileflowTimeOfDay, f as TileflowTimeOfDayVariants, bp as assertValidTileflowRuntimeSource, bq as clearTileflowManifestCache, bs as createTileflowSessionController, bt as createTileflowSessionId, bu as defaultTileflowManifestUrl, bv as defaultTileflowRuntimeView, bx as getTileflowAnalyticsApiUrl, by as getTileflowStyleFontFaces, bz as inferTileflowAnalyticsFromStyleUrl, bA as isTileflowTimeOfDay, bB as loadTileflowManifest, bC as mergeTileflowAnalytics, bD as nearestTileflowBlendTheme, bE as normalizeTileflowRuntimeCenter, bF as normalizeTileflowStaticImageSize, c2 as normalizeTileflowSurfaceId, bG as normalizeTileflowUrl, bH as resolveTileflowAnalyticsRequestUrl, bI as resolveTileflowManifestMap, bJ as resolveTileflowMapMode, bK as resolveTileflowRuntimeStyle, bL as resolveTileflowRuntimeTheme, bM as resolveTileflowRuntimeThemeBlend, bN as resolveTileflowRuntimeView, bO as resolveTileflowStaticImageUrl, bP as shouldLoadTileflowManifest, bQ as startTileflowSession, bS as tileflowStyleFontFaceLimits, bT as tileflowStyleFontFacesMetadataKey, bU as tileflowThemeBlendLimits, bW as tileflowTimesOfDay, bY as validateTileflowRuntimeSource, bZ as validateTileflowThemeBlendSelection, b_ as validateTileflowThemeSelection } from './manifest-types-B0lQjabX.js';
@@ -1,4 +1,4 @@
1
- "use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=zn(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 zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(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,Ce(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),Ce(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),_=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=F;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Nn(o,t,t.next,r,!1)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(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=zn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(e.length/i,n.length),Dn(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 Dn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function kt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Dn(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 vt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function En(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function 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=En(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=En(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ue(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&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=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),ie[r++]=o,o=o.next;while(o!==e);At(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function At(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),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,Se,0),Xe(e,ve,Se,ie,be,8),Xe(e,ie,be,ve,Se,16),Xe(e,ve,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||Ue(e,n)&&Ue(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&&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&&Nn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ue(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 In(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ce(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&&vt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ut(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Dt(e);if(!l||Math.abs(pn(e))<Ct*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=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 _=Math.max(0,o-i),F=Gn(t.roof_height),k,M;if(F!==void 0&&F>0)M=o,k=Math.max(i+Math.min(2,_/2),o-F);else{let y=Math.min(zt(a,d),_*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],N=(y,b)=>{let x=1/0;for(let[T,A,v]of h)x=Math.min(x,T*y+A*b+v);return Math.max(0,x)},K=(y,b)=>k+B*N(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(n[y],n[y+1]));pn($)<0&&Ht($);let D=1.01,Y=[-f*D,-d*D,f*D,-d*D,f*D,d*D,-f*D,d*D],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=$,A=x.length/2;for(let P=0;P<A&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%A*2],x[(P+1)%A*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 v=[];for(let P=0;P<T.length;P+=2)v.push(...I(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[A,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(A,v),Z=z(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=A+(L-A)*j,W=v+(O-v)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=N(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;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=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function 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 Dt(e){let n=Nt(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 k=_*c[0]+F*c[1],M=_*f[0]+F*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let _=(d+g)/2,F=(m+p)/2;t={centre:[_*c[0]+F*f[0],_*c[1]+F*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function Nt(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 jr=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),Nr=Object.freeze([1,1,4,1,3]),Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Gt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=$t(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function $t(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Gt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Zt={commercial:1,active:2,destination:3},Wt={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]))},Xt={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]))},Yt=6,Jt=.5,Kt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=nr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),N=Zt[String(U.building_tone??"")]??0,K=Wt[String(U.class??"")]??0,$=d.get(M)??0,D=u.length,Y=!1;for(let w of tr(B.geometry,t)){let y=w.map(or).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=rr(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Kt/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,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let A=Number.isSafeInteger(B.id),v=gn(A?B.id*.0731:b*.0731+x*.19137+D*1.618),L=!A&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+N):v,O={base:I,top:C,jitter:L,seed:v,tone:N,group:K,use:$,cx:b,cy:x,index:D},V=y.map((S,z)=>er(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),qt(R,O,s,a)):Qt(y,O,s,a);for(let[S,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[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,De=(ne-J)/me*Z;return(je*(le-ne)+De*(de-te))/ce>Jt},se=(H,J)=>R?R.heightAt(H,J):C,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],De=oe=>{let _e=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Fe)||1;return[_e/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=oe===0,Fe=oe+2===he.length,ye=J+(ne-J)*he[oe],Ne=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Ae=Math.hypot(Ve-ye,He-Ne)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Ae,Ze=De(he[oe]),We=De(he[oe+1]),Un=se(ye,Ne),Cn=se(Ve,He),ke=s.write(O,ye,Ne,0,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),s.write(O,ye,Ne,1,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=a.values(),F=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(F.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function 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 qt(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function er(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]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,F)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(F-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let N=Math.tan(Math.abs(I)/2),K=Math.min(t*N,k*.2,M*.2),$=K/N;if($<1){u(p,h);continue}let[D,Y]=[-U*s,B*s],[w,y]=[p-B*K-D*$,h-U*K-Y*$],b=Math.atan2(Y,D),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let A=b+I*T/x,v=[Math.cos(A),Math.sin(A)];u(w+v[0]*$,y+v[1]*$,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}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 nr(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=Xt[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=Yt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let F of r){let[k,M,B,U]=F.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of F.rings)for(let I=0,N=C.length-2;I+1<C.length;N=I,I+=2){let K=C[N],$=C[N+1],D=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-D)*(g-Y)/($-Y)+D&&(E=!E);let w=D-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=F.index)}if(E){m=F.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??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 tr(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 rr(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 or(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=`
1
+ "use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=zn(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 zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(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,Ce(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),Ce(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),_=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=F;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Dn(o,t,t.next,r,!1)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(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=zn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(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 kt(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 vt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function En(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function 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=En(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=En(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ue(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&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=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),ie[r++]=o,o=o.next;while(o!==e);At(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function At(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),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,Se,0),Xe(e,ve,Se,ie,be,8),Xe(e,ie,be,ve,Se,16),Xe(e,ve,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||Ue(e,n)&&Ue(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 Ue(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 In(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ce(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&&vt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ut(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Nt(e);if(!l||Math.abs(pn(e))<Ct*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=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 _=Math.max(0,o-i),F=Gn(t.roof_height),k,M;if(F!==void 0&&F>0)M=o,k=Math.max(i+Math.min(2,_/2),o-F);else{let y=Math.min(zt(a,d),_*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],D=(y,b)=>{let x=1/0;for(let[T,A,v]of h)x=Math.min(x,T*y+A*b+v);return Math.max(0,x)},K=(y,b)=>k+B*D(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(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=$,A=x.length/2;for(let P=0;P<A&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%A*2],x[(P+1)%A*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 v=[];for(let P=0;P<T.length;P+=2)v.push(...I(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[A,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(A,v),Z=z(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=A+(L-A)*j,W=v+(O-v)*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 zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;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=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function 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[_,F]of n){let k=_*c[0]+F*c[1],M=_*f[0]+F*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let _=(d+g)/2,F=(m+p)/2;t={centre:[_*c[0]+F*f[0],_*c[1]+F*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function 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 U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),D=Wt[String(U.building_tone??"")]??0,K=Xt[String(U.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,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let A=Number.isSafeInteger(B.id),v=gn(A?B.id*.0731:b*.0731+x*.19137+N*1.618),L=!A&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+D):v,O={base:I,top:C,jitter:L,seed:v,tone:D,group:K,use:$,cx:b,cy:x,index:N},V=y.map((S,z)=>nr(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,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,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[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):C,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 _e=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Fe)||1;return[_e/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=oe===0,Fe=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],Ae=Math.hypot(Ve-ye,He-De)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Ae,Ze=Ne(he[oe]),We=Ne(he[oe+1]),Un=se(ye,De),Cn=se(Ve,He),ke=s.write(O,ye,De,0,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),s.write(O,ye,De,1,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=a.values(),F=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(F.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function 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]],[_,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,F)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(F-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let D=Math.tan(Math.abs(I)/2),K=Math.min(t*D,k*.2,M*.2),$=K/D;if($<1){u(p,h);continue}let[N,Y]=[-U*s,B*s],[w,y]=[p-B*K-N*$,h-U*K-Y*$],b=Math.atan2(Y,N),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let A=b+I*T/x,v=[Math.cos(A),Math.sin(A)];u(w+v[0]*$,y+v[1]*$,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}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 F of r){let[k,M,B,U]=F.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of F.rings)for(let I=0,D=C.length-2;I+1<C.length;D=I,I+=2){let K=C[D],$=C[D+1],N=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-N)*(g-Y)/($-Y)+N&&(E=!E);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=F.index)}if(E){m=F.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??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=`
2
2
  in float v_haze_depth;
3
3
  uniform vec3 u_haze_colour;
4
4
  uniform vec3 u_haze; // strength; the view depths where the haze starts and is complete
@@ -17,4 +17,4 @@ out vec4 fragColor;
17
17
  void main() {
18
18
  float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());
19
19
  fragColor = vec4(vec3(shade), 1.0);
20
- }`;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=ir(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 ir(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 _=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[_[0],_[1],_[2],_.length>3?_[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(k=>en(k,255));return[h,_,F,r].some(k=>k===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,Mn=12,sr={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}},ar={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}},lr={spacing:30,kerb:0},ur=12,cr=18,fr=9,dr={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"},mr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},hr=new Set(["wall","wall_mounted","wall_bracket"]),pr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(cr),r=new nn(fr),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 _=yr(h),F=br(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,F);let I=ot(E,C,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+=gr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=ur,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,_)=>{let F=fe/m.extent,k=[];for(let N=0;N+1<p.length;N+=2)k.push(p[N]*F,p[N+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let N=2;N<k.length;N+=2){let K=k[N-2],$=k[N-1],D=k[N],Y=k[N+1],w=Math.hypot(D-K,Y-$)*M;if(w!==0){for(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(D-K)/(w/M)*I,T=K+(D-K)*y+b*B,A=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,A))continue;let v=ot(T,A,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,A,7,15,!1))}E+=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"||!kn(m.properties.lit)))for(let p of m.geometry)d(g,p,lr,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=sr[r];if(s&&(n==="streets"||kn(t)))return s;let a=ar[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function yr(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return hr.has(t)?4.5:pr.has(t)?7.5:7}function br(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(mr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=dr[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 gr(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var 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],_n=[1,25],wr=1.2,xr=1.5,Tr=1.3,Mr=1,kr=[.3,10],vr=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"]),Rr=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=Fn(e[t.genus])??Fn(e[t.species])??(o.endsWith("aceae")?void 0:Fn(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&vr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Rr.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 Fn(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]=Ar(r,w/q,y/q);for(let T of o){let[A,v,L,O]=T.bounds;if(x>=v&&x<=O&&(A<=L?b>=A&&b<=L:b>=A||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],A=An(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=An(T.height,ee(y,1))),v===void 0&&(v=L/A),L===void 0&&(L=v*A),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,A)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Fr(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&A!==void 0?d(L,v,An(st[L].height,Te(A/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...O,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),A=xe(b[t.diameterCrown],_n),v=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,A,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),A=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,A,v,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,A=Number(b[t.canopyCover]??30),v=A>=60?3:A>=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,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(v===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<v;ae+=1){let H=ze(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=z+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 _=[],F=e.hedges;if(F){let w=q/F.extent,y=wr/(s/F.extent);for(let b of F.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?Mr:0,T=(xe(b.properties[t.height],kr)??Tr)+x;for(let A of b.geometry){let v=y/2,L=0;for(let O=0;O+3<A.length;O+=2){let[V,R,S,z]=[A[O],A[O+1],A[O+2],A[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,S-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let j=P>0?(v-L)/P:0,G=V+(S-V)*j,W=R+(z-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=0,N=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...N(),variants:Array.from({length:k(y)},N)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let D=new Uint8Array(_.length*tn),Y=new DataView(D.buffer);return _.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(xr*10),!0),D[b+8]=Math.round(w.turn*256)&255,D[b+9]=Math.floor(w.shade*256)&255,D[b+12]=Math.floor(w.seed*256)&255,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:D,tallest:I,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 An([e,n],t){return e+(n-e)*t}function Ar(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 ze(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 ze(e,n,20973)/4294967296}var Sr=[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=Lr(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Lr(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=Br(a,o,r);return l?[l]:[]}))})}}function Br(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Sr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Or(s,o))})}function Or(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Cr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Cr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function 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,Pr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Pr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();
20
+ }`;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 _=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[_[0],_[1],_[2],_.length>3?_[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(k=>en(k,255));return[h,_,F,r].some(k=>k===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,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 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.subclass!=="street_lamp")continue;let _=br(h),F=gr(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,F);let I=ot(E,C,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,_)=>{let F=fe/m.extent,k=[];for(let D=0;D+1<p.length;D+=2)k.push(p[D]*F,p[D+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let D=2;D<k.length;D+=2){let K=k[D-2],$=k[D-1],N=k[D],Y=k[D+1],w=Math.hypot(N-K,Y-$)*M;if(w!==0){for(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(N-K)/(w/M)*I,T=K+(N-K)*y+b*B,A=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,A))continue;let v=ot(T,A,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,A,7,15,!1))}E+=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"||!kn(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"||kn(t)))return s;let a=lr[r];if(a&&kn(t))return a}function kn(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}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var 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],_n=[1,25],xr=1.2,Tr=1.5,Mr=1.3,kr=1,vr=[.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"]),_r=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=Fn(e[t.genus])??Fn(e[t.species])??(o.endsWith("aceae")?void 0:Fn(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&Rr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&_r.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 Fn(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[A,v,L,O]=T.bounds;if(x>=v&&x<=O&&(A<=L?b>=A&&b<=L:b>=A||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],A=An(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=An(T.height,ee(y,1))),v===void 0&&(v=L/A),L===void 0&&(L=v*A),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,A)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Ar(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&A!==void 0?d(L,v,An(st[L].height,Te(A/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...O,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),A=xe(b[t.diameterCrown],_n),v=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,A,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),A=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,A,v,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,A=Number(b[t.canopyCover]??30),v=A>=60?3:A>=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,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(v===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<v;ae+=1){let H=ze(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=z+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 _=[],F=e.hedges;if(F){let w=q/F.extent,y=xr/(s/F.extent);for(let b of F.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?kr:0,T=(xe(b.properties[t.height],vr)??Mr)+x;for(let A of b.geometry){let v=y/2,L=0;for(let O=0;O+3<A.length;O+=2){let[V,R,S,z]=[A[O],A[O+1],A[O+2],A[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,S-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let j=P>0?(v-L)/P:0,G=V+(S-V)*j,W=R+(z-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=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:k(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};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let N=new Uint8Array(_.length*tn),Y=new DataView(N.buffer);return _.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,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:N,tallest:I,mapped:u,canopy:c}}function Ar(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n: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 An([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 ze(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 ze(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(Cr(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(Ur(s,o))})}function Ur(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 Cr(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,Er=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Er.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();
@@ -168,26 +168,36 @@ fails with `TF_BOUNDARY_CHOROPLETH_JOIN`.
168
168
 
169
169
  In React, `useBoundaryFeatureState(map, values, options)` from `@tileflow/react` keeps
170
170
  feature-state equal to `values`; see the
171
- [React README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react/README.md).
171
+ [React README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react/README.md). In
172
+ React Native, the `Map` prop `boundaryFeatureState={{values, labels, state}}` does the same with
173
+ the same rows and options; see the
174
+ [React Native README](https://github.com/tileflow/tileflow-sdk/blob/main/packages/react-native/README.md).
172
175
 
173
176
  ## Join by codes the polygons do not carry
174
177
 
175
- Rows keyed by `iso_3166_2`, `nuts` or `wikidata`, or keyed by `ref` while feature-state uses
176
- registry IDs, go through the release's lookup table, `boundaries-lookup.csv.gz`, with one row per
177
- area and class. Decompress it and parse it with `parseBoundaryLookupCsv`; `joinBoundaryRows`
178
- then re-keys the rows:
178
+ Rows keyed by `iso_3166_1` or `ref` need no table: the polygons carry both codes, and a map that
179
+ promotes `ref` can set feature-state by official code directly. Rows keyed by `iso_3166_2`, `nuts`
180
+ or `wikidata`, or keyed by `ref` while feature-state uses registry IDs, go through the release's
181
+ lookup table.
182
+
183
+ The table is split by class, one gzip CSV per class with one row per area of that class:
184
+ `boundaries-lookup-country.csv.gz`, `boundaries-lookup-region.csv.gz`, and so on for every class.
185
+ The Boundaries TileJSON lists their URLs under `tileflow.boundaries.lookup.classes`, by class, and
186
+ the description of the table under `tileflow.boundaries.lookup.manifest`. Fine classes cover many
187
+ areas worldwide, so join where the data is prepared, on a server or at build time, and send the
188
+ application the joined rows, keyed by `id` or `ref`. Parse a file with `parseBoundaryLookupCsv`;
189
+ `joinBoundaryRows` then re-keys the rows:
179
190
 
180
191
  <!-- docs:check -->
181
192
 
182
193
  ```ts
194
+ import {readFile} from 'node:fs/promises';
195
+ import {gunzipSync} from 'node:zlib';
183
196
  import {createBoundaryLookup, joinBoundaryRows, parseBoundaryLookupCsv} from '@tileflow/core';
184
197
 
185
- export async function regionsByNuts(csvGzipUrl: string, rows: {nuts: string; value: number}[]) {
186
- const response = await fetch(csvGzipUrl);
187
- if (!response.ok || !response.body) throw new Error(`Lookup table failed: ${response.status}`);
188
- const text = await new Response(
189
- response.body.pipeThrough(new DecompressionStream('gzip')),
190
- ).text();
198
+ // A downloaded `boundaries-lookup-region.csv.gz`, read where the data is prepared.
199
+ export async function regionsByNuts(lookupFile: string, rows: {nuts: string; value: number}[]) {
200
+ const text = gunzipSync(await readFile(lookupFile)).toString('utf8');
191
201
  const lookup = createBoundaryLookup(parseBoundaryLookupCsv(text));
192
202
  const joined = joinBoundaryRows(
193
203
  rows.map(({nuts, value}) => ({key: nuts, value})),
@@ -198,6 +208,9 @@ export async function regionsByNuts(csvGzipUrl: string, rows: {nuts: string; val
198
208
  }
199
209
  ```
200
210
 
211
+ Rows from several classes join against one lookup built from the rows of each class file. Lookup
212
+ downloads are web delivery, counted like stored tiles; a native app does not download them.
213
+
201
214
  The result has the same `{joinBy, rows}` shape that `values` and `set` accept, keyed by `id` or,
202
215
  with `to: 'ref'`, by `ref`. It also lists the keys it could not use:
203
216