@aceshooting/lyra-ui 28.1.6 → 29.0.0

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +10 -180
  2. package/README.md +10 -2
  3. package/dist/components/charts/chart/chart.class.js +2 -2
  4. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  5. package/dist/components/data/table/table.class.js +2 -2
  6. package/dist/components/forms/combobox/option.class.js +1 -1
  7. package/dist/components/forms/select/select.class.js +1 -1
  8. package/dist/components/media/map/map-loader.d.ts +9 -1
  9. package/dist/components/media/map/map-loader.js +1 -1
  10. package/dist/components/media/map/map.class.d.ts +20 -11
  11. package/dist/components/media/map/map.class.js +4 -4
  12. package/dist/components/retrieval/graph/graph-model.d.ts +10 -1
  13. package/dist/components/retrieval/graph/graph-spatial-controller.js +30 -0
  14. package/dist/components/retrieval/graph/graph-spatial.js +1 -0
  15. package/dist/components/retrieval/graph/graph.class.d.ts +45 -6
  16. package/dist/components/retrieval/graph/graph.class.js +2 -2
  17. package/dist/components/retrieval/graph/graph.styles.js +1 -1
  18. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.d.ts +22 -5
  19. package/dist/components/retrieval/knowledge-graph-explorer/knowledge-graph-explorer.class.js +6 -2
  20. package/dist/events.d.ts +10 -5
  21. package/dist/framework-types.d.ts +1 -1
  22. package/dist/internal/accessible-text-controller.js +1 -1
  23. package/dist/internal/autoloader-manifest.js +1 -1
  24. package/dist/internal/collection-source-tracker.js +1 -0
  25. package/dist/internal/default-strings/media.generated.js +1 -1
  26. package/dist/internal/default-strings/retrieval.generated.js +1 -1
  27. package/dist/internal/localization-types.d.ts +1 -1
  28. package/dist/internal/localization.js +1 -1
  29. package/dist/internal/package-metadata.js +1 -1
  30. package/dist/internal/positioner.js +1 -1
  31. package/dist/lyra.d.ts +1 -1
  32. package/llms/components/lr-geojson-viewer.md +1 -1
  33. package/llms/components/lr-graph.md +78 -8
  34. package/llms/components/lr-knowledge-graph-explorer.md +15 -2
  35. package/llms/components/lr-map.md +60 -25
  36. package/llms/index.md +1 -1
  37. package/llms/peers.md +4 -3
  38. package/llms/shared/ai-and-peers.md +4 -3
  39. package/llms/shared/imports-and-registration.md +1 -1
  40. package/llms/shared.md +5 -4
  41. package/locales.json +138 -138
  42. package/package.json +12 -6
  43. package/registrations.json +1 -1
  44. package/skills/lyra-ui/SKILL.md +8 -3
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{HostDescriptionController}from"../../../internal/aria-controls.js";import{GlassScrollLayer}from"../../../internal/glass-scroll-layer.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{literalSetConverter,trueDefaultBooleanConverter}from"../../../internal/converters.js";import{devWarnOnce}from"../../../internal/dev-mode-attribute-warning.js";import{litDevWarnings}from"../../../internal/dev-warning.js";import{chevronIcon}from"../../../internal/icons.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{DEFAULT_CANVAS_COLOR,resolveCanvasColor}from"../../../internal/canvas-color.js";import{finiteRange}from"../../../internal/numbers.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{notifyMapCanvasReady}from"../../../internal/map-canvas-ready.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{hostAriaLabel,srOnly}from"../../../internal/a11y.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{loadMaplibre}from"./map-loader.js";import{styles}from"./map.styles.js";import{projectGeoJson,projectAdmittedGeoJson,buildProjectedGeoJsonPropertyDiff}from"./map-geojson-diff.js";import{buildGeoJsonPropertyDiff}from"./map-geojson-diff.js";import{clusterColorExpression,heatmapColorExpression,heatmapWeightExpression,heatmapZoomValue,lineColorExpression,mutedCategoryOpacityExpression,pointColorExpression,pointRadiusExpression,stepExpression}from"./map-data-layers.js";import"../../overlays/skeleton/skeleton.class.js";import{LYRA_DEFAULT_mapFeedback,LYRA_DEFAULT_mapInitializationFailed,LYRA_DEFAULT_mapLegend,LYRA_DEFAULT_mapMarker,LYRA_DEFAULT_mapMissingLibrary,LYRA_DEFAULT_mapResetNorth,LYRA_DEFAULT_mapStyleRequired,LYRA_DEFAULT_mapToggleAttribution,LYRA_DEFAULT_mapWebglUnavailable}from"../../../internal/default-strings/media.generated.js";import{LYRA_DEFAULT_close,LYRA_DEFAULT_items,LYRA_DEFAULT_legendTypeHidden,LYRA_DEFAULT_legendTypeShown,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_paginationSummary,LYRA_DEFAULT_zoomIn,LYRA_DEFAULT_zoomOut}from"../../../internal/default-strings/shared.generated.js";function supportsWebGL2(host){try{const context=host.ownerDocument.createElement("canvas").getContext("webgl2");if(!context)return!1;try{context.getExtension("WEBGL_lose_context")?.loseContext()}catch{}return!0}catch{return!1}}function hasMapStyle(style){return typeof style=="string"?style.trim().length>0:style!==void 0}const LEGEND_CONTROL_ROLE=literalSetConverter(["button","checkbox"],"button"),MAX_MAP_LEGEND_GRADIENT_STOPS=64;function isRuntimeArray(value){try{return Array.isArray(value)}catch{return!1}}function isRuntimeRecord(value){try{return value!==null&&typeof value=="object"&&!Array.isArray(value)}catch{return!1}}function boundedOwnArrayLength(value,limit){if(!isRuntimeArray(value))return;const descriptor=getOwnDataDescriptor(value,"length");if(!(descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR||typeof descriptor.value!="number"||!Number.isSafeInteger(descriptor.value)||descriptor.value<0))return Math.min(descriptor.value,limit)}function isUnsafeDescriptor(descriptor){return descriptor===UNSAFE_OWN_DATA_DESCRIPTOR}function optionalDescriptorValue(descriptor){return descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor)?void 0:descriptor.value}function normalizeMapLegendGradient(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_LEGEND_GRADIENT_STOPS);if(scanCount===void 0)return[];const usable=[];for(let index=0;index<scanCount;index+=1){const stopDescriptor=getOwnDataDescriptor(value,String(index));if(stopDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(stopDescriptor))continue;const stop=stopDescriptor.value,stopLength=boundedOwnArrayLength(stop,2);if(stopLength===void 0||stopLength<2)continue;const valueDescriptor=getOwnDataDescriptor(stop,"0"),colorDescriptor=getOwnDataDescriptor(stop,"1");if(valueDescriptor===MISSING_OWN_DATA_DESCRIPTOR||colorDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(valueDescriptor)||isUnsafeDescriptor(colorDescriptor)||typeof valueDescriptor.value!="number"||!Number.isFinite(valueDescriptor.value)||typeof colorDescriptor.value!="string")continue;const color=sanitizeCssColor(colorDescriptor.value);color&&usable.push([valueDescriptor.value,color])}return usable.length<2?[]:Object.freeze([...usable].sort((a,b)=>a[0]-b[0]))}catch{return[]}}const MAP_LEGEND_ITEM_LIMIT=100,MAP_LEGEND_SCAN_LIMIT=1e3,MAP_LEGEND_LABEL_LIMIT=256,MAP_LEGEND_TOTAL_LABEL_LIMIT=8192,MAP_LEGEND_COLOR_LIMIT=256,MAP_LEGEND_VALUE_LIMIT=256,MAP_LEGEND_PATTERNS=new Set(["solid","diagonal","dots","crosshatch"]),EMPTY_MAP_LEGEND=Object.freeze([]),EMPTY_MAP_LEGEND_PROJECTION=Object.freeze({inputCount:0,renderedCount:0,omittedCount:0,truncatedLabelCount:0,truncated:!1});function boundedLegendText(value,limit){return value.length<=limit?value:`${value.slice(0,Math.max(0,limit-1))}…`}function normalizeMapLegend(value){let input;try{input=Array.isArray(value)?value:[]}catch{input=[]}let inputCount=0;try{inputCount=Math.max(0,Math.min(Number.MAX_SAFE_INTEGER,input.length))}catch{inputCount=0}const entries=[];let labelCharacters=0,truncatedLabelCount=0;const scanCount=Math.min(inputCount,MAP_LEGEND_SCAN_LIMIT);for(let index=0;index<scanCount&&entries.length<MAP_LEGEND_ITEM_LIMIT;index++)try{const candidate=input[index];if(!candidate||typeof candidate!="object")continue;const rawColor=candidate.color,rawLabel=candidate.label,rawPattern=candidate.pattern;if(typeof rawColor!="string"||typeof rawLabel!="string"||typeof rawPattern!="string"||!MAP_LEGEND_PATTERNS.has(rawPattern))continue;const remaining=MAP_LEGEND_TOTAL_LABEL_LIMIT-labelCharacters;if(remaining<=0)break;const labelLimit=Math.min(MAP_LEGEND_LABEL_LIMIT,remaining),label=boundedLegendText(rawLabel,labelLimit);if(!label.trim())continue;rawLabel.length>labelLimit&&truncatedLabelCount++,labelCharacters+=label.length;const rawValue=candidate.value,trimmedValue=typeof rawValue=="string"?rawValue.trim():"",value2=trimmedValue?trimmedValue.slice(0,MAP_LEGEND_VALUE_LIMIT):void 0,rawGroup=candidate.group,trimmedGroup=typeof rawGroup=="string"?rawGroup.trim():"",group=trimmedGroup?boundedLegendText(trimmedGroup,MAP_LEGEND_LABEL_LIMIT):void 0,rawIcon=candidate.icon,icon=isRuntimeRecord(rawIcon)?projectIconPaint(rawIcon):void 0;entries.push(Object.freeze({color:rawColor.slice(0,MAP_LEGEND_COLOR_LIMIT),label,pattern:rawPattern,...value2?{value:value2}:{},...group?{group}:{},...icon?{icon}:{}}))}catch{}const frozenEntries=entries.length?Object.freeze(entries):EMPTY_MAP_LEGEND,omittedCount=Math.max(0,inputCount-frozenEntries.length),projection=Object.freeze({inputCount,renderedCount:frozenEntries.length,omittedCount,truncatedLabelCount,truncated:omittedCount>0||truncatedLabelCount>0});return{entries:frozenEntries,projection,grouped:frozenEntries.some(entry=>entry.group!==void 0)}}const EMPTY_HIDDEN_CATEGORIES=Object.freeze([]);function normalizeMapHiddenCategories(value){let input,length=0;try{input=Array.isArray(value)?value:[],length=Math.max(0,Math.min(MAP_LEGEND_SCAN_LIMIT,input.length))}catch{return EMPTY_HIDDEN_CATEGORIES}const keys=[];for(let index=0;index<length&&keys.length<MAP_LEGEND_ITEM_LIMIT;index++)try{const candidate=input[index];if(typeof candidate!="string")continue;const key=candidate.trim().slice(0,MAP_LEGEND_VALUE_LIMIT);if(!key||keys.includes(key))continue;keys.push(key)}catch{}return keys.length?Object.freeze(keys):EMPTY_HIDDEN_CATEGORIES}function renderLegendIcon(icon){const[x,y,width,height]=icon.viewBox??DEFAULT_ICON_VIEW_BOX,mode=icon.mode??"fill";return html`<svg
1
+ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/collection-snapshot.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{HostDescriptionController}from"../../../internal/aria-controls.js";import{GlassScrollLayer}from"../../../internal/glass-scroll-layer.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{literalSetConverter,trueDefaultBooleanConverter}from"../../../internal/converters.js";import{devWarnOnce}from"../../../internal/dev-mode-attribute-warning.js";import{litDevWarnings}from"../../../internal/dev-warning.js";import{chevronIcon}from"../../../internal/icons.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{DEFAULT_CANVAS_COLOR,resolveCanvasColor}from"../../../internal/canvas-color.js";import{finiteRange}from"../../../internal/numbers.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{notifyMapCanvasReady}from"../../../internal/map-canvas-ready.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import{hostAriaLabel,srOnly}from"../../../internal/a11y.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{loadMaplibre,loadModularMap}from"./map-loader.js";import{styles}from"./map.styles.js";import{projectGeoJson,projectAdmittedGeoJson,buildProjectedGeoJsonPropertyDiff}from"./map-geojson-diff.js";import{buildGeoJsonPropertyDiff}from"./map-geojson-diff.js";import{clusterColorExpression,heatmapColorExpression,heatmapWeightExpression,heatmapZoomValue,lineColorExpression,mutedCategoryOpacityExpression,pointColorExpression,pointRadiusExpression,stepExpression}from"./map-data-layers.js";import"../../overlays/skeleton/skeleton.class.js";import{LYRA_DEFAULT_mapFeedback,LYRA_DEFAULT_mapInitializationFailed,LYRA_DEFAULT_mapLegend,LYRA_DEFAULT_mapMarker,LYRA_DEFAULT_mapMissingLibrary,LYRA_DEFAULT_mapResetNorth,LYRA_DEFAULT_mapStyleRequired,LYRA_DEFAULT_mapToggleAttribution,LYRA_DEFAULT_mapWebglUnavailable}from"../../../internal/default-strings/media.generated.js";import{LYRA_DEFAULT_close,LYRA_DEFAULT_items,LYRA_DEFAULT_legendTypeHidden,LYRA_DEFAULT_legendTypeShown,LYRA_DEFAULT_loading,LYRA_DEFAULT_map,LYRA_DEFAULT_paginationSummary,LYRA_DEFAULT_zoomIn,LYRA_DEFAULT_zoomOut}from"../../../internal/default-strings/shared.generated.js";function supportsWebGL2(host){try{const context=host.ownerDocument.createElement("canvas").getContext("webgl2");if(!context)return!1;try{context.getExtension("WEBGL_lose_context")?.loseContext()}catch{}return!0}catch{return!1}}const MAP_ENGINE=literalSetConverter(["modular","maplibre"],"modular");function hasMapStyle(style){return typeof style=="string"?style.trim().length>0:style!==void 0}const LEGEND_CONTROL_ROLE=literalSetConverter(["button","checkbox"],"button"),MAX_MAP_LEGEND_GRADIENT_STOPS=64;function isRuntimeArray(value){try{return Array.isArray(value)}catch{return!1}}function isRuntimeRecord(value){try{return value!==null&&typeof value=="object"&&!Array.isArray(value)}catch{return!1}}function boundedOwnArrayLength(value,limit){if(!isRuntimeArray(value))return;const descriptor=getOwnDataDescriptor(value,"length");if(!(descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR||typeof descriptor.value!="number"||!Number.isSafeInteger(descriptor.value)||descriptor.value<0))return Math.min(descriptor.value,limit)}function isUnsafeDescriptor(descriptor){return descriptor===UNSAFE_OWN_DATA_DESCRIPTOR}function optionalDescriptorValue(descriptor){return descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor)?void 0:descriptor.value}function normalizeMapLegendGradient(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_LEGEND_GRADIENT_STOPS);if(scanCount===void 0)return[];const usable=[];for(let index=0;index<scanCount;index+=1){const stopDescriptor=getOwnDataDescriptor(value,String(index));if(stopDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(stopDescriptor))continue;const stop=stopDescriptor.value,stopLength=boundedOwnArrayLength(stop,2);if(stopLength===void 0||stopLength<2)continue;const valueDescriptor=getOwnDataDescriptor(stop,"0"),colorDescriptor=getOwnDataDescriptor(stop,"1");if(valueDescriptor===MISSING_OWN_DATA_DESCRIPTOR||colorDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(valueDescriptor)||isUnsafeDescriptor(colorDescriptor)||typeof valueDescriptor.value!="number"||!Number.isFinite(valueDescriptor.value)||typeof colorDescriptor.value!="string")continue;const color=sanitizeCssColor(colorDescriptor.value);color&&usable.push([valueDescriptor.value,color])}return usable.length<2?[]:Object.freeze([...usable].sort((a,b)=>a[0]-b[0]))}catch{return[]}}const MAP_LEGEND_ITEM_LIMIT=100,MAP_LEGEND_SCAN_LIMIT=1e3,MAP_LEGEND_LABEL_LIMIT=256,MAP_LEGEND_TOTAL_LABEL_LIMIT=8192,MAP_LEGEND_COLOR_LIMIT=256,MAP_LEGEND_VALUE_LIMIT=256,MAP_LEGEND_PATTERNS=new Set(["solid","diagonal","dots","crosshatch"]),EMPTY_MAP_LEGEND=Object.freeze([]),EMPTY_MAP_LEGEND_PROJECTION=Object.freeze({inputCount:0,renderedCount:0,omittedCount:0,truncatedLabelCount:0,truncated:!1});function boundedLegendText(value,limit){return value.length<=limit?value:`${value.slice(0,Math.max(0,limit-1))}…`}function normalizeMapLegend(value){let input;try{input=Array.isArray(value)?value:[]}catch{input=[]}let inputCount=0;try{inputCount=Math.max(0,Math.min(Number.MAX_SAFE_INTEGER,input.length))}catch{inputCount=0}const entries=[];let labelCharacters=0,truncatedLabelCount=0;const scanCount=Math.min(inputCount,MAP_LEGEND_SCAN_LIMIT);for(let index=0;index<scanCount&&entries.length<MAP_LEGEND_ITEM_LIMIT;index++)try{const candidate=input[index];if(!candidate||typeof candidate!="object")continue;const rawColor=candidate.color,rawLabel=candidate.label,rawPattern=candidate.pattern;if(typeof rawColor!="string"||typeof rawLabel!="string"||typeof rawPattern!="string"||!MAP_LEGEND_PATTERNS.has(rawPattern))continue;const remaining=MAP_LEGEND_TOTAL_LABEL_LIMIT-labelCharacters;if(remaining<=0)break;const labelLimit=Math.min(MAP_LEGEND_LABEL_LIMIT,remaining),label=boundedLegendText(rawLabel,labelLimit);if(!label.trim())continue;rawLabel.length>labelLimit&&truncatedLabelCount++,labelCharacters+=label.length;const rawValue=candidate.value,trimmedValue=typeof rawValue=="string"?rawValue.trim():"",value2=trimmedValue?trimmedValue.slice(0,MAP_LEGEND_VALUE_LIMIT):void 0,rawGroup=candidate.group,trimmedGroup=typeof rawGroup=="string"?rawGroup.trim():"",group=trimmedGroup?boundedLegendText(trimmedGroup,MAP_LEGEND_LABEL_LIMIT):void 0,rawIcon=candidate.icon,icon=isRuntimeRecord(rawIcon)?projectIconPaint(rawIcon):void 0;entries.push(Object.freeze({color:rawColor.slice(0,MAP_LEGEND_COLOR_LIMIT),label,pattern:rawPattern,...value2?{value:value2}:{},...group?{group}:{},...icon?{icon}:{}}))}catch{}const frozenEntries=entries.length?Object.freeze(entries):EMPTY_MAP_LEGEND,omittedCount=Math.max(0,inputCount-frozenEntries.length),projection=Object.freeze({inputCount,renderedCount:frozenEntries.length,omittedCount,truncatedLabelCount,truncated:omittedCount>0||truncatedLabelCount>0});return{entries:frozenEntries,projection,grouped:frozenEntries.some(entry=>entry.group!==void 0)}}const EMPTY_HIDDEN_CATEGORIES=Object.freeze([]);function normalizeMapHiddenCategories(value){let input,length=0;try{input=Array.isArray(value)?value:[],length=Math.max(0,Math.min(MAP_LEGEND_SCAN_LIMIT,input.length))}catch{return EMPTY_HIDDEN_CATEGORIES}const keys=[];for(let index=0;index<length&&keys.length<MAP_LEGEND_ITEM_LIMIT;index++)try{const candidate=input[index];if(typeof candidate!="string")continue;const key=candidate.trim().slice(0,MAP_LEGEND_VALUE_LIMIT);if(!key||keys.includes(key))continue;keys.push(key)}catch{}return keys.length?Object.freeze(keys):EMPTY_HIDDEN_CATEGORIES}function renderLegendIcon(icon){const[x,y,width,height]=icon.viewBox??DEFAULT_ICON_VIEW_BOX,mode=icon.mode??"fill";return html`<svg
2
2
  class="legend-icon"
3
3
  viewBox=${`${x} ${y} ${width} ${height}`}
4
4
  focusable="false"
@@ -9,7 +9,7 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
9
9
  stroke-width=${icon.strokeWidth??DEFAULT_ICON_STROKE_WIDTH}
10
10
  stroke-linecap=${icon.lineCap??"round"}
11
11
  stroke-linejoin=${icon.lineJoin??"round"}
12
- ></path></svg>`}function addPartToken(element,token){const tokens=new Set((element.getAttribute("part")??"").split(/\s+/).filter(Boolean));tokens.add(token),element.setAttribute("part",[...tokens].join(" "))}const CHOROPLETH_LOG_INTERPOLATION_BASE=.25,CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL=8;function choroplethLogInterpolationFactor(input,lower,upper){const difference=upper-lower;if(difference===0)return 0;const progress=input-lower;return(Math.pow(CHOROPLETH_LOG_INTERPOLATION_BASE,progress)-1)/(Math.pow(CHOROPLETH_LOG_INTERPOLATION_BASE,difference)-1)}function compactGradientPercent(value){return String(Math.round(Math.min(100,Math.max(0,value))*1e4)/1e4)}function choroplethLegendGradientImage(stops,interpolation){const lo=stops[0],span=stops[stops.length-1][0]-lo[0],stopPercent=(value,index)=>span>0?(value-lo[0])/span*100:index/(stops.length-1)*100;if(interpolation!=="logarithmic"||span<=0)return`linear-gradient(to right, ${stops.map(([value,color],index)=>`${color} ${compactGradientPercent(stopPercent(value,index))}%`).join(", ")})`;const image=[`${lo[1]} 0%`];for(let index=1;index<stops.length;index+=1){const lower=stops[index-1],upper=stops[index],interval=upper[0]-lower[0];if(interval<=0){image.push(`${upper[1]} ${compactGradientPercent(stopPercent(upper[0],index))}%`);continue}for(let sample=1;sample<=CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL;sample+=1){const intervalProgress=sample/CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL,input=lower[0]+interval*intervalProgress,position=(input-lo[0])/span*100;if(sample===CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL){image.push(`${upper[1]} ${compactGradientPercent(position)}%`);continue}const factor=Math.min(1,Math.max(0,choroplethLogInterpolationFactor(input,lower[0],upper[0]))),lowerWeight=compactGradientPercent((1-factor)*100),upperWeight=compactGradientPercent(factor*100);image.push(`color-mix(in srgb, ${lower[1]} ${lowerWeight}%, ${upper[1]} ${upperWeight}%) ${compactGradientPercent(position)}%`)}}return`linear-gradient(to right, ${image.join(", ")})`}const MAX_MAP_MARKERS=2e3;function popupText(host,markup){const template=host.ownerDocument.createElement("template");template.innerHTML=markup;for(const hidden of template.content.querySelectorAll('script, style, template, [hidden], [aria-hidden="true"]'))hidden.remove();return(template.content.textContent??"").replace(/\s+/gu," ").trim()}function markerPopupText(host,markup){return typeof markup=="string"&&markup?popupText(host,markup):""}const MAX_MAP_DATA_LAYERS=100,EMPTY_CANONICAL_MAP_DATA_LAYERS=Object.freeze([]);function mapTone(value){switch(value){case"accent":case"success":case"warning":case"danger":case"neutral":return value;default:return}}function projectMapDataLayer(value){try{if(!isRuntimeRecord(value))return;const sourceIdDescriptor=getOwnDataDescriptor(value,"sourceId"),geojsonDescriptor=getOwnDataDescriptor(value,"geojson"),toneDescriptor=getOwnDataDescriptor(value,"tone"),colorDescriptor=getOwnDataDescriptor(value,"color"),strokeColorDescriptor=getOwnDataDescriptor(value,"strokeColor"),lineDescriptor=getOwnDataDescriptor(value,"line"),kindDescriptor=getOwnDataDescriptor(value,"kind"),heatmapDescriptor=getOwnDataDescriptor(value,"heatmap"),clusterDescriptor=getOwnDataDescriptor(value,"cluster");if(sourceIdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||geojsonDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(sourceIdDescriptor)||isUnsafeDescriptor(geojsonDescriptor))return;const sourceId=sourceIdDescriptor.value,geojson=geojsonDescriptor.value;if(typeof sourceId!="string"||sourceId.trim().length===0||!isRuntimeRecord(geojson))return;const tone=mapTone(optionalDescriptorValue(toneDescriptor)),colorValue=optionalDescriptorValue(colorDescriptor),strokeColorValue=optionalDescriptorValue(strokeColorDescriptor),kindValue=optionalDescriptorValue(kindDescriptor),heatmapValue=optionalDescriptorValue(heatmapDescriptor),clusterValue=optionalDescriptorValue(clusterDescriptor),kind=kindValue==="heatmap"?"heatmap":"auto";return Object.freeze({sourceId:sourceId.trim(),geojson,geojsonProjection:projectAdmittedGeoJson(geojson),tone,color:typeof colorValue=="string"?colorValue:void 0,strokeColor:typeof strokeColorValue=="string"?strokeColorValue:void 0,line:kind==="auto"?projectLineOptions(optionalDescriptorValue(lineDescriptor)):void 0,point:kind==="auto"?projectPointOptions(optionalDescriptorValue(getOwnDataDescriptor(value,"point"))):void 0,kind,heatmap:kind==="heatmap"?projectHeatmapOptions(heatmapValue):void 0,cluster:kind==="auto"?normalizedClusterOptions(clusterValue):void 0})}catch{return}}function projectMapDataLayers(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_DATA_LAYERS);if(scanCount===void 0)return EMPTY_CANONICAL_MAP_DATA_LAYERS;const output=[],seenSourceIds=new Set;for(let index=0;index<scanCount;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));if(descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor))continue;const layer=projectMapDataLayer(descriptor.value);!layer||seenSourceIds.has(layer.sourceId)||(seenSourceIds.add(layer.sourceId),output.push(layer))}return output.length?Object.freeze(output):EMPTY_CANONICAL_MAP_DATA_LAYERS}catch{return EMPTY_CANONICAL_MAP_DATA_LAYERS}}const DATA_LAYER_SUFFIXES=["-fill","-line","-circle","-point-icon","-cluster","-cluster-count","-heatmap"],QUERYABLE_DATA_LAYER_SUFFIXES=["-fill","-line","-circle","-cluster","-point-icon"],MAX_MAP_STEP_STOPS=32;function normalizedSteps(value,isOutput,clampThreshold=threshold=>threshold){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_STEP_STOPS);if(scanCount===void 0)return Object.freeze([]);const usable=[];for(let index=0;index<scanCount;index+=1){const stopDescriptor=getOwnDataDescriptor(value,String(index));if(stopDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(stopDescriptor))continue;const stop=stopDescriptor.value,stopLength=boundedOwnArrayLength(stop,2);if(stopLength===void 0||stopLength<2)continue;const thresholdDescriptor=getOwnDataDescriptor(stop,"0"),outputDescriptor=getOwnDataDescriptor(stop,"1");thresholdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||outputDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(thresholdDescriptor)||isUnsafeDescriptor(outputDescriptor)||typeof thresholdDescriptor.value!="number"||!Number.isFinite(thresholdDescriptor.value)||!isOutput(outputDescriptor.value)||usable.push([clampThreshold(thresholdDescriptor.value),outputDescriptor.value])}usable.sort((a,b)=>a[0]-b[0]);const deduplicated=usable.filter((stop,index)=>index===0||stop[0]>usable[index-1][0]);return Object.freeze(deduplicated.map(stop=>Object.freeze(stop)))}catch{return Object.freeze([])}}const isFiniteOutput=candidate=>typeof candidate=="number"&&Number.isFinite(candidate),isColorOutput=candidate=>typeof candidate=="string"&&candidate.trim().length>0,DEFAULT_CLUSTER_RADIUS=50,DEFAULT_CLUSTER_MAX_ZOOM=14,DEFAULT_CLUSTER_RADIUS_STEPS=Object.freeze([[0,14],[10,18],[50,24]]),DEFAULT_HEATMAP_RADIUS=30,DEFAULT_HEATMAP_INTENSITY=1,MAX_CLUSTER_COUNT_FONTS=8;function normalizedClusterOptions(value){try{if(!isRuntimeRecord(value))return;const radiusDescriptor=getOwnDataDescriptor(value,"radius"),maxZoomDescriptor=getOwnDataDescriptor(value,"maxZoom"),radiusStepsDescriptor=getOwnDataDescriptor(value,"radiusSteps"),colorStepsDescriptor=getOwnDataDescriptor(value,"colorSteps"),strokeColorDescriptor=getOwnDataDescriptor(value,"strokeColor"),countFontDescriptor=getOwnDataDescriptor(value,"countFont"),countColorDescriptor=getOwnDataDescriptor(value,"countColor"),countHaloColorDescriptor=getOwnDataDescriptor(value,"countHaloColor"),countHaloWidthDescriptor=getOwnDataDescriptor(value,"countHaloWidth"),radiusValue=optionalDescriptorValue(radiusDescriptor),maxZoomValue=optionalDescriptorValue(maxZoomDescriptor),radiusSteps=normalizedSteps(optionalDescriptorValue(radiusStepsDescriptor),isFiniteOutput),colorSteps=normalizedSteps(optionalDescriptorValue(colorStepsDescriptor),isColorOutput),fonts=normalizedClusterFonts(optionalDescriptorValue(countFontDescriptor)),countHaloWidthValue=optionalDescriptorValue(countHaloWidthDescriptor);return Object.freeze({radius:finiteRange(typeof radiusValue=="number"?radiusValue:Number.NaN,DEFAULT_CLUSTER_RADIUS,1,1e3),maxZoom:finiteRange(typeof maxZoomValue=="number"?maxZoomValue:Number.NaN,DEFAULT_CLUSTER_MAX_ZOOM,0,24),radiusSteps:radiusSteps.length?radiusSteps:DEFAULT_CLUSTER_RADIUS_STEPS,colorSteps,strokeColor:sanitizeCssColor(optionalDescriptorValue(strokeColorDescriptor)),countFont:fonts.length?fonts:void 0,countColor:sanitizeCssColor(optionalDescriptorValue(countColorDescriptor)),countHaloColor:sanitizeCssColor(optionalDescriptorValue(countHaloColorDescriptor)),countHaloWidth:countHaloWidthValue===void 0?1:finiteRange(typeof countHaloWidthValue=="number"?countHaloWidthValue:Number.NaN,1,0,3)})}catch{return}}function normalizedClusterFonts(value){try{const length=boundedOwnArrayLength(value,MAX_CLUSTER_COUNT_FONTS);if(length===void 0)return Object.freeze([]);const fonts=[];for(let index=0;index<length;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor)||typeof descriptor.value!="string"||descriptor.value.trim().length===0||fonts.push(descriptor.value)}return Object.freeze(fonts)}catch{return Object.freeze([])}}const DEFAULT_ICON_VIEW_BOX=Object.freeze([0,0,24,24]),DEFAULT_ICON_STROKE_WIDTH=2,ICON_PATH_GRAMMAR=/^[MmLlHhVvCcSsQqTtAaZz\d.eE+,\s-]+$/u,MAX_ICON_PATH_LENGTH=8192;function projectIconPaint(row){const path=optionalDescriptorValue(getOwnDataDescriptor(row,"path"));if(typeof path!="string"||path.length===0||path.length>MAX_ICON_PATH_LENGTH||!ICON_PATH_GRAMMAR.test(path))return;const rawBox=optionalDescriptorValue(getOwnDataDescriptor(row,"viewBox")),box=[];if(rawBox===void 0)box.push(...DEFAULT_ICON_VIEW_BOX);else{if(boundedOwnArrayLength(rawBox,4)!==4)return;for(let index=0;index<4;index++){const coordinate=optionalDescriptorValue(getOwnDataDescriptor(rawBox,String(index)));if(typeof coordinate!="number"||!Number.isFinite(coordinate)||Math.abs(coordinate)>1e4)return;box.push(coordinate)}if(box[2]<.001||box[3]<.001)return}const mode=optionalDescriptorValue(getOwnDataDescriptor(row,"mode")),strokeWidth=optionalDescriptorValue(getOwnDataDescriptor(row,"strokeWidth")),lineCap=optionalDescriptorValue(getOwnDataDescriptor(row,"lineCap")),lineJoin=optionalDescriptorValue(getOwnDataDescriptor(row,"lineJoin"));return Object.freeze({path,viewBox:Object.freeze(box),mode:mode==="stroke"||mode==="fill-stroke"?mode:"fill",strokeWidth:finiteRange(typeof strokeWidth=="number"?strokeWidth:NaN,DEFAULT_ICON_STROKE_WIDTH,0,200),lineCap:lineCap==="butt"||lineCap==="square"?lineCap:"round",lineJoin:lineJoin==="miter"||lineJoin==="bevel"?lineJoin:"round"})}function projectPointRadius(value){if(!isRuntimeRecord(value))return finiteRange(typeof value=="number"?value:NaN,5,0,200);const read=key=>optionalDescriptorValue(getOwnDataDescriptor(value,key)),field=read("field"),rawFallback=read("fallback"),fallback=finiteRange(typeof rawFallback=="number"?rawFallback:NaN,5,0,200),stops=normalizedSteps(read("stops"),isFiniteOutput).map(([threshold,radius])=>Object.freeze([threshold,finiteRange(radius,5,0,200)]));return typeof field!="string"||!field.trim()||!stops.length?fallback:Object.freeze({field:field.trim(),stops:Object.freeze(stops),fallback,interpolation:read("interpolation")==="linear"?"linear":"step"})}function projectPointOptions(value){if(!isRuntimeRecord(value))return;const read=key=>optionalDescriptorValue(getOwnDataDescriptor(value,key)),string=key=>{const candidate=read(key);return typeof candidate=="string"&&candidate.trim()?candidate:void 0},number=(key,fallback,min,max)=>{const candidate=read(key);return finiteRange(typeof candidate=="number"?candidate:NaN,fallback,min,max)},colors=[],icons=[],project=(input,accept)=>{const length=boundedOwnArrayLength(input,MAX_MAP_STEP_STOPS)??0;for(let index=0;index<length;index++){const row=optionalDescriptorValue(getOwnDataDescriptor(input,String(index)));row!==null&&typeof row=="object"&&accept(row)}};return project(read("colors"),row=>{const key=optionalDescriptorValue(getOwnDataDescriptor(row,"0")),color=optionalDescriptorValue(getOwnDataDescriptor(row,"1"));typeof key!="string"||typeof color!="string"||!sanitizeCssColor(color)||colors.some(([existing])=>existing===key)||colors.push(Object.freeze([key,color]))}),project(read("icons"),row=>{const key=optionalDescriptorValue(getOwnDataDescriptor(row,"value"));if(typeof key!="string"||icons.some(icon=>icon.value===key))return;const paint=projectIconPaint(row);paint&&icons.push(Object.freeze({value:key,...paint}))}),Object.freeze({field:string("field"),colors:Object.freeze(colors),radius:projectPointRadius(read("radius")),strokeWidth:number("strokeWidth",0,0,200),strokeColor:string("strokeColor"),iconField:string("iconField")??string("field"),icons:Object.freeze(icons),iconColor:string("iconColor"),iconSize:number("iconSize",16,1,200)})}const POINT_ICON_RASTER_SIZE=64;function rasterPointIcon(host,icon,color){try{const canvas=host.ownerDocument.createElement("canvas");canvas.width=canvas.height=POINT_ICON_RASTER_SIZE;const context=canvas.getContext("2d"),Path=host.ownerDocument.defaultView?.Path2D;if(!context||!Path)return;const[x,y,width,height]=icon.viewBox,scale=POINT_ICON_RASTER_SIZE/Math.max(width,height);context.translate((POINT_ICON_RASTER_SIZE-width*scale)/2,(POINT_ICON_RASTER_SIZE-height*scale)/2),context.scale(scale,scale),context.translate(-x,-y);const path=new Path(icon.path);return icon.mode!=="stroke"&&(context.fillStyle=color,context.fill(path)),icon.mode!=="fill"&&icon.strokeWidth>0&&(context.strokeStyle=color,context.lineWidth=icon.strokeWidth,context.lineCap=icon.lineCap,context.lineJoin=icon.lineJoin,context.stroke(path)),context.getImageData(0,0,POINT_ICON_RASTER_SIZE,POINT_ICON_RASTER_SIZE)}catch{return}}function projectLineOptions(value){try{if(!isRuntimeRecord(value))return;const field=optionalDescriptorValue(getOwnDataDescriptor(value,"field")),width=optionalDescriptorValue(getOwnDataDescriptor(value,"width")),opacity=optionalDescriptorValue(getOwnDataDescriptor(value,"opacity"));return Object.freeze({field:typeof field=="string"&&field.trim()?field.trim():void 0,stops:Object.freeze(normalizeMapLegendGradient(optionalDescriptorValue(getOwnDataDescriptor(value,"stops"))).filter((stop,index,stops)=>index===0||stop[0]>stops[index-1][0]).map(stop=>Object.freeze(stop))),width:typeof width=="number"?finiteRange(width,2,0,200):2,opacity:typeof opacity=="number"?finiteRange(opacity,1,0,1):1})}catch{return}}function projectedHeatmapRange(value){try{const length=boundedOwnArrayLength(value,2);if(length===void 0||length<2)return;const minDescriptor=getOwnDataDescriptor(value,"0"),maxDescriptor=getOwnDataDescriptor(value,"1");return minDescriptor===MISSING_OWN_DATA_DESCRIPTOR||maxDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(minDescriptor)||isUnsafeDescriptor(maxDescriptor)||typeof minDescriptor.value!="number"||typeof maxDescriptor.value!="number"||!Number.isFinite(minDescriptor.value)||!Number.isFinite(maxDescriptor.value)?void 0:Object.freeze([minDescriptor.value,maxDescriptor.value])}catch{return}}function projectedHeatmapZoomValue(value){if(typeof value=="number"&&Number.isFinite(value))return value;if(isRuntimeArray(value))return normalizedSteps(value,isFiniteOutput,zoom=>finiteRange(zoom,0,0,24))}function projectHeatmapOptions(value){try{if(!isRuntimeRecord(value))return;const weightFieldDescriptor=getOwnDataDescriptor(value,"weightField"),weightRangeDescriptor=getOwnDataDescriptor(value,"weightRange"),stopsDescriptor=getOwnDataDescriptor(value,"stops"),radiusDescriptor=getOwnDataDescriptor(value,"radius"),intensityDescriptor=getOwnDataDescriptor(value,"intensity"),opacityDescriptor=getOwnDataDescriptor(value,"opacity"),weightFieldValue=optionalDescriptorValue(weightFieldDescriptor),opacityValue=optionalDescriptorValue(opacityDescriptor);return Object.freeze({weightField:typeof weightFieldValue=="string"&&weightFieldValue.trim().length>0?weightFieldValue.trim():void 0,weightRange:projectedHeatmapRange(optionalDescriptorValue(weightRangeDescriptor)),stops:normalizedSteps(optionalDescriptorValue(stopsDescriptor),isColorOutput,density=>finiteRange(density,0,0,1)),radius:projectedHeatmapZoomValue(optionalDescriptorValue(radiusDescriptor)),intensity:projectedHeatmapZoomValue(optionalDescriptorValue(intensityDescriptor)),opacity:typeof opacityValue=="number"&&Number.isFinite(opacityValue)?opacityValue:void 0})}catch{return}}function dataLayerShape(layer){if(layer.kind==="heatmap")return"heatmap";const cluster=layer.cluster;return cluster?`cluster:${cluster.radius}:${cluster.maxZoom}:${cluster.countFont?.join(",")??""}`:"auto"}function projectMapChoropleth(value){try{if(!isRuntimeRecord(value))return;const sourceIdDescriptor=getOwnDataDescriptor(value,"sourceId"),geojsonDescriptor=getOwnDataDescriptor(value,"geojson"),fieldDescriptor=getOwnDataDescriptor(value,"field"),stopsDescriptor=getOwnDataDescriptor(value,"stops"),interpolationDescriptor=getOwnDataDescriptor(value,"interpolation"),stepBaseColorDescriptor=getOwnDataDescriptor(value,"stepBaseColor");if(sourceIdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||geojsonDescriptor===MISSING_OWN_DATA_DESCRIPTOR||fieldDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(sourceIdDescriptor)||isUnsafeDescriptor(geojsonDescriptor)||isUnsafeDescriptor(fieldDescriptor))return;const sourceId=sourceIdDescriptor.value,geojson=geojsonDescriptor.value,field=fieldDescriptor.value;if(typeof sourceId!="string"||sourceId.trim().length===0||!isRuntimeRecord(geojson)||typeof field!="string"||field.trim().length===0)return;const interpolationValue=optionalDescriptorValue(interpolationDescriptor),stepBaseColorValue=optionalDescriptorValue(stepBaseColorDescriptor),interpolation=interpolationValue==="logarithmic"||interpolationValue==="step"?interpolationValue:"linear";return Object.freeze({sourceId:sourceId.trim(),geojson,geojsonProjection:projectAdmittedGeoJson(geojson),field:field.trim(),stops:normalizedSteps(optionalDescriptorValue(stopsDescriptor),isColorOutput),interpolation,stepBaseColor:typeof stepBaseColorValue=="string"&&stepBaseColorValue.trim().length>0?stepBaseColorValue:void 0})}catch{return}}const EMPTY_CANONICAL_MAP_MARKERS=Object.freeze([]),UNPROJECTED_MAP_VALUE=Symbol("unprojected-map-value");function projectMarkerLngLat(value){try{const length=boundedOwnArrayLength(value,2);if(length===void 0||length<2)return;const lngDescriptor=getOwnDataDescriptor(value,"0"),latDescriptor=getOwnDataDescriptor(value,"1");return lngDescriptor===MISSING_OWN_DATA_DESCRIPTOR||latDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(lngDescriptor)||isUnsafeDescriptor(latDescriptor)||typeof lngDescriptor.value!="number"||typeof latDescriptor.value!="number"||!Number.isFinite(lngDescriptor.value)||!Number.isFinite(latDescriptor.value)||latDescriptor.value<-90||latDescriptor.value>90?void 0:Object.freeze([lngDescriptor.value,latDescriptor.value])}catch{return}}function projectMapMarker(value){try{if(!isRuntimeRecord(value))return;const idDescriptor=getOwnDataDescriptor(value,"id"),lngLatDescriptor=getOwnDataDescriptor(value,"lngLat"),colorDescriptor=getOwnDataDescriptor(value,"color"),labelDescriptor=getOwnDataDescriptor(value,"label"),unsafeHtmlDescriptor=getOwnDataDescriptor(value,"unsafeHtml");if(lngLatDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(idDescriptor)||isUnsafeDescriptor(lngLatDescriptor)||isUnsafeDescriptor(colorDescriptor)||isUnsafeDescriptor(labelDescriptor)||isUnsafeDescriptor(unsafeHtmlDescriptor))return;const lngLat=projectMarkerLngLat(lngLatDescriptor.value),idValue=optionalDescriptorValue(idDescriptor),labelValue=optionalDescriptorValue(labelDescriptor);if(!lngLat||idValue!==void 0&&typeof idValue!="string"||typeof idValue=="string"&&idValue.trim().length===0||labelValue!==void 0&&typeof labelValue!="string")return;const colorValue=optionalDescriptorValue(colorDescriptor);return Object.freeze({id:typeof idValue=="string"?idValue.trim():void 0,lngLat,color:typeof colorValue=="string"?colorValue:void 0,label:typeof labelValue=="string"?labelValue:void 0,unsafeHtml:optionalDescriptorValue(unsafeHtmlDescriptor)})}catch{return}}function projectMapMarkers(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_MARKERS);if(scanCount===void 0)return EMPTY_CANONICAL_MAP_MARKERS;const output=[],explicitIds=new Set;for(let index=0;index<scanCount;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));if(descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor))continue;const marker=projectMapMarker(descriptor.value);!marker||marker.id!==void 0&&explicitIds.has(marker.id)||(marker.id!==void 0&&explicitIds.add(marker.id),output.push(marker))}return output.length?Object.freeze(output):EMPTY_CANONICAL_MAP_MARKERS}catch{return EMPTY_CANONICAL_MAP_MARKERS}}function setPopupContent(popup,marker){const options=popup.options,focus=options?.focusAfterOpen;return options&&(options.focusAfterOpen=!1),marker.unsafeHtml?popup.setHTML(marker.unsafeHtml):popup.setText(marker.label),options&&(options.focusAfterOpen=focus),popup}const FIT_EVENT_KEY="lyraMapFit";function snapshotCenter(center){return Array.isArray(center)?[center[0],center[1]]:center}function sameCenterValue(a,b){return Array.isArray(a)&&Array.isArray(b)?Object.is(a[0],b[0])&&Object.is(a[1],b[1]):Object.is(a,b)}function isFiniteCoordinate(value){return typeof value=="number"&&Number.isFinite(value)}function normalizeFitBounds(bounds){if(!Array.isArray(bounds)||bounds.length!==2)return;const[southWest,northEast]=bounds;if(!Array.isArray(southWest)||!Array.isArray(northEast)||southWest.length!==2||northEast.length!==2)return;const[west,south]=southWest,[east,north]=northEast;if(!(!isFiniteCoordinate(west)||!isFiniteCoordinate(south)||!isFiniteCoordinate(east)||!isFiniteCoordinate(north))&&!(west<-180||west>180||east<-180||east>west+360)&&!(south<-90||north>90||south>north))return Object.freeze([Object.freeze([west,south]),Object.freeze([west>east?east+360:east,north])])}function normalizeFitPadding(padding){const side=value=>finiteRange(typeof value=="number"?value:0,0,0);if(typeof padding=="number"){const all=side(padding);return Object.freeze({top:all,right:all,bottom:all,left:all})}const record=typeof padding=="object"&&padding!==null?padding:{};return Object.freeze({top:side(record.top),right:side(record.right),bottom:side(record.bottom),left:side(record.left)})}function wrapLongitude(longitude){if(longitude>=-180&&longitude<=180)return longitude;const wrapped=((longitude+180)%360+360)%360-180;return wrapped===-180?180:wrapped}function readPeerCamera(map){let longitude,latitude,zoom;try{({lng:longitude,lat:latitude}=map.getCenter()),zoom=map.getZoom()}catch{return}if(!(!isFiniteCoordinate(longitude)||!isFiniteCoordinate(latitude)||!isFiniteCoordinate(zoom)))return{center:[wrapLongitude(longitude),finiteRange(latitude,0,-90,90)],zoom}}const FALLBACK_FILL_OPACITY=.75;function ownerWindow(host){return host.ownerDocument?.defaultView??null}function choroplethFillOpacity(host){const raw=ownerWindow(host)?.getComputedStyle(host).getPropertyValue("--lr-map-choropleth-fill-opacity").trim()??"",parsed=Number.parseFloat(raw);return Number.isFinite(parsed)?parsed:FALLBACK_FILL_OPACITY}const FALLBACK_HIDDEN_CATEGORY_OPACITY=.15;function hiddenCategoryOpacity(host){const raw=ownerWindow(host)?.getComputedStyle(host).getPropertyValue("--lr-map-hidden-category-opacity").trim()??"";return finiteRange(Number.parseFloat(raw),FALLBACK_HIDDEN_CATEGORY_OPACITY,0,1)}const TONE_TOKEN={accent:"--lr-color-brand",success:"--lr-color-success",warning:"--lr-color-warning",danger:"--lr-color-danger",neutral:"--lr-color-text-quiet"},ON_TONE_TOKEN={accent:"--lr-color-on-brand",success:"--lr-color-on-success",warning:"--lr-color-on-warning",danger:"--lr-color-on-danger",neutral:"--lr-color-on-neutral"},HEATMAP_RAMP_TOKENS=Object.freeze([[.25,"--lr-color-brand"],[.5,"--lr-color-success"],[.75,"--lr-color-warning"],[1,"--lr-color-danger"]]);function dataLayerColor(host,tone){const token=TONE_TOKEN[tone??"accent"];return(ownerWindow(host)?.getComputedStyle(host).getPropertyValue(token).trim()??"")||DEFAULT_CANVAS_COLOR}const BASIC_MAP_PAINT_COLOR_NAMES=new Set(["aqua","black","blue","fuchsia","gray","green","lime","maroon","navy","olive","purple","red","silver","teal","white","yellow","transparent"]);function resolvedMapPaintColor(host,color,preserveLegacy){const candidate=typeof color=="string"?color.trim():"";if(!candidate)return;if(preserveLegacy){const reference=/^var\(\s*(--[\w-]+)\s*\)$/.exec(candidate),plain=reference?ownerWindow(host)?.getComputedStyle(host).getPropertyValue(reference[1]).trim()??"":candidate,namedPeerColor=BASIC_MAP_PAINT_COLOR_NAMES.has(plain.toLowerCase());if(/^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i.test(plain)||(/^rgba?\([\d\s.,/]+\)$/i.test(plain)||namedPeerColor)&&typeof CSS<"u"&&CSS.supports("color",plain))return plain}const resolved=resolveCanvasColor(host,candidate,"");if(!resolved)return;if(/^rgba?\(/i.test(resolved))return resolved;const canvas=host.ownerDocument.createElement("canvas");canvas.width=1,canvas.height=1;try{const context=canvas.getContext("2d",{colorSpace:"srgb",willReadFrequently:!0});if(!context)return;let accepted=!1;for(const sentinel of["rgb(1, 2, 3)","rgb(4, 5, 6)"]){context.fillStyle=sentinel;const before=context.fillStyle;if(context.fillStyle=resolved,context.fillStyle!==before){accepted=!0;break}}if(!accepted)return;context.fillRect(0,0,1,1);const[r=0,g=0,b=0,a=0]=context.getImageData(0,0,1,1).data;return a===255?`rgb(${r}, ${g}, ${b})`:`rgba(${r}, ${g}, ${b}, ${Math.round(a/255*1e3)/1e3})`}catch{return}}function resolvedLayerColor(host,explicit,tone){return resolvedMapPaintColor(host,explicit,!0)??resolvedMapPaintColor(host,dataLayerColor(host,tone),!0)??DEFAULT_CANVAS_COLOR}function resolvedClusterCountColor(host,color){return resolvedMapPaintColor(host,color,!1)}function resolvedClusterStrokeColor(host,clusterStroke,layer){return resolvedMapPaintColor(host,clusterStroke,!0)??resolvedLayerColor(host,layer.strokeColor??layer.color,layer.tone)}function warnOnUntileableProperties(projection,sourceLabel){if(litDevWarnings())for(const feature of projection.diagnostics)for(const[key,value]of feature.properties){if(typeof value!="number"||!Number.isFinite(value)||Math.abs(value)<=Number.MAX_SAFE_INTEGER)continue;const identity=feature.id??`index ${feature.index}`;devWarnOnce(`lyra-map-untileable-property:${sourceLabel}:${key}`,`<lr-map>: feature ${String(identity)} in "${sourceLabel}" carries ${key}=${value}, which is too large to survive maplibre-gl's vector-tile encoding. Tiling happens in a worker, so the failure would reach you only as an opaque "Given varint doesn't fit into 10 bytes" error while the rest of the layer still paints. Carry a reduced figure in the feature and keep the exact value in your own data.`)}}class LyraMap extends LyraElement{static{this.defaultStrings={...super.defaultStrings,close:LYRA_DEFAULT_close,items:LYRA_DEFAULT_items,legendTypeHidden:LYRA_DEFAULT_legendTypeHidden,legendTypeShown:LYRA_DEFAULT_legendTypeShown,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,mapFeedback:LYRA_DEFAULT_mapFeedback,mapInitializationFailed:LYRA_DEFAULT_mapInitializationFailed,mapLegend:LYRA_DEFAULT_mapLegend,mapMarker:LYRA_DEFAULT_mapMarker,mapMissingLibrary:LYRA_DEFAULT_mapMissingLibrary,mapResetNorth:LYRA_DEFAULT_mapResetNorth,mapStyleRequired:LYRA_DEFAULT_mapStyleRequired,mapToggleAttribution:LYRA_DEFAULT_mapToggleAttribution,mapWebglUnavailable:LYRA_DEFAULT_mapWebglUnavailable,paginationSummary:LYRA_DEFAULT_paginationSummary,zoomIn:LYRA_DEFAULT_zoomIn,zoomOut:LYRA_DEFAULT_zoomOut}}static{this.collectionSupport=collectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-map-click","lr-map-legend-panel-toggle-request","lr-map-legend-toggle-request","lr-map-marker-activate","lr-map-view-change"])}static{this.identityEventDetailProperties=Object.freeze({"lr-map-click":Object.freeze(["feature"]),"lr-map-marker-activate":Object.freeze(["marker"])})}static{this.ownedCollectionProperties=Object.freeze(["center","mapStyle","choropleth","markers","dataLayers"])}static{this.identityCollectionProperties=Object.freeze(["markers","dataLayers"])}static{this.identityCollectionObjectProperties=Object.freeze(["choropleth"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static preload(){return loadMaplibre().then(module=>module!==null)}constructor(){super(),this.hostDescription=new HostDescriptionController(this,()=>this._map?.getCanvas?.()??null),this._center=Object.freeze([0,0]),this.zoom=2,this.fitToken=Object.freeze({}),this.semanticsStale=!0,this.boxZoomSettling=!1,this.writingCamera=!1,this.maxBounds=null,this._legend=EMPTY_MAP_LEGEND,this._legendProjection=EMPTY_MAP_LEGEND_PROJECTION,this._legendGrouped=!1,this.hasLegendSlot=!1,this.hasLegendStartSlot=!1,this._legendGradient=Object.freeze([]),this.legendIsLine=!1,this.legendGradientLoLabel=null,this.legendGradientHiLabel=null,this.legendInteractive=!1,this._legendControlRole="button",this.legendCollapsible=!1,this.legendOpen=!0,this._hiddenCategories=EMPTY_HIDDEN_CATEGORIES,this.markers=[],this.dataLayers=[],this._canonicalChoroplethSource=UNPROJECTED_MAP_VALUE,this._canonicalDataLayersSource=UNPROJECTED_MAP_VALUE,this._canonicalDataLayers=EMPTY_CANONICAL_MAP_DATA_LAYERS,this._canonicalMarkersSource=UNPROJECTED_MAP_VALUE,this._canonicalMarkers=EMPTY_CANONICAL_MAP_MARKERS,this.loading=!0,this.announcements=new AnnouncementSinkController(this,{eager:["assertive"]}),this.loadLibrary=loadMaplibre,this.visible=ownerWindow(this)?.IntersectionObserver===void 0,this._styleLoaded=!1,this._appliedDataLayerIds=new Map,this._appliedDataLayerShapes=new Map,this._appliedGeoJson=new Map,this._nextDataLayerId=0,this.nextPointIconId=0,this.appliedPointPaint=new Set,this.appliedPointMuting=new Set,this.appliedPointIcons=new Map,this._webglReady=!1,this._markerInstances=new Map,this._markerLabels=new Map,this._markerPopupIds=new Map,this.markerActivationDetails=new WeakMap,this._configuredPopups=new WeakSet,this._nextPopupId=0,this._markerColors=new Map,this._markerSources=new Map,this._connectGeneration=0,this._styleGeneration=0,this.configuredMarkerElements=new WeakSet,this.onLegendSlotChange=event=>{const slot=event.target,filled=slot.assignedNodes({flatten:!0}).some(node=>node.nodeType===Node.ELEMENT_NODE||(node.textContent??"").trim().length>0);slot.name==="legend-start"?this.hasLegendStartSlot=filled:this.hasLegendSlot=filled},new ThemeWatcher(this,()=>{this.refreshThemePaint(),this.legendIsLine=this.legendDescribesLine(),this.applyMarkers()}),new GlassScrollLayer(this,'[part="legend"]')}get center(){return this._center}set center(value){this._center=value}get legend(){return this._legend}set legend(value){if(value===this._legendSource||value===this._legend)return;this._legendSource=value;const previous=this._legend,normalized=normalizeMapLegend(value);this._legend=normalized.entries,this._legendProjection=normalized.projection,this._legendGrouped=normalized.grouped,this.requestUpdate("legend",previous)}probeLegendSlot(name){for(const child of Array.from(this.children))if(child.getAttribute("slot")===name)return!0;return!1}get legendGradient(){return this._legendGradient}set legendGradient(value){if(value===this._legendGradientSource||value===this._legendGradient)return;this._legendGradientSource=value;const previous=this._legendGradient;this._legendGradient=normalizeMapLegendGradient(value),this.requestUpdate("legendGradient",previous)}warnOnLegendChoroplethMismatch(){if(!litDevWarnings()||this.legendIsLine)return;const layer=this.canonicalChoropleth,legend=this.legendGradient;!layer||legend.length===0||layer.stops.length===0||legend.length===layer.stops.length&&legend.every(([legendValue,legendColor],index)=>{const layerStop=layer.stops[index];return layerStop!==void 0&&layerStop[0]===legendValue&&resolvedLayerColor(this,layerStop[1],void 0)===resolvedLayerColor(this,legendColor,void 0)})||devWarnOnce("lyra-map-legend-choropleth-mismatch",`<${this.localName}>: legendGradient does not match choropleth.stops, so the visible key may misdescribe the map. Assign the same stops array to both, or derive both from one source.`)}legendDescribesLine(){const stops=this.legendGradient;return stops.length<2?!1:this.canonicalDataLayers.some(layer=>layer.kind==="auto"&&!layer.cluster&&layer.line?.field&&layer.line.stops.length===stops.length&&layer.line.stops.every(([value,color],index)=>value===stops[index][0]&&resolvedLayerColor(this,color,layer.tone)===resolvedLayerColor(this,stops[index][1],layer.tone)))}get legendProjection(){return this._legendProjection}set legendProjection(_value){}get legendControlRole(){return this._legendControlRole}set legendControlRole(next){const normalized=LEGEND_CONTROL_ROLE.normalizeReflected(this,"legend-control-role",next),old=this._legendControlRole;old!==normalized&&(this._legendControlRole=normalized,this.requestUpdate("legendControlRole",old))}get legendCollapsed(){return this.legendCollapsible&&!this.legendOpen}toggleLegendPanel(){if(!this.legendCollapsible)return;const open=!this.legendOpen;this.emit("lr-map-legend-panel-toggle-request",{open},{cancelable:!0}).defaultPrevented||(this.legendOpen=open)}renderLegendDisclosure(){return this.legendCollapsible?html`<button
12
+ ></path></svg>`}function addPartToken(element,token){const tokens=new Set((element.getAttribute("part")??"").split(/\s+/).filter(Boolean));tokens.add(token),element.setAttribute("part",[...tokens].join(" "))}const CHOROPLETH_LOG_INTERPOLATION_BASE=.25,CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL=8;function choroplethLogInterpolationFactor(input,lower,upper){const difference=upper-lower;if(difference===0)return 0;const progress=input-lower;return(Math.pow(CHOROPLETH_LOG_INTERPOLATION_BASE,progress)-1)/(Math.pow(CHOROPLETH_LOG_INTERPOLATION_BASE,difference)-1)}function compactGradientPercent(value){return String(Math.round(Math.min(100,Math.max(0,value))*1e4)/1e4)}function choroplethLegendGradientImage(stops,interpolation){const lo=stops[0],span=stops[stops.length-1][0]-lo[0],stopPercent=(value,index)=>span>0?(value-lo[0])/span*100:index/(stops.length-1)*100;if(interpolation!=="logarithmic"||span<=0)return`linear-gradient(to right, ${stops.map(([value,color],index)=>`${color} ${compactGradientPercent(stopPercent(value,index))}%`).join(", ")})`;const image=[`${lo[1]} 0%`];for(let index=1;index<stops.length;index+=1){const lower=stops[index-1],upper=stops[index],interval=upper[0]-lower[0];if(interval<=0){image.push(`${upper[1]} ${compactGradientPercent(stopPercent(upper[0],index))}%`);continue}for(let sample=1;sample<=CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL;sample+=1){const intervalProgress=sample/CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL,input=lower[0]+interval*intervalProgress,position=(input-lo[0])/span*100;if(sample===CHOROPLETH_LEGEND_SAMPLES_PER_INTERVAL){image.push(`${upper[1]} ${compactGradientPercent(position)}%`);continue}const factor=Math.min(1,Math.max(0,choroplethLogInterpolationFactor(input,lower[0],upper[0]))),lowerWeight=compactGradientPercent((1-factor)*100),upperWeight=compactGradientPercent(factor*100);image.push(`color-mix(in srgb, ${lower[1]} ${lowerWeight}%, ${upper[1]} ${upperWeight}%) ${compactGradientPercent(position)}%`)}}return`linear-gradient(to right, ${image.join(", ")})`}const MAX_MAP_MARKERS=2e3;function popupText(host,markup){const template=host.ownerDocument.createElement("template");template.innerHTML=markup;for(const hidden of template.content.querySelectorAll('script, style, template, [hidden], [aria-hidden="true"]'))hidden.remove();return(template.content.textContent??"").replace(/\s+/gu," ").trim()}function markerPopupText(host,markup){return typeof markup=="string"&&markup?popupText(host,markup):""}const MAX_MAP_DATA_LAYERS=100,EMPTY_CANONICAL_MAP_DATA_LAYERS=Object.freeze([]);function mapTone(value){switch(value){case"accent":case"success":case"warning":case"danger":case"neutral":return value;default:return}}function projectMapDataLayer(value){try{if(!isRuntimeRecord(value))return;const sourceIdDescriptor=getOwnDataDescriptor(value,"sourceId"),geojsonDescriptor=getOwnDataDescriptor(value,"geojson"),toneDescriptor=getOwnDataDescriptor(value,"tone"),colorDescriptor=getOwnDataDescriptor(value,"color"),strokeColorDescriptor=getOwnDataDescriptor(value,"strokeColor"),lineDescriptor=getOwnDataDescriptor(value,"line"),kindDescriptor=getOwnDataDescriptor(value,"kind"),heatmapDescriptor=getOwnDataDescriptor(value,"heatmap"),clusterDescriptor=getOwnDataDescriptor(value,"cluster");if(sourceIdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||geojsonDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(sourceIdDescriptor)||isUnsafeDescriptor(geojsonDescriptor))return;const sourceId=sourceIdDescriptor.value,geojson=geojsonDescriptor.value;if(typeof sourceId!="string"||sourceId.trim().length===0||!isRuntimeRecord(geojson))return;const tone=mapTone(optionalDescriptorValue(toneDescriptor)),colorValue=optionalDescriptorValue(colorDescriptor),strokeColorValue=optionalDescriptorValue(strokeColorDescriptor),kindValue=optionalDescriptorValue(kindDescriptor),heatmapValue=optionalDescriptorValue(heatmapDescriptor),clusterValue=optionalDescriptorValue(clusterDescriptor),kind=kindValue==="heatmap"?"heatmap":"auto";return Object.freeze({sourceId:sourceId.trim(),geojson,geojsonProjection:projectAdmittedGeoJson(geojson),tone,color:typeof colorValue=="string"?colorValue:void 0,strokeColor:typeof strokeColorValue=="string"?strokeColorValue:void 0,line:kind==="auto"?projectLineOptions(optionalDescriptorValue(lineDescriptor)):void 0,point:kind==="auto"?projectPointOptions(optionalDescriptorValue(getOwnDataDescriptor(value,"point"))):void 0,kind,heatmap:kind==="heatmap"?projectHeatmapOptions(heatmapValue):void 0,cluster:kind==="auto"?normalizedClusterOptions(clusterValue):void 0})}catch{return}}function projectMapDataLayers(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_DATA_LAYERS);if(scanCount===void 0)return EMPTY_CANONICAL_MAP_DATA_LAYERS;const output=[],seenSourceIds=new Set;for(let index=0;index<scanCount;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));if(descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor))continue;const layer=projectMapDataLayer(descriptor.value);!layer||seenSourceIds.has(layer.sourceId)||(seenSourceIds.add(layer.sourceId),output.push(layer))}return output.length?Object.freeze(output):EMPTY_CANONICAL_MAP_DATA_LAYERS}catch{return EMPTY_CANONICAL_MAP_DATA_LAYERS}}const DATA_LAYER_SUFFIXES=["-fill","-line","-circle","-point-icon","-cluster","-cluster-count","-heatmap"],QUERYABLE_DATA_LAYER_SUFFIXES=["-fill","-line","-circle","-cluster","-point-icon"],MAX_MAP_STEP_STOPS=32;function normalizedSteps(value,isOutput,clampThreshold=threshold=>threshold){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_STEP_STOPS);if(scanCount===void 0)return Object.freeze([]);const usable=[];for(let index=0;index<scanCount;index+=1){const stopDescriptor=getOwnDataDescriptor(value,String(index));if(stopDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(stopDescriptor))continue;const stop=stopDescriptor.value,stopLength=boundedOwnArrayLength(stop,2);if(stopLength===void 0||stopLength<2)continue;const thresholdDescriptor=getOwnDataDescriptor(stop,"0"),outputDescriptor=getOwnDataDescriptor(stop,"1");thresholdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||outputDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(thresholdDescriptor)||isUnsafeDescriptor(outputDescriptor)||typeof thresholdDescriptor.value!="number"||!Number.isFinite(thresholdDescriptor.value)||!isOutput(outputDescriptor.value)||usable.push([clampThreshold(thresholdDescriptor.value),outputDescriptor.value])}usable.sort((a,b)=>a[0]-b[0]);const deduplicated=usable.filter((stop,index)=>index===0||stop[0]>usable[index-1][0]);return Object.freeze(deduplicated.map(stop=>Object.freeze(stop)))}catch{return Object.freeze([])}}const isFiniteOutput=candidate=>typeof candidate=="number"&&Number.isFinite(candidate),isColorOutput=candidate=>typeof candidate=="string"&&candidate.trim().length>0,DEFAULT_CLUSTER_RADIUS=50,DEFAULT_CLUSTER_MAX_ZOOM=14,DEFAULT_CLUSTER_RADIUS_STEPS=Object.freeze([[0,14],[10,18],[50,24]]),DEFAULT_HEATMAP_RADIUS=30,DEFAULT_HEATMAP_INTENSITY=1,MAX_CLUSTER_COUNT_FONTS=8;function normalizedClusterOptions(value){try{if(!isRuntimeRecord(value))return;const radiusDescriptor=getOwnDataDescriptor(value,"radius"),maxZoomDescriptor=getOwnDataDescriptor(value,"maxZoom"),radiusStepsDescriptor=getOwnDataDescriptor(value,"radiusSteps"),colorStepsDescriptor=getOwnDataDescriptor(value,"colorSteps"),strokeColorDescriptor=getOwnDataDescriptor(value,"strokeColor"),countFontDescriptor=getOwnDataDescriptor(value,"countFont"),countColorDescriptor=getOwnDataDescriptor(value,"countColor"),countHaloColorDescriptor=getOwnDataDescriptor(value,"countHaloColor"),countHaloWidthDescriptor=getOwnDataDescriptor(value,"countHaloWidth"),radiusValue=optionalDescriptorValue(radiusDescriptor),maxZoomValue=optionalDescriptorValue(maxZoomDescriptor),radiusSteps=normalizedSteps(optionalDescriptorValue(radiusStepsDescriptor),isFiniteOutput),colorSteps=normalizedSteps(optionalDescriptorValue(colorStepsDescriptor),isColorOutput),fonts=normalizedClusterFonts(optionalDescriptorValue(countFontDescriptor)),countHaloWidthValue=optionalDescriptorValue(countHaloWidthDescriptor);return Object.freeze({radius:finiteRange(typeof radiusValue=="number"?radiusValue:Number.NaN,DEFAULT_CLUSTER_RADIUS,1,1e3),maxZoom:finiteRange(typeof maxZoomValue=="number"?maxZoomValue:Number.NaN,DEFAULT_CLUSTER_MAX_ZOOM,0,24),radiusSteps:radiusSteps.length?radiusSteps:DEFAULT_CLUSTER_RADIUS_STEPS,colorSteps,strokeColor:sanitizeCssColor(optionalDescriptorValue(strokeColorDescriptor)),countFont:fonts.length?fonts:void 0,countColor:sanitizeCssColor(optionalDescriptorValue(countColorDescriptor)),countHaloColor:sanitizeCssColor(optionalDescriptorValue(countHaloColorDescriptor)),countHaloWidth:countHaloWidthValue===void 0?1:finiteRange(typeof countHaloWidthValue=="number"?countHaloWidthValue:Number.NaN,1,0,3)})}catch{return}}function normalizedClusterFonts(value){try{const length=boundedOwnArrayLength(value,MAX_CLUSTER_COUNT_FONTS);if(length===void 0)return Object.freeze([]);const fonts=[];for(let index=0;index<length;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor)||typeof descriptor.value!="string"||descriptor.value.trim().length===0||fonts.push(descriptor.value)}return Object.freeze(fonts)}catch{return Object.freeze([])}}const DEFAULT_ICON_VIEW_BOX=Object.freeze([0,0,24,24]),DEFAULT_ICON_STROKE_WIDTH=2,ICON_PATH_GRAMMAR=/^[MmLlHhVvCcSsQqTtAaZz\d.eE+,\s-]+$/u,MAX_ICON_PATH_LENGTH=8192;function projectIconPaint(row){const path=optionalDescriptorValue(getOwnDataDescriptor(row,"path"));if(typeof path!="string"||path.length===0||path.length>MAX_ICON_PATH_LENGTH||!ICON_PATH_GRAMMAR.test(path))return;const rawBox=optionalDescriptorValue(getOwnDataDescriptor(row,"viewBox")),box=[];if(rawBox===void 0)box.push(...DEFAULT_ICON_VIEW_BOX);else{if(boundedOwnArrayLength(rawBox,4)!==4)return;for(let index=0;index<4;index++){const coordinate=optionalDescriptorValue(getOwnDataDescriptor(rawBox,String(index)));if(typeof coordinate!="number"||!Number.isFinite(coordinate)||Math.abs(coordinate)>1e4)return;box.push(coordinate)}if(box[2]<.001||box[3]<.001)return}const mode=optionalDescriptorValue(getOwnDataDescriptor(row,"mode")),strokeWidth=optionalDescriptorValue(getOwnDataDescriptor(row,"strokeWidth")),lineCap=optionalDescriptorValue(getOwnDataDescriptor(row,"lineCap")),lineJoin=optionalDescriptorValue(getOwnDataDescriptor(row,"lineJoin"));return Object.freeze({path,viewBox:Object.freeze(box),mode:mode==="stroke"||mode==="fill-stroke"?mode:"fill",strokeWidth:finiteRange(typeof strokeWidth=="number"?strokeWidth:NaN,DEFAULT_ICON_STROKE_WIDTH,0,200),lineCap:lineCap==="butt"||lineCap==="square"?lineCap:"round",lineJoin:lineJoin==="miter"||lineJoin==="bevel"?lineJoin:"round"})}function projectPointRadius(value){if(!isRuntimeRecord(value))return finiteRange(typeof value=="number"?value:NaN,5,0,200);const read=key=>optionalDescriptorValue(getOwnDataDescriptor(value,key)),field=read("field"),rawFallback=read("fallback"),fallback=finiteRange(typeof rawFallback=="number"?rawFallback:NaN,5,0,200),stops=normalizedSteps(read("stops"),isFiniteOutput).map(([threshold,radius])=>Object.freeze([threshold,finiteRange(radius,5,0,200)]));return typeof field!="string"||!field.trim()||!stops.length?fallback:Object.freeze({field:field.trim(),stops:Object.freeze(stops),fallback,interpolation:read("interpolation")==="linear"?"linear":"step"})}function projectPointOptions(value){if(!isRuntimeRecord(value))return;const read=key=>optionalDescriptorValue(getOwnDataDescriptor(value,key)),string=key=>{const candidate=read(key);return typeof candidate=="string"&&candidate.trim()?candidate:void 0},number=(key,fallback,min,max)=>{const candidate=read(key);return finiteRange(typeof candidate=="number"?candidate:NaN,fallback,min,max)},colors=[],icons=[],project=(input,accept)=>{const length=boundedOwnArrayLength(input,MAX_MAP_STEP_STOPS)??0;for(let index=0;index<length;index++){const row=optionalDescriptorValue(getOwnDataDescriptor(input,String(index)));row!==null&&typeof row=="object"&&accept(row)}};return project(read("colors"),row=>{const key=optionalDescriptorValue(getOwnDataDescriptor(row,"0")),color=optionalDescriptorValue(getOwnDataDescriptor(row,"1"));typeof key!="string"||typeof color!="string"||!sanitizeCssColor(color)||colors.some(([existing])=>existing===key)||colors.push(Object.freeze([key,color]))}),project(read("icons"),row=>{const key=optionalDescriptorValue(getOwnDataDescriptor(row,"value"));if(typeof key!="string"||icons.some(icon=>icon.value===key))return;const paint=projectIconPaint(row);paint&&icons.push(Object.freeze({value:key,...paint}))}),Object.freeze({field:string("field"),colors:Object.freeze(colors),radius:projectPointRadius(read("radius")),strokeWidth:number("strokeWidth",0,0,200),strokeColor:string("strokeColor"),iconField:string("iconField")??string("field"),icons:Object.freeze(icons),iconColor:string("iconColor"),iconSize:number("iconSize",16,1,200)})}const POINT_ICON_RASTER_SIZE=64;function rasterPointIcon(host,icon,color){try{const canvas=host.ownerDocument.createElement("canvas");canvas.width=canvas.height=POINT_ICON_RASTER_SIZE;const context=canvas.getContext("2d"),Path=host.ownerDocument.defaultView?.Path2D;if(!context||!Path)return;const[x,y,width,height]=icon.viewBox,scale=POINT_ICON_RASTER_SIZE/Math.max(width,height);context.translate((POINT_ICON_RASTER_SIZE-width*scale)/2,(POINT_ICON_RASTER_SIZE-height*scale)/2),context.scale(scale,scale),context.translate(-x,-y);const path=new Path(icon.path);return icon.mode!=="stroke"&&(context.fillStyle=color,context.fill(path)),icon.mode!=="fill"&&icon.strokeWidth>0&&(context.strokeStyle=color,context.lineWidth=icon.strokeWidth,context.lineCap=icon.lineCap,context.lineJoin=icon.lineJoin,context.stroke(path)),context.getImageData(0,0,POINT_ICON_RASTER_SIZE,POINT_ICON_RASTER_SIZE)}catch{return}}function projectLineOptions(value){try{if(!isRuntimeRecord(value))return;const field=optionalDescriptorValue(getOwnDataDescriptor(value,"field")),width=optionalDescriptorValue(getOwnDataDescriptor(value,"width")),opacity=optionalDescriptorValue(getOwnDataDescriptor(value,"opacity"));return Object.freeze({field:typeof field=="string"&&field.trim()?field.trim():void 0,stops:Object.freeze(normalizeMapLegendGradient(optionalDescriptorValue(getOwnDataDescriptor(value,"stops"))).filter((stop,index,stops)=>index===0||stop[0]>stops[index-1][0]).map(stop=>Object.freeze(stop))),width:typeof width=="number"?finiteRange(width,2,0,200):2,opacity:typeof opacity=="number"?finiteRange(opacity,1,0,1):1})}catch{return}}function projectedHeatmapRange(value){try{const length=boundedOwnArrayLength(value,2);if(length===void 0||length<2)return;const minDescriptor=getOwnDataDescriptor(value,"0"),maxDescriptor=getOwnDataDescriptor(value,"1");return minDescriptor===MISSING_OWN_DATA_DESCRIPTOR||maxDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(minDescriptor)||isUnsafeDescriptor(maxDescriptor)||typeof minDescriptor.value!="number"||typeof maxDescriptor.value!="number"||!Number.isFinite(minDescriptor.value)||!Number.isFinite(maxDescriptor.value)?void 0:Object.freeze([minDescriptor.value,maxDescriptor.value])}catch{return}}function projectedHeatmapZoomValue(value){if(typeof value=="number"&&Number.isFinite(value))return value;if(isRuntimeArray(value))return normalizedSteps(value,isFiniteOutput,zoom=>finiteRange(zoom,0,0,24))}function projectHeatmapOptions(value){try{if(!isRuntimeRecord(value))return;const weightFieldDescriptor=getOwnDataDescriptor(value,"weightField"),weightRangeDescriptor=getOwnDataDescriptor(value,"weightRange"),stopsDescriptor=getOwnDataDescriptor(value,"stops"),radiusDescriptor=getOwnDataDescriptor(value,"radius"),intensityDescriptor=getOwnDataDescriptor(value,"intensity"),opacityDescriptor=getOwnDataDescriptor(value,"opacity"),weightFieldValue=optionalDescriptorValue(weightFieldDescriptor),opacityValue=optionalDescriptorValue(opacityDescriptor);return Object.freeze({weightField:typeof weightFieldValue=="string"&&weightFieldValue.trim().length>0?weightFieldValue.trim():void 0,weightRange:projectedHeatmapRange(optionalDescriptorValue(weightRangeDescriptor)),stops:normalizedSteps(optionalDescriptorValue(stopsDescriptor),isColorOutput,density=>finiteRange(density,0,0,1)),radius:projectedHeatmapZoomValue(optionalDescriptorValue(radiusDescriptor)),intensity:projectedHeatmapZoomValue(optionalDescriptorValue(intensityDescriptor)),opacity:typeof opacityValue=="number"&&Number.isFinite(opacityValue)?opacityValue:void 0})}catch{return}}function dataLayerShape(layer){if(layer.kind==="heatmap")return"heatmap";const cluster=layer.cluster;return cluster?`cluster:${cluster.radius}:${cluster.maxZoom}:${cluster.countFont?.join(",")??""}`:"auto"}function projectMapChoropleth(value){try{if(!isRuntimeRecord(value))return;const sourceIdDescriptor=getOwnDataDescriptor(value,"sourceId"),geojsonDescriptor=getOwnDataDescriptor(value,"geojson"),fieldDescriptor=getOwnDataDescriptor(value,"field"),stopsDescriptor=getOwnDataDescriptor(value,"stops"),interpolationDescriptor=getOwnDataDescriptor(value,"interpolation"),stepBaseColorDescriptor=getOwnDataDescriptor(value,"stepBaseColor");if(sourceIdDescriptor===MISSING_OWN_DATA_DESCRIPTOR||geojsonDescriptor===MISSING_OWN_DATA_DESCRIPTOR||fieldDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(sourceIdDescriptor)||isUnsafeDescriptor(geojsonDescriptor)||isUnsafeDescriptor(fieldDescriptor))return;const sourceId=sourceIdDescriptor.value,geojson=geojsonDescriptor.value,field=fieldDescriptor.value;if(typeof sourceId!="string"||sourceId.trim().length===0||!isRuntimeRecord(geojson)||typeof field!="string"||field.trim().length===0)return;const interpolationValue=optionalDescriptorValue(interpolationDescriptor),stepBaseColorValue=optionalDescriptorValue(stepBaseColorDescriptor),interpolation=interpolationValue==="logarithmic"||interpolationValue==="step"?interpolationValue:"linear";return Object.freeze({sourceId:sourceId.trim(),geojson,geojsonProjection:projectAdmittedGeoJson(geojson),field:field.trim(),stops:normalizedSteps(optionalDescriptorValue(stopsDescriptor),isColorOutput),interpolation,stepBaseColor:typeof stepBaseColorValue=="string"&&stepBaseColorValue.trim().length>0?stepBaseColorValue:void 0})}catch{return}}const EMPTY_CANONICAL_MAP_MARKERS=Object.freeze([]),UNPROJECTED_MAP_VALUE=Symbol("unprojected-map-value");function projectMarkerLngLat(value){try{const length=boundedOwnArrayLength(value,2);if(length===void 0||length<2)return;const lngDescriptor=getOwnDataDescriptor(value,"0"),latDescriptor=getOwnDataDescriptor(value,"1");return lngDescriptor===MISSING_OWN_DATA_DESCRIPTOR||latDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(lngDescriptor)||isUnsafeDescriptor(latDescriptor)||typeof lngDescriptor.value!="number"||typeof latDescriptor.value!="number"||!Number.isFinite(lngDescriptor.value)||!Number.isFinite(latDescriptor.value)||latDescriptor.value<-90||latDescriptor.value>90?void 0:Object.freeze([lngDescriptor.value,latDescriptor.value])}catch{return}}function projectMapMarker(value){try{if(!isRuntimeRecord(value))return;const idDescriptor=getOwnDataDescriptor(value,"id"),lngLatDescriptor=getOwnDataDescriptor(value,"lngLat"),colorDescriptor=getOwnDataDescriptor(value,"color"),labelDescriptor=getOwnDataDescriptor(value,"label"),unsafeHtmlDescriptor=getOwnDataDescriptor(value,"unsafeHtml");if(lngLatDescriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(idDescriptor)||isUnsafeDescriptor(lngLatDescriptor)||isUnsafeDescriptor(colorDescriptor)||isUnsafeDescriptor(labelDescriptor)||isUnsafeDescriptor(unsafeHtmlDescriptor))return;const lngLat=projectMarkerLngLat(lngLatDescriptor.value),idValue=optionalDescriptorValue(idDescriptor),labelValue=optionalDescriptorValue(labelDescriptor);if(!lngLat||idValue!==void 0&&typeof idValue!="string"||typeof idValue=="string"&&idValue.trim().length===0||labelValue!==void 0&&typeof labelValue!="string")return;const colorValue=optionalDescriptorValue(colorDescriptor);return Object.freeze({id:typeof idValue=="string"?idValue.trim():void 0,lngLat,color:typeof colorValue=="string"?colorValue:void 0,label:typeof labelValue=="string"?labelValue:void 0,unsafeHtml:optionalDescriptorValue(unsafeHtmlDescriptor)})}catch{return}}function projectMapMarkers(value){try{const scanCount=boundedOwnArrayLength(value,MAX_MAP_MARKERS);if(scanCount===void 0)return EMPTY_CANONICAL_MAP_MARKERS;const output=[],explicitIds=new Set;for(let index=0;index<scanCount;index+=1){const descriptor=getOwnDataDescriptor(value,String(index));if(descriptor===MISSING_OWN_DATA_DESCRIPTOR||isUnsafeDescriptor(descriptor))continue;const marker=projectMapMarker(descriptor.value);!marker||marker.id!==void 0&&explicitIds.has(marker.id)||(marker.id!==void 0&&explicitIds.add(marker.id),output.push(marker))}return output.length?Object.freeze(output):EMPTY_CANONICAL_MAP_MARKERS}catch{return EMPTY_CANONICAL_MAP_MARKERS}}function setPopupContent(popup,marker){const options=popup.options,focus=options?.focusAfterOpen;return options&&(options.focusAfterOpen=!1),marker.unsafeHtml?popup.setHTML(marker.unsafeHtml):popup.setText(marker.label),options&&(options.focusAfterOpen=focus),popup}const FIT_EVENT_KEY="lyraMapFit";function snapshotCenter(center){return Array.isArray(center)?[center[0],center[1]]:center}function sameCenterValue(a,b){return Array.isArray(a)&&Array.isArray(b)?Object.is(a[0],b[0])&&Object.is(a[1],b[1]):Object.is(a,b)}function isFiniteCoordinate(value){return typeof value=="number"&&Number.isFinite(value)}function normalizeFitBounds(bounds){if(!Array.isArray(bounds)||bounds.length!==2)return;const[southWest,northEast]=bounds;if(!Array.isArray(southWest)||!Array.isArray(northEast)||southWest.length!==2||northEast.length!==2)return;const[west,south]=southWest,[east,north]=northEast;if(!(!isFiniteCoordinate(west)||!isFiniteCoordinate(south)||!isFiniteCoordinate(east)||!isFiniteCoordinate(north))&&!(west<-180||west>180||east<-180||east>west+360)&&!(south<-90||north>90||south>north))return Object.freeze([Object.freeze([west,south]),Object.freeze([west>east?east+360:east,north])])}function normalizeFitPadding(padding){const side=value=>finiteRange(typeof value=="number"?value:0,0,0);if(typeof padding=="number"){const all=side(padding);return Object.freeze({top:all,right:all,bottom:all,left:all})}const record=typeof padding=="object"&&padding!==null?padding:{};return Object.freeze({top:side(record.top),right:side(record.right),bottom:side(record.bottom),left:side(record.left)})}function wrapLongitude(longitude){if(longitude>=-180&&longitude<=180)return longitude;const wrapped=((longitude+180)%360+360)%360-180;return wrapped===-180?180:wrapped}function readPeerCamera(map){let longitude,latitude,zoom;try{({lng:longitude,lat:latitude}=map.getCenter()),zoom=map.getZoom()}catch{return}if(!(!isFiniteCoordinate(longitude)||!isFiniteCoordinate(latitude)||!isFiniteCoordinate(zoom)))return{center:[wrapLongitude(longitude),finiteRange(latitude,0,-90,90)],zoom}}const FALLBACK_FILL_OPACITY=.75;function ownerWindow(host){return host.ownerDocument?.defaultView??null}function choroplethFillOpacity(host){const raw=ownerWindow(host)?.getComputedStyle(host).getPropertyValue("--lr-map-choropleth-fill-opacity").trim()??"",parsed=Number.parseFloat(raw);return Number.isFinite(parsed)?parsed:FALLBACK_FILL_OPACITY}const FALLBACK_HIDDEN_CATEGORY_OPACITY=.15;function hiddenCategoryOpacity(host){const raw=ownerWindow(host)?.getComputedStyle(host).getPropertyValue("--lr-map-hidden-category-opacity").trim()??"";return finiteRange(Number.parseFloat(raw),FALLBACK_HIDDEN_CATEGORY_OPACITY,0,1)}const TONE_TOKEN={accent:"--lr-color-brand",success:"--lr-color-success",warning:"--lr-color-warning",danger:"--lr-color-danger",neutral:"--lr-color-text-quiet"},ON_TONE_TOKEN={accent:"--lr-color-on-brand",success:"--lr-color-on-success",warning:"--lr-color-on-warning",danger:"--lr-color-on-danger",neutral:"--lr-color-on-neutral"},HEATMAP_RAMP_TOKENS=Object.freeze([[.25,"--lr-color-brand"],[.5,"--lr-color-success"],[.75,"--lr-color-warning"],[1,"--lr-color-danger"]]);function dataLayerColor(host,tone){const token=TONE_TOKEN[tone??"accent"];return(ownerWindow(host)?.getComputedStyle(host).getPropertyValue(token).trim()??"")||DEFAULT_CANVAS_COLOR}const BASIC_MAP_PAINT_COLOR_NAMES=new Set(["aqua","black","blue","fuchsia","gray","green","lime","maroon","navy","olive","purple","red","silver","teal","white","yellow","transparent"]);function resolvedMapPaintColor(host,color,preserveLegacy){const candidate=typeof color=="string"?color.trim():"";if(!candidate)return;if(preserveLegacy){const reference=/^var\(\s*(--[\w-]+)\s*\)$/.exec(candidate),plain=reference?ownerWindow(host)?.getComputedStyle(host).getPropertyValue(reference[1]).trim()??"":candidate,namedPeerColor=BASIC_MAP_PAINT_COLOR_NAMES.has(plain.toLowerCase());if(/^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$/i.test(plain)||(/^rgba?\([\d\s.,/]+\)$/i.test(plain)||namedPeerColor)&&typeof CSS<"u"&&CSS.supports("color",plain))return plain}const resolved=resolveCanvasColor(host,candidate,"");if(!resolved)return;if(/^rgba?\(/i.test(resolved))return resolved;const canvas=host.ownerDocument.createElement("canvas");canvas.width=1,canvas.height=1;try{const context=canvas.getContext("2d",{colorSpace:"srgb",willReadFrequently:!0});if(!context)return;let accepted=!1;for(const sentinel of["rgb(1, 2, 3)","rgb(4, 5, 6)"]){context.fillStyle=sentinel;const before=context.fillStyle;if(context.fillStyle=resolved,context.fillStyle!==before){accepted=!0;break}}if(!accepted)return;context.fillRect(0,0,1,1);const[r=0,g=0,b=0,a=0]=context.getImageData(0,0,1,1).data;return a===255?`rgb(${r}, ${g}, ${b})`:`rgba(${r}, ${g}, ${b}, ${Math.round(a/255*1e3)/1e3})`}catch{return}}function resolvedLayerColor(host,explicit,tone){return resolvedMapPaintColor(host,explicit,!0)??resolvedMapPaintColor(host,dataLayerColor(host,tone),!0)??DEFAULT_CANVAS_COLOR}function resolvedClusterCountColor(host,color){return resolvedMapPaintColor(host,color,!1)}function resolvedClusterStrokeColor(host,clusterStroke,layer){return resolvedMapPaintColor(host,clusterStroke,!0)??resolvedLayerColor(host,layer.strokeColor??layer.color,layer.tone)}function warnOnUntileableProperties(projection,sourceLabel){if(litDevWarnings())for(const feature of projection.diagnostics)for(const[key,value]of feature.properties){if(typeof value!="number"||!Number.isFinite(value)||Math.abs(value)<=Number.MAX_SAFE_INTEGER)continue;const identity=feature.id??`index ${feature.index}`;devWarnOnce(`lyra-map-untileable-property:${sourceLabel}:${key}`,`<lr-map>: feature ${String(identity)} in "${sourceLabel}" carries ${key}=${value}, which is too large to survive maplibre-gl's vector-tile encoding. Tiling happens in a worker, so the failure would reach you only as an opaque "Given varint doesn't fit into 10 bytes" error while the rest of the layer still paints. Carry a reduced figure in the feature and keep the exact value in your own data.`)}}class LyraMap extends LyraElement{static{this.defaultStrings={...super.defaultStrings,close:LYRA_DEFAULT_close,items:LYRA_DEFAULT_items,legendTypeHidden:LYRA_DEFAULT_legendTypeHidden,legendTypeShown:LYRA_DEFAULT_legendTypeShown,loading:LYRA_DEFAULT_loading,map:LYRA_DEFAULT_map,mapFeedback:LYRA_DEFAULT_mapFeedback,mapInitializationFailed:LYRA_DEFAULT_mapInitializationFailed,mapLegend:LYRA_DEFAULT_mapLegend,mapMarker:LYRA_DEFAULT_mapMarker,mapMissingLibrary:LYRA_DEFAULT_mapMissingLibrary,mapResetNorth:LYRA_DEFAULT_mapResetNorth,mapStyleRequired:LYRA_DEFAULT_mapStyleRequired,mapToggleAttribution:LYRA_DEFAULT_mapToggleAttribution,mapWebglUnavailable:LYRA_DEFAULT_mapWebglUnavailable,paginationSummary:LYRA_DEFAULT_paginationSummary,zoomIn:LYRA_DEFAULT_zoomIn,zoomOut:LYRA_DEFAULT_zoomOut}}static{this.collectionSupport=collectionSupport}static{this.immutableEventDetails=Object.freeze(["lr-map-click","lr-map-legend-panel-toggle-request","lr-map-legend-toggle-request","lr-map-marker-activate","lr-map-view-change"])}static{this.identityEventDetailProperties=Object.freeze({"lr-map-click":Object.freeze(["feature"]),"lr-map-marker-activate":Object.freeze(["marker"])})}static{this.ownedCollectionProperties=Object.freeze(["center","mapStyle","choropleth","markers","dataLayers"])}static{this.identityCollectionProperties=Object.freeze(["markers","dataLayers"])}static{this.identityCollectionObjectProperties=Object.freeze(["choropleth"])}static{this.styles=[LyraElement.styles,styles,srOnly]}static preload(engine="modular"){return(engine==="maplibre"?loadMaplibre():loadModularMap()).then(module=>module!==null)}constructor(){super(),this.hostDescription=new HostDescriptionController(this,()=>this._map?.getCanvas?.()??null),this._center=Object.freeze([0,0]),this.zoom=2,this.fitToken=Object.freeze({}),this.semanticsStale=!0,this.boxZoomSettling=!1,this.writingCamera=!1,this.maxBounds=null,this._legend=EMPTY_MAP_LEGEND,this._legendProjection=EMPTY_MAP_LEGEND_PROJECTION,this._legendGrouped=!1,this.hasLegendSlot=!1,this.hasLegendStartSlot=!1,this._legendGradient=Object.freeze([]),this.legendIsLine=!1,this.legendGradientLoLabel=null,this.legendGradientHiLabel=null,this.legendInteractive=!1,this._legendControlRole="button",this.legendCollapsible=!1,this.legendOpen=!0,this._hiddenCategories=EMPTY_HIDDEN_CATEGORIES,this.markers=[],this.dataLayers=[],this._canonicalChoroplethSource=UNPROJECTED_MAP_VALUE,this._canonicalDataLayersSource=UNPROJECTED_MAP_VALUE,this._canonicalDataLayers=EMPTY_CANONICAL_MAP_DATA_LAYERS,this._canonicalMarkersSource=UNPROJECTED_MAP_VALUE,this._canonicalMarkers=EMPTY_CANONICAL_MAP_MARKERS,this.engine="modular",this.loading=!0,this.announcements=new AnnouncementSinkController(this,{eager:["assertive"]}),this.loadLibrary=engine=>engine==="maplibre"?loadMaplibre():loadModularMap(),this.visible=ownerWindow(this)?.IntersectionObserver===void 0,this._styleLoaded=!1,this._appliedDataLayerIds=new Map,this._appliedDataLayerShapes=new Map,this._appliedGeoJson=new Map,this._nextDataLayerId=0,this.nextPointIconId=0,this.appliedPointPaint=new Set,this.appliedPointMuting=new Set,this.appliedPointIcons=new Map,this._webglReady=!1,this._markerInstances=new Map,this._markerLabels=new Map,this._markerPopupIds=new Map,this.markerActivationDetails=new WeakMap,this._configuredPopups=new WeakSet,this._nextPopupId=0,this._markerColors=new Map,this._markerSources=new Map,this._connectGeneration=0,this._styleGeneration=0,this.featureGeneration=0,this.preparingFeatures=!1,this.pendingMapLoad=!1,this.rebuildGeneratedLayers=!1,this.configuredMarkerElements=new WeakSet,this.onLegendSlotChange=event=>{const slot=event.target,filled=slot.assignedNodes({flatten:!0}).some(node=>node.nodeType===Node.ELEMENT_NODE||(node.textContent??"").trim().length>0);slot.name==="legend-start"?this.hasLegendStartSlot=filled:this.hasLegendSlot=filled},new ThemeWatcher(this,()=>{this.refreshThemePaint(),this.legendIsLine=this.legendDescribesLine(),this.applyMarkers()}),new GlassScrollLayer(this,'[part="legend"]')}get center(){return this._center}set center(value){this._center=value}get legend(){return this._legend}set legend(value){if(value===this._legendSource||value===this._legend)return;this._legendSource=value;const previous=this._legend,normalized=normalizeMapLegend(value);this._legend=normalized.entries,this._legendProjection=normalized.projection,this._legendGrouped=normalized.grouped,this.requestUpdate("legend",previous)}probeLegendSlot(name){for(const child of Array.from(this.children))if(child.getAttribute("slot")===name)return!0;return!1}get legendGradient(){return this._legendGradient}set legendGradient(value){if(value===this._legendGradientSource||value===this._legendGradient)return;this._legendGradientSource=value;const previous=this._legendGradient;this._legendGradient=normalizeMapLegendGradient(value),this.requestUpdate("legendGradient",previous)}warnOnLegendChoroplethMismatch(){if(!litDevWarnings()||this.legendIsLine)return;const layer=this.canonicalChoropleth,legend=this.legendGradient;!layer||legend.length===0||layer.stops.length===0||legend.length===layer.stops.length&&legend.every(([legendValue,legendColor],index)=>{const layerStop=layer.stops[index];return layerStop!==void 0&&layerStop[0]===legendValue&&resolvedLayerColor(this,layerStop[1],void 0)===resolvedLayerColor(this,legendColor,void 0)})||devWarnOnce("lyra-map-legend-choropleth-mismatch",`<${this.localName}>: legendGradient does not match choropleth.stops, so the visible key may misdescribe the map. Assign the same stops array to both, or derive both from one source.`)}legendDescribesLine(){const stops=this.legendGradient;return stops.length<2?!1:this.canonicalDataLayers.some(layer=>layer.kind==="auto"&&!layer.cluster&&layer.line?.field&&layer.line.stops.length===stops.length&&layer.line.stops.every(([value,color],index)=>value===stops[index][0]&&resolvedLayerColor(this,color,layer.tone)===resolvedLayerColor(this,stops[index][1],layer.tone)))}get legendProjection(){return this._legendProjection}set legendProjection(_value){}get legendControlRole(){return this._legendControlRole}set legendControlRole(next){const normalized=LEGEND_CONTROL_ROLE.normalizeReflected(this,"legend-control-role",next),old=this._legendControlRole;old!==normalized&&(this._legendControlRole=normalized,this.requestUpdate("legendControlRole",old))}get legendCollapsed(){return this.legendCollapsible&&!this.legendOpen}toggleLegendPanel(){if(!this.legendCollapsible)return;const open=!this.legendOpen;this.emit("lr-map-legend-panel-toggle-request",{open},{cancelable:!0}).defaultPrevented||(this.legendOpen=open)}renderLegendDisclosure(){return this.legendCollapsible?html`<button
13
13
  part="legend-disclosure"
14
14
  type="button"
15
15
  aria-expanded=${this.legendOpen?"true":"false"}
@@ -17,7 +17,7 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
17
17
  @click=${()=>this.toggleLegendPanel()}
18
18
  ><span part="legend-disclosure-icon" class="legend-disclosure-icon" aria-hidden="true"
19
19
  >${chevronIcon()}</span
20
- ><span>${this.localize("mapLegend")}</span></button>`:nothing}get hiddenCategories(){return this._hiddenCategories}set hiddenCategories(value){if(value===this._hiddenCategoriesSource||value===this._hiddenCategories)return;this._hiddenCategoriesSource=value;const previous=this._hiddenCategories;this._hiddenCategories=normalizeMapHiddenCategories(value),this.requestUpdate("hiddenCategories",previous)}get canonicalChoropleth(){const source=this.choropleth;return Object.is(source,this._canonicalChoroplethSource)?this._canonicalChoropleth:(this._canonicalChoroplethSource=source,this._canonicalChoropleth=projectMapChoropleth(source),this._canonicalChoropleth)}get canonicalDataLayers(){const source=this.dataLayers;return Object.is(source,this._canonicalDataLayersSource)?this._canonicalDataLayers:(this._canonicalDataLayersSource=source,this._canonicalDataLayers=projectMapDataLayers(source),this._canonicalDataLayers)}get canonicalMarkers(){const source=this.markers;return Object.is(source,this._canonicalMarkersSource)?this._canonicalMarkers:(this._canonicalMarkersSource=source,this._canonicalMarkers=projectMapMarkers(source),this._canonicalMarkers)}get map(){return this._map}pushGeoJson(source,resolvedSourceId,geojson,projection=projectGeoJson(geojson)){const previous=this._appliedGeoJson.get(resolvedSourceId);if(previous===projection)return;const diff=typeof source.updateData=="function"&&previous!==void 0?buildProjectedGeoJsonPropertyDiff(previous,projection):null;diff===null||typeof source.updateData!="function"?source.setData(geojson):(diff.update.length>0||diff.add?.length||diff.remove?.length)&&source.updateData(diff),this._appliedGeoJson.set(resolvedSourceId,projection)}get safeMaxBounds(){const bounds=this.maxBounds;if(!Array.isArray(bounds)||bounds.length!==2)return null;const[southWest,northEast]=bounds;if(!Array.isArray(southWest)||!Array.isArray(northEast))return null;const[west,south]=southWest,[east,north]=northEast,values=[west,south,east,north].map(Number);if(!values.every(value=>Number.isFinite(value)))return null;const[w,s,e,n]=values;return w>=e||s>=n||w<-180||e>180||s<-90||n>90?null:[[w,s],[e,n]]}applyMaxBounds(){const map=this._map;if(!map||typeof map.setMaxBounds!="function")return;const bounds=this.safeMaxBounds;let zoomBefore,centerBefore;try{if(zoomBefore=map.getZoom(),centerBefore=map.getCenter(),map.setMaxBounds(bounds),bounds===null||Number.isFinite(map.getZoom()))return}catch{}try{map.setMaxBounds(null)}catch{}typeof zoomBefore=="number"&&Number.isFinite(zoomBefore)&&map.setZoom(zoomBefore),centerBefore&&map.setCenter([centerBefore.lng,centerBefore.lat]),devWarnOnce("lyra-map-max-bounds-rejected","<lr-map>: maxBounds left maplibre-gl without a usable camera, so it was dropped and the camera restored. This is a peer limitation, not a bad value -- it shows up at sub-1 fractional zooms in wide containers. Raise the zoom, narrow the box, or leave maxBounds unset.")}get safeZoom(){return finiteRange(this.zoom,2,0,22)}get safeCenter(){const center=Array.isArray(this.center)?this.center:[];return[finiteRange(Number(center[0]),0,-180,180),finiteRange(Number(center[1]),0,-90,90)]}fitBounds(bounds,options={}){const box=normalizeFitBounds(bounds);if(!box)return devWarnOnce("lyra-map-fit-bounds-rejected",`<${this.localName}>: fitBounds() ignored a box that is not [[west, south], [east, north]] with finite coordinates, latitudes in [-90, 90], south <= north, and longitudes in [-180, 180] (east may run past 180, up to one full turn east of west, for a box crossing the antimeridian).`),!1;const settings=typeof options=="object"&&options!==null?options:{},maxZoom=settings.maxZoom,fit=Object.freeze({bounds:box,padding:normalizeFitPadding(settings.padding),maxZoom:isFiniteCoordinate(maxZoom)?finiteRange(maxZoom,22,0,22):void 0,animate:settings.animate!==!1}),map=this._map;return map?(this.pendingFit=void 0,this.applyFit(map,fit,fit.animate&&!prefersReducedMotion(this))):(this.pendingFit=Object.freeze({fit,center:snapshotCenter(this.center),zoom:this.zoom}),!0)}applyFit(map,fit,animate){if(typeof map.fitBounds!="function")return!1;const[[west,south],[east,north]]=fit.bounds;try{map.fitBounds([[west,south],[east,north]],{padding:{...fit.padding},...fit.maxZoom===void 0?{}:{maxZoom:fit.maxZoom},animate},{[FIT_EVENT_KEY]:this.fitToken})}catch{return!1}return!0}applyPendingFit(){const map=this._map,pending=this.pendingFit;!map||!pending||(this.pendingFit=void 0,!(!sameCenterValue(this.center,pending.center)||!Object.is(this.zoom,pending.zoom))&&this.applyFit(map,pending.fit,!1))}reflectCamera(map,source){const camera=readPeerCamera(map);if(!camera)return;const center=Object.freeze(camera.center),{zoom}=camera;this.reflectedCamera={center,zoom};const previousCenter=this._center;this._center=center,this.requestUpdate("center",previousCenter),this.zoom=zoom,this.emit("lr-map-view-change",{center,zoom,source})}pushCamera(changed){const reflected=this.reflectedCamera;this.reflectedCamera=void 0;const map=this._map;if(!map||!changed.has("center")&&!changed.has("zoom"))return;const center=this.safeCenter,zoom=this.safeZoom,shown=readPeerCamera(map),showsCenter=camera=>camera!==void 0&&center[0]===camera.center[0]&&center[1]===camera.center[1];let pushCenter=changed.has("center")&&!showsCenter(reflected)&&!showsCenter(shown),pushZoom=changed.has("zoom")&&zoom!==reflected?.zoom&&zoom!==shown?.zoom;if(!pushCenter&&!pushZoom)return;let interrupting=!1;try{interrupting=map.isMoving?.()===!0}catch{}interrupting&&(pushCenter=!showsCenter(shown),pushZoom=zoom!==shown?.zoom),this.writeCamera(()=>{pushCenter&&map.setCenter(center),pushZoom&&map.setZoom(zoom)})}writeCamera(write){const previous=this.writingCamera;this.writingCamera=!0;try{write()}finally{this.writingCamera=previous}}connectedCallback(){super.connectedCallback();const generation=++this._connectGeneration,IntersectionObserverCtor=ownerWindow(this)?.IntersectionObserver;if(this.visible=IntersectionObserverCtor===void 0,this.failure=void 0,this.loading=!0,this._webglReady=!1,IntersectionObserverCtor){const observer=new IntersectionObserverCtor(entries=>{entries[0]?.isIntersecting&&(this.visible=!0)});this.intersectionObserver=observer,observer.observe(this)}(async()=>{let mod;try{mod=await this.loadLibrary()}catch{generation===this._connectGeneration&&this.isConnected&&this.failInitialization("missing-peer");return}if(!(generation!==this._connectGeneration||!this.isConnected)){if(this.loading=!1,!mod){this.failInitialization("missing-peer");return}if(this._maplibreModule=mod,!hasMapStyle(this.mapStyle)){this.failInitialization("style-required");return}if(!supportsWebGL2(this)){this.failInitialization("webgl-unavailable");return}this._webglReady=!0,await this.updateComplete,!(generation!==this._connectGeneration||!this.containerEl||!this.isConnected)&&this.tryConstructMap()}})()}disconnectedCallback(){super.disconnectedCallback(),this.disposeMap(),this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0;for(const marker of this._markerInstances.values()){const markerElement=marker.getElement?.();markerElement&&this.markerActivationDetails.delete(markerElement),marker.remove()}this._markerInstances.clear(),this._markerColors.clear(),this._markerLabels.clear(),this._markerPopupIds.clear(),this._markerSources.clear()}failureMessage(reason=this.failure??"initialization-failed"){switch(reason){case"missing-peer":return this.localize("mapMissingLibrary");case"style-required":return this.localize("mapStyleRequired");case"webgl-unavailable":return this.localize("mapWebglUnavailable");case"initialization-failed":return this.localize("mapInitializationFailed")}}failInitialization(reason,partialMap){try{partialMap?.remove()}catch{}this.disposeMap(),this.loading=!1,this.failure=reason,this.announcements.announceAssertive(this.failureMessage(reason))}scheduleStyleRequiredFailure(){const generation=this._connectGeneration,module=this._maplibreModule;this.scheduleAfterUpdate(()=>{!this.isConnected||generation!==this._connectGeneration||module!==this._maplibreModule||hasMapStyle(this.mapStyle)||this.failInitialization("style-required")},"map-style-required")}disposeMap(){this.stopObservingMapAllocation(),this.stopObservingPeerChrome();try{this._map?.remove()}catch{}this._map=void 0,this._styleLoaded=!1,this.boxZoomSettling=!1,this.reflectedCamera=void 0,this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0,this._appliedDataLayerIds.clear(),this._appliedDataLayerShapes.clear(),this.appliedPointIcons.clear(),this.appliedPointPaint.clear(),this.appliedPointMuting.clear(),this._appliedGeoJson.clear()}adoptedCallback(){super.adoptedCallback(),this.hostDescription.adopted(),this.stopObservingMapAllocation(),this.stopObservingPeerChrome(),this.announcements.adopted(),this._map&&this.containerEl&&this.isConnected&&this.observeMapAllocation(this._map,this.containerEl)}tryConstructMap(){if(this._map||!this._maplibreModule||!this._webglReady||!this.containerEl||!this.visible||!this.isConnected)return;if(!hasMapStyle(this.mapStyle)){this.scheduleStyleRequiredFailure();return}const mod=this._maplibreModule;let candidate;try{candidate=new mod.Map({container:this.containerEl,style:this.mapStyle,center:this.safeCenter,zoom:this.safeZoom,...typeof this.renderWorldCopies=="boolean"?{renderWorldCopies:this.renderWorldCopies}:{},locale:{"Map.Title":this.effectiveMapLabel,"Marker.Title":this.localize("mapMarker"),"Popup.Close":this.localize("close"),"AttributionControl.ToggleAttribution":this.localize("mapToggleAttribution"),"AttributionControl.MapFeedback":this.localize("mapFeedback"),"NavigationControl.ZoomIn":this.localize("zoomIn"),"NavigationControl.ZoomOut":this.localize("zoomOut"),"NavigationControl.ResetBearing":this.localize("mapResetNorth")}}),candidate.on("error",event=>{if(this._map===candidate&&!this._styleLoaded){this.failInitialization("initialization-failed");return}console.error("lr-map:",event.error??event)}),candidate.on("load",()=>{if(this._map===candidate)try{this._styleLoaded=!0,this.applyChoropleth(),this.applyMarkers(),this.applyDataLayers(),this.emit("lr-map-load")}catch{this.failInitialization("initialization-failed")}}),candidate.on("click",event=>{if(this._map!==candidate)return;const fillLayerId=this._appliedFillLayerId,layerIds=[];fillLayerId&&candidate.getLayer(fillLayerId)&&layerIds.push(fillLayerId);for(const resolvedSourceId of this._appliedDataLayerIds.values())for(const suffix of QUERYABLE_DATA_LAYER_SUFFIXES){const layerId=`${resolvedSourceId}${suffix}`;candidate.getLayer(layerId)&&layerIds.push(layerId)}const hit=(layerIds.length?candidate.queryRenderedFeatures(event.point,{layers:layerIds}):[])[0],hitLayerId=hit?.layer?.id;let origin,sourceId;if(hitLayerId!==void 0){if(hitLayerId===fillLayerId)origin="choropleth";else for(const[publicSourceId,resolvedSourceId]of this._appliedDataLayerIds)if(hitLayerId.startsWith(`${resolvedSourceId}-`)){origin=hitLayerId===`${resolvedSourceId}-cluster`?"cluster":"data-layer",sourceId=publicSourceId;break}}this.emit("lr-map-click",{lngLat:[event.lngLat.lng,event.lngLat.lat],feature:hit,origin,sourceId})}),candidate.on("boxzoomend",()=>{this._map===candidate&&(this.boxZoomSettling=!0)}),candidate.on("moveend",event=>{if(this._map!==candidate)return;const fit=event?.[FIT_EVENT_KEY]===this.fitToken,afterBoxZoom=!fit&&this.boxZoomSettling;if(fit||(this.boxZoomSettling=!1),this.writingCamera)return;const source=fit?"fit":event?.originalEvent||afterBoxZoom?"user":void 0;source&&this.reflectCamera(candidate,source)});const canvas=candidate.getCanvas?.();canvas&&notifyMapCanvasReady(this,canvas),this._map=candidate,this.observeMapAllocation(candidate,this.containerEl),this.observePeerChrome(),this.failure=void 0}catch{this.failInitialization("initialization-failed",candidate);return}this.applyMaxBounds(),this.pendingFit&&this.scheduleAfterUpdate(()=>this.applyPendingFit(),"map-pending-fit")}requestUpdate(...args){super.requestUpdate(...args),this.isUpdatePending&&args[0]!=="center"&&args[0]!=="zoom"&&(this.semanticsStale=!0)}updated(changed){if(super.updated(changed),this.setAttribute("aria-busy",String(this.loading)),this.legendCollapsed&&(changed.has("legendOpen")||changed.has("legendCollapsible"))){const legend=this.shadowRoot?.querySelector('[part="legend"]');legend&&(legend.scrollTop=0)}if((changed.has("choropleth")||changed.has("legendGradient"))&&this.warnOnLegendChoroplethMismatch(),changed.has("visible")&&this.visible&&this.tryConstructMap(),changed.has("mapStyle")&&(this._styleGeneration+=1),changed.has("mapStyle")&&!hasMapStyle(this.mapStyle)&&this._maplibreModule)this.scheduleStyleRequiredFailure();else if(changed.has("mapStyle")&&!this._map&&this._maplibreModule&&hasMapStyle(this.mapStyle))this.tryConstructMap();else if(changed.has("mapStyle")&&this._map){this._styleLoaded=!1,this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0;const map=this._map,style=this.mapStyle,generation=this._connectGeneration,styleGeneration=this._styleGeneration,current=()=>this.isConnected&&this._map===map&&generation===this._connectGeneration&&styleGeneration===this._styleGeneration&&this.mapStyle===style,failStyle=()=>{current()&&this.scheduleAfterUpdate(()=>{current()&&this.failInitialization("initialization-failed")},`map-style-failure-${styleGeneration}`)};try{for(const sourceId of this.appliedPointIcons.keys())this.removePointIcons(sourceId);map.once("style.load",()=>{if(current())try{this._styleLoaded=!0,this._appliedDataLayerIds.clear(),this._appliedDataLayerShapes.clear(),this.appliedPointPaint.clear(),this.appliedPointMuting.clear(),this._appliedGeoJson.clear(),this.applyChoropleth(),this.applyDataLayers()}catch{failStyle()}}),map.setStyle(style)}catch{failStyle()}}else if(this._styleLoaded&&(changed.has("dataLayers")||changed.has("choropleth"))){const choropleth=this.canonicalChoropleth,nextChoroplethSourceId=choropleth?this.resolveChoroplethSourceId(choropleth.sourceId):void 0;this._appliedChoroplethSourceId&&this._appliedChoroplethSourceId!==nextChoroplethSourceId&&this.removeChoropleth(),changed.has("dataLayers")&&this.applyDataLayers(),this.applyChoropleth()}changed.has("hiddenCategories")&&this._map&&this._styleLoaded&&this.refreshThemePaint(),this.pushCamera(changed),changed.has("maxBounds")&&this._map&&this.writeCamera(()=>this.applyMaxBounds()),changed.has("markers")&&this._map&&this.applyMarkers(),this.semanticsStale&&(this.semanticsStale=!1,this.syncMapSemantics())}willUpdate(changed){super.willUpdate(changed),(changed.has("legendGradient")||changed.has("dataLayers"))&&(this.legendIsLine=this.legendDescribesLine()),changed.has("mapStyle")&&!this._map&&this._maplibreModule&&hasMapStyle(this.mapStyle)&&(this._webglReady||(this._webglReady=supportsWebGL2(this)),this.failure=this._webglReady?void 0:"webgl-unavailable",this._webglReady||(this.loading=!1,this.announcements.announceAssertive(this.failureMessage("webgl-unavailable"))))}refreshThemePaint(){if(!this._map||!this._styleLoaded)return;const fillOpacity=choroplethFillOpacity(this);if(this._appliedFillLayerId){const choropleth=this.canonicalChoropleth;choropleth&&choropleth.stops.length>0&&this._map.setPaintProperty(this._appliedFillLayerId,"fill-color",this.choroplethColorExpression(choropleth)),this._map.setPaintProperty(this._appliedFillLayerId,"fill-opacity",fillOpacity)}const dataLayersBySourceId=new Map(this.canonicalDataLayers.map(layer=>[layer.sourceId,layer]));for(const[publicSourceId,sourceId]of this._appliedDataLayerIds){const dataLayer=dataLayersBySourceId.get(publicSourceId);dataLayer&&this.paintDataLayer(sourceId,dataLayer)}}applyChoropleth(){if(!this._map)return;const choropleth=this.canonicalChoropleth;if(!choropleth){this.removeChoropleth();return}const{geojson,geojsonProjection,stops}=choropleth,sourceId=this.resolveChoroplethSourceId(choropleth.sourceId),fillLayerId=`${sourceId}-fill`;this._appliedChoroplethSourceId&&this._appliedChoroplethSourceId!==sourceId&&this.removeChoropleth(),warnOnUntileableProperties(geojsonProjection,"choropleth");const existingSource=this._map.getSource(sourceId);if(existingSource?this.pushGeoJson(existingSource,sourceId,geojson,geojsonProjection):(this._map.addSource(sourceId,{type:"geojson",data:geojson}),this._appliedGeoJson.set(sourceId,geojsonProjection)),this._appliedChoroplethSourceId=sourceId,stops.length===0)return;const colorExpr=this.choroplethColorExpression(choropleth);this._map.getLayer(fillLayerId)?(this._map.setPaintProperty(fillLayerId,"fill-color",colorExpr),this._map.setPaintProperty(fillLayerId,"fill-opacity",choroplethFillOpacity(this))):this._map.addLayer({id:fillLayerId,type:"fill",source:sourceId,paint:{"fill-color":colorExpr,"fill-opacity":choroplethFillOpacity(this)}}),this._appliedFillLayerId=fillLayerId}choroplethColorExpression(choropleth){const{field,stops}=choropleth,resolvedStops=stops.map(([value,color])=>[value,resolvedLayerColor(this,color,void 0)]);let colorExpr;if(choropleth.interpolation==="step"){const base=choropleth.stepBaseColor?resolvedLayerColor(this,choropleth.stepBaseColor,void 0):resolvedStops[0][1];colorExpr=["step",["get",field],base];for(const[value,color]of resolvedStops)colorExpr.push(value,color)}else{colorExpr=["interpolate",choropleth.interpolation==="logarithmic"?["exponential",CHOROPLETH_LOG_INTERPOLATION_BASE]:["linear"],["get",field]];for(const[value,color]of resolvedStops)colorExpr.push(value,color)}return colorExpr}resolveChoroplethSourceId(sourceId){const dataSourceIds=new Set(this.canonicalDataLayers.map(layer=>layer.sourceId));let resolved=sourceId;for(;dataSourceIds.has(resolved);)resolved=`lr-choropleth-${resolved}`;return resolved}removeChoropleth(){!this._map||!this._appliedChoroplethSourceId||(this._appliedFillLayerId&&this._map.getLayer(this._appliedFillLayerId)&&this._map.removeLayer(this._appliedFillLayerId),this._map.getSource(this._appliedChoroplethSourceId)&&this._map.removeSource(this._appliedChoroplethSourceId),this._appliedGeoJson.delete(this._appliedChoroplethSourceId),this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0)}applyDataLayers(){if(!this._map)return;const layers=this.canonicalDataLayers,nextIds=new Set(layers.map(layer=>layer.sourceId));for(const publicSourceId of this._appliedDataLayerIds.keys())nextIds.has(publicSourceId)||this.removeDataLayer(publicSourceId);for(const layer of layers){const{sourceId:publicSourceId,geojson,geojsonProjection}=layer,shape=dataLayerShape(layer),appliedShape=this._appliedDataLayerShapes.get(publicSourceId);appliedShape!==void 0&&appliedShape!==shape&&this.removeDataLayer(publicSourceId);const sourceId=this.resolveDataLayerSourceId(publicSourceId);warnOnUntileableProperties(geojsonProjection,publicSourceId);const cluster=layer.cluster,existingSource=this._map.getSource(sourceId);existingSource?this.pushGeoJson(existingSource,sourceId,geojson,geojsonProjection):(this._map.addSource(sourceId,{type:"geojson",data:geojson,...cluster?{cluster:!0,clusterRadius:cluster.radius,clusterMaxZoom:cluster.maxZoom}:{}}),this._appliedGeoJson.set(sourceId,geojsonProjection)),this.applyDataLayerRendering(sourceId,layer),this._appliedDataLayerIds.set(publicSourceId,sourceId),this._appliedDataLayerShapes.set(publicSourceId,shape)}}applyDataLayerRendering(sourceId,layer){if(layer.kind==="heatmap"){this.applyHeatmapLayer(sourceId,layer);return}const cluster=layer.cluster;cluster?this.applyClusterLayers(sourceId,layer,cluster):this.applyGeometryLayers(sourceId,layer),this.applyPointIcons(sourceId,layer)}paintDataLayer(sourceId,layer){if(layer.kind==="heatmap"){this.paintHeatmapLayer(sourceId,layer);return}const cluster=layer.cluster;cluster?this.paintClusterLayers(sourceId,layer,cluster):this.paintGeometryLayers(sourceId,layer),this.paintPointIcons(sourceId,layer)}applyGeometryLayers(sourceId,layer){if(!this._map)return;const tone=layer.tone,color=resolvedLayerColor(this,layer.color,tone),stroke=resolvedLayerColor(this,layer.strokeColor??layer.color,tone),fillId=`${sourceId}-fill`,lineId=`${sourceId}-line`,circleId=`${sourceId}-circle`;this._map.getLayer(fillId)||this._map.addLayer({id:fillId,type:"fill",source:sourceId,filter:["==",["geometry-type"],"Polygon"],paint:{"fill-color":color,"fill-opacity":choroplethFillOpacity(this)}}),this._map.getLayer(lineId)||this._map.addLayer({id:lineId,type:"line",source:sourceId,filter:["in",["geometry-type"],["literal",["LineString","Polygon"]]],paint:{"line-color":this.lineColor(layer),"line-width":layer.line?.width??2,...layer.line?{"line-opacity":layer.line.opacity}:{}}}),this._map.getLayer(circleId)||this._map.addLayer({id:circleId,type:"circle",source:sourceId,filter:["==",["geometry-type"],"Point"],paint:{"circle-color":stroke,"circle-radius":5}}),this._map.setPaintProperty(lineId,"line-width",layer.line?.width??2),this._map.setPaintProperty(lineId,"line-opacity",layer.line?.opacity??1),this.paintGeometryLayers(sourceId,layer)}paintGeometryLayers(sourceId,layer){if(!this._map)return;const tone=layer.tone,color=resolvedLayerColor(this,layer.color,tone);this._map.setPaintProperty(`${sourceId}-fill`,"fill-color",color),this._map.setPaintProperty(`${sourceId}-fill`,"fill-opacity",choroplethFillOpacity(this)),this._map.setPaintProperty(`${sourceId}-line`,"line-color",this.lineColor(layer)),this.paintPoints(sourceId,layer)}lineColor(layer){const fallback=resolvedLayerColor(this,layer.strokeColor??layer.color,layer.tone),line=layer.line;return!line?.field||line.stops.length<2?fallback:lineColorExpression(line.field,line.stops.map(([value,color])=>[value,resolvedLayerColor(this,color,layer.tone)]),fallback)}mutedPointOpacity(layerId,field){const muted=field?this.hiddenCategories:EMPTY_HIDDEN_CATEGORIES;if(!muted.length)return this.appliedPointMuting.delete(layerId)?1:void 0;this.appliedPointMuting.add(layerId);const dim=hiddenCategoryOpacity(this);return mutedCategoryOpacityExpression(field,muted,dim)}paintPoints(sourceId,layer){if(!this._map)return;const point=layer.point,fallback=resolvedLayerColor(this,layer.strokeColor??layer.color,layer.tone),color=pointColorExpression(point?.field,point?.field&&point.colors.length?point.colors.map(([value,paint])=>[value,resolvedLayerColor(this,paint,layer.tone)]):[],fallback),id=`${sourceId}-circle`;this._map.setPaintProperty(id,"circle-color",color);const opacity=this.mutedPointOpacity(id,point?.field);opacity!==void 0&&(this._map.setPaintProperty(id,"circle-opacity",opacity),this._map.setPaintProperty(id,"circle-stroke-opacity",opacity)),!(!point&&!this.appliedPointPaint.has(sourceId))&&(this._map.setPaintProperty(id,"circle-radius",pointRadiusExpression(point?.radius??5)),this._map.setPaintProperty(id,"circle-stroke-width",point?.strokeWidth??0),this._map.setPaintProperty(id,"circle-stroke-color",point?.strokeColor?resolvedLayerColor(this,point.strokeColor,layer.tone):fallback),point?this.appliedPointPaint.add(sourceId):this.appliedPointPaint.delete(sourceId))}pointIconColor(layer){const resolved=resolvedLayerColor(this,layer.point?.iconColor??`var(${ON_TONE_TOKEN[layer.tone??"accent"]})`,layer.tone);return resolveCanvasColor(this,resolved,dataLayerColor(this,layer.tone))}removePointIcons(sourceId){const applied=this.appliedPointIcons.get(sourceId);if(!applied||!this._map)return;const id=`${sourceId}-point-icon`;this._map.getLayer(id)&&this._map.removeLayer(id);for(const{id:imageId}of applied.icons)this._map.hasImage?.(imageId)&&this._map.removeImage?.(imageId);this.appliedPointIcons.delete(sourceId),this.appliedPointMuting.delete(id)}applyPointIcons(sourceId,layer){const map=this._map,point=layer.point,signature=JSON.stringify([point?.iconField,point?.iconSize,point?.icons]);if(this.appliedPointIcons.get(sourceId)?.signature===signature){this.paintPointIcons(sourceId,layer);return}if(this.removePointIcons(sourceId),!point?.iconField||!point.icons.length||!map||typeof map.addImage!="function"||typeof map.hasImage!="function"||typeof map.updateImage!="function"||typeof map.removeImage!="function")return;const color=this.pointIconColor(layer),icons=[];this.appliedPointIcons.set(sourceId,{signature,color,icons});for(const icon of point.icons){const raster=rasterPointIcon(this,icon,color);if(!raster)continue;let id;do id=`lr-point-icon-${this.nextPointIconId++}`;while(map.hasImage(id));icons.push({id,icon}),map.addImage(id,raster,{pixelRatio:2})}icons.length&&map.addLayer({id:`${sourceId}-point-icon`,type:"symbol",source:sourceId,filter:layer.cluster?["all",["==",["geometry-type"],"Point"],["!",["has","point_count"]]]:["==",["geometry-type"],"Point"],layout:{"icon-image":["match",["get",point.iconField],...icons.flatMap(({id,icon})=>[icon.value,id]),""],"icon-size":point.iconSize/(POINT_ICON_RASTER_SIZE/2),"icon-allow-overlap":!0,"icon-ignore-placement":!0}})}paintPointIcons(sourceId,layer){const applied=this.appliedPointIcons.get(sourceId);if(!applied)return;const iconLayerId=`${sourceId}-point-icon`,opacity=this.mutedPointOpacity(iconLayerId,layer.point?.iconField);opacity!==void 0&&this._map?.setPaintProperty(iconLayerId,"icon-opacity",opacity);const color=this.pointIconColor(layer);if(color!==applied.color){for(const{id,icon}of applied.icons){const raster=rasterPointIcon(this,icon,color);raster&&this._map?.updateImage?.(id,raster)}applied.color=color}}clusterColorExpression(layer,cluster){const tone=layer.tone;return clusterColorExpression(cluster.colorSteps.map(([count,stepColor])=>[count,resolvedLayerColor(this,stepColor,tone)]),()=>resolvedLayerColor(this,layer.color,tone))}applyClusterLayers(sourceId,layer,cluster){if(!this._map)return;const tone=layer.tone,stroke=resolvedClusterStrokeColor(this,cluster.strokeColor,layer),clusterId=`${sourceId}-cluster`,countId=`${sourceId}-cluster-count`,circleId=`${sourceId}-circle`,clusterColor=this.clusterColorExpression(layer,cluster),clusterRadius=stepExpression(["get","point_count"],cluster.radiusSteps),countColor=resolvedClusterCountColor(this,cluster.countColor)??resolvedLayerColor(this,`var(${ON_TONE_TOKEN[tone??"accent"]})`,tone),countHaloColor=resolvedClusterCountColor(this,cluster.countHaloColor);this._map.getLayer(clusterId)||this._map.addLayer({id:clusterId,type:"circle",source:sourceId,filter:["has","point_count"],paint:{"circle-color":clusterColor,"circle-radius":clusterRadius,"circle-stroke-width":1,"circle-stroke-color":stroke}}),this.styleProvidesGlyphs()&&!this._map.getLayer(countId)&&this._map.addLayer({id:countId,type:"symbol",source:sourceId,filter:["has","point_count"],layout:{"text-field":["get","point_count_abbreviated"],"text-size":12,...cluster.countFont?{"text-font":[...cluster.countFont]}:{}},paint:{"text-color":countColor,...countHaloColor?{"text-halo-color":countHaloColor,"text-halo-width":cluster.countHaloWidth}:{}}}),this._map.getLayer(circleId)||this._map.addLayer({id:circleId,type:"circle",source:sourceId,filter:["all",["==",["geometry-type"],"Point"],["!",["has","point_count"]]],paint:{"circle-color":stroke,"circle-radius":5}}),this.paintClusterLayers(sourceId,layer,cluster)}paintClusterLayers(sourceId,layer,cluster){if(!this._map)return;const tone=layer.tone,stroke=resolvedClusterStrokeColor(this,cluster.strokeColor,layer),clusterId=`${sourceId}-cluster`;if(this._map.setPaintProperty(clusterId,"circle-color",this.clusterColorExpression(layer,cluster)),this._map.setPaintProperty(clusterId,"circle-radius",stepExpression(["get","point_count"],cluster.radiusSteps)),this._map.setPaintProperty(clusterId,"circle-stroke-color",stroke),this.styleProvidesGlyphs()){this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-color",resolvedClusterCountColor(this,cluster.countColor)??resolvedLayerColor(this,`var(${ON_TONE_TOKEN[tone??"accent"]})`,tone));const countHaloColor=resolvedClusterCountColor(this,cluster.countHaloColor);this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-halo-color",countHaloColor??null),this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-halo-width",countHaloColor?cluster.countHaloWidth:null)}this.paintPoints(sourceId,layer)}applyHeatmapLayer(sourceId,layer){if(!this._map)return;const heatmapId=`${sourceId}-heatmap`,options=layer.heatmap,weight=heatmapWeightExpression(options),color=this.heatmapColorExpression(layer),radius=heatmapZoomValue(options?.radius,DEFAULT_HEATMAP_RADIUS,1,200),intensity=heatmapZoomValue(options?.intensity,DEFAULT_HEATMAP_INTENSITY,0,100),opacity=finiteRange(options?.opacity??Number.NaN,1,0,1);if(!this._map.getLayer(heatmapId)){this._map.addLayer({id:heatmapId,type:"heatmap",source:sourceId,paint:{...weight?{"heatmap-weight":weight}:{},"heatmap-intensity":intensity,"heatmap-color":color,"heatmap-radius":radius,...options?.opacity===void 0?{}:{"heatmap-opacity":opacity}}});return}this.paintHeatmapLayer(sourceId,layer)}paintHeatmapLayer(sourceId,layer){if(!this._map)return;const heatmapId=`${sourceId}-heatmap`;this._map.setPaintProperty(heatmapId,"heatmap-weight",heatmapWeightExpression(layer.heatmap)??1),this._map.setPaintProperty(heatmapId,"heatmap-intensity",heatmapZoomValue(layer.heatmap?.intensity,DEFAULT_HEATMAP_INTENSITY,0,100)),this._map.setPaintProperty(heatmapId,"heatmap-color",this.heatmapColorExpression(layer)),this._map.setPaintProperty(heatmapId,"heatmap-radius",heatmapZoomValue(layer.heatmap?.radius,DEFAULT_HEATMAP_RADIUS,1,200)),this._map.setPaintProperty(heatmapId,"heatmap-opacity",finiteRange(layer.heatmap?.opacity??Number.NaN,1,0,1))}heatmapColorExpression(layer){const tone=layer.tone,authored=(layer.heatmap?.stops??[]).map(([density,color])=>[density,resolvedLayerColor(this,color,tone)]);return heatmapColorExpression(authored,()=>HEATMAP_RAMP_TOKENS.map(([density,token])=>[density,resolvedLayerColor(this,`var(${token})`,tone)]))}styleProvidesGlyphs(){try{const liveGlyphs=this._map?.getStyle?.()?.glyphs;if(typeof liveGlyphs=="string"&&liveGlyphs.trim().length>0)return!0}catch{}const declared=this.mapStyle,declaredGlyphs=declared&&typeof declared=="object"?declared.glyphs:void 0;return typeof declaredGlyphs=="string"&&declaredGlyphs.trim().length>0}resolveDataLayerSourceId(publicSourceId){const applied=this._appliedDataLayerIds.get(publicSourceId);if(applied)return applied;let sourceId;do sourceId=`lr-data-layer-${this._nextDataLayerId++}`;while(this._map?.getSource(sourceId)||DATA_LAYER_SUFFIXES.some(suffix=>this._map?.getLayer(`${sourceId}${suffix}`)));return sourceId}removeDataLayer(publicSourceId){if(!this._map)return;const sourceId=this._appliedDataLayerIds.get(publicSourceId);if(sourceId){this.removePointIcons(sourceId),this.appliedPointPaint.delete(sourceId);for(const suffix of DATA_LAYER_SUFFIXES){const layerId=`${sourceId}${suffix}`;this.appliedPointMuting.delete(layerId),this._map.getLayer(layerId)&&this._map.removeLayer(layerId)}this._map.getSource(sourceId)&&this._map.removeSource(sourceId),this._appliedDataLayerIds.delete(publicSourceId),this._appliedDataLayerShapes.delete(publicSourceId),this._appliedGeoJson.delete(sourceId)}}applyMarkers(){const map=this._map,mod=this._maplibreModule;if(!map||!mod)return;const visible=new Set,coordCounts=new Map,explicitIds=new Set;let defaultColor;for(const m of this.canonicalMarkers){const lngLat=m.lngLat,mapLngLat=[lngLat[0],lngLat[1]];let key,id;if(m.id!==void 0){if(id=m.id,explicitIds.has(id))continue;explicitIds.add(id),key=`id:${id}`}else{const coordKey=`${lngLat[0]},${lngLat[1]}`,occurrence=coordCounts.get(coordKey)??0;coordCounts.set(coordKey,occurrence+1),key=`coordinate:${coordKey}#${occurrence}`}visible.add(key);let existing=this._markerInstances.get(key);const markerColor=sanitizeCssColor(m.color)??(m.color===void 0?defaultColor??=dataLayerColor(this,"accent"):void 0),previous=this._markerSources.get(key);this._markerSources.set(key,m);const sameColor=this._markerColors.get(key)===markerColor,sameContent=previous!==void 0&&previous.label===m.label&&Object.is(previous.unsafeHtml,m.unsafeHtml);if(existing&&sameColor&&sameContent&&previous.lngLat[0]===lngLat[0]&&previous.lngLat[1]===lngLat[1])continue;if(existing&&!sameColor){const existingElement=existing.getElement?.();existingElement&&this.markerActivationDetails.delete(existingElement),existing.remove(),this._markerInstances.delete(key),this._markerColors.delete(key),existing=void 0}if(existing){existing.setLngLat(mapLngLat);const popup=existing.getPopup();if(!m.unsafeHtml&&!m.label)popup&&existing.setPopup(void 0);else if(popup)sameContent||setPopupContent(popup,m);else{const nextPopup=setPopupContent(new mod.Popup({offset:12}),m);existing.setPopup(nextPopup),this.configurePopupSemantics(key,existing,nextPopup)}}else{const marker=new mod.Marker(markerColor?{color:markerColor}:void 0).setLngLat(mapLngLat);if(m.unsafeHtml||m.label){const popup=setPopupContent(new mod.Popup({offset:12}),m);marker.setPopup(popup),this.configurePopupSemantics(key,marker,popup)}marker.addTo(map),this._markerInstances.set(key,marker),this._markerColors.set(key,markerColor)}const markerLabel=m.label?.trim()||markerPopupText(this,m.unsafeHtml);this._markerLabels.set(key,markerLabel||void 0);const markerElement=this._markerInstances.get(key)?.getElement?.();if(markerElement){addPartToken(markerElement,"marker");const currentMarker=this._markerInstances.get(key);this.configureMarkerInteraction(markerElement,{id,lngLat,marker:m},markerLabel);const popup=currentMarker?.getPopup();popup&&currentMarker?(this.configurePopupSemantics(key,currentMarker,popup),this.syncPopupSemantics(key,currentMarker,popup)):(markerElement.removeAttribute("aria-controls"),markerElement.removeAttribute("aria-expanded"),markerElement.removeAttribute("aria-haspopup"))}}for(const[key,marker]of this._markerInstances)if(!visible.has(key)){const markerElement=marker.getElement?.();markerElement&&this.markerActivationDetails.delete(markerElement),marker.remove(),this._markerInstances.delete(key),this._markerColors.delete(key),this._markerLabels.delete(key),this._markerPopupIds.delete(key),this._markerSources.delete(key)}}configureMarkerInteraction(markerElement,activation,markerLabel=activation.marker.label?.trim()||markerPopupText(this,activation.marker.unsafeHtml)){this.markerActivationDetails.set(markerElement,activation),markerElement.setAttribute("role","button"),markerElement.tabIndex=0,markerElement.setAttribute("aria-label",markerLabel||this.localize("mapMarker")),markerElement.setAttribute("lang",this.effectiveLocale),!this.configuredMarkerElements.has(markerElement)&&(this.configuredMarkerElements.add(markerElement),markerElement.addEventListener("click",event=>{event.defaultPrevented||this.emitMarkerActivation(markerElement,"pointer")}),markerElement.addEventListener("keydown",event=>{event.key!==" "&&event.key!=="Enter"||event.repeat||event.defaultPrevented||(event.key===" "&&event.preventDefault(),this.emitMarkerActivation(markerElement,"keyboard"))},{capture:!0}))}emitMarkerActivation(markerElement,source){if(!this.isConnected)return;const activation=this.markerActivationDetails.get(markerElement);activation&&this.emit("lr-map-marker-activate",{...activation,source})}get effectiveMapLabel(){return hostAriaLabel(this)??this.label??this.localize("map")}popupId(key){let id=this._markerPopupIds.get(key);return id||(id=`map-popup-${this._connectGeneration}-${++this._nextPopupId}`,this._markerPopupIds.set(key,id)),id}configurePopupSemantics(key,marker,popup){!popup||typeof popup!="object"||this._configuredPopups.has(popup)||(this._configuredPopups.add(popup),popup.on?.("open",()=>this.syncPopupSemantics(key,marker,popup)),popup.on?.("close",()=>{marker.getElement?.()?.setAttribute("aria-expanded","false")}))}stopObservingMapAllocation(){this.mapResizeObserver?.disconnect(),this.mapResizeObserver=void 0,this.observedMapContainer=void 0}observeMapAllocation(map,container){this.stopObservingMapAllocation();const ResizeObserverCtor=container.ownerDocument.defaultView?.ResizeObserver;if(!ResizeObserverCtor)return;let observer;observer=new ResizeObserverCtor(()=>{if(!(this.mapResizeObserver!==observer||this.observedMapContainer!==container||this.containerEl!==container||this._map!==map||!this.isConnected))try{map.resize()}catch{}}),this.mapResizeObserver=observer,this.observedMapContainer=container;try{observer.observe(container)}catch{this.stopObservingMapAllocation()}}stopObservingPeerChrome(){const pending=this.peerControlsResizeFrame;this.peerControlsResizeFrame=void 0,pending&&pending.view.cancelAnimationFrame(pending.handle),this.peerControlsResizeObserver?.disconnect(),this.peerControlsResizeObserver=void 0,this.peerChromeObserver?.disconnect(),this.peerChromeObserver=void 0,this.observedPeerContainer=void 0}schedulePeerControlInsets(observer,container){if(this.peerControlsResizeObserver!==observer||this.observedPeerContainer!==container||this.containerEl!==container||!this.isConnected||this.peerControlsResizeFrame)return;const view=container.ownerDocument.defaultView;if(!view)return;const pending={view,handle:0};this.peerControlsResizeFrame=pending,pending.handle=view.requestAnimationFrame(()=>{this.peerControlsResizeFrame===pending&&(this.peerControlsResizeFrame=void 0,!(this.peerControlsResizeObserver!==observer||this.observedPeerContainer!==container||this.containerEl!==container||container.ownerDocument.defaultView!==view||!this.isConnected)&&this.measurePeerControlInsets(container))})}measurePeerControlInsets(container){if(!(!this.isConnected||this.containerEl!==container)){for(const scale of container.querySelectorAll(".maplibregl-ctrl-scale")){const width=scale.style.width;width&&scale.style.getPropertyValue("--_lr-map-scale-width")!==width&&scale.style.setProperty("--_lr-map-scale-width",width)}for(const edge of["top","bottom"]){const height=Math.max(0,...[...container.querySelectorAll(`.maplibregl-ctrl-${edge}-left, .maplibregl-ctrl-${edge}-right`)].map(corner=>corner.offsetHeight)),base=container.parentElement,name=`--_lr-map-controls-${edge}`,value=`${height}px`;base&&base.style.getPropertyValue(name)!==value&&base.style.setProperty(name,value)}}}syncPeerChromeParts(root=this.containerEl??this.renderRoot){const selectors=[[".maplibregl-marker","marker"],[".maplibregl-popup","popup"],[".maplibregl-popup-content","popup-content"],[".maplibregl-popup-close-button","popup-close-button"],[".maplibregl-ctrl-attrib","attribution"],[".maplibregl-ctrl-attrib-button","attribution-toggle"],[".maplibregl-ctrl-group:has(.maplibregl-ctrl-zoom-in, .maplibregl-ctrl-compass)","navigation"],[".maplibregl-ctrl-zoom-in","zoom-in"],[".maplibregl-ctrl-zoom-out","zoom-out"],[".maplibregl-ctrl-compass","compass"],[".maplibregl-ctrl-scale","scale"]];for(const[selector,part]of selectors){const candidate=root,elements=[...root.querySelectorAll(selector)];candidate.matches?.(selector)&&elements.push(candidate);for(const element of elements){addPartToken(element,part);const label=part==="attribution-toggle"?this.localize("mapToggleAttribution"):part==="zoom-in"?this.localize("zoomIn"):part==="zoom-out"?this.localize("zoomOut"):part==="compass"?this.localize("mapResetNorth"):void 0;label!==void 0&&(element.setAttribute("aria-label",label),element.setAttribute("title",label))}}}observePeerChrome(){const container=this.containerEl;if(!container||(this.syncPeerChromeParts(container),this.observedPeerContainer===container&&this.peerChromeObserver))return;this.stopObservingPeerChrome();const MutationObserverCtor=container.ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;this.observedPeerContainer=container;const ResizeObserverCtor=container.ownerDocument.defaultView?.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(()=>this.schedulePeerControlInsets(observer,container));this.peerControlsResizeObserver=observer;for(const corner of container.querySelectorAll(".maplibregl-ctrl-top-left, .maplibregl-ctrl-top-right, .maplibregl-ctrl-bottom-left, .maplibregl-ctrl-bottom-right"))this.peerControlsResizeObserver.observe(corner)}this.measurePeerControlInsets(container),this.peerChromeObserver=new MutationObserverCtor(records=>{if(!(!this.isConnected||this.containerEl!==container)){for(const record of records)for(const node of record.addedNodes)node.nodeType===Node.ELEMENT_NODE&&this.syncPeerChromeParts(node);this.measurePeerControlInsets(container)}}),this.peerChromeObserver.observe(container,{childList:!0,subtree:!0})}syncPopupSemantics(key,marker,popup){const markerElement=marker?.getElement?.();if(!markerElement)return;const id=this.popupId(key);markerElement.setAttribute("aria-controls",id),markerElement.setAttribute("aria-haspopup","dialog"),markerElement.setAttribute("aria-expanded",popup?.isOpen?.()?"true":"false");const popupElement=popup?.getElement?.();if(!popupElement)return;addPartToken(markerElement,"marker"),addPartToken(popupElement,"popup"),popupElement.id=id,popupElement.setAttribute("role","dialog"),popupElement.setAttribute("lang",this.effectiveLocale),popupElement.setAttribute("aria-label",this._markerLabels.get(key)||this.effectiveMapLabel);const popupContent=popupElement.querySelector(".maplibregl-popup-content");popupContent&&addPartToken(popupContent,"popup-content");const closeButton=popupElement.querySelector(".maplibregl-popup-close-button");closeButton&&addPartToken(closeButton,"popup-close-button"),closeButton?.setAttribute("aria-label",this.localize("close"))}syncMapSemantics(){const canvas=this._map?.getCanvas?.();canvas&&(canvas.setAttribute("aria-label",this.effectiveMapLabel),canvas.setAttribute("lang",this.effectiveLocale),this.legend.length||this.legendGradient.length>=2||this.hasLegendSlot||this.hasLegendStartSlot||this.legendProjection.truncated?canvas.setAttribute("aria-describedby","map-legend"):canvas.removeAttribute("aria-describedby")),this.hostDescription.refresh();for(const[key,marker]of this._markerInstances){const markerElement=marker.getElement?.();if(!markerElement)continue;addPartToken(markerElement,"marker"),markerElement.setAttribute("role","button"),markerElement.tabIndex=0,markerElement.setAttribute("aria-label",this._markerLabels.get(key)||this.localize("map")),markerElement.setAttribute("lang",this.effectiveLocale);const popup=marker.getPopup?.();popup?this.syncPopupSemantics(key,marker,popup):(markerElement.removeAttribute("aria-controls"),markerElement.removeAttribute("aria-expanded"),markerElement.removeAttribute("aria-haspopup"))}this.syncPeerChromeParts()}formatCount(value){return getNumberFormat(this.effectiveLocale).format(value)}legendLimitText(){return this.localize("paginationSummary",void 0,{start:this.formatCount(this.legend.length===0?0:1),end:this.formatCount(this.legend.length),total:this.formatCount(this.legendProjection.inputCount),itemLabel:this.localize("items")})}renderLegendRowContent(entry){const paint=sanitizeCssColor(entry.color);return html`${entry.icon?html`<span
20
+ ><span>${this.localize("mapLegend")}</span></button>`:nothing}get hiddenCategories(){return this._hiddenCategories}set hiddenCategories(value){if(value===this._hiddenCategoriesSource||value===this._hiddenCategories)return;this._hiddenCategoriesSource=value;const previous=this._hiddenCategories;this._hiddenCategories=normalizeMapHiddenCategories(value),this.requestUpdate("hiddenCategories",previous)}get canonicalChoropleth(){const source=this.choropleth;return Object.is(source,this._canonicalChoroplethSource)?this._canonicalChoropleth:(this._canonicalChoroplethSource=source,this._canonicalChoropleth=projectMapChoropleth(source),this._canonicalChoropleth)}get canonicalDataLayers(){const source=this.dataLayers;return Object.is(source,this._canonicalDataLayersSource)?this._canonicalDataLayers:(this._canonicalDataLayersSource=source,this._canonicalDataLayers=projectMapDataLayers(source),this._canonicalDataLayers)}get canonicalMarkers(){const source=this.markers;return Object.is(source,this._canonicalMarkersSource)?this._canonicalMarkers:(this._canonicalMarkersSource=source,this._canonicalMarkers=projectMapMarkers(source),this._canonicalMarkers)}get map(){return this._map}pushGeoJson(source,resolvedSourceId,geojson,projection=projectGeoJson(geojson)){const previous=this._appliedGeoJson.get(resolvedSourceId);if(previous===projection)return;const diff=typeof source.updateData=="function"&&previous!==void 0?buildProjectedGeoJsonPropertyDiff(previous,projection):null;diff===null||typeof source.updateData!="function"?source.setData(geojson):(diff.update.length>0||diff.add?.length||diff.remove?.length)&&source.updateData(diff),this._appliedGeoJson.set(resolvedSourceId,projection)}get safeMaxBounds(){const bounds=this.maxBounds;if(!Array.isArray(bounds)||bounds.length!==2)return null;const[southWest,northEast]=bounds;if(!Array.isArray(southWest)||!Array.isArray(northEast))return null;const[west,south]=southWest,[east,north]=northEast,values=[west,south,east,north].map(Number);if(!values.every(value=>Number.isFinite(value)))return null;const[w,s,e,n]=values;return w>=e||s>=n||w<-180||e>180||s<-90||n>90?null:[[w,s],[e,n]]}applyMaxBounds(){const map=this._map;if(!map||typeof map.setMaxBounds!="function")return;const bounds=this.safeMaxBounds;let zoomBefore,centerBefore;try{if(zoomBefore=map.getZoom(),centerBefore=map.getCenter(),map.setMaxBounds(bounds),bounds===null||Number.isFinite(map.getZoom()))return}catch{}try{map.setMaxBounds(null)}catch{}typeof zoomBefore=="number"&&Number.isFinite(zoomBefore)&&map.setZoom(zoomBefore),centerBefore&&map.setCenter([centerBefore.lng,centerBefore.lat]),devWarnOnce("lyra-map-max-bounds-rejected","<lr-map>: maxBounds left maplibre-gl without a usable camera, so it was dropped and the camera restored. This is a peer limitation, not a bad value -- it shows up at sub-1 fractional zooms in wide containers. Raise the zoom, narrow the box, or leave maxBounds unset.")}get safeZoom(){return finiteRange(this.zoom,2,0,22)}get safeCenter(){const center=Array.isArray(this.center)?this.center:[];return[finiteRange(Number(center[0]),0,-180,180),finiteRange(Number(center[1]),0,-90,90)]}fitBounds(bounds,options={}){const box=normalizeFitBounds(bounds);if(!box)return devWarnOnce("lyra-map-fit-bounds-rejected",`<${this.localName}>: fitBounds() ignored a box that is not [[west, south], [east, north]] with finite coordinates, latitudes in [-90, 90], south <= north, and longitudes in [-180, 180] (east may run past 180, up to one full turn east of west, for a box crossing the antimeridian).`),!1;const settings=typeof options=="object"&&options!==null?options:{},maxZoom=settings.maxZoom,fit=Object.freeze({bounds:box,padding:normalizeFitPadding(settings.padding),maxZoom:isFiniteCoordinate(maxZoom)?finiteRange(maxZoom,22,0,22):void 0,animate:settings.animate!==!1}),map=this._map;return map?(this.pendingFit=void 0,this.applyFit(map,fit,fit.animate&&!prefersReducedMotion(this))):(this.pendingFit=Object.freeze({fit,center:snapshotCenter(this.center),zoom:this.zoom}),!0)}applyFit(map,fit,animate){if(typeof map.fitBounds!="function")return!1;const[[west,south],[east,north]]=fit.bounds;try{map.fitBounds([[west,south],[east,north]],{padding:{...fit.padding},...fit.maxZoom===void 0?{}:{maxZoom:fit.maxZoom},animate},{[FIT_EVENT_KEY]:this.fitToken})}catch{return!1}return!0}applyPendingFit(){const map=this._map,pending=this.pendingFit;!map||!pending||(this.pendingFit=void 0,!(!sameCenterValue(this.center,pending.center)||!Object.is(this.zoom,pending.zoom))&&this.applyFit(map,pending.fit,!1))}reflectCamera(map,source){const camera=readPeerCamera(map);if(!camera)return;const center=Object.freeze(camera.center),{zoom}=camera;this.reflectedCamera={center,zoom};const previousCenter=this._center;this._center=center,this.requestUpdate("center",previousCenter),this.zoom=zoom,this.emit("lr-map-view-change",{center,zoom,source})}pushCamera(changed){const reflected=this.reflectedCamera;this.reflectedCamera=void 0;const map=this._map;if(!map||!changed.has("center")&&!changed.has("zoom"))return;const center=this.safeCenter,zoom=this.safeZoom,shown=readPeerCamera(map),showsCenter=camera=>camera!==void 0&&center[0]===camera.center[0]&&center[1]===camera.center[1];let pushCenter=changed.has("center")&&!showsCenter(reflected)&&!showsCenter(shown),pushZoom=changed.has("zoom")&&zoom!==reflected?.zoom&&zoom!==shown?.zoom;if(!pushCenter&&!pushZoom)return;let interrupting=!1;try{interrupting=map.isMoving?.()===!0}catch{}interrupting&&(pushCenter=!showsCenter(shown),pushZoom=zoom!==shown?.zoom),this.writeCamera(()=>{pushCenter&&map.setCenter(center),pushZoom&&map.setZoom(zoom)})}writeCamera(write){const previous=this.writingCamera;this.writingCamera=!0;try{write()}finally{this.writingCamera=previous}}connectedCallback(){super.connectedCallback();const generation=++this._connectGeneration,IntersectionObserverCtor=ownerWindow(this)?.IntersectionObserver;if(this.visible=IntersectionObserverCtor===void 0,this.failure=void 0,this.loading=!0,this._webglReady=!1,IntersectionObserverCtor){const observer=new IntersectionObserverCtor(entries=>{entries[0]?.isIntersecting&&(this.visible=!0)});this.intersectionObserver=observer,observer.observe(this)}(async()=>{let mod;try{mod=await this.loadLibrary(this.engine)}catch{generation===this._connectGeneration&&this.isConnected&&this.failInitialization("missing-peer");return}if(!(generation!==this._connectGeneration||!this.isConnected)){if(this.loading=!1,!mod){this.failInitialization("missing-peer");return}if(this._maplibreModule=mod,!hasMapStyle(this.mapStyle)){this.failInitialization("style-required");return}if(!supportsWebGL2(this)){this.failInitialization("webgl-unavailable");return}this._webglReady=!0,await this.updateComplete,!(generation!==this._connectGeneration||!this.containerEl||!this.isConnected)&&this.tryConstructMap()}})()}disconnectedCallback(){super.disconnectedCallback(),this.disposeMap(),this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0;for(const marker of this._markerInstances.values()){const markerElement=marker.getElement?.();markerElement&&this.markerActivationDetails.delete(markerElement),marker.remove()}this._markerInstances.clear(),this._markerColors.clear(),this._markerLabels.clear(),this._markerPopupIds.clear(),this._markerSources.clear()}failureMessage(reason=this.failure??"initialization-failed"){switch(reason){case"missing-peer":return this.localize("mapMissingLibrary",void 0,{package:this.engine==="maplibre"?"maplibre-gl":"@aceshooting/lyra-map"});case"style-required":return this.localize("mapStyleRequired");case"webgl-unavailable":return this.localize("mapWebglUnavailable");case"initialization-failed":return this.localize("mapInitializationFailed")}}failInitialization(reason,partialMap){try{partialMap?.remove()}catch{}this.disposeMap(),this.loading=!1,this.failure=reason,this.announcements.announceAssertive(this.failureMessage(reason))}scheduleStyleRequiredFailure(){const generation=this._connectGeneration,module=this._maplibreModule;this.scheduleAfterUpdate(()=>{!this.isConnected||generation!==this._connectGeneration||module!==this._maplibreModule||hasMapStyle(this.mapStyle)||this.failInitialization("style-required")},"map-style-required")}disposeMap(){this.cancelFeaturePreparation(),this.preparedFeatureSignature=void 0,this.pendingMapLoad=!1,this.rebuildGeneratedLayers=!1,this.stopObservingMapAllocation(),this.stopObservingPeerChrome();try{this._map?.remove()}catch{}this._map=void 0,this._styleLoaded=!1,this.boxZoomSettling=!1,this.reflectedCamera=void 0,this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0,this._appliedDataLayerIds.clear(),this._appliedDataLayerShapes.clear(),this.appliedPointIcons.clear(),this.appliedPointPaint.clear(),this.appliedPointMuting.clear(),this._appliedGeoJson.clear()}adoptedCallback(){super.adoptedCallback(),this.hostDescription.adopted(),this.stopObservingMapAllocation(),this.stopObservingPeerChrome(),this.announcements.adopted(),this._map&&this.containerEl&&this.isConnected&&this.observeMapAllocation(this._map,this.containerEl)}tryConstructMap(){if(this._map||!this._maplibreModule||!this._webglReady||!this.containerEl||!this.visible||!this.isConnected)return;if(!hasMapStyle(this.mapStyle)){this.scheduleStyleRequiredFailure();return}const mod=this._maplibreModule;let candidate;try{candidate=new mod.Map({container:this.containerEl,style:this.mapStyle,center:this.safeCenter,zoom:this.safeZoom,...typeof this.renderWorldCopies=="boolean"?{renderWorldCopies:this.renderWorldCopies}:{},locale:{"Map.Title":this.effectiveMapLabel,"Marker.Title":this.localize("mapMarker"),"Popup.Close":this.localize("close"),"AttributionControl.ToggleAttribution":this.localize("mapToggleAttribution"),"AttributionControl.MapFeedback":this.localize("mapFeedback"),"NavigationControl.ZoomIn":this.localize("zoomIn"),"NavigationControl.ZoomOut":this.localize("zoomOut"),"NavigationControl.ResetBearing":this.localize("mapResetNorth")}}),candidate.on("error",event=>{if(this._map===candidate&&!this._styleLoaded){this.failInitialization("initialization-failed");return}console.error("lr-map:",event.error??event)}),candidate.on("load",()=>{if(this._map===candidate)try{this._styleLoaded=!0,this.pendingMapLoad=!0,this.rebuildGeneratedLayers=!0,this.applyMarkers(),this.reconcileGeneratedLayers()}catch{this.failInitialization("initialization-failed")}}),candidate.on("click",event=>{if(this._map!==candidate)return;const fillLayerId=this._appliedFillLayerId,layerIds=[];fillLayerId&&candidate.getLayer(fillLayerId)&&layerIds.push(fillLayerId);for(const resolvedSourceId of this._appliedDataLayerIds.values())for(const suffix of QUERYABLE_DATA_LAYER_SUFFIXES){const layerId=`${resolvedSourceId}${suffix}`;candidate.getLayer(layerId)&&layerIds.push(layerId)}const hit=(layerIds.length?candidate.queryRenderedFeatures(event.point,{layers:layerIds}):[])[0],hitLayerId=hit?.layer?.id;let origin,sourceId;if(hitLayerId!==void 0){if(hitLayerId===fillLayerId)origin="choropleth";else for(const[publicSourceId,resolvedSourceId]of this._appliedDataLayerIds)if(hitLayerId.startsWith(`${resolvedSourceId}-`)){origin=hitLayerId===`${resolvedSourceId}-cluster`?"cluster":"data-layer",sourceId=publicSourceId;break}}this.emit("lr-map-click",{lngLat:[event.lngLat.lng,event.lngLat.lat],feature:hit,origin,sourceId})}),candidate.on("boxzoomend",()=>{this._map===candidate&&(this.boxZoomSettling=!0)}),candidate.on("moveend",event=>{if(this._map!==candidate)return;const fit=event?.[FIT_EVENT_KEY]===this.fitToken,afterBoxZoom=!fit&&this.boxZoomSettling;if(fit||(this.boxZoomSettling=!1),this.writingCamera)return;const source=fit?"fit":event?.originalEvent||afterBoxZoom?"user":void 0;source&&this.reflectCamera(candidate,source)});const canvas=candidate.getCanvas?.();canvas&&notifyMapCanvasReady(this,canvas),this._map=candidate,this.observeMapAllocation(candidate,this.containerEl),this.observePeerChrome(),this.failure=void 0}catch{this.failInitialization("initialization-failed",candidate);return}this.applyMaxBounds(),this.pendingFit&&this.scheduleAfterUpdate(()=>this.applyPendingFit(),"map-pending-fit")}requestUpdate(...args){super.requestUpdate(...args),this.isUpdatePending&&args[0]!=="center"&&args[0]!=="zoom"&&(this.semanticsStale=!0)}updated(changed){if(super.updated(changed),this.setAttribute("aria-busy",String(this.loading)),this.legendCollapsed&&(changed.has("legendOpen")||changed.has("legendCollapsible"))){const legend=this.shadowRoot?.querySelector('[part="legend"]');legend&&(legend.scrollTop=0)}if((changed.has("choropleth")||changed.has("legendGradient"))&&this.warnOnLegendChoroplethMismatch(),changed.has("visible")&&this.visible&&this.tryConstructMap(),changed.has("mapStyle")&&(this._styleGeneration+=1,this.cancelFeaturePreparation(),this.preparedFeatureSignature=void 0),changed.has("mapStyle")&&!hasMapStyle(this.mapStyle)&&this._maplibreModule)this.scheduleStyleRequiredFailure();else if(changed.has("mapStyle")&&!this._map&&this._maplibreModule&&hasMapStyle(this.mapStyle))this.tryConstructMap();else if(changed.has("mapStyle")&&this._map){this._styleLoaded=!1,this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0;const map=this._map,style=this.mapStyle,generation=this._connectGeneration,styleGeneration=this._styleGeneration,current=()=>this.isConnected&&this._map===map&&generation===this._connectGeneration&&styleGeneration===this._styleGeneration&&this.mapStyle===style,failStyle=()=>{current()&&this.scheduleAfterUpdate(()=>{current()&&this.failInitialization("initialization-failed")},`map-style-failure-${styleGeneration}`)};try{for(const sourceId of this.appliedPointIcons.keys())this.removePointIcons(sourceId);map.once("style.load",()=>{if(current())try{this._styleLoaded=!0,this._appliedDataLayerIds.clear(),this._appliedDataLayerShapes.clear(),this.appliedPointPaint.clear(),this.appliedPointMuting.clear(),this._appliedGeoJson.clear(),this.rebuildGeneratedLayers=!0,this.reconcileGeneratedLayers()}catch{failStyle()}}),map.setStyle(style)}catch{failStyle()}}else this._styleLoaded&&(changed.has("dataLayers")||changed.has("choropleth"))&&this.reconcileGeneratedLayers();changed.has("hiddenCategories")&&this._map&&this._styleLoaded&&this.refreshThemePaint(),this.pushCamera(changed),changed.has("maxBounds")&&this._map&&this.writeCamera(()=>this.applyMaxBounds()),changed.has("markers")&&this._map&&this.applyMarkers(),this.semanticsStale&&(this.semanticsStale=!1,this.syncMapSemantics())}willUpdate(changed){super.willUpdate(changed),(changed.has("legendGradient")||changed.has("dataLayers"))&&(this.legendIsLine=this.legendDescribesLine()),changed.has("mapStyle")&&!this._map&&this._maplibreModule&&hasMapStyle(this.mapStyle)&&(this._webglReady||(this._webglReady=supportsWebGL2(this)),this.failure=this._webglReady?void 0:"webgl-unavailable",this._webglReady||(this.loading=!1,this.announcements.announceAssertive(this.failureMessage("webgl-unavailable"))))}refreshThemePaint(){if(!this._map||!this._styleLoaded||this.preparingFeatures)return;const fillOpacity=choroplethFillOpacity(this);if(this._appliedFillLayerId){const choropleth=this.canonicalChoropleth;choropleth&&choropleth.stops.length>0&&this._map.setPaintProperty(this._appliedFillLayerId,"fill-color",this.choroplethColorExpression(choropleth)),this._map.setPaintProperty(this._appliedFillLayerId,"fill-opacity",fillOpacity)}const dataLayersBySourceId=new Map(this.canonicalDataLayers.map(layer=>[layer.sourceId,layer]));for(const[publicSourceId,sourceId]of this._appliedDataLayerIds){const dataLayer=dataLayersBySourceId.get(publicSourceId);dataLayer&&this.paintDataLayer(sourceId,dataLayer)}}cancelFeaturePreparation(){this.featureGeneration+=1,this.featureAbort?.abort(),this.featureAbort=void 0,this.preparingFeatures=!1}generatedFeatureRequirements(){const sources={},layers=[],add=(source,types)=>{for(const[index,type]of types.entries())layers.push({id:`${source}-${type}-${index}`,type,source})},choropleth=this.canonicalChoropleth;choropleth&&(sources.choropleth={type:"geojson",data:choropleth.geojson},choropleth.stops.length&&add("choropleth",["fill"]));for(const[index,layer]of this.canonicalDataLayers.entries()){const source=`data-${index}`,cluster=layer.cluster;sources[source]={type:"geojson",data:layer.geojson,...cluster?{cluster:!0,clusterRadius:cluster.radius,clusterMaxZoom:cluster.maxZoom}:{}},layer.kind==="heatmap"?add(source,["heatmap"]):(add(source,cluster?["circle"]:["fill","line","circle"]),(cluster&&this.styleProvidesGlyphs()||layer.point?.iconField&&layer.point.icons.length)&&add(source,["symbol"]))}return{sources,layers}}reconcileGeneratedLayers(){const map=this._map;if(!map||!this._styleLoaded)return;this.cancelFeaturePreparation();const generation=this.featureGeneration,connection=this._connectGeneration,styleGeneration=this._styleGeneration,style=this.mapStyle,dataLayers=this.dataLayers,choropleth=this.choropleth,current=()=>this.isConnected&&this._map===map&&generation===this.featureGeneration&&connection===this._connectGeneration&&styleGeneration===this._styleGeneration&&style===this.mapStyle&&dataLayers===this.dataLayers&&choropleth===this.choropleth,apply=()=>{const next=this.canonicalChoropleth,nextId=next?this.resolveChoroplethSourceId(next.sourceId):void 0;this._appliedChoroplethSourceId&&this._appliedChoroplethSourceId!==nextId&&this.removeChoropleth(),this.rebuildGeneratedLayers?(this.applyChoropleth(),this.applyDataLayers(),this.rebuildGeneratedLayers=!1):(this.applyDataLayers(),this.applyChoropleth()),this.pendingMapLoad&&(this.pendingMapLoad=!1,this.emit("lr-map-load"))},fail=()=>{if(current()){if(this.pendingMapLoad){this.failInitialization("initialization-failed");return}this.scheduleAfterUpdate(()=>{current()&&this.failInitialization("initialization-failed")},`map-feature-failure-${generation}`)}};try{if(!map.prepareFeatures){apply();return}const requirements=this.generatedFeatureRequirements(),signature=JSON.stringify([Object.values(requirements.sources??{}).map(source=>source.type),(requirements.layers??[]).map(layer=>layer.type)]);if(signature===this.preparedFeatureSignature){apply();return}const controller=new AbortController;this.featureAbort=controller,this.preparingFeatures=!0,(async()=>{try{if(await map.prepareFeatures(requirements,{signal:controller.signal}),!current()||controller.signal.aborted)return;this.featureAbort=void 0,this.preparingFeatures=!1,this.preparedFeatureSignature=signature,apply()}catch{if(!current()||controller.signal.aborted)return;this.preparingFeatures=!1,fail()}})()}catch{fail()}}applyChoropleth(){if(!this._map)return;const choropleth=this.canonicalChoropleth;if(!choropleth){this.removeChoropleth();return}const{geojson,geojsonProjection,stops}=choropleth,sourceId=this.resolveChoroplethSourceId(choropleth.sourceId),fillLayerId=`${sourceId}-fill`;this._appliedChoroplethSourceId&&this._appliedChoroplethSourceId!==sourceId&&this.removeChoropleth(),warnOnUntileableProperties(geojsonProjection,"choropleth");const existingSource=this._map.getSource(sourceId);if(existingSource?this.pushGeoJson(existingSource,sourceId,geojson,geojsonProjection):(this._map.addSource(sourceId,{type:"geojson",data:geojson}),this._appliedGeoJson.set(sourceId,geojsonProjection)),this._appliedChoroplethSourceId=sourceId,stops.length===0)return;const colorExpr=this.choroplethColorExpression(choropleth);this._map.getLayer(fillLayerId)?(this._map.setPaintProperty(fillLayerId,"fill-color",colorExpr),this._map.setPaintProperty(fillLayerId,"fill-opacity",choroplethFillOpacity(this))):this._map.addLayer({id:fillLayerId,type:"fill",source:sourceId,paint:{"fill-color":colorExpr,"fill-opacity":choroplethFillOpacity(this)}}),this._appliedFillLayerId=fillLayerId}choroplethColorExpression(choropleth){const{field,stops}=choropleth,resolvedStops=stops.map(([value,color])=>[value,resolvedLayerColor(this,color,void 0)]);let colorExpr;if(choropleth.interpolation==="step"){const base=choropleth.stepBaseColor?resolvedLayerColor(this,choropleth.stepBaseColor,void 0):resolvedStops[0][1];colorExpr=["step",["get",field],base];for(const[value,color]of resolvedStops)colorExpr.push(value,color)}else{colorExpr=["interpolate",choropleth.interpolation==="logarithmic"?["exponential",CHOROPLETH_LOG_INTERPOLATION_BASE]:["linear"],["get",field]];for(const[value,color]of resolvedStops)colorExpr.push(value,color)}return colorExpr}resolveChoroplethSourceId(sourceId){const dataSourceIds=new Set(this.canonicalDataLayers.map(layer=>layer.sourceId));let resolved=sourceId;for(;dataSourceIds.has(resolved);)resolved=`lr-choropleth-${resolved}`;return resolved}removeChoropleth(){!this._map||!this._appliedChoroplethSourceId||(this._appliedFillLayerId&&this._map.getLayer(this._appliedFillLayerId)&&this._map.removeLayer(this._appliedFillLayerId),this._map.getSource(this._appliedChoroplethSourceId)&&this._map.removeSource(this._appliedChoroplethSourceId),this._appliedGeoJson.delete(this._appliedChoroplethSourceId),this._appliedChoroplethSourceId=void 0,this._appliedFillLayerId=void 0)}applyDataLayers(){if(!this._map)return;const layers=this.canonicalDataLayers,nextIds=new Set(layers.map(layer=>layer.sourceId));for(const publicSourceId of this._appliedDataLayerIds.keys())nextIds.has(publicSourceId)||this.removeDataLayer(publicSourceId);for(const layer of layers){const{sourceId:publicSourceId,geojson,geojsonProjection}=layer,shape=dataLayerShape(layer),appliedShape=this._appliedDataLayerShapes.get(publicSourceId);appliedShape!==void 0&&appliedShape!==shape&&this.removeDataLayer(publicSourceId);const sourceId=this.resolveDataLayerSourceId(publicSourceId);warnOnUntileableProperties(geojsonProjection,publicSourceId);const cluster=layer.cluster,existingSource=this._map.getSource(sourceId);existingSource?this.pushGeoJson(existingSource,sourceId,geojson,geojsonProjection):(this._map.addSource(sourceId,{type:"geojson",data:geojson,...cluster?{cluster:!0,clusterRadius:cluster.radius,clusterMaxZoom:cluster.maxZoom}:{}}),this._appliedGeoJson.set(sourceId,geojsonProjection)),this.applyDataLayerRendering(sourceId,layer),this._appliedDataLayerIds.set(publicSourceId,sourceId),this._appliedDataLayerShapes.set(publicSourceId,shape)}}applyDataLayerRendering(sourceId,layer){if(layer.kind==="heatmap"){this.applyHeatmapLayer(sourceId,layer);return}const cluster=layer.cluster;cluster?this.applyClusterLayers(sourceId,layer,cluster):this.applyGeometryLayers(sourceId,layer),this.applyPointIcons(sourceId,layer)}paintDataLayer(sourceId,layer){if(layer.kind==="heatmap"){this.paintHeatmapLayer(sourceId,layer);return}const cluster=layer.cluster;cluster?this.paintClusterLayers(sourceId,layer,cluster):this.paintGeometryLayers(sourceId,layer),this.paintPointIcons(sourceId,layer)}applyGeometryLayers(sourceId,layer){if(!this._map)return;const tone=layer.tone,color=resolvedLayerColor(this,layer.color,tone),stroke=resolvedLayerColor(this,layer.strokeColor??layer.color,tone),fillId=`${sourceId}-fill`,lineId=`${sourceId}-line`,circleId=`${sourceId}-circle`;this._map.getLayer(fillId)||this._map.addLayer({id:fillId,type:"fill",source:sourceId,filter:["==",["geometry-type"],"Polygon"],paint:{"fill-color":color,"fill-opacity":choroplethFillOpacity(this)}}),this._map.getLayer(lineId)||this._map.addLayer({id:lineId,type:"line",source:sourceId,filter:["in",["geometry-type"],["literal",["LineString","Polygon"]]],paint:{"line-color":this.lineColor(layer),"line-width":layer.line?.width??2,...layer.line?{"line-opacity":layer.line.opacity}:{}}}),this._map.getLayer(circleId)||this._map.addLayer({id:circleId,type:"circle",source:sourceId,filter:["==",["geometry-type"],"Point"],paint:{"circle-color":stroke,"circle-radius":5}}),this._map.setPaintProperty(lineId,"line-width",layer.line?.width??2),this._map.setPaintProperty(lineId,"line-opacity",layer.line?.opacity??1),this.paintGeometryLayers(sourceId,layer)}paintGeometryLayers(sourceId,layer){if(!this._map)return;const tone=layer.tone,color=resolvedLayerColor(this,layer.color,tone);this._map.setPaintProperty(`${sourceId}-fill`,"fill-color",color),this._map.setPaintProperty(`${sourceId}-fill`,"fill-opacity",choroplethFillOpacity(this)),this._map.setPaintProperty(`${sourceId}-line`,"line-color",this.lineColor(layer)),this.paintPoints(sourceId,layer)}lineColor(layer){const fallback=resolvedLayerColor(this,layer.strokeColor??layer.color,layer.tone),line=layer.line;return!line?.field||line.stops.length<2?fallback:lineColorExpression(line.field,line.stops.map(([value,color])=>[value,resolvedLayerColor(this,color,layer.tone)]),fallback)}mutedPointOpacity(layerId,field){const muted=field?this.hiddenCategories:EMPTY_HIDDEN_CATEGORIES;if(!muted.length)return this.appliedPointMuting.delete(layerId)?1:void 0;this.appliedPointMuting.add(layerId);const dim=hiddenCategoryOpacity(this);return mutedCategoryOpacityExpression(field,muted,dim)}paintPoints(sourceId,layer){if(!this._map)return;const point=layer.point,fallback=resolvedLayerColor(this,layer.strokeColor??layer.color,layer.tone),color=pointColorExpression(point?.field,point?.field&&point.colors.length?point.colors.map(([value,paint])=>[value,resolvedLayerColor(this,paint,layer.tone)]):[],fallback),id=`${sourceId}-circle`;this._map.setPaintProperty(id,"circle-color",color);const opacity=this.mutedPointOpacity(id,point?.field);opacity!==void 0&&(this._map.setPaintProperty(id,"circle-opacity",opacity),this._map.setPaintProperty(id,"circle-stroke-opacity",opacity)),!(!point&&!this.appliedPointPaint.has(sourceId))&&(this._map.setPaintProperty(id,"circle-radius",pointRadiusExpression(point?.radius??5)),this._map.setPaintProperty(id,"circle-stroke-width",point?.strokeWidth??0),this._map.setPaintProperty(id,"circle-stroke-color",point?.strokeColor?resolvedLayerColor(this,point.strokeColor,layer.tone):fallback),point?this.appliedPointPaint.add(sourceId):this.appliedPointPaint.delete(sourceId))}pointIconColor(layer){const resolved=resolvedLayerColor(this,layer.point?.iconColor??`var(${ON_TONE_TOKEN[layer.tone??"accent"]})`,layer.tone);return resolveCanvasColor(this,resolved,dataLayerColor(this,layer.tone))}removePointIcons(sourceId){const applied=this.appliedPointIcons.get(sourceId);if(!applied||!this._map)return;const id=`${sourceId}-point-icon`;this._map.getLayer(id)&&this._map.removeLayer(id);for(const{id:imageId}of applied.icons)this._map.hasImage?.(imageId)&&this._map.removeImage?.(imageId);this.appliedPointIcons.delete(sourceId),this.appliedPointMuting.delete(id)}applyPointIcons(sourceId,layer){const map=this._map,point=layer.point,signature=JSON.stringify([point?.iconField,point?.iconSize,point?.icons]);if(this.appliedPointIcons.get(sourceId)?.signature===signature){this.paintPointIcons(sourceId,layer);return}if(this.removePointIcons(sourceId),!point?.iconField||!point.icons.length||!map||typeof map.addImage!="function"||typeof map.hasImage!="function"||typeof map.updateImage!="function"||typeof map.removeImage!="function")return;const color=this.pointIconColor(layer),icons=[];this.appliedPointIcons.set(sourceId,{signature,color,icons});for(const icon of point.icons){const raster=rasterPointIcon(this,icon,color);if(!raster)continue;let id;do id=`lr-point-icon-${this.nextPointIconId++}`;while(map.hasImage(id));icons.push({id,icon}),map.addImage(id,raster,{pixelRatio:2})}icons.length&&map.addLayer({id:`${sourceId}-point-icon`,type:"symbol",source:sourceId,filter:layer.cluster?["all",["==",["geometry-type"],"Point"],["!",["has","point_count"]]]:["==",["geometry-type"],"Point"],layout:{"icon-image":["match",["get",point.iconField],...icons.flatMap(({id,icon})=>[icon.value,id]),""],"icon-size":point.iconSize/(POINT_ICON_RASTER_SIZE/2),"icon-allow-overlap":!0,"icon-ignore-placement":!0}})}paintPointIcons(sourceId,layer){const applied=this.appliedPointIcons.get(sourceId);if(!applied)return;const iconLayerId=`${sourceId}-point-icon`,opacity=this.mutedPointOpacity(iconLayerId,layer.point?.iconField);opacity!==void 0&&this._map?.setPaintProperty(iconLayerId,"icon-opacity",opacity);const color=this.pointIconColor(layer);if(color!==applied.color){for(const{id,icon}of applied.icons){const raster=rasterPointIcon(this,icon,color);raster&&this._map?.updateImage?.(id,raster)}applied.color=color}}clusterColorExpression(layer,cluster){const tone=layer.tone;return clusterColorExpression(cluster.colorSteps.map(([count,stepColor])=>[count,resolvedLayerColor(this,stepColor,tone)]),()=>resolvedLayerColor(this,layer.color,tone))}applyClusterLayers(sourceId,layer,cluster){if(!this._map)return;const tone=layer.tone,stroke=resolvedClusterStrokeColor(this,cluster.strokeColor,layer),clusterId=`${sourceId}-cluster`,countId=`${sourceId}-cluster-count`,circleId=`${sourceId}-circle`,clusterColor=this.clusterColorExpression(layer,cluster),clusterRadius=stepExpression(["get","point_count"],cluster.radiusSteps),countColor=resolvedClusterCountColor(this,cluster.countColor)??resolvedLayerColor(this,`var(${ON_TONE_TOKEN[tone??"accent"]})`,tone),countHaloColor=resolvedClusterCountColor(this,cluster.countHaloColor);this._map.getLayer(clusterId)||this._map.addLayer({id:clusterId,type:"circle",source:sourceId,filter:["has","point_count"],paint:{"circle-color":clusterColor,"circle-radius":clusterRadius,"circle-stroke-width":1,"circle-stroke-color":stroke}}),this.styleProvidesGlyphs()&&!this._map.getLayer(countId)&&this._map.addLayer({id:countId,type:"symbol",source:sourceId,filter:["has","point_count"],layout:{"text-field":["get","point_count_abbreviated"],"text-size":12,...cluster.countFont?{"text-font":[...cluster.countFont]}:{}},paint:{"text-color":countColor,...countHaloColor?{"text-halo-color":countHaloColor,"text-halo-width":cluster.countHaloWidth}:{}}}),this._map.getLayer(circleId)||this._map.addLayer({id:circleId,type:"circle",source:sourceId,filter:["all",["==",["geometry-type"],"Point"],["!",["has","point_count"]]],paint:{"circle-color":stroke,"circle-radius":5}}),this.paintClusterLayers(sourceId,layer,cluster)}paintClusterLayers(sourceId,layer,cluster){if(!this._map)return;const tone=layer.tone,stroke=resolvedClusterStrokeColor(this,cluster.strokeColor,layer),clusterId=`${sourceId}-cluster`;if(this._map.setPaintProperty(clusterId,"circle-color",this.clusterColorExpression(layer,cluster)),this._map.setPaintProperty(clusterId,"circle-radius",stepExpression(["get","point_count"],cluster.radiusSteps)),this._map.setPaintProperty(clusterId,"circle-stroke-color",stroke),this.styleProvidesGlyphs()){this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-color",resolvedClusterCountColor(this,cluster.countColor)??resolvedLayerColor(this,`var(${ON_TONE_TOKEN[tone??"accent"]})`,tone));const countHaloColor=resolvedClusterCountColor(this,cluster.countHaloColor);this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-halo-color",countHaloColor??null),this._map.setPaintProperty(`${sourceId}-cluster-count`,"text-halo-width",countHaloColor?cluster.countHaloWidth:null)}this.paintPoints(sourceId,layer)}applyHeatmapLayer(sourceId,layer){if(!this._map)return;const heatmapId=`${sourceId}-heatmap`,options=layer.heatmap,weight=heatmapWeightExpression(options),color=this.heatmapColorExpression(layer),radius=heatmapZoomValue(options?.radius,DEFAULT_HEATMAP_RADIUS,1,200),intensity=heatmapZoomValue(options?.intensity,DEFAULT_HEATMAP_INTENSITY,0,100),opacity=finiteRange(options?.opacity??Number.NaN,1,0,1);if(!this._map.getLayer(heatmapId)){this._map.addLayer({id:heatmapId,type:"heatmap",source:sourceId,paint:{...weight?{"heatmap-weight":weight}:{},"heatmap-intensity":intensity,"heatmap-color":color,"heatmap-radius":radius,...options?.opacity===void 0?{}:{"heatmap-opacity":opacity}}});return}this.paintHeatmapLayer(sourceId,layer)}paintHeatmapLayer(sourceId,layer){if(!this._map)return;const heatmapId=`${sourceId}-heatmap`;this._map.setPaintProperty(heatmapId,"heatmap-weight",heatmapWeightExpression(layer.heatmap)??1),this._map.setPaintProperty(heatmapId,"heatmap-intensity",heatmapZoomValue(layer.heatmap?.intensity,DEFAULT_HEATMAP_INTENSITY,0,100)),this._map.setPaintProperty(heatmapId,"heatmap-color",this.heatmapColorExpression(layer)),this._map.setPaintProperty(heatmapId,"heatmap-radius",heatmapZoomValue(layer.heatmap?.radius,DEFAULT_HEATMAP_RADIUS,1,200)),this._map.setPaintProperty(heatmapId,"heatmap-opacity",finiteRange(layer.heatmap?.opacity??Number.NaN,1,0,1))}heatmapColorExpression(layer){const tone=layer.tone,authored=(layer.heatmap?.stops??[]).map(([density,color])=>[density,resolvedLayerColor(this,color,tone)]);return heatmapColorExpression(authored,()=>HEATMAP_RAMP_TOKENS.map(([density,token])=>[density,resolvedLayerColor(this,`var(${token})`,tone)]))}styleProvidesGlyphs(){try{const liveGlyphs=this._map?.getStyle?.()?.glyphs;if(typeof liveGlyphs=="string"&&liveGlyphs.trim().length>0)return!0}catch{}const declared=this.mapStyle,declaredGlyphs=declared&&typeof declared=="object"?declared.glyphs:void 0;return typeof declaredGlyphs=="string"&&declaredGlyphs.trim().length>0}resolveDataLayerSourceId(publicSourceId){const applied=this._appliedDataLayerIds.get(publicSourceId);if(applied)return applied;let sourceId;do sourceId=`lr-data-layer-${this._nextDataLayerId++}`;while(this._map?.getSource(sourceId)||DATA_LAYER_SUFFIXES.some(suffix=>this._map?.getLayer(`${sourceId}${suffix}`)));return sourceId}removeDataLayer(publicSourceId){if(!this._map)return;const sourceId=this._appliedDataLayerIds.get(publicSourceId);if(sourceId){this.removePointIcons(sourceId),this.appliedPointPaint.delete(sourceId);for(const suffix of DATA_LAYER_SUFFIXES){const layerId=`${sourceId}${suffix}`;this.appliedPointMuting.delete(layerId),this._map.getLayer(layerId)&&this._map.removeLayer(layerId)}this._map.getSource(sourceId)&&this._map.removeSource(sourceId),this._appliedDataLayerIds.delete(publicSourceId),this._appliedDataLayerShapes.delete(publicSourceId),this._appliedGeoJson.delete(sourceId)}}applyMarkers(){const map=this._map,mod=this._maplibreModule;if(!map||!mod)return;const visible=new Set,coordCounts=new Map,explicitIds=new Set;let defaultColor;for(const m of this.canonicalMarkers){const lngLat=m.lngLat,mapLngLat=[lngLat[0],lngLat[1]];let key,id;if(m.id!==void 0){if(id=m.id,explicitIds.has(id))continue;explicitIds.add(id),key=`id:${id}`}else{const coordKey=`${lngLat[0]},${lngLat[1]}`,occurrence=coordCounts.get(coordKey)??0;coordCounts.set(coordKey,occurrence+1),key=`coordinate:${coordKey}#${occurrence}`}visible.add(key);let existing=this._markerInstances.get(key);const markerColor=sanitizeCssColor(m.color)??(m.color===void 0?defaultColor??=dataLayerColor(this,"accent"):void 0),previous=this._markerSources.get(key);this._markerSources.set(key,m);const sameColor=this._markerColors.get(key)===markerColor,sameContent=previous!==void 0&&previous.label===m.label&&Object.is(previous.unsafeHtml,m.unsafeHtml);if(existing&&sameColor&&sameContent&&previous.lngLat[0]===lngLat[0]&&previous.lngLat[1]===lngLat[1])continue;if(existing&&!sameColor){const existingElement=existing.getElement?.();existingElement&&this.markerActivationDetails.delete(existingElement),existing.remove(),this._markerInstances.delete(key),this._markerColors.delete(key),existing=void 0}if(existing){existing.setLngLat(mapLngLat);const popup=existing.getPopup();if(!m.unsafeHtml&&!m.label)popup&&existing.setPopup(void 0);else if(popup)sameContent||setPopupContent(popup,m);else{const nextPopup=setPopupContent(new mod.Popup({offset:12}),m);existing.setPopup(nextPopup),this.configurePopupSemantics(key,existing,nextPopup)}}else{const marker=new mod.Marker(markerColor?{color:markerColor}:void 0).setLngLat(mapLngLat);if(m.unsafeHtml||m.label){const popup=setPopupContent(new mod.Popup({offset:12}),m);marker.setPopup(popup),this.configurePopupSemantics(key,marker,popup)}marker.addTo(map),this._markerInstances.set(key,marker),this._markerColors.set(key,markerColor)}const markerLabel=m.label?.trim()||markerPopupText(this,m.unsafeHtml);this._markerLabels.set(key,markerLabel||void 0);const markerElement=this._markerInstances.get(key)?.getElement?.();if(markerElement){addPartToken(markerElement,"marker");const currentMarker=this._markerInstances.get(key);this.configureMarkerInteraction(markerElement,{id,lngLat,marker:m},markerLabel);const popup=currentMarker?.getPopup();popup&&currentMarker?(this.configurePopupSemantics(key,currentMarker,popup),this.syncPopupSemantics(key,currentMarker,popup)):(markerElement.removeAttribute("aria-controls"),markerElement.removeAttribute("aria-expanded"),markerElement.removeAttribute("aria-haspopup"))}}for(const[key,marker]of this._markerInstances)if(!visible.has(key)){const markerElement=marker.getElement?.();markerElement&&this.markerActivationDetails.delete(markerElement),marker.remove(),this._markerInstances.delete(key),this._markerColors.delete(key),this._markerLabels.delete(key),this._markerPopupIds.delete(key),this._markerSources.delete(key)}}configureMarkerInteraction(markerElement,activation,markerLabel=activation.marker.label?.trim()||markerPopupText(this,activation.marker.unsafeHtml)){this.markerActivationDetails.set(markerElement,activation),markerElement.setAttribute("role","button"),markerElement.tabIndex=0,markerElement.setAttribute("aria-label",markerLabel||this.localize("mapMarker")),markerElement.setAttribute("lang",this.effectiveLocale),!this.configuredMarkerElements.has(markerElement)&&(this.configuredMarkerElements.add(markerElement),markerElement.addEventListener("click",event=>{event.defaultPrevented||this.emitMarkerActivation(markerElement,"pointer")}),markerElement.addEventListener("keydown",event=>{event.key!==" "&&event.key!=="Enter"||event.repeat||event.defaultPrevented||(event.key===" "&&event.preventDefault(),this.emitMarkerActivation(markerElement,"keyboard"))},{capture:!0}))}emitMarkerActivation(markerElement,source){if(!this.isConnected)return;const activation=this.markerActivationDetails.get(markerElement);activation&&this.emit("lr-map-marker-activate",{...activation,source})}get effectiveMapLabel(){return hostAriaLabel(this)??this.label??this.localize("map")}popupId(key){let id=this._markerPopupIds.get(key);return id||(id=`map-popup-${this._connectGeneration}-${++this._nextPopupId}`,this._markerPopupIds.set(key,id)),id}configurePopupSemantics(key,marker,popup){!popup||typeof popup!="object"||this._configuredPopups.has(popup)||(this._configuredPopups.add(popup),popup.on?.("open",()=>this.syncPopupSemantics(key,marker,popup)),popup.on?.("close",()=>{marker.getElement?.()?.setAttribute("aria-expanded","false")}))}stopObservingMapAllocation(){this.mapResizeObserver?.disconnect(),this.mapResizeObserver=void 0,this.observedMapContainer=void 0}observeMapAllocation(map,container){this.stopObservingMapAllocation();const ResizeObserverCtor=container.ownerDocument.defaultView?.ResizeObserver;if(!ResizeObserverCtor)return;let observer;observer=new ResizeObserverCtor(()=>{if(!(this.mapResizeObserver!==observer||this.observedMapContainer!==container||this.containerEl!==container||this._map!==map||!this.isConnected))try{map.resize()}catch{}}),this.mapResizeObserver=observer,this.observedMapContainer=container;try{observer.observe(container)}catch{this.stopObservingMapAllocation()}}stopObservingPeerChrome(){const pending=this.peerControlsResizeFrame;this.peerControlsResizeFrame=void 0,pending&&pending.view.cancelAnimationFrame(pending.handle),this.peerControlsResizeObserver?.disconnect(),this.peerControlsResizeObserver=void 0,this.peerChromeObserver?.disconnect(),this.peerChromeObserver=void 0,this.observedPeerContainer=void 0}schedulePeerControlInsets(observer,container){if(this.peerControlsResizeObserver!==observer||this.observedPeerContainer!==container||this.containerEl!==container||!this.isConnected||this.peerControlsResizeFrame)return;const view=container.ownerDocument.defaultView;if(!view)return;const pending={view,handle:0};this.peerControlsResizeFrame=pending,pending.handle=view.requestAnimationFrame(()=>{this.peerControlsResizeFrame===pending&&(this.peerControlsResizeFrame=void 0,!(this.peerControlsResizeObserver!==observer||this.observedPeerContainer!==container||this.containerEl!==container||container.ownerDocument.defaultView!==view||!this.isConnected)&&this.measurePeerControlInsets(container))})}measurePeerControlInsets(container){if(!(!this.isConnected||this.containerEl!==container)){for(const scale of container.querySelectorAll(".maplibregl-ctrl-scale")){const width=scale.style.width;width&&scale.style.getPropertyValue("--_lr-map-scale-width")!==width&&scale.style.setProperty("--_lr-map-scale-width",width)}for(const edge of["top","bottom"]){const height=Math.max(0,...[...container.querySelectorAll(`.maplibregl-ctrl-${edge}-left, .maplibregl-ctrl-${edge}-right`)].map(corner=>corner.offsetHeight)),base=container.parentElement,name=`--_lr-map-controls-${edge}`,value=`${height}px`;base&&base.style.getPropertyValue(name)!==value&&base.style.setProperty(name,value)}}}syncPeerChromeParts(root=this.containerEl??this.renderRoot){const selectors=[[".maplibregl-marker","marker"],[".maplibregl-popup","popup"],[".maplibregl-popup-content","popup-content"],[".maplibregl-popup-close-button","popup-close-button"],[".maplibregl-ctrl-attrib","attribution"],[".maplibregl-ctrl-attrib-button","attribution-toggle"],[".maplibregl-ctrl-group:has(.maplibregl-ctrl-zoom-in, .maplibregl-ctrl-compass)","navigation"],[".maplibregl-ctrl-zoom-in","zoom-in"],[".maplibregl-ctrl-zoom-out","zoom-out"],[".maplibregl-ctrl-compass","compass"],[".maplibregl-ctrl-scale","scale"]];for(const[selector,part]of selectors){const candidate=root,elements=[...root.querySelectorAll(selector)];candidate.matches?.(selector)&&elements.push(candidate);for(const element of elements){addPartToken(element,part);const label=part==="attribution-toggle"?this.localize("mapToggleAttribution"):part==="zoom-in"?this.localize("zoomIn"):part==="zoom-out"?this.localize("zoomOut"):part==="compass"?this.localize("mapResetNorth"):void 0;label!==void 0&&(element.setAttribute("aria-label",label),element.setAttribute("title",label))}}}observePeerChrome(){const container=this.containerEl;if(!container||(this.syncPeerChromeParts(container),this.observedPeerContainer===container&&this.peerChromeObserver))return;this.stopObservingPeerChrome();const MutationObserverCtor=container.ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor)return;this.observedPeerContainer=container;const ResizeObserverCtor=container.ownerDocument.defaultView?.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(()=>this.schedulePeerControlInsets(observer,container));this.peerControlsResizeObserver=observer;for(const corner of container.querySelectorAll(".maplibregl-ctrl-top-left, .maplibregl-ctrl-top-right, .maplibregl-ctrl-bottom-left, .maplibregl-ctrl-bottom-right"))this.peerControlsResizeObserver.observe(corner)}this.measurePeerControlInsets(container),this.peerChromeObserver=new MutationObserverCtor(records=>{if(!(!this.isConnected||this.containerEl!==container)){for(const record of records)for(const node of record.addedNodes)node.nodeType===Node.ELEMENT_NODE&&this.syncPeerChromeParts(node);this.measurePeerControlInsets(container)}}),this.peerChromeObserver.observe(container,{childList:!0,subtree:!0})}syncPopupSemantics(key,marker,popup){const markerElement=marker?.getElement?.();if(!markerElement)return;const id=this.popupId(key);markerElement.setAttribute("aria-controls",id),markerElement.setAttribute("aria-haspopup","dialog"),markerElement.setAttribute("aria-expanded",popup?.isOpen?.()?"true":"false");const popupElement=popup?.getElement?.();if(!popupElement)return;addPartToken(markerElement,"marker"),addPartToken(popupElement,"popup"),popupElement.id=id,popupElement.setAttribute("role","dialog"),popupElement.setAttribute("lang",this.effectiveLocale),popupElement.setAttribute("aria-label",this._markerLabels.get(key)||this.effectiveMapLabel);const popupContent=popupElement.querySelector(".maplibregl-popup-content");popupContent&&addPartToken(popupContent,"popup-content");const closeButton=popupElement.querySelector(".maplibregl-popup-close-button");closeButton&&addPartToken(closeButton,"popup-close-button"),closeButton?.setAttribute("aria-label",this.localize("close"))}syncMapSemantics(){const canvas=this._map?.getCanvas?.();canvas&&(canvas.setAttribute("aria-label",this.effectiveMapLabel),canvas.setAttribute("lang",this.effectiveLocale),this.legend.length||this.legendGradient.length>=2||this.hasLegendSlot||this.hasLegendStartSlot||this.legendProjection.truncated?canvas.setAttribute("aria-describedby","map-legend"):canvas.removeAttribute("aria-describedby")),this.hostDescription.refresh();for(const[key,marker]of this._markerInstances){const markerElement=marker.getElement?.();if(!markerElement)continue;addPartToken(markerElement,"marker"),markerElement.setAttribute("role","button"),markerElement.tabIndex=0,markerElement.setAttribute("aria-label",this._markerLabels.get(key)||this.localize("map")),markerElement.setAttribute("lang",this.effectiveLocale);const popup=marker.getPopup?.();popup?this.syncPopupSemantics(key,marker,popup):(markerElement.removeAttribute("aria-controls"),markerElement.removeAttribute("aria-expanded"),markerElement.removeAttribute("aria-haspopup"))}this.syncPeerChromeParts()}formatCount(value){return getNumberFormat(this.effectiveLocale).format(value)}legendLimitText(){return this.localize("paginationSummary",void 0,{start:this.formatCount(this.legend.length===0?0:1),end:this.formatCount(this.legend.length),total:this.formatCount(this.legendProjection.inputCount),itemLabel:this.localize("items")})}renderLegendRowContent(entry){const paint=sanitizeCssColor(entry.color);return html`${entry.icon?html`<span
21
21
  part="legend-swatch"
22
22
  data-pattern=${entry.pattern}
23
23
  data-icon="true"
@@ -103,4 +103,4 @@ import{__decorate}from"tslib";import{collectionSupport}from"../../../internal/co
103
103
  <slot name="legend" ?hidden=${this.legendCollapsed} @slotchange=${this.onLegendSlotChange}></slot>
104
104
  </div>`:nothing}
105
105
  </div>
106
- `}}__decorate([property({type:Array})],LyraMap.prototype,"center",null),__decorate([property({type:Number})],LyraMap.prototype,"zoom",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"renderWorldCopies",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"maxBounds",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"mapStyle",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"legend",null),__decorate([state()],LyraMap.prototype,"hasLegendSlot",void 0),__decorate([state()],LyraMap.prototype,"hasLegendStartSlot",void 0),__decorate([property({attribute:"legend-gradient-lo-label"})],LyraMap.prototype,"legendGradientLoLabel",void 0),__decorate([property({attribute:"legend-gradient-hi-label"})],LyraMap.prototype,"legendGradientHiLabel",void 0),__decorate([property({type:Boolean,attribute:"legend-interactive",reflect:!0})],LyraMap.prototype,"legendInteractive",void 0),__decorate([property({converter:LEGEND_CONTROL_ROLE,attribute:"legend-control-role",reflect:!0})],LyraMap.prototype,"legendControlRole",null),__decorate([property({type:Boolean,attribute:"legend-collapsible",reflect:!0})],LyraMap.prototype,"legendCollapsible",void 0),__decorate([property({attribute:"legend-open",reflect:!0,converter:trueDefaultBooleanConverter})],LyraMap.prototype,"legendOpen",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"hiddenCategories",null),__decorate([property({attribute:!1})],LyraMap.prototype,"choropleth",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"markers",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"dataLayers",void 0),__decorate([property()],LyraMap.prototype,"label",void 0),__decorate([state()],LyraMap.prototype,"loading",void 0),__decorate([state()],LyraMap.prototype,"failure",void 0),__decorate([state()],LyraMap.prototype,"visible",void 0),__decorate([query('[part="container"]')],LyraMap.prototype,"containerEl",void 0);export{LyraMap,buildGeoJsonPropertyDiff};
106
+ `}}__decorate([property({type:Array})],LyraMap.prototype,"center",null),__decorate([property({type:Number})],LyraMap.prototype,"zoom",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"renderWorldCopies",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"maxBounds",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"mapStyle",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"legend",null),__decorate([state()],LyraMap.prototype,"hasLegendSlot",void 0),__decorate([state()],LyraMap.prototype,"hasLegendStartSlot",void 0),__decorate([property({attribute:"legend-gradient-lo-label"})],LyraMap.prototype,"legendGradientLoLabel",void 0),__decorate([property({attribute:"legend-gradient-hi-label"})],LyraMap.prototype,"legendGradientHiLabel",void 0),__decorate([property({type:Boolean,attribute:"legend-interactive",reflect:!0})],LyraMap.prototype,"legendInteractive",void 0),__decorate([property({converter:LEGEND_CONTROL_ROLE,attribute:"legend-control-role",reflect:!0})],LyraMap.prototype,"legendControlRole",null),__decorate([property({type:Boolean,attribute:"legend-collapsible",reflect:!0})],LyraMap.prototype,"legendCollapsible",void 0),__decorate([property({attribute:"legend-open",reflect:!0,converter:trueDefaultBooleanConverter})],LyraMap.prototype,"legendOpen",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"hiddenCategories",null),__decorate([property({attribute:!1})],LyraMap.prototype,"choropleth",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"markers",void 0),__decorate([property({attribute:!1})],LyraMap.prototype,"dataLayers",void 0),__decorate([property()],LyraMap.prototype,"label",void 0),__decorate([property({converter:MAP_ENGINE})],LyraMap.prototype,"engine",void 0),__decorate([state()],LyraMap.prototype,"loading",void 0),__decorate([state()],LyraMap.prototype,"failure",void 0),__decorate([state()],LyraMap.prototype,"visible",void 0),__decorate([query('[part="container"]')],LyraMap.prototype,"containerEl",void 0);export{LyraMap,buildGeoJsonPropertyDiff};
@@ -3,7 +3,16 @@ import type{ComplexAttributeConverter}from'lit';import type{LyraNodeTypeStyle}fr
3
3
  * `vw` or `vh` unit stays the authored CSS length, resolved to pixels when it is used; any other
4
4
  * value parses with `Number()`, exactly as the pixel-only attributes always have (a plain number
5
5
  * is pixels, a removed attribute is `null`). */
6
- export declare const graphLengthConverter:ComplexAttributeConverter<number|string>;export interface LyraGraphNode{readonly id:string;readonly label?:string;
6
+ export declare const graphLengthConverter:ComplexAttributeConverter<number|string>;
7
+ /** A world-space point for the optional spatial view. Coordinates are bounded to ±1,000,000. */
8
+ export interface LyraGraphPosition{readonly x:number;readonly y:number;readonly z:number;}
9
+ /** Orbit camera: radians for yaw/pitch, graph units for distance and target. */
10
+ export interface LyraGraphCamera{readonly yaw:number;readonly pitch:number;readonly distance:number;readonly target:LyraGraphPosition;}
11
+ /** The default 2D diagram, an orbitable perspective view, or a visible paginated data list. */
12
+ export type LyraGraphView='2d'|'3d'|'list';export interface LyraGraphNode{readonly id:string;
13
+ /** Authoritative x/y/z placement in view="3d"; ignored by the 2D layouts. Missing, inherited,
14
+ * accessor-backed or non-finite coordinates use deterministic spatial placement keyed by id. */
15
+ readonly position?:LyraGraphPosition;readonly label?:string;
7
16
  /** Spoken label when it needs more context than the visible label. */
8
17
  readonly accessibleLabel?:string;
9
18
  /** Preferred bounded tooltip/summary text in both renderers. */
@@ -0,0 +1,30 @@
1
+ import{html,nothing}from"lit";import{finiteRange}from"../../../internal/numbers.js";import{nextId}from"../../../internal/a11y.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{graphLinkIdentity}from"./graph-model.js";import{fittedGraphCamera,normalizeGraphCamera,panGraphCamera,pickSpatialScene,projectSpatialPoint,projectSpatialScene,spatialNodePosition}from"./graph-spatial.js";const PAGE_SIZE=200,ORBIT_STEP=Math.PI/18;class GraphSpatialController{constructor(host,options){this.host=host,this.options=options,this.world=[],this.edges=[],this.items=[],this.communityCounts=new Map,this.worldById=new Map,this.nodeIndexById=new Map,this.currentCamera=normalizeGraphCamera(void 0,{yaw:0,pitch:0,distance:500,target:{x:0,y:0,z:0}}),this.fittedDistance=500,this.cameraInitialized=!1,this.pendingInitialFit=!1,this.visible=!0,this.notifyCamera=!1,this.contextFailed=!1,this.page=0,this.focusAfterViewChange=!1,this.instructionsId=nextId("graph-spatial-instructions"),this.pointerDown=event=>{if(!(event.button!==0||this.gesture)){this.canvas?.focus(),this.gesture={id:event.pointerId,startX:event.clientX,startY:event.clientY,x:event.clientX,y:event.clientY,moved:!1,pan:event.shiftKey};try{this.canvas?.setPointerCapture(event.pointerId)}catch{}this.setHover(void 0)}},this.pointerMove=event=>{const gesture=this.gesture;if(!gesture){this.setHover(this.hit(event.clientX,event.clientY));return}if(gesture.id!==event.pointerId)return;gesture.moved||=Math.hypot(event.clientX-gesture.startX,event.clientY-gesture.startY)>5;const dx=event.clientX-gesture.x,dy=event.clientY-gesture.y;gesture.x=event.clientX,gesture.y=event.clientY,gesture.moved&&(gesture.pan?this.changeCamera(panGraphCamera(this.currentCamera,dx,dy,this.viewport())):this.orbit(dx*.008,-dy*.008))},this.pointerUp=event=>{const gesture=this.gesture;if(!(!gesture||gesture.id!==event.pointerId)&&(this.cancelGesture(),!gesture.moved&&Math.hypot(event.clientX-gesture.startX,event.clientY-gesture.startY)<=5)){const hit=this.hit(event.clientX,event.clientY);hit&&this.options.activate(hit,event)}},this.pointerCancel=event=>{event.pointerId===this.gesture?.id&&this.cancelGesture()},this.wheel=event=>{this.host.shadowRoot?.activeElement!==this.canvas&&!this.gesture||(event.preventDefault(),this.zoom(Math.exp(-finiteRange(event.deltaY,0,-300,300)*.002)))},this.keyDown=event=>{const direction=this.options.direction()==="rtl"?-1:1,dx=event.key==="ArrowRight"?direction:event.key==="ArrowLeft"?-direction:0,dy=event.key==="ArrowDown"?1:event.key==="ArrowUp"?-1:0;dx||dy?(event.preventDefault(),event.shiftKey?this.changeCamera(panGraphCamera(this.currentCamera,dx*24,dy*24,this.viewport())):this.orbit(dx*ORBIT_STEP,-dy*ORBIT_STEP)):event.key==="+"||event.key==="="||event.key==="-"?(event.preventDefault(),this.zoom(event.key==="-"?1/1.2:1.2)):event.key==="Home"?(event.preventDefault(),this.fit()):event.key==="Escape"&&this.options.clearSelection()}}prepare(){const model=this.options.model();if(this.source!==model||this.hiddenTypes!==this.host.hiddenTypes){this.source=model,this.hiddenTypes=this.host.hiddenTypes;const hidden=new Set(this.host.hiddenTypes),allIds=new Set(model.nodes.map(node=>node.id));this.world=model.nodes.filter(node=>node.type==null||!hidden.has(node.type)).map(node=>({node,position:spatialNodePosition(node),radius:finiteRange(node.radius??15,15,6,24),shape:this.options.nodeShape(node)})),this.worldById=new Map(this.world.map(node=>[node.node.id,node])),this.nodeIndexById=new Map(this.world.map((node,index)=>[node.node.id,index])),this.edges=model.links.filter(edge=>this.worldById.has(edge.source)&&(this.worldById.has(edge.target)||!allIds.has(edge.target)));const communityMembers=new Map;for(const{node}of this.world){if(!node.communityId)continue;let members=communityMembers.get(node.communityId);members||communityMembers.set(node.communityId,members=new Set),members.add(node.id)}this.communityCounts=new Map;const communities=model.communities.filter(community=>{const members=communityMembers.get(community.id)??new Set;for(const id of community.memberIds)this.worldById.has(id)&&members.add(id);return this.communityCounts.set(community.id,members.size),members.size>0});this.items=[...this.world.map(({node})=>({kind:"node",node})),...this.edges.map(edge=>({kind:"link",edge})),...communities.map(community=>({kind:"community",community}))];const focused=this.host.shadowRoot?.activeElement;if(focused?.getAttribute("part")==="spatial-list-item"){const id=focused.getAttribute("data-node-id");id&&!this.worldById.has(id)&&(this.focusAfterViewChange=!0)}this.page=Math.min(this.page,Math.max(0,Math.ceil(this.items.length/PAGE_SIZE)-1)),this.scene=void 0,this.setHover(void 0),!this.cameraInitialized&&this.world.length&&(this.currentCamera=fittedGraphCamera(this.world,this.viewport()),this.fittedDistance=this.currentCamera.distance,this.cameraInitialized=!0,this.pendingInitialFit=!0)}this.authoredCamera!==this.host.camera&&(this.authoredCamera=this.host.camera,this.pendingInitialFit=!1,this.currentCamera=this.authoredCamera?normalizeGraphCamera(this.authoredCamera,this.currentCamera):fittedGraphCamera(this.world,this.viewport()),this.scene=void 0)}update(){if(!this.host.isConnected||this.host.view==="2d"){this.disconnect();return}this.paint=void 0;const next=this.host.renderRoot.querySelector('[part="spatial-canvas"]')??void 0;if(this.canvas!==next){this.cancelGesture(),this.resize?.disconnect(),this.intersection?.disconnect(),this.canvas=next,this.scene=void 0,this.fitInitialCanvas();try{this.context=next?.getContext("2d")??void 0}catch{this.context=void 0}next&&!this.context&&!this.contextFailed&&(this.contextFailed=!0,this.options.afterUpdate(()=>{!this.contextFailed||this.host.view!=="3d"||(this.options.unavailable(),this.host.requestUpdate())},"graph-spatial-context"));const view=this.host.ownerDocument.defaultView;if(next&&view){const Resize=view.ResizeObserver;Resize&&(this.resize=new Resize(()=>{this.fitInitialCanvas(),this.scene=void 0,this.schedule()}),this.resize.observe(next));const Intersection=view.IntersectionObserver;Intersection&&(this.intersection=new Intersection(entries=>{this.visible=entries[0]?.isIntersecting??!0,this.visible&&this.schedule()}),this.intersection.observe(next))}}this.schedule(),this.focusAfterViewChange&&(this.focusAfterViewChange=!1,(this.host.renderRoot.querySelector('[part="spatial-list-item"]')??this.host.renderRoot.querySelector('[part="spatial-canvas"]')??this.host.renderRoot.querySelector('[data-spatial-action="3d"]'))?.focus())}disconnect(){this.cancelGesture(),this.frame!==void 0&&this.frameWindow?.cancelAnimationFrame(this.frame),this.frame=void 0,this.frameWindow=void 0,this.notifyCamera=!1,this.lastKeyActivation=void 0,this.resize?.disconnect(),this.resize=void 0,this.intersection?.disconnect(),this.intersection=void 0,this.canvas=void 0,this.context=void 0,this.scene=void 0,this.hover=void 0,this.visible=!0,this.contextFailed=!1}invalidate(){this.paint=void 0,this.scene=void 0,this.schedule()}fitInitialCanvas(){!this.pendingInitialFit||!this.canvas?.clientWidth||!this.canvas.clientHeight||(this.pendingInitialFit=!1,this.currentCamera=fittedGraphCamera(this.world,this.viewport()),this.fittedDistance=this.currentCamera.distance,this.scene=void 0)}viewport(){return{width:Math.max(1,this.canvas?.clientWidth||this.options.viewport().width),height:Math.max(1,this.canvas?.clientHeight||this.options.viewport().height)}}position(id){return this.prepare(),this.worldById.get(id)?.position}screenPosition(id){if(this.host.view!=="3d"||!this.canvas)return;const node=this.worldById.get(id),point=node&&projectSpatialPoint(node.position,this.currentCamera,this.viewport());if(!point)return;const bounds=this.canvas.getBoundingClientRect(),hostBounds=this.host.getBoundingClientRect();return{x:bounds.left-hostBounds.left+point.x,y:bounds.top-hostBounds.top+point.y}}fit(padding){if(this.prepare(),!this.world.length)return;const camera=fittedGraphCamera(this.world,this.viewport(),padding);this.fittedDistance=camera.distance,this.changeCamera(camera)}focusNode(id,zoom){this.prepare();const node=this.worldById.get(id);return node?((this.host.view==="list"||this.contextFailed)&&(this.page=Math.floor((this.nodeIndexById.get(id)??0)/PAGE_SIZE),this.host.requestUpdate()),this.changeCamera({...this.currentCamera,target:node.position,distance:zoom===void 0?this.currentCamera.distance:this.fittedDistance/this.safeZoom(zoom)}),!0):!1}safeZoom(value){const min=finiteRange(this.host.minZoom,.1,.001,1e3),max=finiteRange(this.host.maxZoom,8,.001,1e3);return finiteRange(value,1,Math.min(min,max),Math.max(min,max))}zoom(factor){const zoom=this.safeZoom(this.fittedDistance/this.currentCamera.distance*factor);this.changeCamera({...this.currentCamera,distance:this.fittedDistance/zoom})}orbit(yaw,pitch){this.changeCamera({...this.currentCamera,yaw:this.currentCamera.yaw+yaw,pitch:this.currentCamera.pitch+pitch})}changeCamera(camera){this.pendingInitialFit=!1,this.currentCamera=normalizeGraphCamera(camera,this.currentCamera),this.scene=void 0,this.notifyCamera=!0,this.schedule()}schedule(){if(!this.host.isConnected||this.host.view==="2d"||this.frame!==void 0||!this.visible&&!this.notifyCamera)return;const view=this.host.ownerDocument.defaultView;view&&(this.frameWindow=view,this.frame=view.requestAnimationFrame(()=>{this.frame=void 0,this.frameWindow=void 0,!(!this.host.isConnected||this.host.view==="2d")&&(this.visible&&this.draw(),this.notifyCamera&&(this.notifyCamera=!1,this.options.cameraChanged(normalizeGraphCamera(this.currentCamera,this.currentCamera))))}))}projectedScene(){const paint=this.paint??=this.options.paint(this.world,this.edges),viewport=this.viewport(),previousEdges=this.sceneVisibleEdges;return(this.sceneViewport?.width!==viewport.width||this.sceneViewport.height!==viewport.height||!previousEdges||previousEdges.size!==paint.visibleEdges.size||[...paint.visibleEdges].some(id=>!previousEdges.has(id)))&&(this.scene=void 0),this.scene||(this.scene=projectSpatialScene(this.world,this.edges.filter(edge=>paint.visibleEdges.has(graphLinkIdentity(edge))),this.currentCamera,viewport),this.sceneViewport=viewport,this.sceneVisibleEdges=paint.visibleEdges),this.scene}draw(){const canvas=this.canvas,ctx=this.context;if(!canvas||!ctx||this.host.view!=="3d")return;const size=this.viewport(),dpr=finiteRange(this.host.ownerDocument.defaultView?.devicePixelRatio??1,1,1,4),scale=Math.min(dpr,8192/Math.max(size.width,size.height)),width=Math.max(1,Math.round(size.width*scale)),height=Math.max(1,Math.round(size.height*scale));(canvas.width!==width||canvas.height!==height)&&(canvas.width=width,canvas.height=height),ctx.setTransform(scale,0,0,scale,0,0),ctx.clearRect(0,0,size.width,size.height);const paint=this.paint??=this.options.paint(this.world,this.edges);ctx.font=`${paint.fontSize}px ${paint.font}`,ctx.textBaseline="middle";const selectedNodes=new Set(this.host.selectedNodeIds),selectedEdges=new Set(this.host.selectedEdgeIds),dimmedNodes=new Set(this.host.dimmedNodeIds),dimmedEdges=new Set(this.host.dimmedEdgeIds),zoom=this.fittedDistance/this.currentCamera.distance,scene=this.projectedScene(),projectedById=new Map(scene.nodes.map(node=>[node.node.id,node]));for(const primitive of scene.primitives){if(ctx.save(),primitive.kind==="node"){const entry=primitive.value,id=entry.node.id;ctx.globalAlpha=dimmedNodes.has(id)?paint.dimmedOpacity:1,this.drawNode(ctx,entry,paint.nodes.get(id)??paint.text),(selectedNodes.has(id)||this.host.focusNodeId===id||this.hover?.kind==="node"&&this.hover.id===id)&&(ctx.strokeStyle=paint.selected,ctx.lineWidth=2,ctx.beginPath(),ctx.arc(entry.x,entry.y,entry.screenRadius+4,0,Math.PI*2),ctx.stroke()),this.host.nodeLabels!=="none"&&(this.host.nodeLabels==="always"||zoom>=.5)&&(ctx.fillStyle=paint.text,ctx.fillText(entry.node.label??entry.node.id,entry.x+entry.screenRadius+4,entry.y)),entry.node.expandable&&(ctx.fillStyle=paint.text,ctx.fillText("+",entry.x+entry.screenRadius,entry.y-entry.screenRadius))}else{const entry=primitive.value;ctx.globalAlpha=dimmedEdges.has(entry.id)?paint.dimmedOpacity:1;const selected=selectedEdges.has(entry.id)||this.hover?.kind==="link"&&this.hover.id===entry.id;this.drawSegment(ctx,entry,selected?paint.selected:paint.edges.get(entry.id)??paint.text,selected,projectedById.get(entry.edge.target)?.screenRadius??0),entry.middle&&this.host.withEdgeLabels&&zoom>=finiteRange(this.host.edgeLabelMinZoom,.6,.001,1e3)&&entry.edge.label&&(ctx.fillStyle=paint.text,ctx.fillText(entry.edge.label,entry.a.x,entry.a.y-paint.fontSize))}ctx.restore()}}drawNode(ctx,node,fill){ctx.fillStyle=fill,ctx.beginPath();const r=node.screenRadius;if(node.shape==="circle")ctx.arc(node.x,node.y,r,0,Math.PI*2);else if(node.shape==="square"){const half=r*Math.sqrt(Math.PI)/2;ctx.rect(node.x-half,node.y-half,2*half,2*half)}else{const half=r*Math.sqrt(Math.PI/2);ctx.moveTo(node.x,node.y-half),ctx.lineTo(node.x+half,node.y),ctx.lineTo(node.x,node.y+half),ctx.lineTo(node.x-half,node.y),ctx.closePath()}ctx.fill()}drawSegment(ctx,segment,color,selected,targetRadius){const{a,b,edge}=segment;ctx.strokeStyle=color,ctx.fillStyle=color,ctx.lineWidth=finiteRange(edge.width??1.5,1.5,0,1e3)+(selected?2:0);const dash=edge.dash;if(ctx.setLineDash(segment.dangling?[4,4]:Array.isArray(dash)&&dash.length<=32&&dash.every(value=>Number.isFinite(value)&&value>=0)?[...dash]:[]),ctx.lineDashOffset=-segment.offset,ctx.beginPath(),ctx.moveTo(a.x,a.y),ctx.lineTo(b.x,b.y),ctx.stroke(),segment.last&&edge.directed){const angle=Math.atan2(b.y-a.y,b.x-a.x),inset=targetRadius,x=b.x-Math.cos(angle)*inset,y=b.y-Math.sin(angle)*inset,size=Math.max(6,ctx.lineWidth*3);ctx.beginPath(),ctx.moveTo(x,y),ctx.lineTo(x-Math.cos(angle-.45)*size,y-Math.sin(angle-.45)*size),ctx.lineTo(x-Math.cos(angle+.45)*size,y-Math.sin(angle+.45)*size),ctx.closePath(),ctx.fill()}}hit(clientX,clientY){const bounds=this.canvas?.getBoundingClientRect();if(!bounds)return;const scene=this.projectedScene();return pickSpatialScene(scene,clientX-bounds.left,clientY-bounds.top)}setHover(next){if(this.hover?.kind===next?.kind&&this.hover?.id===next?.id)return;const previous=this.hover;this.hover=next,this.canvas&&(this.canvas.title=next?.kind==="node"?this.options.nodeTooltip(next.node):next?.kind==="link"?this.options.edgeTooltip(next.edge):""),this.options.hover(previous,next),this.schedule()}cancelGesture(){const gesture=this.gesture;this.gesture=void 0,gesture&&this.canvas?.hasPointerCapture(gesture.id)&&this.canvas.releasePointerCapture(gesture.id)}changeView(view){this.cancelGesture(),view==="3d"&&(this.contextFailed=!1),this.host.view=view,this.host.requestUpdate(),this.focusAfterViewChange=!0,this.options.viewChanged()}changePage(delta){this.page=Math.max(0,Math.min(Math.ceil(this.items.length/PAGE_SIZE)-1,this.page+delta)),this.focusAfterViewChange=!0,this.host.requestUpdate()}listKeyDown(item,event){if(item.kind!=="node"||event.key!=="Enter"&&event.key!==" "||event.repeat)return;const time=this.host.ownerDocument.defaultView?.performance.now()??0;this.lastKeyActivation?.id===item.node.id&&time-this.lastKeyActivation.time<=500?(this.lastKeyActivation=void 0,this.options.expand(item.node.id)):this.lastKeyActivation={id:item.node.id,time}}activateItem(item,event){item.kind==="node"?this.options.activate({kind:"node",id:item.node.id,node:item.node},event):item.kind==="link"?this.options.activate({kind:"link",id:graphLinkIdentity(item.edge),edge:item.edge},event):this.options.community(item.community)}render(limitNotices){this.prepare();const messages=this.options.messages(),list=this.host.view==="list"||this.contextFailed,pageItems=this.items.slice(this.page*PAGE_SIZE,(this.page+1)*PAGE_SIZE),number=getNumberFormat(this.options.locale()),selectedNodes=new Set(this.host.selectedNodeIds),selectedEdges=new Set(this.host.selectedEdgeIds),button=(action,label,callback)=>html`<button type="button" part="spatial-control" data-spatial-action=${action} @click=${callback}>${label}</button>`;return html`<div part="base" class="spatial-base">
2
+ <div part="spatial-toolbar" role="group" aria-label=${messages.controls}>
3
+ <button type="button" part="spatial-control" data-spatial-action="3d" aria-pressed=${String(!list)} @click=${()=>this.changeView("3d")}>${messages.view3d}</button>
4
+ <button type="button" part="spatial-control" data-spatial-action="list" aria-pressed=${String(list)} @click=${()=>this.changeView("list")}>${messages.viewList}</button>
5
+ ${list?nothing:html`${button("fit",messages.fit,()=>this.fit())}${button("left",messages.left,()=>this.orbit(-ORBIT_STEP,0))}${button("right",messages.right,()=>this.orbit(ORBIT_STEP,0))}${button("up",messages.up,()=>this.orbit(0,ORBIT_STEP))}${button("down",messages.down,()=>this.orbit(0,-ORBIT_STEP))}${button("zoom-in",messages.zoomIn,()=>this.zoom(1.2))}${button("zoom-out",messages.zoomOut,()=>this.zoom(1/1.2))}`}
6
+ </div>
7
+ ${this.contextFailed?html`<p part="error">${messages.unavailable}</p>`:nothing}
8
+ ${list?html`<div part="spatial-list" tabindex="-1" @keydown=${event=>{event.key==="Escape"&&this.options.clearSelection()}}>
9
+ <ul aria-label=${messages.dataList}>
10
+ ${pageItems.map((item,index)=>{const id=item.kind==="node"?item.node.id:item.kind==="link"?graphLinkIdentity(item.edge):item.community.id,selected=item.kind==="node"?selectedNodes.has(id):item.kind==="link"?selectedEdges.has(id):!1,text=item.kind==="node"?this.options.nodeText(item.node):item.kind==="link"?this.options.edgeText(item.edge):this.options.communityText({label:item.community.label??id,count:number.format(this.communityCounts.get(id)??0)});return html`<li aria-posinset=${this.page*PAGE_SIZE+index+1} aria-setsize=${this.items.length}><button type="button" part="spatial-list-item" data-node-id=${item.kind==="node"?id:nothing}
11
+ aria-pressed=${item.kind!=="community"&&this.host.selectionMode!=="none"?String(selected):nothing}
12
+ aria-current=${item.kind!=="community"&&this.host.selectionMode==="none"&&selected?"true":nothing}
13
+ @keydown=${event=>this.listKeyDown(item,event)} @click=${event=>this.activateItem(item,event)} @dblclick=${()=>{item.kind==="node"&&this.options.expand(id)}}
14
+ >${text}</button></li>`})}
15
+ </ul>
16
+ ${this.items.length?nothing:html`<p part="empty">${messages.noData}</p>`}
17
+ <p part="spatial-page-count">${this.options.pageText({page:number.format(this.page+1),pages:number.format(Math.max(1,Math.ceil(this.items.length/PAGE_SIZE))),total:number.format(this.items.length)})}</p>
18
+ <div part="spatial-pagination">
19
+ <button type="button" part="spatial-control" data-spatial-action="previous" ?disabled=${this.page===0} @click=${()=>this.changePage(-1)}>${messages.previous}</button>
20
+ <button type="button" part="spatial-control" data-spatial-action="next" ?disabled=${(this.page+1)*PAGE_SIZE>=this.items.length} @click=${()=>this.changePage(1)}>${messages.next}</button>
21
+ </div>
22
+ </div>`:html`<p part="spatial-instructions" id=${this.instructionsId}>${messages.instructions}</p>
23
+ <canvas part="spatial-canvas" tabindex="0" role="img" aria-label=${this.host.accessibleLabel??this.host.label??messages.view3d}
24
+ aria-describedby=${this.instructionsId} @pointerdown=${this.pointerDown} @pointermove=${this.pointerMove} @pointerup=${this.pointerUp}
25
+ @pointercancel=${this.pointerCancel} @lostpointercapture=${this.pointerCancel} @pointerleave=${()=>{this.gesture||this.setHover(void 0)}}
26
+ @wheel=${this.wheel} @keydown=${this.keyDown} @dblclick=${event=>{const hit=this.hit(event.clientX,event.clientY);hit?.kind==="node"&&this.options.expand(hit.id)}}
27
+ ></canvas>
28
+ ${this.world.length?nothing:html`<p part="empty">${messages.noData}</p>`}`}
29
+ ${limitNotices}
30
+ </div>`}}export{GraphSpatialController};
@@ -0,0 +1 @@
1
+ import{finiteRange}from"../../../internal/numbers.js";import{getOwnDataDescriptor}from"../../../internal/data-descriptors.js";import{graphLinkIdentity}from"./graph-model.js";const WORLD_LIMIT=1e6,CAMERA_LIMIT=WORLD_LIMIT*10,EDGE_SEGMENTS=16,FIELD_OF_VIEW=Math.PI/4,NO_POSITION=Object.freeze({x:0,y:0,z:0});function own(value,key){if(value===null||typeof value!="object")return;const descriptor=getOwnDataDescriptor(value,key);return typeof descriptor=="object"?descriptor.value:void 0}function coordinate(value,fallback){return finiteRange(typeof value=="number"?value:NaN,fallback,-WORLD_LIMIT,WORLD_LIMIT)}function positionValue(value){const x=own(value,"x"),y=own(value,"y"),z=own(value,"z");if([x,y,z].every(entry=>typeof entry=="number"&&Number.isFinite(entry)))return Object.freeze({x:coordinate(x,0),y:coordinate(y,0),z:coordinate(z,0)})}function normalizeGraphCamera(value,fallback){const yaw=own(value,"yaw"),pitch=own(value,"pitch"),distance=own(value,"distance");return Object.freeze({yaw:finiteRange(typeof yaw=="number"?yaw:NaN,fallback.yaw,-CAMERA_LIMIT,CAMERA_LIMIT)%(Math.PI*2),pitch:finiteRange(typeof pitch=="number"?pitch:NaN,fallback.pitch,-Math.PI/2+.01,Math.PI/2-.01),distance:finiteRange(typeof distance=="number"?distance:NaN,fallback.distance,.01,CAMERA_LIMIT),target:positionValue(own(value,"target"))??Object.freeze({...fallback.target})})}function spatialNodePosition(node){const explicit=positionValue(own(node,"position"));if(explicit)return explicit;let hash=2166136261;for(const character of node.id)hash=Math.imul(hash^character.charCodeAt(0),16777619);const latitude=(hash>>>0)/4294967296*2-1,angle=(Math.imul(hash,2246822519)>>>0)/4294967296*Math.PI*2,radius=120+(hash>>>8)%81,ring=Math.sqrt(Math.max(0,1-latitude*latitude));return Object.freeze({x:radius*ring*Math.cos(angle),y:radius*latitude,z:radius*ring*Math.sin(angle)})}function cameraPoint(point,camera){const dx=point.x-camera.target.x,dy=point.y-camera.target.y,dz=point.z-camera.target.z,x=Math.cos(camera.yaw)*dx-Math.sin(camera.yaw)*dz,z=Math.sin(camera.yaw)*dx+Math.cos(camera.yaw)*dz;return{x,y:Math.cos(camera.pitch)*dy-Math.sin(camera.pitch)*z,z:camera.distance-(Math.sin(camera.pitch)*dy+Math.cos(camera.pitch)*z)}}function perspective(point,viewport){const scale=viewport.height/(2*Math.tan(FIELD_OF_VIEW/2)*point.z);return{x:viewport.width/2+point.x*scale,y:viewport.height/2+point.y*scale,depth:point.z,scale}}function nearPlane(camera){return Math.max(.01,camera.distance*1e-4)}function projectSpatialPoint(point,camera,viewport){const transformed=cameraPoint(point,camera);return transformed.z<nearPlane(camera)?void 0:perspective(transformed,viewport)}function fittedGraphCamera(nodes,viewport,padding=24){if(!nodes.length)return normalizeGraphCamera(void 0,{yaw:0,pitch:0,distance:500,target:NO_POSITION});let minX=1/0,minY=1/0,minZ=1/0,maxX=-1/0,maxY=-1/0,maxZ=-1/0;for(const{position:p,radius:radius2}of nodes)minX=Math.min(minX,p.x-radius2),maxX=Math.max(maxX,p.x+radius2),minY=Math.min(minY,p.y-radius2),maxY=Math.max(maxY,p.y+radius2),minZ=Math.min(minZ,p.z-radius2),maxZ=Math.max(maxZ,p.z+radius2);const target={x:(minX+maxX)/2,y:(minY+maxY)/2,z:(minZ+maxZ)/2},radius=Math.max(1,Math.hypot(maxX-minX,maxY-minY,maxZ-minZ)/2),safePadding=finiteRange(padding,24,0,Math.min(viewport.width,viewport.height)*.45),aspect=Math.min((viewport.width-2*safePadding)/viewport.height,(viewport.height-2*safePadding)/viewport.height),angle=Math.atan(Math.tan(FIELD_OF_VIEW/2)*Math.max(.01,aspect));return normalizeGraphCamera({yaw:0,pitch:0,distance:radius/Math.sin(angle),target},{yaw:0,pitch:0,distance:500,target:NO_POSITION})}function interpolate(a,b,t){return{x:a.x+(b.x-a.x)*t,y:a.y+(b.y-a.y)*t,z:a.z+(b.z-a.z)*t}}function projectSpatialScene(nodes,edges,camera,viewport){const byId=new Map(nodes.map(node=>[node.node.id,node])),projected=[],segments=[],primitives=[];for(const node of nodes){const point=projectSpatialPoint(node.position,camera,viewport);if(!point)continue;const entry={...node,...point,screenRadius:Math.min(Math.max(viewport.width,viewport.height)*2,node.radius*point.scale)};projected.push(entry),primitives.push({kind:"node",value:entry,depth:entry.depth})}for(const edge of edges){if(finiteRange(edge.width??1.5,1.5,0)===0)continue;const source=byId.get(edge.source);if(!source)continue;const target=byId.get(edge.target),self=edge.source===edge.target,end=target?.position??{x:source.position.x+28,y:source.position.y-28,z:source.position.z};let offset=0;for(let index=0;index<EDGE_SEGMENTS;index++){const at=t=>self?{x:source.position.x+Math.sin(t*Math.PI*2)*source.radius*1.6,y:source.position.y-(1-Math.cos(t*Math.PI*2))*source.radius*1.6,z:source.position.z}:interpolate(source.position,end,t);let a=cameraPoint(at(index/EDGE_SEGMENTS),camera),b=cameraPoint(at((index+1)/EDGE_SEGMENTS),camera);const near=nearPlane(camera);if(a.z<near&&b.z<near)continue;a.z<near&&(a=interpolate(a,b,(near-a.z)/(b.z-a.z))),b.z<near&&(b=interpolate(b,a,(near-b.z)/(a.z-b.z)));const entry={edge,id:graphLinkIdentity(edge),a:perspective(a,viewport),b:perspective(b,viewport),depth:(a.z+b.z)/2,last:index===EDGE_SEGMENTS-1,middle:index===EDGE_SEGMENTS/2,dangling:!target,offset};offset+=Math.hypot(entry.b.x-entry.a.x,entry.b.y-entry.a.y),segments.push(entry),primitives.push({kind:"link",value:entry,depth:entry.depth})}}return primitives.sort((a,b)=>b.depth-a.depth||(a.kind===b.kind?0:a.kind==="link"?-1:1)),{nodes:projected,segments,primitives}}function pickSpatialScene(scene,x,y){let result,nearest=1/0;for(const node of scene.nodes){const dx=Math.abs(x-node.x),dy=Math.abs(y-node.y),r=Math.max(12,node.screenRadius);(node.shape==="square"?Math.max(dx,dy)<=Math.max(12,node.screenRadius*Math.sqrt(Math.PI)/2):node.shape==="diamond"?dx+dy<=r*Math.sqrt(Math.PI/2):Math.hypot(dx,dy)<=r)&&node.depth<=nearest&&(nearest=node.depth,result={kind:"node",id:node.node.id,node:node.node})}for(const segment of scene.segments){if(segment.dangling)continue;const dx=segment.b.x-segment.a.x,dy=segment.b.y-segment.a.y,t=Math.min(1,Math.max(0,((x-segment.a.x)*dx+(y-segment.a.y)*dy)/(dx*dx+dy*dy||1))),depth=1/((1-t)/segment.a.depth+t/segment.b.depth),width=finiteRange(segment.edge.width??1.5,1.5,0,1e3);Math.hypot(x-segment.a.x-dx*t,y-segment.a.y-dy*t)<=Math.max(6,width/2)&&(depth<nearest-.001||result?.kind==="link"&&depth===nearest)&&(nearest=depth,result={kind:"link",id:segment.id,edge:segment.edge})}return result}function panGraphCamera(camera,dx,dy,viewport){const units=2*camera.distance*Math.tan(FIELD_OF_VIEW/2)/viewport.height,sy=Math.sin(camera.yaw),cy=Math.cos(camera.yaw),sp=Math.sin(camera.pitch),cp=Math.cos(camera.pitch);return normalizeGraphCamera({...camera,target:{x:camera.target.x-units*(cy*dx+sy*sp*dy),y:camera.target.y-units*cp*dy,z:camera.target.z-units*(-sy*dx+cy*sp*dy)}},camera)}export{fittedGraphCamera,normalizeGraphCamera,panGraphCamera,pickSpatialScene,projectSpatialPoint,projectSpatialScene,spatialNodePosition};