{"version":3,"file":"autk-map.umd.cjs","names":["degrees","degrees","cubehelix","formatDecimal","formatRounded","formatPrefixAuto","identity","formatGroup","formatNumerals","formatTypes","formatTrim","exponent","formatLocale","exponent","exponent","exponent","constant","rgb","colorRgb","basis","basisClosed","value","value","number","constant","number","rgb","string","date","numberArray","object","identity","identity","decompose","number","colorCubehelix","color","value","identity","precisionPrefix","precisionRound","precisionFixed","transformer","identity","interpolate","interpolateRound","identity","interpolate","interpolateRound","colors","colors","colors","colors","colors","colors","colors","colors","colors","colors","colors","interpolateRgbBasis","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","scheme","colors","ramp","colors","ramp","interpolateCubehelixLong","cubehelix","interpolateCubehelixLong","cubehelix","c","colors","d3_color.rgb","rgb","d3_scheme","d3_format.format","d3_scale.scaleDiverging","d3_scale.scaleSequential","create","glMatrix.ARRAY_TYPE","identity","create","glMatrix.ARRAY_TYPE","vec3.create","mat4.create","vec3.fromValues","mat4.mul","vec3.length","scale","vec3.cross","vec3.add","vec3.scale","mat4.lookAt","mat4.perspectiveZO","rasterVertexSource","rasterFragmentSource","trianglesVertexSource","trianglesFragmentSource","picking3dTerrainVertexSource","pickingVertexSource","pickingFragmentSource","buildingsVS01","buildingsFS01","buildingsVS02","buildingsFS02","buildingsTerrainFS02","linesVertexSource","linesFragmentSource","spriteVertexSource","spriteFragmentSource","pickingVertexSource","pickingFragmentSource","expansionSource","pickingVertexSource","vertexSource","pickingFragmentSource","fragmentSource","parseTypenames","get","set","namespaces","namespace","selector","Selection","selectorAll","Selection","matcher","Selection","Selection","sparse","constant","Selection","Selection","sparse","Selection","Selection","attrRemove","attrRemoveNS","attrConstant","attrConstantNS","attrFunction","attrFunctionNS","namespace","styleRemove","styleConstant","styleFunction","defaultView","textConstant","textFunction","creator","creator","selector","defaultView","Selection","selection_select","selection_selectAll","selection_selectChild","selection_selectChildren","selection_filter","selection_data","selection_enter","selection_exit","selection_join","selection_merge","selection_order","selection_sort","selection_call","selection_nodes","selection_node","selection_size","selection_empty","selection_each","selection_attr","selection_style","selection_property","selection_classed","selection_text","selection_html","selection_raise","selection_lower","selection_append","selection_insert","selection_remove","selection_clone","selection_datum","selection_on","selection_dispatch","selection_iterator","Selection","timeout","interpolateNumber","interpolateRgb","interpolateString","namespace","interpolateTransform","interpolate","namespace","matcher","selector","selectorAll","style","interpolateTransform","interpolate","transition_select","transition_selectAll","transition_filter","transition_merge","transition_selection","transition_transition","transition_on","transition_attr","transition_attrTween","transition_style","transition_styleTween","transition_text","transition_textTween","transition_remove","transition_tween","transition_delay","transition_duration","transition_ease","transition_easeVarying","transition_end","easeCubicInOut","selection_interrupt","selection_transition","d3.select","background","surface","parks","water","roads","buildings","points","polylines","polygons","background","surface","parks","water","roads","buildings","points","polylines","polygons","background","surface","parks","water","roads","buildings","points","polylines","polygons","background","surface","parks","water","roads","buildings","points","polylines","polygons","background","surface","parks","water","roads","buildings","points","polylines","polygons","defaultStyle","light","google","apple","osm","poster","terrainVertexSource","terrainFragmentSource","terrainPickingFragmentSource","terrainBoundsReduceSource","vectorLayer","factory","global","exports","__defProp","__exportAll","target","name","all","no_symbols","DEFAULT_POINT_SIZE","DEFAULT_LINE_WIDTH","ColorMapDomainStrategy","\"USER\"","\"MIN_MAX\"","\"PERCENTILE\"","ColorMapInterpolator","\"CAT_ACCENT\"","\"CAT_DARK2\"","\"CAT_CATEGORY10\"","\"CAT_OBSERVABLE10\"","\"CAT_PAIRED\"","\"CAT_PASTEL1\"","\"CAT_PASTEL2\"","\"CAT_SET1\"","\"CAT_SET2\"","\"CAT_SET3\"","\"CAT_TABLEAU10\"","\"SEQ_REDS\"","\"SEQ_BLUES\"","\"SEQ_GREENS\"","\"SEQ_GREYS\"","\"SEQ_ORANGES\"","\"SEQ_PURPLES\"","\"SEQ_TURBO\"","\"SEQ_VIRIDIS\"","\"SEQ_INFERNO\"","\"SEQ_MAGMA\"","\"SEQ_PLASMA\"","\"SEQ_CIVIDIS\"","\"SEQ_WARM\"","\"SEQ_COOL\"","\"SEQ_CUBEHELIX_DEFAULT\"","\"SEQ_BU_GN\"","\"SEQ_BU_PU\"","\"SEQ_GN_BU\"","\"SEQ_OR_RD\"","\"SEQ_PU_BU_GN\"","\"SEQ_PU_BU\"","\"SEQ_PU_RD\"","\"SEQ_RD_PU\"","\"SEQ_YL_GN_BU\"","\"SEQ_YL_GN\"","\"SEQ_YL_OR_BR\"","\"SEQ_YL_OR_RD\"","\"DIV_BR_BG\"","\"DIV_PR_GN\"","\"DIV_PI_YG\"","\"DIV_PU_OR\"","\"DIV_RED_BLUE\"","\"DIV_RED_GREY\"","\"DIV_RED_YELLOW_BLUE\"","\"DIV_RED_YELLOW_GREEN\"","\"DIV_SPECTRAL\"","define_default","prototype","constructor","extend","parent","key","definition","Color","darker","brighter","reI","reN","reP","reHex","reRgbInteger","reRgbPercent","reRgbaInteger","reRgbaPercent","reHslPercent","reHslaPercent","named","color","channels","color_formatHex","color_formatHex8","color_formatHsl","color_formatRgb","hslConvert","m","l","format","rgbn","Rgb","rgba","hsla","n","a","r","g","b","rgbConvert","o","rgb","opacity","k","clampi","clampa","rgb_formatHex","rgb_formatHex8","rgb_formatRgb","hex","value","s","Hsl","h","min","max","hsl","m2","m1","hsl2rgb","clamph","clampt","radians","degrees$1","A","B","C","D","E","ED","EB","BC_DA","cubehelixConvert","Cubehelix","bl","cubehelix$1","cosh","sinh","formatDecimal_default","x","formatDecimalParts","i","p","coefficient","exponent_default","formatGroup_default","t","j","grouping","length","width","thousands","formatNumerals_default","numerals","re","formatSpecifier","specifier","match","FormatSpecifier","formatTrim_default","i0","i1","prefixExponent","formatPrefixAuto_default","d","exponent","formatRounded_default","formatTypes_default","\"b\"","\"c\"","\"d\"","\"e\"","\"f\"","\"g\"","\"o\"","\"p\"","\"r\"","\"s\"","\"X\"","\"x\"","identity_default","map","prefixes","locale_default","group","locale","currencyPrefix","currencySuffix","decimal","percent","minus","nan","newFormat","fill","align","sign","symbol","zero","comma","precision","trim","type","prefix","options","suffix","formatType","maybeSuffix","valuePrefix","valueSuffix","c","valueNegative","padding","formatPrefix","e","f","defaultLocale","precisionFixed_default","step","precisionPrefix_default","precisionRound_default","e10","e5","e2","tickSpec","stop","start","count","power","error","factor","i2","inc","ticks","reverse","tickIncrement","tickStep","initInterpolator","domain","interpolator","basis","t2","t1","t3","v0","v1","v2","v3","basis_default","values","constant_default$1","linear","exponential","y","hue","gamma","nogamma","rgb_default","rgbGamma","rgb$2","end","rgbSpline","colors","spline","rgbBasis","numberArray_default","isNumberArray","genericArray","nb","na","value_default","date_default","number_default","object_default","reA","reB","one","string_default","bi","am","bm","bs","q","round_default","degrees","identity$3","decompose_default","scaleX","scaleY","skewX","svgNode","parseCss","parseSvg","interpolateTransform","pop","translate","xa","xb","ya","yb","pxComma","pxParen","rotate","degParen","scale","parse","interpolateTransformCss","interpolateTransformSvg","cubehelix","cubehelixGamma","cubehelixLong","piecewise","interpolate","v","I","identity$2","tickFormat","linearish","prestep","maxIter","transformer$1","x0","x1","t0","k10","transform","clamp","unknown","_","range","r0","r1","copy","source","sequential","transformer","x2","k21","r2","diverging","colors_default","category10_default","Accent_default","Dark2_default","observable10_default","Paired_default","Pastel1_default","Pastel2_default","Set1_default","Set2_default","Set3_default","Tableau10_default","ramp_default","scheme","scheme$26","BrBG_default","scheme$25","PRGn_default","scheme$24","PiYG_default","scheme$23","PuOr_default","scheme$22","RdBu_default","scheme$21","RdGy_default","scheme$20","RdYlBu_default","scheme$19","RdYlGn_default","scheme$18","Spectral_default","scheme$17","BuGn_default","scheme$16","BuPu_default","scheme$15","GnBu_default","scheme$14","OrRd_default","scheme$13","PuBuGn_default","scheme$12","PuBu_default","scheme$11","PuRd_default","scheme$10","RdPu_default","scheme$9","YlGnBu_default","scheme$8","YlGn_default","scheme$7","YlOrBr_default","scheme$6","YlOrRd_default","scheme$5","Blues_default","scheme$4","Greens_default","scheme$3","Greys_default","scheme$2","Purples_default","scheme$1","Reds_default","Oranges_default","cividis_default","cubehelix_default","warm","cool","c$1","rainbow_default","ts","pi_1_3","pi_2_3","sinebow_default","turbo_default","ramp","viridis_default","magma","inferno","plasma","src_exports","CATEGORICAL_INTERPOLATORS","DIVERGING_INTERPOLATORS","ColorMap","res","tex","id","result","rgb$1","mode","config","params","numeric","center","finiteValues","lowerPercentile","upperPercentile","low","high","maxAbs","acc","formatter","idx","sorted","lo","hi","DEFAULT_TRANSFER_FUNCTION","buildTransferContext","resolvedConfig","computeAlphaByte","context","maxAbsDistance","shaped","TriangulatorPoints","instances","components","collection","geojson","fId","feature","before","origin","coordinates","instanceCount","geom","geometries","featureIndex","geometryType","PolylineBuilder","geometry","attributes","paths","nPoints","nTriangles","path","points","invalid","coordinate","last","closed","position","indices","current","previous","next","vertex","base","child","offsetPolyline","clean","index","prev","point","distance","left","right","curr","prevNormal","getUnitLeftNormal","nextNormal","leftPoint","computeOffsetPoint","rightPoint","polygon","normalizeRing","ring","normalized","first","computeRingArea","area","y1","y2","polygonPerimeter","perimeter","dx","dy","isConvex","e1x","e1y","e2x","turn","currentSign","side","intersection","intersectLines","avgX","avgY","avgLength","a1","a2","x3","b1","y3","x4","b2","y4","denom","detA","detB","steiners","filteredOut","earcut","hasHoles","holeIndices","outerLen","dim","data","outerNode","linkedList","triangles","minX","minY","invSize","eliminateHoles","maxX","maxY","earcutLinked","clockwise","signedArea","insertNode","equals","removeNode","filterPoints","full","again","indexCurve","ear","cured","isEarHashed","isEar","cureLocalIntersections","splitEarcut","ax","bx","cx","ay","by","cy","y0","pointInTriangle","minZ","zOrder","maxZ","intersects","locallyInside","isValidDiagonal","splitPolygon","indexActive","queue","len","list","getLeftmost","compareXYSlope","buildBlockIndex","indexSegment","eliminateHole","bridge","findHoleBridge","hole","bridgeReverse","bridge2","K","blockBBox","numBlocks","blockHead","blockStop","maxBlocks","maxNodes","numHoles","head","growBlock","tail","liveBlockStop","liveBlockHead","hx","hy","qx","mx","my","tminY","tmaxY","tanMin","tan","sectorContainsSector","sortArr","sortBuf","zArr","zBuf","counts","sortNodes","node","z","radixPass","srcZ","shift","sum","pos","src","leftmost","px","py","zeroLength","intersectsPolygon","middleInside","p1","p2","o1","q1","o2","q2","o3","o4","includeBoundary","onSegment","inside","createNode","an","bp","TriangulatorPolylines","mesh","comps","\"features\"","meshes","resolvedOffset","resolveOffset","offset","triangulation","coord","flatIds","ls","flatCoords","syntheticFeature","highway","TriangulatorPolygons","border","borders","nLines","polyline","cord","lineString","coords","holes","ids","nCoords","pointCount","uniquePointCount","DEFAULT_ROOF_ANGLE","MERGE_EPS","heightFromAngle","perim","angleDeg","buildWalls","ri","rings","open","minH","maxH","flatRoof","outer","allVerts","holeStarts","triIds","height","flatFloor","pyramidRoof","baseH","roofH","domeRoof","rings3D","alpha","cosA","sinA","currentRing","vx","vy","vz","bottomRing","topRing","apex","subdivideMesh","nextCoords","nextIds","edgeCache","getMidpoint","m01","m12","m20","roundRoof","maxLen","ex","ey","tx","ty","projs","minT","maxT","centerT","radiusT","norm","edgeCounts","outCoords","outIds","minV","maxV","z1","z2","skillionRoof","rad","directionDeg","minP","maxP","elevs","eI","eJ","inwardNormals","pts","bisectorVelocities","sv","n1","norms","n2","s1","speeds","s2","vert","cross","collapseTime","dPx","pj","pi","dPy","dVx","vi","vj","dVy","dot","dvl2","deduplicateVertsInitial","verts","eps","classifyGables","edges","mainDx","mainDy","getEdgeSpeeds","defaultSpeeds","info","isGable","eaveCount","buildStraightSkeleton","bboxMinX","bboxMaxX","bboxMinY","bboxMaxY","bboxPad","faces","iter","vels","tMin","capped","maxHCap","newPos","newH","localMax","oldI","oldJ","newI","newJ","mh","nextSv","skeletonToMesh","maxSkH","face","skeletonRoof","extractRoofInfo","props","rawAngle","buildBuildingPartMesh","maxRoofH","roof","normalizeBuildingFeature","part","metadata","indexed","seen","parts","getBuildingParts","buildingProps","byIndex","geometryIndex","properties","keys","TriangulatorBuildings","skippedNoHeight","partGeom","partProps","heightInfo","hasHeightTag","allowZeroHeightBuildings","partFeature","chunks","chunk","FLOOR_HEIGHT","num","\"height\"","\"levels\"","min_height","\"min_height\"","\"min_level\"","TriangulatorRaster","bbox","geotiff","p0","p3","texCoords","valueAtPath","item","resolved","record","isNumericLike","trimmed","heightfieldFromRaster","rasterValues","property","isArrayLike","minHeight","maxHeight","nonFinite","bounds","ARRAY_TYPE","create$2","out","identity$1","multiply","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b0","b3","perspectiveZO","fovy","aspect","far","nf","near","orthoZO","lr","bt","bottom","top","lookAt","z0","eyex","eye","eyey","eyez","upx","up","upy","upz","centerx","centery","centerz","mul","create$1","fromValues","add","subtract","scaleAndAdd","normalize","az","bz","rotateZ","sub","vec","stride","fn","arg","Camera","wLookAt","wEye","wUp","direction","zoomScale","delta","dir","scale$1","X","view","proj","wRight","upOffset","rightOffset","EventEmitter","event","listener","arr","payload","LAYER_TYPE_VALUES","OSM_BASE_LAYER_ORDER","computeOrigin","computeBoundingBox","minLon","minLat","maxLon","maxLat","expand","expandGeometry","line","poly","mapGeometryTypeToLayerType","KeyEvents","canvas","styles","MapEvent","\"PICKING\"","MouseStatus","\"IDLE\"","\"DRAG\"","MouseEvents","canvasStyle","cssWidth","cssHeight","wasTouchPointer","rect","mouseX","mouseY","activePickingLayer","gesture","distanceDelta","centerDx","centerDy","ResizeEvents","devicePixelRatio","Renderer","_style","entry","adapter","device","canvasConfig","desc","pickingTextureView","depthDesc","pickingDepthTextureView","colorTextureView","multiSampleDesc","multiSampleTextureView","sky","depthTextureDesc","depthTextureView","currentTextureView","renderPassDesc","loadOp","depthLoadOp","pickCount","bufferSize","slot","slotIndex","pickIndex","arrayBuffer","Layer","layerInfo","layerRenderInfo","canPick","nextInfo","raster_vert_default","raster_frag_default","COLORMAP_HEIGHT","Pipeline","renderer","camera","cMapSampler","layer","computedDomain","isNumericDomain","isCategoricalDomain","categoryCount","colorMapTexture","cache","PipelineTriangleRaster","vsmDesc","fsmDesc","raster","rasterSampler","positionAttribDesc","texCoordAttribDesc","positionBufferDesc","texCoordBufferDesc","fragment","primitive","multisample","depthStencil","pipelineLayoutDesc","pipelineDesc","passEncoder","indexCount","RasterLayer","layerData","totalVerts","totalIndices","totalTexCoords","layerGeometry","texCoord","vOffset","iOffset","tOffset","vertexCount","accum","cId","layerComponents","comp","isRGBA","rasterData","validValues","colorDomain","numericDomain","transferValues","transferContext","effectiveDomain","rasterPipeline","triangle_01_vert_default","triangle_01_frag_default","PipelineTriangleFlat","thematicAttribDesc","highlightedAttribDesc","thematicValidityAttribDesc","skippedAttribDesc","thematicBufferDesc","highlightedBufferDesc","thematicValidityBufferDesc","skippedBufferDesc","picking_vert_default","picking_frag_default","picking_3d_terrain_vert_default","PipelineTrianglePicking","dimension","heightTextureView","numVertices","compId","sTri","eTri","shifted","idAttribDesc","idBufferDesc","ownsPass","VectorLayer","vertsAdded","layerThematic","thematic","thematicValidity","aggr","vertexIndex","sPoint","component","nPoint","visited","sTriangle","eTriangle","buildings_01_vert_default","buildings_01_frag_default","buildings_02_vert_default","buildings_02_frag_default","buildings_02_terrain_frag_default","PipelineBuildingSSAO","shared","bindGroup","terrainDepthTextureView","layout","existing","colorsSharedTexture","normalsSharedTexture","depthTexturePass01","colorsSharedBuffer","normalsSharedBuffer","depthBufferPass01","texSampler","texturesPass02BindGroupLayout","terrainCompositeBindGroupLayout","texturesPass02BindGroup","vertModule02","fragModule02","terrainFragModule02","state","Triangles3DLayer","triIdx","e1z","e2y","e2z","nx","ny","nz","mag","triangle_02_vert_default","triangle_02_frag_default","DEFAULT_BORDER_COLOR","PipelineTriangleBorder","Triangles2DLayer","borderComponents","dataDirty","renderInfoDirty","sprite_vert_default","sprite_frag_default","PipelineSprite","size","quadBufferDesc","instanceBufferDesc","sprite_picking_vert_default","sprite_picking_frag_default","PipelineSpritePicking","instanceId","idsBufferDesc","SpriteLayer","polyline_expansion_default","polyline_vert_default","polyline_picking_vert_default","polyline_picking_frag_default","PipelinePolyline","picking","stateAttributes","widths","fallback","PolylineLayer","LayerManager","layerRender","layerId","candidate","osmIdx","layerType","typeLayer","noop","dispatch","Dispatch","parseTypenames$1","typenames","types","T","typename","get$1","callback","set$1","args","that","namespaces_default","namespace_default","creatorInherit","document","uri","creatorFixed","fullname","creator_default","none","selector_default","selector","select_default$2","select","groups","subgroups","subgroup","subnode","Selection$1","array","empty","selectorAll_default","arrayAll","selectAll_default$1","parents","matcher_default","childMatcher","find","childFind","childFirst","selectChild_default","filter","children","childrenFilter","selectChildren_default","filter_default$1","sparse_default","update","enter_default","EnterNode","datum","constant_default","bindIndex","groupLength","dataLength","bindKey","nodeByKeyValue","keyValues","keyValue","data_default","bind","enter","exit","arraylike","enterGroup","updateGroup","exit_default","join_default","onenter","onupdate","onexit","merge_default$1","selection","groups0","groups1","m0","merges","group0","group1","merge","order_default","sort_default","compare","ascending","compareNode","sortgroups","sortgroup","call_default","nodes_default","node_default","size_default","empty_default","each_default","attrRemove$1","attrRemoveNS$1","attrConstant$1","attrConstantNS$1","attrFunction$1","attrFunctionNS$1","attr_default$1","window_default","styleRemove$1","styleConstant$1","priority","styleFunction$1","style_default$1","styleValue","propertyRemove","propertyConstant","propertyFunction","property_default","classArray","string","classList","ClassList","classedAdd","names","classedRemove","classedTrue","classedFalse","classedFunction","classed_default","textRemove","textConstant$1","textFunction$1","text_default$1","htmlRemove","htmlConstant","htmlFunction","html_default","raise","raise_default","lower","lower_default","append_default","create","constantNull","insert_default","remove","remove_default$1","selection_cloneShallow","clone","selection_cloneDeep","clone_default","deep","datum_default","contextListener","parseTypenames","onRemove","on","onAdd","on_default$1","dispatchEvent","window","dispatchConstant","dispatchFunction","dispatch_default","iterator_default","root","selection_selection","select_default$1","frame","timeout","interval","pokeDelay","taskHead","taskTail","clockLast","clockNow","clockSkew","clock","setFrame","now","clearNow","Timer","time","delay","sleep","timer","timerFlush","wake","nap","poke","timeout_default","elapsed","emptyOn","emptyTween","schedule_default","schedules","timing","init","schedule","get","set","tween","self","tick","interrupt_default$1","active","interrupt_default","tweenRemove","tween0","tween1","tweenFunction","tween_default","tweenValue","transition","interpolate_default","attrRemove","attrRemoveNS","attrConstant","string00","string1","value1","interpolate0","string0","attrConstantNS","attrFunction","string10","attrFunctionNS","attr_default","attrInterpolate","attrInterpolateNS","attrTweenNS","attrTween","attrTween_default","delayFunction","delayConstant","delay_default","durationFunction","durationConstant","duration_default","easeConstant","ease_default","easeVarying","easeVarying_default","filter_default","Transition","merge_default","onFunction","on0","on1","sit","on_default","removeFunction","remove_default","select_default","selectAll_default","inherit","Selection","selection_default","styleNull","styleRemove","styleConstant","styleFunction","styleMaybeRemove","listener0","style_default","styleInterpolate","styleTween","styleTween_default","textConstant","textFunction","text_default","textInterpolate","textTween","textTween_default","transition_default$1","id0","id1","newId","end_default","cancel","reject","resolve","selection_prototype","cubicInOut","defaultTiming","transition_default","Transform","location","identity","EYE_SVG","RAMP_SVG","CURSOR_SVG","AutkMapUi","fps","frameTimeMs","resolvedLayer","isColorMap","opening","section","title","innerWidth","innerHeight","labels","categoricalSize","isCategorical","slc","colorMap","svg","rectWidth","rectH","textData","row","eyeBtn","paletteBtn","cursorBtn","nameEl","btn","onClick","text","currentLayer","default_default","light_default","google_default","apple_default","osm_default","poster_default","PRESET_IDS","MAP_STYLE_KEYS","HEX_COLOR_RE","MapStyle","presetId","style","MapCamera","onChange","FlatMapRenderPath","layerManager","pendingPick","visible3DLayers","geometryPassEncoder","mainPassEncoder","pickReadbackSlot","MapPickingController","mapEvents","pickableLayer","terrain_frag_default","terrain_picking_frag_default","terrain_vert_default","terrain_bounds_reduce_comp_default","PATCH_CELLS","PATCH_VERTICES","MAX_LOD_LEVEL","MAX_INSTANCES","TARGET_CELL_PIXELS","TERRAIN_LOD_REFERENCE_HEIGHT","BOUNDS_PREPASS_SIZE","REDUCE_WORKGROUP_SIZE","BOUNDS_PIXEL_COUNT","BOUNDS_PASS_1_COUNT","BOUNDS_PASS_2_COUNT","BOUNDS_PASS_3_COUNT","TerrainRenderer","_heightfield","createPatchMesh","createReduceParamsBuffer","createStorageBuffer","overlaySampler","bindGroupLayout","overlayTextureView","overlayPickingTextureView","vertexShaderModule","fragmentShaderModule","pickingFragmentShaderModule","reduceShaderModule","vertexBuffers","colorFormat","depthFormat","sampleCount","reduceTextureBindGroupLayout","reduceBufferBindGroupLayout","emptyBindGroupLayout","uniform","overlayBounds","overlayUvRect","waterColor","block","pass","showMesh","renderPass","encoder","computePass","skipped","changed","requestRender","cameraPosition","markerSize","vertices","planes","extractFrustumPlanes","projectionScale","rootSize","nextPowerOfTwo","stack","createBlock","blocks","rangesOverlap","enableCulling","blockIntersectsFrustum","shouldSplitBlock","childSize","childLevel","gridIndex","i3","lineIndices","createLineIndices","vertexData","indexData","lineIndexData","vertexBuffer","indexBuffer","lineIndexBuffer","distanceToBlock3d","baseCellSize","plane","pz","normalizePlane","matrix","minA","maxB","minB","maxA","vec4Count","total","buffer","TERRAIN_OVERLAY_TEXTURE_SIZE","TerrainMapRenderPath","heightfield","overlaySize","activeTerrain","fallbackBounds","reducedBounds","overlayPixelRect","overlayPass","terrainPass","terrainDepthPass","terrainHeightView","buildingCompositePass","centerX","centerY","halfFovTangent","distanceForHeight","distanceForWidth","buildingPickingPass","overlayPickingPass","terrainPickingPass","terrainDiagonal","terrainBounds","maxRayDistance","groundDistance","rawMinX","rawMaxX","textureWidth","textureHeight","boundsAspect","textureAspect","terrainOverlap","fallbackOverlap","showUi","sType","loadConfig","features","propertyResolver","sample","dataType","resolvedDomain","thematicByFeatureIndex","thematicByFeatureId","storeThematicValue","featureId","rawValues","rawValue","categoricalDomain","categoryIndex","thematicData","rasterLayer","transferFunction","currentConfig","mergedColorMap","nextColormap","thematicValues","existingDomain","needsLegend","needsLayerList","removed","settings","previousDelta","currentDelta","families","visitGeometry","family","otherLayer","activeLayerId","layerName","layerMesh","layerBorder","lines","pointInstances","buildingsZeroHeight"],"sources":["../src/types-layers.ts","../../autk-core/src/types-colormap.ts","../../node_modules/d3-color/src/define.js","../../node_modules/d3-color/src/color.js","../../node_modules/d3-color/src/math.js","../../node_modules/d3-color/src/cubehelix.js","../../node_modules/d3-format/src/formatDecimal.js","../../node_modules/d3-format/src/exponent.js","../../node_modules/d3-format/src/formatGroup.js","../../node_modules/d3-format/src/formatNumerals.js","../../node_modules/d3-format/src/formatSpecifier.js","../../node_modules/d3-format/src/formatTrim.js","../../node_modules/d3-format/src/formatPrefixAuto.js","../../node_modules/d3-format/src/formatRounded.js","../../node_modules/d3-format/src/formatTypes.js","../../node_modules/d3-format/src/identity.js","../../node_modules/d3-format/src/locale.js","../../node_modules/d3-format/src/defaultLocale.js","../../node_modules/d3-format/src/precisionFixed.js","../../node_modules/d3-format/src/precisionPrefix.js","../../node_modules/d3-format/src/precisionRound.js","../../node_modules/d3-array/src/ticks.js","../../node_modules/d3-scale/src/init.js","../../node_modules/d3-interpolate/src/basis.js","../../node_modules/d3-interpolate/src/basisClosed.js","../../node_modules/d3-interpolate/src/constant.js","../../node_modules/d3-interpolate/src/color.js","../../node_modules/d3-interpolate/src/rgb.js","../../node_modules/d3-interpolate/src/numberArray.js","../../node_modules/d3-interpolate/src/array.js","../../node_modules/d3-interpolate/src/date.js","../../node_modules/d3-interpolate/src/number.js","../../node_modules/d3-interpolate/src/object.js","../../node_modules/d3-interpolate/src/string.js","../../node_modules/d3-interpolate/src/value.js","../../node_modules/d3-interpolate/src/round.js","../../node_modules/d3-interpolate/src/transform/decompose.js","../../node_modules/d3-interpolate/src/transform/parse.js","../../node_modules/d3-interpolate/src/transform/index.js","../../node_modules/d3-interpolate/src/cubehelix.js","../../node_modules/d3-interpolate/src/piecewise.js","../../node_modules/d3-scale/src/continuous.js","../../node_modules/d3-scale/src/tickFormat.js","../../node_modules/d3-scale/src/linear.js","../../node_modules/d3-scale/src/sequential.js","../../node_modules/d3-scale/src/diverging.js","../../node_modules/d3-scale-chromatic/src/colors.js","../../node_modules/d3-scale-chromatic/src/categorical/category10.js","../../node_modules/d3-scale-chromatic/src/categorical/Accent.js","../../node_modules/d3-scale-chromatic/src/categorical/Dark2.js","../../node_modules/d3-scale-chromatic/src/categorical/observable10.js","../../node_modules/d3-scale-chromatic/src/categorical/Paired.js","../../node_modules/d3-scale-chromatic/src/categorical/Pastel1.js","../../node_modules/d3-scale-chromatic/src/categorical/Pastel2.js","../../node_modules/d3-scale-chromatic/src/categorical/Set1.js","../../node_modules/d3-scale-chromatic/src/categorical/Set2.js","../../node_modules/d3-scale-chromatic/src/categorical/Set3.js","../../node_modules/d3-scale-chromatic/src/categorical/Tableau10.js","../../node_modules/d3-scale-chromatic/src/ramp.js","../../node_modules/d3-scale-chromatic/src/diverging/BrBG.js","../../node_modules/d3-scale-chromatic/src/diverging/PRGn.js","../../node_modules/d3-scale-chromatic/src/diverging/PiYG.js","../../node_modules/d3-scale-chromatic/src/diverging/PuOr.js","../../node_modules/d3-scale-chromatic/src/diverging/RdBu.js","../../node_modules/d3-scale-chromatic/src/diverging/RdGy.js","../../node_modules/d3-scale-chromatic/src/diverging/RdYlBu.js","../../node_modules/d3-scale-chromatic/src/diverging/RdYlGn.js","../../node_modules/d3-scale-chromatic/src/diverging/Spectral.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/BuGn.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/BuPu.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/GnBu.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/OrRd.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/PuBuGn.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/PuBu.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/PuRd.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/RdPu.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/YlGnBu.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/YlGn.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/YlOrBr.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/YlOrRd.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Blues.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Greens.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Greys.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Purples.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Reds.js","../../node_modules/d3-scale-chromatic/src/sequential-single/Oranges.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/cividis.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/cubehelix.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/rainbow.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/sinebow.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/turbo.js","../../node_modules/d3-scale-chromatic/src/sequential-multi/viridis.js","../../node_modules/d3-scale-chromatic/src/index.js","../../autk-core/src/colormap.ts","../../autk-core/src/transfer-function.ts","../../autk-core/src/triangulator-points.ts","../../autk-core/src/polyline-builder.ts","../../autk-core/src/utils-geometry.ts","../../node_modules/earcut/src/earcut.js","../../autk-core/src/triangulator-polylines.ts","../../autk-core/src/triangulator-polygons.ts","../../autk-core/src/triangulator-roofs.ts","../../autk-core/src/building-feature.ts","../../autk-core/src/triangulator-buildings.ts","../../autk-core/src/triangulator-raster.ts","../../autk-core/src/utils-data.ts","../../autk-core/src/heightfield.ts","../../node_modules/gl-matrix/esm/common.js","../../node_modules/gl-matrix/esm/mat4.js","../../node_modules/gl-matrix/esm/vec3.js","../../autk-core/src/camera.ts","../../autk-core/src/event-emitter.ts","../../autk-core/src/types-layer.ts","../../autk-core/src/utils-geojson.ts","../../autk-core/src/utils-layer.ts","../src/events-key.ts","../src/types-events.ts","../src/events-mouse.ts","../src/events-resize.ts","../src/renderer.ts","../src/layer.ts","../src/shaders/raster.vert.wgsl","../src/shaders/raster.frag.wgsl","../src/pipeline.ts","../src/pipeline-triangle-raster.ts","../src/layer-raster.ts","../src/shaders/triangle-01.vert.wgsl","../src/shaders/triangle-01.frag.wgsl","../src/pipeline-triangle-flat.ts","../src/shaders/picking.vert.wgsl","../src/shaders/picking.frag.wgsl","../src/shaders/picking-3d-terrain.vert.wgsl","../src/pipeline-triangle-picking.ts","../src/layer-vector.ts","../src/shaders/buildings-01.vert.wgsl","../src/shaders/buildings-01.frag.wgsl","../src/shaders/buildings-02.vert.wgsl","../src/shaders/buildings-02.frag.wgsl","../src/shaders/buildings-02-terrain.frag.wgsl","../src/pipeline-triangle-ssao.ts","../src/layer-triangles3D.ts","../src/shaders/triangle-02.vert.wgsl","../src/shaders/triangle-02.frag.wgsl","../src/pipeline-triangle-border.ts","../src/layer-triangles2D.ts","../src/shaders/sprite.vert.wgsl","../src/shaders/sprite.frag.wgsl","../src/pipeline-sprite.ts","../src/shaders/sprite-picking.vert.wgsl","../src/shaders/sprite-picking.frag.wgsl","../src/pipeline-sprite-picking.ts","../src/layer-sprite.ts","../src/shaders/polyline-expansion.wgsl","../src/shaders/polyline.vert.wgsl","../src/shaders/polyline-picking.vert.wgsl","../src/shaders/polyline-picking.frag.wgsl","../src/pipeline-polyline.ts","../src/layer-polyline.ts","../src/layer-manager.ts","../../node_modules/d3-dispatch/src/dispatch.js","../../node_modules/d3-selection/src/namespaces.js","../../node_modules/d3-selection/src/namespace.js","../../node_modules/d3-selection/src/creator.js","../../node_modules/d3-selection/src/selector.js","../../node_modules/d3-selection/src/selection/select.js","../../node_modules/d3-selection/src/array.js","../../node_modules/d3-selection/src/selectorAll.js","../../node_modules/d3-selection/src/selection/selectAll.js","../../node_modules/d3-selection/src/matcher.js","../../node_modules/d3-selection/src/selection/selectChild.js","../../node_modules/d3-selection/src/selection/selectChildren.js","../../node_modules/d3-selection/src/selection/filter.js","../../node_modules/d3-selection/src/selection/sparse.js","../../node_modules/d3-selection/src/selection/enter.js","../../node_modules/d3-selection/src/constant.js","../../node_modules/d3-selection/src/selection/data.js","../../node_modules/d3-selection/src/selection/exit.js","../../node_modules/d3-selection/src/selection/join.js","../../node_modules/d3-selection/src/selection/merge.js","../../node_modules/d3-selection/src/selection/order.js","../../node_modules/d3-selection/src/selection/sort.js","../../node_modules/d3-selection/src/selection/call.js","../../node_modules/d3-selection/src/selection/nodes.js","../../node_modules/d3-selection/src/selection/node.js","../../node_modules/d3-selection/src/selection/size.js","../../node_modules/d3-selection/src/selection/empty.js","../../node_modules/d3-selection/src/selection/each.js","../../node_modules/d3-selection/src/selection/attr.js","../../node_modules/d3-selection/src/window.js","../../node_modules/d3-selection/src/selection/style.js","../../node_modules/d3-selection/src/selection/property.js","../../node_modules/d3-selection/src/selection/classed.js","../../node_modules/d3-selection/src/selection/text.js","../../node_modules/d3-selection/src/selection/html.js","../../node_modules/d3-selection/src/selection/raise.js","../../node_modules/d3-selection/src/selection/lower.js","../../node_modules/d3-selection/src/selection/append.js","../../node_modules/d3-selection/src/selection/insert.js","../../node_modules/d3-selection/src/selection/remove.js","../../node_modules/d3-selection/src/selection/clone.js","../../node_modules/d3-selection/src/selection/datum.js","../../node_modules/d3-selection/src/selection/on.js","../../node_modules/d3-selection/src/selection/dispatch.js","../../node_modules/d3-selection/src/selection/iterator.js","../../node_modules/d3-selection/src/selection/index.js","../../node_modules/d3-selection/src/select.js","../../node_modules/d3-timer/src/timer.js","../../node_modules/d3-timer/src/timeout.js","../../node_modules/d3-transition/src/transition/schedule.js","../../node_modules/d3-transition/src/interrupt.js","../../node_modules/d3-transition/src/selection/interrupt.js","../../node_modules/d3-transition/src/transition/tween.js","../../node_modules/d3-transition/src/transition/interpolate.js","../../node_modules/d3-transition/src/transition/attr.js","../../node_modules/d3-transition/src/transition/attrTween.js","../../node_modules/d3-transition/src/transition/delay.js","../../node_modules/d3-transition/src/transition/duration.js","../../node_modules/d3-transition/src/transition/ease.js","../../node_modules/d3-transition/src/transition/easeVarying.js","../../node_modules/d3-transition/src/transition/filter.js","../../node_modules/d3-transition/src/transition/merge.js","../../node_modules/d3-transition/src/transition/on.js","../../node_modules/d3-transition/src/transition/remove.js","../../node_modules/d3-transition/src/transition/select.js","../../node_modules/d3-transition/src/transition/selectAll.js","../../node_modules/d3-transition/src/transition/selection.js","../../node_modules/d3-transition/src/transition/style.js","../../node_modules/d3-transition/src/transition/styleTween.js","../../node_modules/d3-transition/src/transition/text.js","../../node_modules/d3-transition/src/transition/textTween.js","../../node_modules/d3-transition/src/transition/transition.js","../../node_modules/d3-transition/src/transition/end.js","../../node_modules/d3-transition/src/transition/index.js","../../node_modules/d3-ease/src/cubic.js","../../node_modules/d3-transition/src/selection/transition.js","../../node_modules/d3-transition/src/selection/index.js","../../node_modules/d3-brush/src/brush.js","../../node_modules/d3-zoom/src/transform.js","../src/map-ui.ts","../src/styles/default.json","../src/styles/light.json","../src/styles/google.json","../src/styles/apple.json","../src/styles/osm.json","../src/styles/poster.json","../src/map-style.ts","../src/map-camera.ts","../src/map-flat.ts","../src/map-picking.ts","../src/shaders/terrain.frag.wgsl","../src/shaders/terrain-picking.frag.wgsl","../src/shaders/terrain.vert.wgsl","../src/shaders/terrain-bounds-reduce.comp.wgsl","../src/renderer-terrain.ts","../src/map-terrain.ts","../src/map.ts"],"sourcesContent":["/**\n * @module AutkMapLayerTypes\n * Shared layer metadata and render payload types for `@urban-toolkit/autk-map`.\n *\n * This module groups the data shapes passed between layer loaders, render\n * controllers, and GPU-backed layer implementations. It describes the static\n * layer identity used to order the stack, the mutable render and colormap\n * state, and the render-ready geometry, border, raster, and thematic payloads\n * consumed by the different layer pipelines.\n */\n\nimport type {\n    ColorMapConfig,\n    ColorRGB,\n    ResolvedDomain,\n    LayerBorder,\n    LayerBorderComponent,\n    LayerComponent,\n    LayerGeometry,\n    LayerType,\n} from '@urban-toolkit/autk-core';\n\n/** Default point radius in local planar units. */\nexport const DEFAULT_POINT_SIZE = 64;\n\n/** Default full width of generic polylines in local planar units. */\nexport const DEFAULT_LINE_WIDTH = 12;\n\n/** Static metadata used to identify and order a layer in the map stack. */\nexport interface LayerInfo {\n    /** Stable layer identifier used for lookup and updates. */\n    id: string;\n    /** Rendering order relative to other layers. */\n    zIndex: number;\n    /** Semantic layer type and geometry family handled by the layer. */\n    typeLayer: LayerType;\n}\n\n/** Runtime colormap state associated with a layer. */\nexport interface LayerColormap {\n    /** User colormap configuration used for thematic styling. */\n    config: ColorMapConfig;\n    /** Domain resolved from the current thematic or raster data, if available. */\n    computedDomain?: ResolvedDomain;\n    /** Legend labels derived from the resolved domain, if available. */\n    computedLabels?: string[];\n}\n\n/** Mutable render state associated with a layer. */\nexport interface LayerRenderInfo {\n    /** Point radius in local planar units. Defaults to DEFAULT_POINT_SIZE (64); camera transforms provide all zoom scaling. */\n    pointSize?: number;\n    /** Full polyline/road width in local planar units. Defaults to DEFAULT_LINE_WIDTH (12) for polylines; overrides road category widths when set. */\n    polylinesWidth?: number;\n    /** Default full widths per component, used for OSM road styling when polylinesWidth is omitted. */\n    polylinesWidthByComponent?: Float32Array;\n    /** Optional fixed layer color used when thematic color mapping is disabled. */\n    color?: ColorRGB;\n    /** Optional fixed border/outline color used by layers with a border pass. */\n    strokeColor?: ColorRGB;\n    /** Draws available polygon borders unless false. Can be toggled through updateRenderInfo without rebuilding geometry. */\n    showBorders?: boolean;\n    /** Layer opacity in the range `[0, 1]`. */\n    opacity: number;\n    /** Enables thematic color interpolation when `true`. */\n    isColorMap?: boolean;\n    /** Skips rendering work for this layer when `true`. */\n    isSkip?: boolean;\n    /** Enables picking for this layer when `true`. */\n    isPick?: boolean;\n    /** Current colormap configuration and derived runtime domain or label state. */\n    colormap: LayerColormap;\n    /** Pending canvas-relative pick coordinates `[x, y]` in CSS pixels, if any. */\n    pickedComps?: number[];\n}\n\n/** Render-ready layer payload produced by loaders and triangulation steps. */\nexport interface LayerData {\n    /** Geometry buffers for the layer primitives. */\n    geometry: LayerGeometry[];\n    /** Per-primitive component metadata aligned with `geometry`. */\n    components: LayerComponent[];\n    /** Optional border geometry for outlined 2D triangle layers. */\n    border?: LayerBorder[];\n    /** Cumulative border-component metadata aligned with `border`. */\n    borderComponents?: LayerBorderComponent[];\n    /** Packed point-instance centers `[x, y, ...]` for instanced point rendering. */\n    pointInstances?: Float32Array;\n    /** Number of point instances stored in `pointInstances`. */\n    pointInstanceCount?: number;\n    /** Width-independent polyline adjacency: previous XY and next XY per node (five topology vertices per node). */\n    polylineAttributes?: Float32Array;\n    /** Raster grid width in cells, for raster layers only. */\n    rasterResX?: number;\n    /** Raster grid height in cells, for raster layers only. */\n    rasterResY?: number;\n    /** Raster scalar values, for raster layers only. */\n    raster?: Float32Array;\n    /** Per-component or per-cell thematic values used for color mapping. */\n    thematic?: LayerThematic[];\n}\n\n/** Numeric thematic payload associated with a layer. */\nexport interface LayerThematic {\n    /** Scalar value aligned with one rendered component or raster cell. */\n    value: number;\n    /** Numeric validity flag propagated with the thematic value. */\n    valid: number;\n}\n","/**\n * @module ColorMapTypes\n * Shared enums and types for color mapping, legend generation, and color-buffer\n * exchange across the toolkit.\n *\n * This module defines the contracts used by the shared color-mapping API in\n * `autk-core` and `@urban-toolkit/autk-map`. It describes how a domain is requested and\n * resolved, which d3-backed interpolators can be selected, and how colors are\n * represented when exchanged as hex strings, RGBA objects, or flat texture\n * buffers.\n */\n\n/**\n * Strategies for deriving a colormap domain.\n *\n * The selected strategy determines whether the domain is supplied directly,\n * computed from numeric min/max values, or computed from numeric percentiles.\n */\nexport enum ColorMapDomainStrategy {\n  /** Use the caller-provided domain verbatim. */\n  USER = 'user',\n  /** Derive the domain from the observed minimum and maximum values. */\n  MIN_MAX = 'minMax',\n  /** Derive the domain from lower and upper percentiles. */\n  PERCENTILE = 'percentile',\n}\n\n/**\n * Domain resolved from input data and a colormap configuration.\n *\n * Numeric domains are returned for continuous interpolators, while string\n * domains are returned for categorical schemes and legend labeling.\n */\nexport type ResolvedDomain = number[] | string[];\n\n/**\n * Specification for how a colormap domain should be derived.\n *\n * `USER` supplies an explicit domain, `MIN_MAX` derives a numeric range from\n * the input values, and `PERCENTILE` derives a numeric range from percentile\n * bounds.\n */\nexport type ColorMapDomainSpec =\n  /** Explicit domain supplied by the caller. */\n  | { type: ColorMapDomainStrategy.USER; params: number[] | string[] }\n  /** Domain inferred from the minimum and maximum numeric values. */\n  | { type: ColorMapDomainStrategy.MIN_MAX }\n  /** Domain inferred from lower and upper numeric percentiles in the 0-100 range. */\n  | { type: ColorMapDomainStrategy.PERCENTILE; params?: [number, number] };\n\n/**\n * Identifiers for the supported color schemes and interpolators.\n *\n * Values map to d3-scale-chromatic categorical, sequential, and diverging\n * schemes used by the shared color-mapping engine.\n */\nexport enum ColorMapInterpolator {\n  /** Accent categorical scheme. */\n  CAT_ACCENT = 'schemeAccent',\n  /** Dark2 categorical scheme. */\n  CAT_DARK2 = 'schemeDark2',\n  /** Category10 categorical scheme. */\n  CAT_CATEGORY10 = 'schemeCategory10',\n  /** Observable10 categorical scheme. */\n  CAT_OBSERVABLE10 = 'schemeObservable10',\n  /** Paired categorical scheme. */\n  CAT_PAIRED = 'schemePaired',\n  /** Pastel1 categorical scheme. */\n  CAT_PASTEL1 = 'schemePastel1',\n  /** Pastel2 categorical scheme. */\n  CAT_PASTEL2 = 'schemePastel2',\n  /** Set1 categorical scheme. */\n  CAT_SET1 = 'schemeSet1',\n  /** Set2 categorical scheme. */\n  CAT_SET2 = 'schemeSet2',\n  /** Set3 categorical scheme. */\n  CAT_SET3 = 'schemeSet3',\n  /** Tableau10 categorical scheme. */\n  CAT_TABLEAU10 = 'schemeTableau10',\n  /** Reds sequential scheme. */\n  SEQ_REDS = 'interpolateReds',\n  /** Blues sequential scheme. */\n  SEQ_BLUES = 'interpolateBlues',\n  /** Greens sequential scheme. */\n  SEQ_GREENS = 'interpolateGreens',\n  /** Greys sequential scheme. */\n  SEQ_GREYS = 'interpolateGreys',\n  /** Oranges sequential scheme. */\n  SEQ_ORANGES = 'interpolateOranges',\n  /** Purples sequential scheme. */\n  SEQ_PURPLES = 'interpolatePurples',\n  /** Turbo sequential scheme. */\n  SEQ_TURBO = 'interpolateTurbo',\n  /** Viridis sequential scheme. */\n  SEQ_VIRIDIS = 'interpolateViridis',\n  /** Inferno sequential scheme. */\n  SEQ_INFERNO = 'interpolateInferno',\n  /** Magma sequential scheme. */\n  SEQ_MAGMA = 'interpolateMagma',\n  /** Plasma sequential scheme. */\n  SEQ_PLASMA = 'interpolatePlasma',\n  /** Cividis sequential scheme. */\n  SEQ_CIVIDIS = 'interpolateCividis',\n  /** Warm sequential scheme. */\n  SEQ_WARM = 'interpolateWarm',\n  /** Cool sequential scheme. */\n  SEQ_COOL = 'interpolateCool',\n  /** Default cubehelix sequential scheme. */\n  SEQ_CUBEHELIX_DEFAULT = 'interpolateCubehelixDefault',\n  /** Blue-Green sequential scheme. */\n  SEQ_BU_GN = 'interpolateBuGn',\n  /** Blue-Purple sequential scheme. */\n  SEQ_BU_PU = 'interpolateBuPu',\n  /** Green-Blue sequential scheme. */\n  SEQ_GN_BU = 'interpolateGnBu',\n  /** Orange-Red sequential scheme. */\n  SEQ_OR_RD = 'interpolateOrRd',\n  /** Purple-Blue-Green sequential scheme. */\n  SEQ_PU_BU_GN = 'interpolatePuBuGn',\n  /** Purple-Blue sequential scheme. */\n  SEQ_PU_BU = 'interpolatePuBu',\n  /** Purple-Red sequential scheme. */\n  SEQ_PU_RD = 'interpolatePuRd',\n  /** Red-Purple sequential scheme. */\n  SEQ_RD_PU = 'interpolateRdPu',\n  /** Yellow-Green-Blue sequential scheme. */\n  SEQ_YL_GN_BU = 'interpolateYlGnBu',\n  /** Yellow-Green sequential scheme. */\n  SEQ_YL_GN = 'interpolateYlGn',\n  /** Yellow-Orange-Brown sequential scheme. */\n  SEQ_YL_OR_BR = 'interpolateYlOrBr',\n  /** Yellow-Orange-Red sequential scheme. */\n  SEQ_YL_OR_RD = 'interpolateYlOrRd',\n  /** Brown-Blue-Green diverging scheme. */\n  DIV_BR_BG = 'interpolateBrBG',\n  /** Purple-Green diverging scheme. */\n  DIV_PR_GN = 'interpolatePRGn',\n  /** Pink-Yellow-Green diverging scheme. */\n  DIV_PI_YG = 'interpolatePiYG',\n  /** Purple-Orange diverging scheme. */\n  DIV_PU_OR = 'interpolatePuOr',\n  /** Red-Blue diverging scheme. */\n  DIV_RED_BLUE = 'interpolateRdBu',\n  /** Red-Grey diverging scheme. */\n  DIV_RED_GREY = 'interpolateRdGy',\n  /** Red-Yellow-Blue diverging scheme. */\n  DIV_RED_YELLOW_BLUE = 'interpolateRdYlBu',\n  /** Red-Yellow-Green diverging scheme. */\n  DIV_RED_YELLOW_GREEN = 'interpolateRdYlGn',\n  /** Spectral diverging scheme. */\n  DIV_SPECTRAL = 'interpolateSpectral',\n}\n\n/**\n * Unified color-map configuration used by map rendering and legend generation.\n *\n * This config couples the selected interpolator with the domain strategy so\n * both `autk-core` and `@urban-toolkit/autk-map` resolve and display the same scale.\n */\nexport type ColorMapConfig = {\n  /** Selected interpolator or color scheme. */\n  interpolator: ColorMapInterpolator;\n  /** Strategy used to derive the domain passed to the interpolator. */\n  domainSpec: ColorMapDomainSpec;\n};\n\n/**\n * Hexadecimal color string used by styling APIs.\n */\nexport type ColorHEX = `#${string}`;\n\n/**\n * RGBA color representation used by sampling and map styling APIs.\n */\nexport type ColorRGB = {\n  /** Red channel value. */\n  r: number;\n  /** Green channel value. */\n  g: number;\n  /** Blue channel value. */\n  b: number;\n  /** Alpha channel value, typically normalized to the 0-1 range. */\n  alpha: number;\n};\n\n/**\n * Flat RGBA texture buffer laid out as `[r, g, b, a, ...]`.\n */\nexport type ColorTEX = number[];\n","export default function(constructor, factory, prototype) {\n  constructor.prototype = factory.prototype = prototype;\n  prototype.constructor = constructor;\n}\n\nexport function extend(parent, definition) {\n  var prototype = Object.create(parent.prototype);\n  for (var key in definition) prototype[key] = definition[key];\n  return prototype;\n}\n","import define, {extend} from \"./define.js\";\n\nexport function Color() {}\n\nexport var darker = 0.7;\nexport var brighter = 1 / darker;\n\nvar reI = \"\\\\s*([+-]?\\\\d+)\\\\s*\",\n    reN = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)\\\\s*\",\n    reP = \"\\\\s*([+-]?(?:\\\\d*\\\\.)?\\\\d+(?:[eE][+-]?\\\\d+)?)%\\\\s*\",\n    reHex = /^#([0-9a-f]{3,8})$/,\n    reRgbInteger = new RegExp(`^rgb\\\\(${reI},${reI},${reI}\\\\)$`),\n    reRgbPercent = new RegExp(`^rgb\\\\(${reP},${reP},${reP}\\\\)$`),\n    reRgbaInteger = new RegExp(`^rgba\\\\(${reI},${reI},${reI},${reN}\\\\)$`),\n    reRgbaPercent = new RegExp(`^rgba\\\\(${reP},${reP},${reP},${reN}\\\\)$`),\n    reHslPercent = new RegExp(`^hsl\\\\(${reN},${reP},${reP}\\\\)$`),\n    reHslaPercent = new RegExp(`^hsla\\\\(${reN},${reP},${reP},${reN}\\\\)$`);\n\nvar named = {\n  aliceblue: 0xf0f8ff,\n  antiquewhite: 0xfaebd7,\n  aqua: 0x00ffff,\n  aquamarine: 0x7fffd4,\n  azure: 0xf0ffff,\n  beige: 0xf5f5dc,\n  bisque: 0xffe4c4,\n  black: 0x000000,\n  blanchedalmond: 0xffebcd,\n  blue: 0x0000ff,\n  blueviolet: 0x8a2be2,\n  brown: 0xa52a2a,\n  burlywood: 0xdeb887,\n  cadetblue: 0x5f9ea0,\n  chartreuse: 0x7fff00,\n  chocolate: 0xd2691e,\n  coral: 0xff7f50,\n  cornflowerblue: 0x6495ed,\n  cornsilk: 0xfff8dc,\n  crimson: 0xdc143c,\n  cyan: 0x00ffff,\n  darkblue: 0x00008b,\n  darkcyan: 0x008b8b,\n  darkgoldenrod: 0xb8860b,\n  darkgray: 0xa9a9a9,\n  darkgreen: 0x006400,\n  darkgrey: 0xa9a9a9,\n  darkkhaki: 0xbdb76b,\n  darkmagenta: 0x8b008b,\n  darkolivegreen: 0x556b2f,\n  darkorange: 0xff8c00,\n  darkorchid: 0x9932cc,\n  darkred: 0x8b0000,\n  darksalmon: 0xe9967a,\n  darkseagreen: 0x8fbc8f,\n  darkslateblue: 0x483d8b,\n  darkslategray: 0x2f4f4f,\n  darkslategrey: 0x2f4f4f,\n  darkturquoise: 0x00ced1,\n  darkviolet: 0x9400d3,\n  deeppink: 0xff1493,\n  deepskyblue: 0x00bfff,\n  dimgray: 0x696969,\n  dimgrey: 0x696969,\n  dodgerblue: 0x1e90ff,\n  firebrick: 0xb22222,\n  floralwhite: 0xfffaf0,\n  forestgreen: 0x228b22,\n  fuchsia: 0xff00ff,\n  gainsboro: 0xdcdcdc,\n  ghostwhite: 0xf8f8ff,\n  gold: 0xffd700,\n  goldenrod: 0xdaa520,\n  gray: 0x808080,\n  green: 0x008000,\n  greenyellow: 0xadff2f,\n  grey: 0x808080,\n  honeydew: 0xf0fff0,\n  hotpink: 0xff69b4,\n  indianred: 0xcd5c5c,\n  indigo: 0x4b0082,\n  ivory: 0xfffff0,\n  khaki: 0xf0e68c,\n  lavender: 0xe6e6fa,\n  lavenderblush: 0xfff0f5,\n  lawngreen: 0x7cfc00,\n  lemonchiffon: 0xfffacd,\n  lightblue: 0xadd8e6,\n  lightcoral: 0xf08080,\n  lightcyan: 0xe0ffff,\n  lightgoldenrodyellow: 0xfafad2,\n  lightgray: 0xd3d3d3,\n  lightgreen: 0x90ee90,\n  lightgrey: 0xd3d3d3,\n  lightpink: 0xffb6c1,\n  lightsalmon: 0xffa07a,\n  lightseagreen: 0x20b2aa,\n  lightskyblue: 0x87cefa,\n  lightslategray: 0x778899,\n  lightslategrey: 0x778899,\n  lightsteelblue: 0xb0c4de,\n  lightyellow: 0xffffe0,\n  lime: 0x00ff00,\n  limegreen: 0x32cd32,\n  linen: 0xfaf0e6,\n  magenta: 0xff00ff,\n  maroon: 0x800000,\n  mediumaquamarine: 0x66cdaa,\n  mediumblue: 0x0000cd,\n  mediumorchid: 0xba55d3,\n  mediumpurple: 0x9370db,\n  mediumseagreen: 0x3cb371,\n  mediumslateblue: 0x7b68ee,\n  mediumspringgreen: 0x00fa9a,\n  mediumturquoise: 0x48d1cc,\n  mediumvioletred: 0xc71585,\n  midnightblue: 0x191970,\n  mintcream: 0xf5fffa,\n  mistyrose: 0xffe4e1,\n  moccasin: 0xffe4b5,\n  navajowhite: 0xffdead,\n  navy: 0x000080,\n  oldlace: 0xfdf5e6,\n  olive: 0x808000,\n  olivedrab: 0x6b8e23,\n  orange: 0xffa500,\n  orangered: 0xff4500,\n  orchid: 0xda70d6,\n  palegoldenrod: 0xeee8aa,\n  palegreen: 0x98fb98,\n  paleturquoise: 0xafeeee,\n  palevioletred: 0xdb7093,\n  papayawhip: 0xffefd5,\n  peachpuff: 0xffdab9,\n  peru: 0xcd853f,\n  pink: 0xffc0cb,\n  plum: 0xdda0dd,\n  powderblue: 0xb0e0e6,\n  purple: 0x800080,\n  rebeccapurple: 0x663399,\n  red: 0xff0000,\n  rosybrown: 0xbc8f8f,\n  royalblue: 0x4169e1,\n  saddlebrown: 0x8b4513,\n  salmon: 0xfa8072,\n  sandybrown: 0xf4a460,\n  seagreen: 0x2e8b57,\n  seashell: 0xfff5ee,\n  sienna: 0xa0522d,\n  silver: 0xc0c0c0,\n  skyblue: 0x87ceeb,\n  slateblue: 0x6a5acd,\n  slategray: 0x708090,\n  slategrey: 0x708090,\n  snow: 0xfffafa,\n  springgreen: 0x00ff7f,\n  steelblue: 0x4682b4,\n  tan: 0xd2b48c,\n  teal: 0x008080,\n  thistle: 0xd8bfd8,\n  tomato: 0xff6347,\n  turquoise: 0x40e0d0,\n  violet: 0xee82ee,\n  wheat: 0xf5deb3,\n  white: 0xffffff,\n  whitesmoke: 0xf5f5f5,\n  yellow: 0xffff00,\n  yellowgreen: 0x9acd32\n};\n\ndefine(Color, color, {\n  copy(channels) {\n    return Object.assign(new this.constructor, this, channels);\n  },\n  displayable() {\n    return this.rgb().displayable();\n  },\n  hex: color_formatHex, // Deprecated! Use color.formatHex.\n  formatHex: color_formatHex,\n  formatHex8: color_formatHex8,\n  formatHsl: color_formatHsl,\n  formatRgb: color_formatRgb,\n  toString: color_formatRgb\n});\n\nfunction color_formatHex() {\n  return this.rgb().formatHex();\n}\n\nfunction color_formatHex8() {\n  return this.rgb().formatHex8();\n}\n\nfunction color_formatHsl() {\n  return hslConvert(this).formatHsl();\n}\n\nfunction color_formatRgb() {\n  return this.rgb().formatRgb();\n}\n\nexport default function color(format) {\n  var m, l;\n  format = (format + \"\").trim().toLowerCase();\n  return (m = reHex.exec(format)) ? (l = m[1].length, m = parseInt(m[1], 16), l === 6 ? rgbn(m) // #ff0000\n      : l === 3 ? new Rgb((m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1) // #f00\n      : l === 8 ? rgba(m >> 24 & 0xff, m >> 16 & 0xff, m >> 8 & 0xff, (m & 0xff) / 0xff) // #ff000000\n      : l === 4 ? rgba((m >> 12 & 0xf) | (m >> 8 & 0xf0), (m >> 8 & 0xf) | (m >> 4 & 0xf0), (m >> 4 & 0xf) | (m & 0xf0), (((m & 0xf) << 4) | (m & 0xf)) / 0xff) // #f000\n      : null) // invalid hex\n      : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)\n      : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)\n      : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)\n      : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)\n      : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)\n      : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)\n      : named.hasOwnProperty(format) ? rgbn(named[format]) // eslint-disable-line no-prototype-builtins\n      : format === \"transparent\" ? new Rgb(NaN, NaN, NaN, 0)\n      : null;\n}\n\nfunction rgbn(n) {\n  return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);\n}\n\nfunction rgba(r, g, b, a) {\n  if (a <= 0) r = g = b = NaN;\n  return new Rgb(r, g, b, a);\n}\n\nexport function rgbConvert(o) {\n  if (!(o instanceof Color)) o = color(o);\n  if (!o) return new Rgb;\n  o = o.rgb();\n  return new Rgb(o.r, o.g, o.b, o.opacity);\n}\n\nexport function rgb(r, g, b, opacity) {\n  return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);\n}\n\nexport function Rgb(r, g, b, opacity) {\n  this.r = +r;\n  this.g = +g;\n  this.b = +b;\n  this.opacity = +opacity;\n}\n\ndefine(Rgb, rgb, extend(Color, {\n  brighter(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n  },\n  darker(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);\n  },\n  rgb() {\n    return this;\n  },\n  clamp() {\n    return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));\n  },\n  displayable() {\n    return (-0.5 <= this.r && this.r < 255.5)\n        && (-0.5 <= this.g && this.g < 255.5)\n        && (-0.5 <= this.b && this.b < 255.5)\n        && (0 <= this.opacity && this.opacity <= 1);\n  },\n  hex: rgb_formatHex, // Deprecated! Use color.formatHex.\n  formatHex: rgb_formatHex,\n  formatHex8: rgb_formatHex8,\n  formatRgb: rgb_formatRgb,\n  toString: rgb_formatRgb\n}));\n\nfunction rgb_formatHex() {\n  return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;\n}\n\nfunction rgb_formatHex8() {\n  return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;\n}\n\nfunction rgb_formatRgb() {\n  const a = clampa(this.opacity);\n  return `${a === 1 ? \"rgb(\" : \"rgba(\"}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? \")\" : `, ${a})`}`;\n}\n\nfunction clampa(opacity) {\n  return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));\n}\n\nfunction clampi(value) {\n  return Math.max(0, Math.min(255, Math.round(value) || 0));\n}\n\nfunction hex(value) {\n  value = clampi(value);\n  return (value < 16 ? \"0\" : \"\") + value.toString(16);\n}\n\nfunction hsla(h, s, l, a) {\n  if (a <= 0) h = s = l = NaN;\n  else if (l <= 0 || l >= 1) h = s = NaN;\n  else if (s <= 0) h = NaN;\n  return new Hsl(h, s, l, a);\n}\n\nexport function hslConvert(o) {\n  if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);\n  if (!(o instanceof Color)) o = color(o);\n  if (!o) return new Hsl;\n  if (o instanceof Hsl) return o;\n  o = o.rgb();\n  var r = o.r / 255,\n      g = o.g / 255,\n      b = o.b / 255,\n      min = Math.min(r, g, b),\n      max = Math.max(r, g, b),\n      h = NaN,\n      s = max - min,\n      l = (max + min) / 2;\n  if (s) {\n    if (r === max) h = (g - b) / s + (g < b) * 6;\n    else if (g === max) h = (b - r) / s + 2;\n    else h = (r - g) / s + 4;\n    s /= l < 0.5 ? max + min : 2 - max - min;\n    h *= 60;\n  } else {\n    s = l > 0 && l < 1 ? 0 : h;\n  }\n  return new Hsl(h, s, l, o.opacity);\n}\n\nexport function hsl(h, s, l, opacity) {\n  return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);\n}\n\nfunction Hsl(h, s, l, opacity) {\n  this.h = +h;\n  this.s = +s;\n  this.l = +l;\n  this.opacity = +opacity;\n}\n\ndefine(Hsl, hsl, extend(Color, {\n  brighter(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Hsl(this.h, this.s, this.l * k, this.opacity);\n  },\n  darker(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Hsl(this.h, this.s, this.l * k, this.opacity);\n  },\n  rgb() {\n    var h = this.h % 360 + (this.h < 0) * 360,\n        s = isNaN(h) || isNaN(this.s) ? 0 : this.s,\n        l = this.l,\n        m2 = l + (l < 0.5 ? l : 1 - l) * s,\n        m1 = 2 * l - m2;\n    return new Rgb(\n      hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),\n      hsl2rgb(h, m1, m2),\n      hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),\n      this.opacity\n    );\n  },\n  clamp() {\n    return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));\n  },\n  displayable() {\n    return (0 <= this.s && this.s <= 1 || isNaN(this.s))\n        && (0 <= this.l && this.l <= 1)\n        && (0 <= this.opacity && this.opacity <= 1);\n  },\n  formatHsl() {\n    const a = clampa(this.opacity);\n    return `${a === 1 ? \"hsl(\" : \"hsla(\"}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? \")\" : `, ${a})`}`;\n  }\n}));\n\nfunction clamph(value) {\n  value = (value || 0) % 360;\n  return value < 0 ? value + 360 : value;\n}\n\nfunction clampt(value) {\n  return Math.max(0, Math.min(1, value || 0));\n}\n\n/* From FvD 13.37, CSS Color Module Level 3 */\nfunction hsl2rgb(h, m1, m2) {\n  return (h < 60 ? m1 + (m2 - m1) * h / 60\n      : h < 180 ? m2\n      : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60\n      : m1) * 255;\n}\n","export const radians = Math.PI / 180;\nexport const degrees = 180 / Math.PI;\n","import define, {extend} from \"./define.js\";\nimport {Color, rgbConvert, Rgb, darker, brighter} from \"./color.js\";\nimport {degrees, radians} from \"./math.js\";\n\nvar A = -0.14861,\n    B = +1.78277,\n    C = -0.29227,\n    D = -0.90649,\n    E = +1.97294,\n    ED = E * D,\n    EB = E * B,\n    BC_DA = B * C - D * A;\n\nfunction cubehelixConvert(o) {\n  if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);\n  if (!(o instanceof Rgb)) o = rgbConvert(o);\n  var r = o.r / 255,\n      g = o.g / 255,\n      b = o.b / 255,\n      l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),\n      bl = b - l,\n      k = (E * (g - l) - C * bl) / D,\n      s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1\n      h = s ? Math.atan2(k, bl) * degrees - 120 : NaN;\n  return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);\n}\n\nexport default function cubehelix(h, s, l, opacity) {\n  return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);\n}\n\nexport function Cubehelix(h, s, l, opacity) {\n  this.h = +h;\n  this.s = +s;\n  this.l = +l;\n  this.opacity = +opacity;\n}\n\ndefine(Cubehelix, cubehelix, extend(Color, {\n  brighter(k) {\n    k = k == null ? brighter : Math.pow(brighter, k);\n    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n  },\n  darker(k) {\n    k = k == null ? darker : Math.pow(darker, k);\n    return new Cubehelix(this.h, this.s, this.l * k, this.opacity);\n  },\n  rgb() {\n    var h = isNaN(this.h) ? 0 : (this.h + 120) * radians,\n        l = +this.l,\n        a = isNaN(this.s) ? 0 : this.s * l * (1 - l),\n        cosh = Math.cos(h),\n        sinh = Math.sin(h);\n    return new Rgb(\n      255 * (l + a * (A * cosh + B * sinh)),\n      255 * (l + a * (C * cosh + D * sinh)),\n      255 * (l + a * (E * cosh)),\n      this.opacity\n    );\n  }\n}));\n","export default function(x) {\n  return Math.abs(x = Math.round(x)) >= 1e21\n      ? x.toLocaleString(\"en\").replace(/,/g, \"\")\n      : x.toString(10);\n}\n\n// Computes the decimal coefficient and exponent of the specified number x with\n// significant digits p, where x is positive and p is in [1, 21] or undefined.\n// For example, formatDecimalParts(1.23) returns [\"123\", 0].\nexport function formatDecimalParts(x, p) {\n  if (!isFinite(x) || x === 0) return null; // NaN, ±Infinity, ±0\n  var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf(\"e\"), coefficient = x.slice(0, i);\n\n  // The string returned by toExponential either has the form \\d\\.\\d+e[-+]\\d+\n  // (e.g., 1.2e+3) or the form \\de[-+]\\d+ (e.g., 1e+3).\n  return [\n    coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,\n    +x.slice(i + 1)\n  ];\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x) {\n  return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;\n}\n","export default function(grouping, thousands) {\n  return function(value, width) {\n    var i = value.length,\n        t = [],\n        j = 0,\n        g = grouping[0],\n        length = 0;\n\n    while (i > 0 && g > 0) {\n      if (length + g + 1 > width) g = Math.max(1, width - length);\n      t.push(value.substring(i -= g, i + g));\n      if ((length += g + 1) > width) break;\n      g = grouping[j = (j + 1) % grouping.length];\n    }\n\n    return t.reverse().join(thousands);\n  };\n}\n","export default function(numerals) {\n  return function(value) {\n    return value.replace(/[0-9]/g, function(i) {\n      return numerals[+i];\n    });\n  };\n}\n","// [[fill]align][sign][symbol][0][width][,][.precision][~][type]\nvar re = /^(?:(.)?([<>=^]))?([+\\-( ])?([$#])?(0)?(\\d+)?(,)?(\\.\\d+)?(~)?([a-z%])?$/i;\n\nexport default function formatSpecifier(specifier) {\n  if (!(match = re.exec(specifier))) throw new Error(\"invalid format: \" + specifier);\n  var match;\n  return new FormatSpecifier({\n    fill: match[1],\n    align: match[2],\n    sign: match[3],\n    symbol: match[4],\n    zero: match[5],\n    width: match[6],\n    comma: match[7],\n    precision: match[8] && match[8].slice(1),\n    trim: match[9],\n    type: match[10]\n  });\n}\n\nformatSpecifier.prototype = FormatSpecifier.prototype; // instanceof\n\nexport function FormatSpecifier(specifier) {\n  this.fill = specifier.fill === undefined ? \" \" : specifier.fill + \"\";\n  this.align = specifier.align === undefined ? \">\" : specifier.align + \"\";\n  this.sign = specifier.sign === undefined ? \"-\" : specifier.sign + \"\";\n  this.symbol = specifier.symbol === undefined ? \"\" : specifier.symbol + \"\";\n  this.zero = !!specifier.zero;\n  this.width = specifier.width === undefined ? undefined : +specifier.width;\n  this.comma = !!specifier.comma;\n  this.precision = specifier.precision === undefined ? undefined : +specifier.precision;\n  this.trim = !!specifier.trim;\n  this.type = specifier.type === undefined ? \"\" : specifier.type + \"\";\n}\n\nFormatSpecifier.prototype.toString = function() {\n  return this.fill\n      + this.align\n      + this.sign\n      + this.symbol\n      + (this.zero ? \"0\" : \"\")\n      + (this.width === undefined ? \"\" : Math.max(1, this.width | 0))\n      + (this.comma ? \",\" : \"\")\n      + (this.precision === undefined ? \"\" : \".\" + Math.max(0, this.precision | 0))\n      + (this.trim ? \"~\" : \"\")\n      + this.type;\n};\n","// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k.\nexport default function(s) {\n  out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {\n    switch (s[i]) {\n      case \".\": i0 = i1 = i; break;\n      case \"0\": if (i0 === 0) i0 = i; i1 = i; break;\n      default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break;\n    }\n  }\n  return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport var prefixExponent;\n\nexport default function(x, p) {\n  var d = formatDecimalParts(x, p);\n  if (!d) return prefixExponent = undefined, x.toPrecision(p);\n  var coefficient = d[0],\n      exponent = d[1],\n      i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,\n      n = coefficient.length;\n  return i === n ? coefficient\n      : i > n ? coefficient + new Array(i - n + 1).join(\"0\")\n      : i > 0 ? coefficient.slice(0, i) + \".\" + coefficient.slice(i)\n      : \"0.\" + new Array(1 - i).join(\"0\") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y!\n}\n","import {formatDecimalParts} from \"./formatDecimal.js\";\n\nexport default function(x, p) {\n  var d = formatDecimalParts(x, p);\n  if (!d) return x + \"\";\n  var coefficient = d[0],\n      exponent = d[1];\n  return exponent < 0 ? \"0.\" + new Array(-exponent).join(\"0\") + coefficient\n      : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + \".\" + coefficient.slice(exponent + 1)\n      : coefficient + new Array(exponent - coefficient.length + 2).join(\"0\");\n}\n","import formatDecimal from \"./formatDecimal.js\";\nimport formatPrefixAuto from \"./formatPrefixAuto.js\";\nimport formatRounded from \"./formatRounded.js\";\n\nexport default {\n  \"%\": (x, p) => (x * 100).toFixed(p),\n  \"b\": (x) => Math.round(x).toString(2),\n  \"c\": (x) => x + \"\",\n  \"d\": formatDecimal,\n  \"e\": (x, p) => x.toExponential(p),\n  \"f\": (x, p) => x.toFixed(p),\n  \"g\": (x, p) => x.toPrecision(p),\n  \"o\": (x) => Math.round(x).toString(8),\n  \"p\": (x, p) => formatRounded(x * 100, p),\n  \"r\": formatRounded,\n  \"s\": formatPrefixAuto,\n  \"X\": (x) => Math.round(x).toString(16).toUpperCase(),\n  \"x\": (x) => Math.round(x).toString(16)\n};\n","export default function(x) {\n  return x;\n}\n","import exponent from \"./exponent.js\";\nimport formatGroup from \"./formatGroup.js\";\nimport formatNumerals from \"./formatNumerals.js\";\nimport formatSpecifier from \"./formatSpecifier.js\";\nimport formatTrim from \"./formatTrim.js\";\nimport formatTypes from \"./formatTypes.js\";\nimport {prefixExponent} from \"./formatPrefixAuto.js\";\nimport identity from \"./identity.js\";\n\nvar map = Array.prototype.map,\n    prefixes = [\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"µ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"];\n\nexport default function(locale) {\n  var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + \"\"),\n      currencyPrefix = locale.currency === undefined ? \"\" : locale.currency[0] + \"\",\n      currencySuffix = locale.currency === undefined ? \"\" : locale.currency[1] + \"\",\n      decimal = locale.decimal === undefined ? \".\" : locale.decimal + \"\",\n      numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)),\n      percent = locale.percent === undefined ? \"%\" : locale.percent + \"\",\n      minus = locale.minus === undefined ? \"−\" : locale.minus + \"\",\n      nan = locale.nan === undefined ? \"NaN\" : locale.nan + \"\";\n\n  function newFormat(specifier, options) {\n    specifier = formatSpecifier(specifier);\n\n    var fill = specifier.fill,\n        align = specifier.align,\n        sign = specifier.sign,\n        symbol = specifier.symbol,\n        zero = specifier.zero,\n        width = specifier.width,\n        comma = specifier.comma,\n        precision = specifier.precision,\n        trim = specifier.trim,\n        type = specifier.type;\n\n    // The \"n\" type is an alias for \",g\".\n    if (type === \"n\") comma = true, type = \"g\";\n\n    // The \"\" type, and any invalid type, is an alias for \".12~g\".\n    else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = \"g\";\n\n    // If zero fill is specified, padding goes after sign and before digits.\n    if (zero || (fill === \"0\" && align === \"=\")) zero = true, fill = \"0\", align = \"=\";\n\n    // Compute the prefix and suffix.\n    // For SI-prefix, the suffix is lazily computed.\n    var prefix = (options && options.prefix !== undefined ? options.prefix : \"\") + (symbol === \"$\" ? currencyPrefix : symbol === \"#\" && /[boxX]/.test(type) ? \"0\" + type.toLowerCase() : \"\"),\n        suffix = (symbol === \"$\" ? currencySuffix : /[%p]/.test(type) ? percent : \"\") + (options && options.suffix !== undefined ? options.suffix : \"\");\n\n    // What format function should we use?\n    // Is this an integer type?\n    // Can this type generate exponential notation?\n    var formatType = formatTypes[type],\n        maybeSuffix = /[defgprs%]/.test(type);\n\n    // Set the default precision if not specified,\n    // or clamp the specified precision to the supported range.\n    // For significant precision, it must be in [1, 21].\n    // For fixed precision, it must be in [0, 20].\n    precision = precision === undefined ? 6\n        : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))\n        : Math.max(0, Math.min(20, precision));\n\n    function format(value) {\n      var valuePrefix = prefix,\n          valueSuffix = suffix,\n          i, n, c;\n\n      if (type === \"c\") {\n        valueSuffix = formatType(value) + valueSuffix;\n        value = \"\";\n      } else {\n        value = +value;\n\n        // Determine the sign. -0 is not less than 0, but 1 / -0 is!\n        var valueNegative = value < 0 || 1 / value < 0;\n\n        // Perform the initial formatting.\n        value = isNaN(value) ? nan : formatType(Math.abs(value), precision);\n\n        // Trim insignificant zeros.\n        if (trim) value = formatTrim(value);\n\n        // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign.\n        if (valueNegative && +value === 0 && sign !== \"+\") valueNegative = false;\n\n        // Compute the prefix and suffix.\n        valuePrefix = (valueNegative ? (sign === \"(\" ? sign : minus) : sign === \"-\" || sign === \"(\" ? \"\" : sign) + valuePrefix;\n        valueSuffix = (type === \"s\" && !isNaN(value) && prefixExponent !== undefined ? prefixes[8 + prefixExponent / 3] : \"\") + valueSuffix + (valueNegative && sign === \"(\" ? \")\" : \"\");\n\n        // Break the formatted value into the integer “value” part that can be\n        // grouped, and fractional or exponential “suffix” part that is not.\n        if (maybeSuffix) {\n          i = -1, n = value.length;\n          while (++i < n) {\n            if (c = value.charCodeAt(i), 48 > c || c > 57) {\n              valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;\n              value = value.slice(0, i);\n              break;\n            }\n          }\n        }\n      }\n\n      // If the fill character is not \"0\", grouping is applied before padding.\n      if (comma && !zero) value = group(value, Infinity);\n\n      // Compute the padding.\n      var length = valuePrefix.length + value.length + valueSuffix.length,\n          padding = length < width ? new Array(width - length + 1).join(fill) : \"\";\n\n      // If the fill character is \"0\", grouping is applied after padding.\n      if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = \"\";\n\n      // Reconstruct the final output based on the desired alignment.\n      switch (align) {\n        case \"<\": value = valuePrefix + value + valueSuffix + padding; break;\n        case \"=\": value = valuePrefix + padding + value + valueSuffix; break;\n        case \"^\": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;\n        default: value = padding + valuePrefix + value + valueSuffix; break;\n      }\n\n      return numerals(value);\n    }\n\n    format.toString = function() {\n      return specifier + \"\";\n    };\n\n    return format;\n  }\n\n  function formatPrefix(specifier, value) {\n    var e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3,\n        k = Math.pow(10, -e),\n        f = newFormat((specifier = formatSpecifier(specifier), specifier.type = \"f\", specifier), {suffix: prefixes[8 + e / 3]});\n    return function(value) {\n      return f(k * value);\n    };\n  }\n\n  return {\n    format: newFormat,\n    formatPrefix: formatPrefix\n  };\n}\n","import formatLocale from \"./locale.js\";\n\nvar locale;\nexport var format;\nexport var formatPrefix;\n\ndefaultLocale({\n  thousands: \",\",\n  grouping: [3],\n  currency: [\"$\", \"\"]\n});\n\nexport default function defaultLocale(definition) {\n  locale = formatLocale(definition);\n  format = locale.format;\n  formatPrefix = locale.formatPrefix;\n  return locale;\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step) {\n  return Math.max(0, -exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, value) {\n  return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step)));\n}\n","import exponent from \"./exponent.js\";\n\nexport default function(step, max) {\n  step = Math.abs(step), max = Math.abs(max) - step;\n  return Math.max(0, exponent(max) - exponent(step)) + 1;\n}\n","const e10 = Math.sqrt(50),\n    e5 = Math.sqrt(10),\n    e2 = Math.sqrt(2);\n\nfunction tickSpec(start, stop, count) {\n  const step = (stop - start) / Math.max(0, count),\n      power = Math.floor(Math.log10(step)),\n      error = step / Math.pow(10, power),\n      factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;\n  let i1, i2, inc;\n  if (power < 0) {\n    inc = Math.pow(10, -power) / factor;\n    i1 = Math.round(start * inc);\n    i2 = Math.round(stop * inc);\n    if (i1 / inc < start) ++i1;\n    if (i2 / inc > stop) --i2;\n    inc = -inc;\n  } else {\n    inc = Math.pow(10, power) * factor;\n    i1 = Math.round(start / inc);\n    i2 = Math.round(stop / inc);\n    if (i1 * inc < start) ++i1;\n    if (i2 * inc > stop) --i2;\n  }\n  if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2);\n  return [i1, i2, inc];\n}\n\nexport default function ticks(start, stop, count) {\n  stop = +stop, start = +start, count = +count;\n  if (!(count > 0)) return [];\n  if (start === stop) return [start];\n  const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count);\n  if (!(i2 >= i1)) return [];\n  const n = i2 - i1 + 1, ticks = new Array(n);\n  if (reverse) {\n    if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) / -inc;\n    else for (let i = 0; i < n; ++i) ticks[i] = (i2 - i) * inc;\n  } else {\n    if (inc < 0) for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) / -inc;\n    else for (let i = 0; i < n; ++i) ticks[i] = (i1 + i) * inc;\n  }\n  return ticks;\n}\n\nexport function tickIncrement(start, stop, count) {\n  stop = +stop, start = +start, count = +count;\n  return tickSpec(start, stop, count)[2];\n}\n\nexport function tickStep(start, stop, count) {\n  stop = +stop, start = +start, count = +count;\n  const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);\n  return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);\n}\n","export function initRange(domain, range) {\n  switch (arguments.length) {\n    case 0: break;\n    case 1: this.range(domain); break;\n    default: this.range(range).domain(domain); break;\n  }\n  return this;\n}\n\nexport function initInterpolator(domain, interpolator) {\n  switch (arguments.length) {\n    case 0: break;\n    case 1: {\n      if (typeof domain === \"function\") this.interpolator(domain);\n      else this.range(domain);\n      break;\n    }\n    default: {\n      this.domain(domain);\n      if (typeof interpolator === \"function\") this.interpolator(interpolator);\n      else this.range(interpolator);\n      break;\n    }\n  }\n  return this;\n}\n","export function basis(t1, v0, v1, v2, v3) {\n  var t2 = t1 * t1, t3 = t2 * t1;\n  return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n      + (4 - 6 * t2 + 3 * t3) * v1\n      + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n      + t3 * v3) / 6;\n}\n\nexport default function(values) {\n  var n = values.length - 1;\n  return function(t) {\n    var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),\n        v1 = values[i],\n        v2 = values[i + 1],\n        v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,\n        v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n    return basis((t - i / n) * n, v0, v1, v2, v3);\n  };\n}\n","import {basis} from \"./basis.js\";\n\nexport default function(values) {\n  var n = values.length;\n  return function(t) {\n    var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),\n        v0 = values[(i + n - 1) % n],\n        v1 = values[i % n],\n        v2 = values[(i + 1) % n],\n        v3 = values[(i + 2) % n];\n    return basis((t - i / n) * n, v0, v1, v2, v3);\n  };\n}\n","export default x => () => x;\n","import constant from \"./constant.js\";\n\nfunction linear(a, d) {\n  return function(t) {\n    return a + t * d;\n  };\n}\n\nfunction exponential(a, b, y) {\n  return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {\n    return Math.pow(a + t * b, y);\n  };\n}\n\nexport function hue(a, b) {\n  var d = b - a;\n  return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);\n}\n\nexport function gamma(y) {\n  return (y = +y) === 1 ? nogamma : function(a, b) {\n    return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);\n  };\n}\n\nexport default function nogamma(a, b) {\n  var d = b - a;\n  return d ? linear(a, d) : constant(isNaN(a) ? b : a);\n}\n","import {rgb as colorRgb} from \"d3-color\";\nimport basis from \"./basis.js\";\nimport basisClosed from \"./basisClosed.js\";\nimport nogamma, {gamma} from \"./color.js\";\n\nexport default (function rgbGamma(y) {\n  var color = gamma(y);\n\n  function rgb(start, end) {\n    var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),\n        g = color(start.g, end.g),\n        b = color(start.b, end.b),\n        opacity = nogamma(start.opacity, end.opacity);\n    return function(t) {\n      start.r = r(t);\n      start.g = g(t);\n      start.b = b(t);\n      start.opacity = opacity(t);\n      return start + \"\";\n    };\n  }\n\n  rgb.gamma = rgbGamma;\n\n  return rgb;\n})(1);\n\nfunction rgbSpline(spline) {\n  return function(colors) {\n    var n = colors.length,\n        r = new Array(n),\n        g = new Array(n),\n        b = new Array(n),\n        i, color;\n    for (i = 0; i < n; ++i) {\n      color = colorRgb(colors[i]);\n      r[i] = color.r || 0;\n      g[i] = color.g || 0;\n      b[i] = color.b || 0;\n    }\n    r = spline(r);\n    g = spline(g);\n    b = spline(b);\n    color.opacity = 1;\n    return function(t) {\n      color.r = r(t);\n      color.g = g(t);\n      color.b = b(t);\n      return color + \"\";\n    };\n  };\n}\n\nexport var rgbBasis = rgbSpline(basis);\nexport var rgbBasisClosed = rgbSpline(basisClosed);\n","export default function(a, b) {\n  if (!b) b = [];\n  var n = a ? Math.min(b.length, a.length) : 0,\n      c = b.slice(),\n      i;\n  return function(t) {\n    for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;\n    return c;\n  };\n}\n\nexport function isNumberArray(x) {\n  return ArrayBuffer.isView(x) && !(x instanceof DataView);\n}\n","import value from \"./value.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n  return (isNumberArray(b) ? numberArray : genericArray)(a, b);\n}\n\nexport function genericArray(a, b) {\n  var nb = b ? b.length : 0,\n      na = a ? Math.min(nb, a.length) : 0,\n      x = new Array(na),\n      c = new Array(nb),\n      i;\n\n  for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);\n  for (; i < nb; ++i) c[i] = b[i];\n\n  return function(t) {\n    for (i = 0; i < na; ++i) c[i] = x[i](t);\n    return c;\n  };\n}\n","export default function(a, b) {\n  var d = new Date;\n  return a = +a, b = +b, function(t) {\n    return d.setTime(a * (1 - t) + b * t), d;\n  };\n}\n","export default function(a, b) {\n  return a = +a, b = +b, function(t) {\n    return a * (1 - t) + b * t;\n  };\n}\n","import value from \"./value.js\";\n\nexport default function(a, b) {\n  var i = {},\n      c = {},\n      k;\n\n  if (a === null || typeof a !== \"object\") a = {};\n  if (b === null || typeof b !== \"object\") b = {};\n\n  for (k in b) {\n    if (k in a) {\n      i[k] = value(a[k], b[k]);\n    } else {\n      c[k] = b[k];\n    }\n  }\n\n  return function(t) {\n    for (k in i) c[k] = i[k](t);\n    return c;\n  };\n}\n","import number from \"./number.js\";\n\nvar reA = /[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,\n    reB = new RegExp(reA.source, \"g\");\n\nfunction zero(b) {\n  return function() {\n    return b;\n  };\n}\n\nfunction one(b) {\n  return function(t) {\n    return b(t) + \"\";\n  };\n}\n\nexport default function(a, b) {\n  var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b\n      am, // current match in a\n      bm, // current match in b\n      bs, // string preceding current number in b, if any\n      i = -1, // index in s\n      s = [], // string constants and placeholders\n      q = []; // number interpolators\n\n  // Coerce inputs to strings.\n  a = a + \"\", b = b + \"\";\n\n  // Interpolate pairs of numbers in a & b.\n  while ((am = reA.exec(a))\n      && (bm = reB.exec(b))) {\n    if ((bs = bm.index) > bi) { // a string precedes the next number in b\n      bs = b.slice(bi, bs);\n      if (s[i]) s[i] += bs; // coalesce with previous string\n      else s[++i] = bs;\n    }\n    if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match\n      if (s[i]) s[i] += bm; // coalesce with previous string\n      else s[++i] = bm;\n    } else { // interpolate non-matching numbers\n      s[++i] = null;\n      q.push({i: i, x: number(am, bm)});\n    }\n    bi = reB.lastIndex;\n  }\n\n  // Add remains of b.\n  if (bi < b.length) {\n    bs = b.slice(bi);\n    if (s[i]) s[i] += bs; // coalesce with previous string\n    else s[++i] = bs;\n  }\n\n  // Special optimization for only a single match.\n  // Otherwise, interpolate each of the numbers and rejoin the string.\n  return s.length < 2 ? (q[0]\n      ? one(q[0].x)\n      : zero(b))\n      : (b = q.length, function(t) {\n          for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);\n          return s.join(\"\");\n        });\n}\n","import {color} from \"d3-color\";\nimport rgb from \"./rgb.js\";\nimport {genericArray} from \"./array.js\";\nimport date from \"./date.js\";\nimport number from \"./number.js\";\nimport object from \"./object.js\";\nimport string from \"./string.js\";\nimport constant from \"./constant.js\";\nimport numberArray, {isNumberArray} from \"./numberArray.js\";\n\nexport default function(a, b) {\n  var t = typeof b, c;\n  return b == null || t === \"boolean\" ? constant(b)\n      : (t === \"number\" ? number\n      : t === \"string\" ? ((c = color(b)) ? (b = c, rgb) : string)\n      : b instanceof color ? rgb\n      : b instanceof Date ? date\n      : isNumberArray(b) ? numberArray\n      : Array.isArray(b) ? genericArray\n      : typeof b.valueOf !== \"function\" && typeof b.toString !== \"function\" || isNaN(b) ? object\n      : number)(a, b);\n}\n","export default function(a, b) {\n  return a = +a, b = +b, function(t) {\n    return Math.round(a * (1 - t) + b * t);\n  };\n}\n","var degrees = 180 / Math.PI;\n\nexport var identity = {\n  translateX: 0,\n  translateY: 0,\n  rotate: 0,\n  skewX: 0,\n  scaleX: 1,\n  scaleY: 1\n};\n\nexport default function(a, b, c, d, e, f) {\n  var scaleX, scaleY, skewX;\n  if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;\n  if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;\n  if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;\n  if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;\n  return {\n    translateX: e,\n    translateY: f,\n    rotate: Math.atan2(b, a) * degrees,\n    skewX: Math.atan(skewX) * degrees,\n    scaleX: scaleX,\n    scaleY: scaleY\n  };\n}\n","import decompose, {identity} from \"./decompose.js\";\n\nvar svgNode;\n\n/* eslint-disable no-undef */\nexport function parseCss(value) {\n  const m = new (typeof DOMMatrix === \"function\" ? DOMMatrix : WebKitCSSMatrix)(value + \"\");\n  return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);\n}\n\nexport function parseSvg(value) {\n  if (value == null) return identity;\n  if (!svgNode) svgNode = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n  svgNode.setAttribute(\"transform\", value);\n  if (!(value = svgNode.transform.baseVal.consolidate())) return identity;\n  value = value.matrix;\n  return decompose(value.a, value.b, value.c, value.d, value.e, value.f);\n}\n","import number from \"../number.js\";\nimport {parseCss, parseSvg} from \"./parse.js\";\n\nfunction interpolateTransform(parse, pxComma, pxParen, degParen) {\n\n  function pop(s) {\n    return s.length ? s.pop() + \" \" : \"\";\n  }\n\n  function translate(xa, ya, xb, yb, s, q) {\n    if (xa !== xb || ya !== yb) {\n      var i = s.push(\"translate(\", null, pxComma, null, pxParen);\n      q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n    } else if (xb || yb) {\n      s.push(\"translate(\" + xb + pxComma + yb + pxParen);\n    }\n  }\n\n  function rotate(a, b, s, q) {\n    if (a !== b) {\n      if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path\n      q.push({i: s.push(pop(s) + \"rotate(\", null, degParen) - 2, x: number(a, b)});\n    } else if (b) {\n      s.push(pop(s) + \"rotate(\" + b + degParen);\n    }\n  }\n\n  function skewX(a, b, s, q) {\n    if (a !== b) {\n      q.push({i: s.push(pop(s) + \"skewX(\", null, degParen) - 2, x: number(a, b)});\n    } else if (b) {\n      s.push(pop(s) + \"skewX(\" + b + degParen);\n    }\n  }\n\n  function scale(xa, ya, xb, yb, s, q) {\n    if (xa !== xb || ya !== yb) {\n      var i = s.push(pop(s) + \"scale(\", null, \",\", null, \")\");\n      q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});\n    } else if (xb !== 1 || yb !== 1) {\n      s.push(pop(s) + \"scale(\" + xb + \",\" + yb + \")\");\n    }\n  }\n\n  return function(a, b) {\n    var s = [], // string constants and placeholders\n        q = []; // number interpolators\n    a = parse(a), b = parse(b);\n    translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);\n    rotate(a.rotate, b.rotate, s, q);\n    skewX(a.skewX, b.skewX, s, q);\n    scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);\n    a = b = null; // gc\n    return function(t) {\n      var i = -1, n = q.length, o;\n      while (++i < n) s[(o = q[i]).i] = o.x(t);\n      return s.join(\"\");\n    };\n  };\n}\n\nexport var interpolateTransformCss = interpolateTransform(parseCss, \"px, \", \"px)\", \"deg)\");\nexport var interpolateTransformSvg = interpolateTransform(parseSvg, \", \", \")\", \")\");\n","import {cubehelix as colorCubehelix} from \"d3-color\";\nimport color, {hue} from \"./color.js\";\n\nfunction cubehelix(hue) {\n  return (function cubehelixGamma(y) {\n    y = +y;\n\n    function cubehelix(start, end) {\n      var h = hue((start = colorCubehelix(start)).h, (end = colorCubehelix(end)).h),\n          s = color(start.s, end.s),\n          l = color(start.l, end.l),\n          opacity = color(start.opacity, end.opacity);\n      return function(t) {\n        start.h = h(t);\n        start.s = s(t);\n        start.l = l(Math.pow(t, y));\n        start.opacity = opacity(t);\n        return start + \"\";\n      };\n    }\n\n    cubehelix.gamma = cubehelixGamma;\n\n    return cubehelix;\n  })(1);\n}\n\nexport default cubehelix(hue);\nexport var cubehelixLong = cubehelix(color);\n","import {default as value} from \"./value.js\";\n\nexport default function piecewise(interpolate, values) {\n  if (values === undefined) values = interpolate, interpolate = value;\n  var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);\n  while (i < n) I[i] = interpolate(v, v = values[++i]);\n  return function(t) {\n    var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));\n    return I[i](t - i);\n  };\n}\n","import {bisect} from \"d3-array\";\nimport {interpolate as interpolateValue, interpolateNumber, interpolateRound} from \"d3-interpolate\";\nimport constant from \"./constant.js\";\nimport number from \"./number.js\";\n\nvar unit = [0, 1];\n\nexport function identity(x) {\n  return x;\n}\n\nfunction normalize(a, b) {\n  return (b -= (a = +a))\n      ? function(x) { return (x - a) / b; }\n      : constant(isNaN(b) ? NaN : 0.5);\n}\n\nfunction clamper(a, b) {\n  var t;\n  if (a > b) t = a, a = b, b = t;\n  return function(x) { return Math.max(a, Math.min(b, x)); };\n}\n\n// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].\n// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].\nfunction bimap(domain, range, interpolate) {\n  var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];\n  if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);\n  else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);\n  return function(x) { return r0(d0(x)); };\n}\n\nfunction polymap(domain, range, interpolate) {\n  var j = Math.min(domain.length, range.length) - 1,\n      d = new Array(j),\n      r = new Array(j),\n      i = -1;\n\n  // Reverse descending domains.\n  if (domain[j] < domain[0]) {\n    domain = domain.slice().reverse();\n    range = range.slice().reverse();\n  }\n\n  while (++i < j) {\n    d[i] = normalize(domain[i], domain[i + 1]);\n    r[i] = interpolate(range[i], range[i + 1]);\n  }\n\n  return function(x) {\n    var i = bisect(domain, x, 1, j) - 1;\n    return r[i](d[i](x));\n  };\n}\n\nexport function copy(source, target) {\n  return target\n      .domain(source.domain())\n      .range(source.range())\n      .interpolate(source.interpolate())\n      .clamp(source.clamp())\n      .unknown(source.unknown());\n}\n\nexport function transformer() {\n  var domain = unit,\n      range = unit,\n      interpolate = interpolateValue,\n      transform,\n      untransform,\n      unknown,\n      clamp = identity,\n      piecewise,\n      output,\n      input;\n\n  function rescale() {\n    var n = Math.min(domain.length, range.length);\n    if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);\n    piecewise = n > 2 ? polymap : bimap;\n    output = input = null;\n    return scale;\n  }\n\n  function scale(x) {\n    return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));\n  }\n\n  scale.invert = function(y) {\n    return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));\n  };\n\n  scale.domain = function(_) {\n    return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();\n  };\n\n  scale.range = function(_) {\n    return arguments.length ? (range = Array.from(_), rescale()) : range.slice();\n  };\n\n  scale.rangeRound = function(_) {\n    return range = Array.from(_), interpolate = interpolateRound, rescale();\n  };\n\n  scale.clamp = function(_) {\n    return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;\n  };\n\n  scale.interpolate = function(_) {\n    return arguments.length ? (interpolate = _, rescale()) : interpolate;\n  };\n\n  scale.unknown = function(_) {\n    return arguments.length ? (unknown = _, scale) : unknown;\n  };\n\n  return function(t, u) {\n    transform = t, untransform = u;\n    return rescale();\n  };\n}\n\nexport default function continuous() {\n  return transformer()(identity, identity);\n}\n","import {tickStep} from \"d3-array\";\nimport {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from \"d3-format\";\n\nexport default function tickFormat(start, stop, count, specifier) {\n  var step = tickStep(start, stop, count),\n      precision;\n  specifier = formatSpecifier(specifier == null ? \",f\" : specifier);\n  switch (specifier.type) {\n    case \"s\": {\n      var value = Math.max(Math.abs(start), Math.abs(stop));\n      if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;\n      return formatPrefix(specifier, value);\n    }\n    case \"\":\n    case \"e\":\n    case \"g\":\n    case \"p\":\n    case \"r\": {\n      if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === \"e\");\n      break;\n    }\n    case \"f\":\n    case \"%\": {\n      if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === \"%\") * 2;\n      break;\n    }\n  }\n  return format(specifier);\n}\n","import {ticks, tickIncrement} from \"d3-array\";\nimport continuous, {copy} from \"./continuous.js\";\nimport {initRange} from \"./init.js\";\nimport tickFormat from \"./tickFormat.js\";\n\nexport function linearish(scale) {\n  var domain = scale.domain;\n\n  scale.ticks = function(count) {\n    var d = domain();\n    return ticks(d[0], d[d.length - 1], count == null ? 10 : count);\n  };\n\n  scale.tickFormat = function(count, specifier) {\n    var d = domain();\n    return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);\n  };\n\n  scale.nice = function(count) {\n    if (count == null) count = 10;\n\n    var d = domain();\n    var i0 = 0;\n    var i1 = d.length - 1;\n    var start = d[i0];\n    var stop = d[i1];\n    var prestep;\n    var step;\n    var maxIter = 10;\n\n    if (stop < start) {\n      step = start, start = stop, stop = step;\n      step = i0, i0 = i1, i1 = step;\n    }\n    \n    while (maxIter-- > 0) {\n      step = tickIncrement(start, stop, count);\n      if (step === prestep) {\n        d[i0] = start\n        d[i1] = stop\n        return domain(d);\n      } else if (step > 0) {\n        start = Math.floor(start / step) * step;\n        stop = Math.ceil(stop / step) * step;\n      } else if (step < 0) {\n        start = Math.ceil(start * step) / step;\n        stop = Math.floor(stop * step) / step;\n      } else {\n        break;\n      }\n      prestep = step;\n    }\n\n    return scale;\n  };\n\n  return scale;\n}\n\nexport default function linear() {\n  var scale = continuous();\n\n  scale.copy = function() {\n    return copy(scale, linear());\n  };\n\n  initRange.apply(scale, arguments);\n\n  return linearish(scale);\n}\n","import {interpolate, interpolateRound} from \"d3-interpolate\";\nimport {identity} from \"./continuous.js\";\nimport {initInterpolator} from \"./init.js\";\nimport {linearish} from \"./linear.js\";\nimport {loggish} from \"./log.js\";\nimport {symlogish} from \"./symlog.js\";\nimport {powish} from \"./pow.js\";\n\nfunction transformer() {\n  var x0 = 0,\n      x1 = 1,\n      t0,\n      t1,\n      k10,\n      transform,\n      interpolator = identity,\n      clamp = false,\n      unknown;\n\n  function scale(x) {\n    return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? ([x0, x1] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];\n  };\n\n  scale.clamp = function(_) {\n    return arguments.length ? (clamp = !!_, scale) : clamp;\n  };\n\n  scale.interpolator = function(_) {\n    return arguments.length ? (interpolator = _, scale) : interpolator;\n  };\n\n  function range(interpolate) {\n    return function(_) {\n      var r0, r1;\n      return arguments.length ? ([r0, r1] = _, interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];\n    };\n  }\n\n  scale.range = range(interpolate);\n\n  scale.rangeRound = range(interpolateRound);\n\n  scale.unknown = function(_) {\n    return arguments.length ? (unknown = _, scale) : unknown;\n  };\n\n  return function(t) {\n    transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);\n    return scale;\n  };\n}\n\nexport function copy(source, target) {\n  return target\n      .domain(source.domain())\n      .interpolator(source.interpolator())\n      .clamp(source.clamp())\n      .unknown(source.unknown());\n}\n\nexport default function sequential() {\n  var scale = linearish(transformer()(identity));\n\n  scale.copy = function() {\n    return copy(scale, sequential());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialLog() {\n  var scale = loggish(transformer()).domain([1, 10]);\n\n  scale.copy = function() {\n    return copy(scale, sequentialLog()).base(scale.base());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSymlog() {\n  var scale = symlogish(transformer());\n\n  scale.copy = function() {\n    return copy(scale, sequentialSymlog()).constant(scale.constant());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialPow() {\n  var scale = powish(transformer());\n\n  scale.copy = function() {\n    return copy(scale, sequentialPow()).exponent(scale.exponent());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function sequentialSqrt() {\n  return sequentialPow.apply(null, arguments).exponent(0.5);\n}\n","import {interpolate, interpolateRound, piecewise} from \"d3-interpolate\";\nimport {identity} from \"./continuous.js\";\nimport {initInterpolator} from \"./init.js\";\nimport {linearish} from \"./linear.js\";\nimport {loggish} from \"./log.js\";\nimport {copy} from \"./sequential.js\";\nimport {symlogish} from \"./symlog.js\";\nimport {powish} from \"./pow.js\";\n\nfunction transformer() {\n  var x0 = 0,\n      x1 = 0.5,\n      x2 = 1,\n      s = 1,\n      t0,\n      t1,\n      t2,\n      k10,\n      k21,\n      interpolator = identity,\n      transform,\n      clamp = false,\n      unknown;\n\n  function scale(x) {\n    return isNaN(x = +x) ? unknown : (x = 0.5 + ((x = +transform(x)) - t1) * (s * x < s * t1 ? k10 : k21), interpolator(clamp ? Math.max(0, Math.min(1, x)) : x));\n  }\n\n  scale.domain = function(_) {\n    return arguments.length ? ([x0, x1, x2] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), t2 = transform(x2 = +x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1, scale) : [x0, x1, x2];\n  };\n\n  scale.clamp = function(_) {\n    return arguments.length ? (clamp = !!_, scale) : clamp;\n  };\n\n  scale.interpolator = function(_) {\n    return arguments.length ? (interpolator = _, scale) : interpolator;\n  };\n\n  function range(interpolate) {\n    return function(_) {\n      var r0, r1, r2;\n      return arguments.length ? ([r0, r1, r2] = _, interpolator = piecewise(interpolate, [r0, r1, r2]), scale) : [interpolator(0), interpolator(0.5), interpolator(1)];\n    };\n  }\n\n  scale.range = range(interpolate);\n\n  scale.rangeRound = range(interpolateRound);\n\n  scale.unknown = function(_) {\n    return arguments.length ? (unknown = _, scale) : unknown;\n  };\n\n  return function(t) {\n    transform = t, t0 = t(x0), t1 = t(x1), t2 = t(x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1;\n    return scale;\n  };\n}\n\nexport default function diverging() {\n  var scale = linearish(transformer()(identity));\n\n  scale.copy = function() {\n    return copy(scale, diverging());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function divergingLog() {\n  var scale = loggish(transformer()).domain([0.1, 1, 10]);\n\n  scale.copy = function() {\n    return copy(scale, divergingLog()).base(scale.base());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function divergingSymlog() {\n  var scale = symlogish(transformer());\n\n  scale.copy = function() {\n    return copy(scale, divergingSymlog()).constant(scale.constant());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function divergingPow() {\n  var scale = powish(transformer());\n\n  scale.copy = function() {\n    return copy(scale, divergingPow()).exponent(scale.exponent());\n  };\n\n  return initInterpolator.apply(scale, arguments);\n}\n\nexport function divergingSqrt() {\n  return divergingPow.apply(null, arguments).exponent(0.5);\n}\n","export default function(specifier) {\n  var n = specifier.length / 6 | 0, colors = new Array(n), i = 0;\n  while (i < n) colors[i] = \"#\" + specifier.slice(i * 6, ++i * 6);\n  return colors;\n}\n","import colors from \"../colors.js\";\n\nexport default colors(\"1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"4269d0efb118ff725c6cc5b03ca951ff8ab7a463f297bbf59c6b4e9498a0\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f\");\n","import colors from \"../colors.js\";\n\nexport default colors(\"4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab\");\n","import {interpolateRgbBasis} from \"d3-interpolate\";\n\nexport default scheme => interpolateRgbBasis(scheme[scheme.length - 1]);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"d8b365f5f5f55ab4ac\",\n  \"a6611adfc27d80cdc1018571\",\n  \"a6611adfc27df5f5f580cdc1018571\",\n  \"8c510ad8b365f6e8c3c7eae55ab4ac01665e\",\n  \"8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e\",\n  \"8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e\",\n  \"8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e\",\n  \"5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30\",\n  \"5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"af8dc3f7f7f77fbf7b\",\n  \"7b3294c2a5cfa6dba0008837\",\n  \"7b3294c2a5cff7f7f7a6dba0008837\",\n  \"762a83af8dc3e7d4e8d9f0d37fbf7b1b7837\",\n  \"762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837\",\n  \"762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837\",\n  \"762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837\",\n  \"40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b\",\n  \"40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e9a3c9f7f7f7a1d76a\",\n  \"d01c8bf1b6dab8e1864dac26\",\n  \"d01c8bf1b6daf7f7f7b8e1864dac26\",\n  \"c51b7de9a3c9fde0efe6f5d0a1d76a4d9221\",\n  \"c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221\",\n  \"c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221\",\n  \"c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221\",\n  \"8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419\",\n  \"8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"998ec3f7f7f7f1a340\",\n  \"5e3c99b2abd2fdb863e66101\",\n  \"5e3c99b2abd2f7f7f7fdb863e66101\",\n  \"542788998ec3d8daebfee0b6f1a340b35806\",\n  \"542788998ec3d8daebf7f7f7fee0b6f1a340b35806\",\n  \"5427888073acb2abd2d8daebfee0b6fdb863e08214b35806\",\n  \"5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806\",\n  \"2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08\",\n  \"2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"ef8a62f7f7f767a9cf\",\n  \"ca0020f4a58292c5de0571b0\",\n  \"ca0020f4a582f7f7f792c5de0571b0\",\n  \"b2182bef8a62fddbc7d1e5f067a9cf2166ac\",\n  \"b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac\",\n  \"b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac\",\n  \"b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac\",\n  \"67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061\",\n  \"67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"ef8a62ffffff999999\",\n  \"ca0020f4a582bababa404040\",\n  \"ca0020f4a582ffffffbababa404040\",\n  \"b2182bef8a62fddbc7e0e0e09999994d4d4d\",\n  \"b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d\",\n  \"b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d\",\n  \"b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d\",\n  \"67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a\",\n  \"67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fc8d59ffffbf91bfdb\",\n  \"d7191cfdae61abd9e92c7bb6\",\n  \"d7191cfdae61ffffbfabd9e92c7bb6\",\n  \"d73027fc8d59fee090e0f3f891bfdb4575b4\",\n  \"d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4\",\n  \"d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4\",\n  \"d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4\",\n  \"a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695\",\n  \"a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fc8d59ffffbf91cf60\",\n  \"d7191cfdae61a6d96a1a9641\",\n  \"d7191cfdae61ffffbfa6d96a1a9641\",\n  \"d73027fc8d59fee08bd9ef8b91cf601a9850\",\n  \"d73027fc8d59fee08bffffbfd9ef8b91cf601a9850\",\n  \"d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850\",\n  \"d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850\",\n  \"a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837\",\n  \"a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fc8d59ffffbf99d594\",\n  \"d7191cfdae61abdda42b83ba\",\n  \"d7191cfdae61ffffbfabdda42b83ba\",\n  \"d53e4ffc8d59fee08be6f59899d5943288bd\",\n  \"d53e4ffc8d59fee08bffffbfe6f59899d5943288bd\",\n  \"d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd\",\n  \"d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd\",\n  \"9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2\",\n  \"9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e5f5f999d8c92ca25f\",\n  \"edf8fbb2e2e266c2a4238b45\",\n  \"edf8fbb2e2e266c2a42ca25f006d2c\",\n  \"edf8fbccece699d8c966c2a42ca25f006d2c\",\n  \"edf8fbccece699d8c966c2a441ae76238b45005824\",\n  \"f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824\",\n  \"f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e0ecf49ebcda8856a7\",\n  \"edf8fbb3cde38c96c688419d\",\n  \"edf8fbb3cde38c96c68856a7810f7c\",\n  \"edf8fbbfd3e69ebcda8c96c68856a7810f7c\",\n  \"edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b\",\n  \"f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b\",\n  \"f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e0f3dba8ddb543a2ca\",\n  \"f0f9e8bae4bc7bccc42b8cbe\",\n  \"f0f9e8bae4bc7bccc443a2ca0868ac\",\n  \"f0f9e8ccebc5a8ddb57bccc443a2ca0868ac\",\n  \"f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e\",\n  \"f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e\",\n  \"f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fee8c8fdbb84e34a33\",\n  \"fef0d9fdcc8afc8d59d7301f\",\n  \"fef0d9fdcc8afc8d59e34a33b30000\",\n  \"fef0d9fdd49efdbb84fc8d59e34a33b30000\",\n  \"fef0d9fdd49efdbb84fc8d59ef6548d7301f990000\",\n  \"fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000\",\n  \"fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"ece2f0a6bddb1c9099\",\n  \"f6eff7bdc9e167a9cf02818a\",\n  \"f6eff7bdc9e167a9cf1c9099016c59\",\n  \"f6eff7d0d1e6a6bddb67a9cf1c9099016c59\",\n  \"f6eff7d0d1e6a6bddb67a9cf3690c002818a016450\",\n  \"fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450\",\n  \"fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"ece7f2a6bddb2b8cbe\",\n  \"f1eef6bdc9e174a9cf0570b0\",\n  \"f1eef6bdc9e174a9cf2b8cbe045a8d\",\n  \"f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d\",\n  \"f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b\",\n  \"fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b\",\n  \"fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e7e1efc994c7dd1c77\",\n  \"f1eef6d7b5d8df65b0ce1256\",\n  \"f1eef6d7b5d8df65b0dd1c77980043\",\n  \"f1eef6d4b9dac994c7df65b0dd1c77980043\",\n  \"f1eef6d4b9dac994c7df65b0e7298ace125691003f\",\n  \"f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f\",\n  \"f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fde0ddfa9fb5c51b8a\",\n  \"feebe2fbb4b9f768a1ae017e\",\n  \"feebe2fbb4b9f768a1c51b8a7a0177\",\n  \"feebe2fcc5c0fa9fb5f768a1c51b8a7a0177\",\n  \"feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177\",\n  \"fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177\",\n  \"fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"edf8b17fcdbb2c7fb8\",\n  \"ffffcca1dab441b6c4225ea8\",\n  \"ffffcca1dab441b6c42c7fb8253494\",\n  \"ffffccc7e9b47fcdbb41b6c42c7fb8253494\",\n  \"ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84\",\n  \"ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84\",\n  \"ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"f7fcb9addd8e31a354\",\n  \"ffffccc2e69978c679238443\",\n  \"ffffccc2e69978c67931a354006837\",\n  \"ffffccd9f0a3addd8e78c67931a354006837\",\n  \"ffffccd9f0a3addd8e78c67941ab5d238443005a32\",\n  \"ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32\",\n  \"ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fff7bcfec44fd95f0e\",\n  \"ffffd4fed98efe9929cc4c02\",\n  \"ffffd4fed98efe9929d95f0e993404\",\n  \"ffffd4fee391fec44ffe9929d95f0e993404\",\n  \"ffffd4fee391fec44ffe9929ec7014cc4c028c2d04\",\n  \"ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04\",\n  \"ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"ffeda0feb24cf03b20\",\n  \"ffffb2fecc5cfd8d3ce31a1c\",\n  \"ffffb2fecc5cfd8d3cf03b20bd0026\",\n  \"ffffb2fed976feb24cfd8d3cf03b20bd0026\",\n  \"ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026\",\n  \"ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026\",\n  \"ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"deebf79ecae13182bd\",\n  \"eff3ffbdd7e76baed62171b5\",\n  \"eff3ffbdd7e76baed63182bd08519c\",\n  \"eff3ffc6dbef9ecae16baed63182bd08519c\",\n  \"eff3ffc6dbef9ecae16baed64292c62171b5084594\",\n  \"f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594\",\n  \"f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"e5f5e0a1d99b31a354\",\n  \"edf8e9bae4b374c476238b45\",\n  \"edf8e9bae4b374c47631a354006d2c\",\n  \"edf8e9c7e9c0a1d99b74c47631a354006d2c\",\n  \"edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32\",\n  \"f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32\",\n  \"f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"f0f0f0bdbdbd636363\",\n  \"f7f7f7cccccc969696525252\",\n  \"f7f7f7cccccc969696636363252525\",\n  \"f7f7f7d9d9d9bdbdbd969696636363252525\",\n  \"f7f7f7d9d9d9bdbdbd969696737373525252252525\",\n  \"fffffff0f0f0d9d9d9bdbdbd969696737373525252252525\",\n  \"fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"efedf5bcbddc756bb1\",\n  \"f2f0f7cbc9e29e9ac86a51a3\",\n  \"f2f0f7cbc9e29e9ac8756bb154278f\",\n  \"f2f0f7dadaebbcbddc9e9ac8756bb154278f\",\n  \"f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486\",\n  \"fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486\",\n  \"fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fee0d2fc9272de2d26\",\n  \"fee5d9fcae91fb6a4acb181d\",\n  \"fee5d9fcae91fb6a4ade2d26a50f15\",\n  \"fee5d9fcbba1fc9272fb6a4ade2d26a50f15\",\n  \"fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d\",\n  \"fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d\",\n  \"fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d\"\n).map(colors);\n\nexport default ramp(scheme);\n","import colors from \"../colors.js\";\nimport ramp from \"../ramp.js\";\n\nexport var scheme = new Array(3).concat(\n  \"fee6cefdae6be6550d\",\n  \"feeddefdbe85fd8d3cd94701\",\n  \"feeddefdbe85fd8d3ce6550da63603\",\n  \"feeddefdd0a2fdae6bfd8d3ce6550da63603\",\n  \"feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04\",\n  \"fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04\",\n  \"fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704\"\n).map(colors);\n\nexport default ramp(scheme);\n","export default function(t) {\n  t = Math.max(0, Math.min(1, t));\n  return \"rgb(\"\n      + Math.max(0, Math.min(255, Math.round(-4.54 - t * (35.34 - t * (2381.73 - t * (6402.7 - t * (7024.72 - t * 2710.57))))))) + \", \"\n      + Math.max(0, Math.min(255, Math.round(32.49 + t * (170.73 + t * (52.82 - t * (131.46 - t * (176.58 - t * 67.37))))))) + \", \"\n      + Math.max(0, Math.min(255, Math.round(81.24 + t * (442.36 - t * (2482.43 - t * (6167.24 - t * (6614.94 - t * 2475.67)))))))\n      + \")\";\n}\n","import {cubehelix} from \"d3-color\";\nimport {interpolateCubehelixLong} from \"d3-interpolate\";\n\nexport default interpolateCubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));\n","import {cubehelix} from \"d3-color\";\nimport {interpolateCubehelixLong} from \"d3-interpolate\";\n\nexport var warm = interpolateCubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nexport var cool = interpolateCubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));\n\nvar c = cubehelix();\n\nexport default function(t) {\n  if (t < 0 || t > 1) t -= Math.floor(t);\n  var ts = Math.abs(t - 0.5);\n  c.h = 360 * t - 100;\n  c.s = 1.5 - 1.5 * ts;\n  c.l = 0.8 - 0.9 * ts;\n  return c + \"\";\n}\n","import {rgb} from \"d3-color\";\n\nvar c = rgb(),\n    pi_1_3 = Math.PI / 3,\n    pi_2_3 = Math.PI * 2 / 3;\n\nexport default function(t) {\n  var x;\n  t = (0.5 - t) * Math.PI;\n  c.r = 255 * (x = Math.sin(t)) * x;\n  c.g = 255 * (x = Math.sin(t + pi_1_3)) * x;\n  c.b = 255 * (x = Math.sin(t + pi_2_3)) * x;\n  return c + \"\";\n}\n","export default function(t) {\n  t = Math.max(0, Math.min(1, t));\n  return \"rgb(\"\n      + Math.max(0, Math.min(255, Math.round(34.61 + t * (1172.33 - t * (10793.56 - t * (33300.12 - t * (38394.49 - t * 14825.05))))))) + \", \"\n      + Math.max(0, Math.min(255, Math.round(23.31 + t * (557.33 + t * (1225.33 - t * (3574.96 - t * (1073.77 + t * 707.56))))))) + \", \"\n      + Math.max(0, Math.min(255, Math.round(27.2 + t * (3211.1 - t * (15327.97 - t * (27814 - t * (22569.18 - t * 6838.66)))))))\n      + \")\";\n}\n","import colors from \"../colors.js\";\n\nfunction ramp(range) {\n  var n = range.length;\n  return function(t) {\n    return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];\n  };\n}\n\nexport default ramp(colors(\"44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725\"));\n\nexport var magma = ramp(colors(\"00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf\"));\n\nexport var inferno = ramp(colors(\"00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4\"));\n\nexport var plasma = ramp(colors(\"0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921\"));\n","export {default as schemeCategory10} from \"./categorical/category10.js\";\nexport {default as schemeAccent} from \"./categorical/Accent.js\";\nexport {default as schemeDark2} from \"./categorical/Dark2.js\";\nexport {default as schemeObservable10} from \"./categorical/observable10.js\";\nexport {default as schemePaired} from \"./categorical/Paired.js\";\nexport {default as schemePastel1} from \"./categorical/Pastel1.js\";\nexport {default as schemePastel2} from \"./categorical/Pastel2.js\";\nexport {default as schemeSet1} from \"./categorical/Set1.js\";\nexport {default as schemeSet2} from \"./categorical/Set2.js\";\nexport {default as schemeSet3} from \"./categorical/Set3.js\";\nexport {default as schemeTableau10} from \"./categorical/Tableau10.js\";\nexport {default as interpolateBrBG, scheme as schemeBrBG} from \"./diverging/BrBG.js\";\nexport {default as interpolatePRGn, scheme as schemePRGn} from \"./diverging/PRGn.js\";\nexport {default as interpolatePiYG, scheme as schemePiYG} from \"./diverging/PiYG.js\";\nexport {default as interpolatePuOr, scheme as schemePuOr} from \"./diverging/PuOr.js\";\nexport {default as interpolateRdBu, scheme as schemeRdBu} from \"./diverging/RdBu.js\";\nexport {default as interpolateRdGy, scheme as schemeRdGy} from \"./diverging/RdGy.js\";\nexport {default as interpolateRdYlBu, scheme as schemeRdYlBu} from \"./diverging/RdYlBu.js\";\nexport {default as interpolateRdYlGn, scheme as schemeRdYlGn} from \"./diverging/RdYlGn.js\";\nexport {default as interpolateSpectral, scheme as schemeSpectral} from \"./diverging/Spectral.js\";\nexport {default as interpolateBuGn, scheme as schemeBuGn} from \"./sequential-multi/BuGn.js\";\nexport {default as interpolateBuPu, scheme as schemeBuPu} from \"./sequential-multi/BuPu.js\";\nexport {default as interpolateGnBu, scheme as schemeGnBu} from \"./sequential-multi/GnBu.js\";\nexport {default as interpolateOrRd, scheme as schemeOrRd} from \"./sequential-multi/OrRd.js\";\nexport {default as interpolatePuBuGn, scheme as schemePuBuGn} from \"./sequential-multi/PuBuGn.js\";\nexport {default as interpolatePuBu, scheme as schemePuBu} from \"./sequential-multi/PuBu.js\";\nexport {default as interpolatePuRd, scheme as schemePuRd} from \"./sequential-multi/PuRd.js\";\nexport {default as interpolateRdPu, scheme as schemeRdPu} from \"./sequential-multi/RdPu.js\";\nexport {default as interpolateYlGnBu, scheme as schemeYlGnBu} from \"./sequential-multi/YlGnBu.js\";\nexport {default as interpolateYlGn, scheme as schemeYlGn} from \"./sequential-multi/YlGn.js\";\nexport {default as interpolateYlOrBr, scheme as schemeYlOrBr} from \"./sequential-multi/YlOrBr.js\";\nexport {default as interpolateYlOrRd, scheme as schemeYlOrRd} from \"./sequential-multi/YlOrRd.js\";\nexport {default as interpolateBlues, scheme as schemeBlues} from \"./sequential-single/Blues.js\";\nexport {default as interpolateGreens, scheme as schemeGreens} from \"./sequential-single/Greens.js\";\nexport {default as interpolateGreys, scheme as schemeGreys} from \"./sequential-single/Greys.js\";\nexport {default as interpolatePurples, scheme as schemePurples} from \"./sequential-single/Purples.js\";\nexport {default as interpolateReds, scheme as schemeReds} from \"./sequential-single/Reds.js\";\nexport {default as interpolateOranges, scheme as schemeOranges} from \"./sequential-single/Oranges.js\";\nexport {default as interpolateCividis} from \"./sequential-multi/cividis.js\";\nexport {default as interpolateCubehelixDefault} from \"./sequential-multi/cubehelix.js\";\nexport {default as interpolateRainbow, warm as interpolateWarm, cool as interpolateCool} from \"./sequential-multi/rainbow.js\";\nexport {default as interpolateSinebow} from \"./sequential-multi/sinebow.js\";\nexport {default as interpolateTurbo} from \"./sequential-multi/turbo.js\";\nexport {default as interpolateViridis, magma as interpolateMagma, inferno as interpolateInferno, plasma as interpolatePlasma} from \"./sequential-multi/viridis.js\";\n","/**\n * @module ColorMap\n * Color-domain resolution, sampling, and legend-label utilities.\n *\n * This module centralizes the logic for turning raw numeric or categorical\n * inputs into resolved color-map domains, d3-backed interpolators, GPU-ready\n * texture data, and human-readable legend labels. It also exposes helpers for\n * converting between RGB and hex representations.\n */\nimport * as d3_color from 'd3-color';\nimport * as d3_format from 'd3-format';\nimport * as d3_scale from 'd3-scale';\nimport * as d3_scheme from 'd3-scale-chromatic';\n\nimport {\n    ColorMapDomainStrategy,\n    ColorMapConfig,\n    ColorHEX,\n    ColorMapInterpolator,\n    ResolvedDomain,\n    ColorRGB,\n    ColorTEX,\n} from './types-colormap';\n\nimport type { TypedArray } from './types-buffer';\n\n/** Two-point numeric domain used by sequential color interpolators. */\nexport type SequentialDomain = [number, number];\n/** Three-point numeric domain used by diverging color interpolators. */\nexport type DivergingDomain = [number, number, number];\n/** Ordered set of category labels used by categorical color schemes. */\nexport type CategoricalDomain = string[];\n\n/** Default number of texels used to sample continuous color maps. */\nexport const DEFAULT_COLORMAP_RESOLUTION = 256;\n\n/** Interpolators backed by discrete categorical color schemes. */\nconst CATEGORICAL_INTERPOLATORS = new Set<ColorMapInterpolator>([\n    ColorMapInterpolator.CAT_ACCENT,\n    ColorMapInterpolator.CAT_DARK2,\n    ColorMapInterpolator.CAT_CATEGORY10,\n    ColorMapInterpolator.CAT_OBSERVABLE10,\n    ColorMapInterpolator.CAT_PAIRED,\n    ColorMapInterpolator.CAT_PASTEL1,\n    ColorMapInterpolator.CAT_PASTEL2,\n    ColorMapInterpolator.CAT_SET1,\n    ColorMapInterpolator.CAT_SET2,\n    ColorMapInterpolator.CAT_SET3,\n    ColorMapInterpolator.CAT_TABLEAU10,\n]);\n\n/** Interpolators backed by diverging continuous color scales. */\nconst DIVERGING_INTERPOLATORS = new Set<ColorMapInterpolator>([\n    ColorMapInterpolator.DIV_BR_BG,\n    ColorMapInterpolator.DIV_PR_GN,\n    ColorMapInterpolator.DIV_PI_YG,\n    ColorMapInterpolator.DIV_PU_OR,\n    ColorMapInterpolator.DIV_RED_BLUE,\n    ColorMapInterpolator.DIV_RED_GREY,\n    ColorMapInterpolator.DIV_RED_YELLOW_BLUE,\n    ColorMapInterpolator.DIV_RED_YELLOW_GREEN,\n    ColorMapInterpolator.DIV_SPECTRAL,\n]);\n\n/**\n * Color utility for resolving domains, sampling color scales, and building\n * legend and texture representations.\n *\n * `ColorMap` decides whether a scheme should be treated as categorical,\n * sequential, or diverging; derives a compatible domain from data and\n * configuration; and exposes helpers for sampling colors or generating flat\n * RGBA textures for GPU upload.\n */\nexport class ColorMap {\n    /**\n     * Samples a color interpolator at a normalized value, returning RGBA.\n     *\n     * @param value - Normalized sample position in `[0, 1]`.\n     * @param color - Interpolator identifier to sample.\n     * @param domain - Optional explicit domain used to parameterize the scale.\n     * @returns Sampled color in RGBA object form.\n     * @throws Never throws.\n     * @example\n     * const c = ColorMap.getColor(0.5, ColorMapInterpolator.SEQ_VIRIDIS);\n     * // c → { r: 33, g: 144, b: 141, alpha: 1 }\n     */\n    public static getColor(value: number, color: ColorMapInterpolator, domain?: SequentialDomain | DivergingDomain | CategoricalDomain): ColorRGB {\n        const interpolator = ColorMap.buildInterpolator(color, domain);\n        const { r, g, b } = d3_color.rgb(interpolator(value));\n        return { r, g, b, alpha: 1 };\n    }\n\n    /**\n     * Builds a flat RGBA texture array for GPU upload from a color scheme.\n     *\n     * @param color - Interpolator identifier to sample.\n     * @param res - Number of texels to generate (default `256`).\n     * @param domain - Optional explicit domain used to parameterize the scale.\n     * @returns Flat RGBA texture values `[r, g, b, a, ...]`.\n     * @throws Never throws. Non-positive `res` returns an empty array.\n     * @example\n     * const tex = ColorMap.getColorMap(ColorMapInterpolator.SEQ_VIRIDIS, 4);\n     * // tex → [68, 1, 84, 1, 59, 82, 139, 1, 33, 144, 141, 1, 253, 231, 37, 1]\n     */\n    public static getColorMap(\n        color: ColorMapInterpolator,\n        res: number = DEFAULT_COLORMAP_RESOLUTION,\n        domain?: SequentialDomain | DivergingDomain | CategoricalDomain,\n    ): ColorTEX {\n        if (res <= 0) { return []; }\n        if (res === 1) {\n            const { r, g, b } = d3_color.rgb(ColorMap.buildInterpolator(color, domain)(0.5));\n            return [r, g, b, 1];\n        }\n\n        const interpolator = ColorMap.buildInterpolator(color, domain);\n        const tex: number[] = [];\n        for (let id = 0; id < res; id++) {\n            const { r, g, b } = d3_color.rgb(interpolator(id / (res - 1)));\n            tex.push(r, g, b, 1);\n        }\n        return tex;\n    }\n\n    /**\n     * Builds an array of sampled RGBA color objects from a color scheme.\n     *\n     * @param color - Interpolator identifier to sample.\n     * @param res - Number of samples to generate (default `256`).\n     * @param domain - Optional explicit domain used to parameterize the scale.\n     * @returns Array of sampled RGBA color objects.\n     * @throws Never throws. Non-positive `res` returns an empty array.\n     * @example\n     * const colors = ColorMap.getColorArray(ColorMapInterpolator.CAT_SET1, 3);\n     * // colors → [{ r: 228, g: 26, b: 28, alpha: 1 }, ...]\n     */\n    public static getColorArray(\n        color: ColorMapInterpolator,\n        res: number = DEFAULT_COLORMAP_RESOLUTION,\n        domain?: SequentialDomain | DivergingDomain | CategoricalDomain,\n    ): ColorRGB[] {\n        if (res <= 0) { return []; }\n        if (res === 1) {\n            const { r, g, b } = d3_color.rgb(ColorMap.buildInterpolator(color, domain)(0.5));\n            return [{ r, g, b, alpha: 1 }];\n        }\n\n        const interpolator = ColorMap.buildInterpolator(color, domain);\n        const result: ColorRGB[] = [];\n        for (let id = 0; id < res; id++) {\n            const { r, g, b } = d3_color.rgb(interpolator(id / (res - 1)));\n            result.push({ r, g, b, alpha: 1 });\n        }\n        return result;\n    }\n\n    /**\n     * Converts an RGBA color object into a hex color string.\n     *\n     * @param color - RGB color to convert.\n     * @returns Hexadecimal color string.\n     * @throws Never throws.\n     * @example\n     * ColorMap.rgbToHex({ r: 255, g: 128, b: 0, alpha: 1 }); // '#ff8000'\n     */\n    public static rgbToHex(color: ColorRGB): ColorHEX {\n        const hex = d3_color.rgb(color.r, color.g, color.b, 1).formatHex();\n        return <ColorHEX>hex;\n    }\n\n    /**\n     * Converts a hex color string into an RGBA color object.\n     *\n     * @param color - Hexadecimal color string to convert.\n     * @returns RGBA color object with alpha fixed to `1`.\n     * @throws Never throws.\n     * @example\n     * ColorMap.hexToRgb('#ff8000'); // { r: 255, g: 128, b: 0, alpha: 1 }\n     */\n    public static hexToRgb(color: ColorHEX): ColorRGB {\n        const rgb = d3_color.rgb(color);\n        return { r: rgb.r, g: rgb.g, b: rgb.b, alpha: 1.0 };\n    }\n\n    /**\n     * Computes the numeric minimum and maximum of a value array.\n     *\n     * @param values - Numeric values to inspect.\n     * @returns Two-element tuple `[min, max]`, or `[0, 0]` when the input is empty.\n     * @throws Never throws. Empty input returns `[0, 0]`.\n     * @example\n     * ColorMap.computeMinMaxRange([3, 7, 2, 9, 4]); // [2, 9]\n     */\n    public static computeMinMaxRange(values: number[] | TypedArray): [number, number] {\n        if (values.length === 0) return [0, 0];\n        let min = Infinity;\n        let max = -Infinity;\n        for (let i = 0; i < values.length; i++) {\n            const v = values[i];\n            if (v < min) min = v;\n            if (v > max) max = v;\n        }\n        return [min, max];\n    }\n\n    /**\n     * Returns `true` when an interpolator uses a discrete categorical scheme.\n     *\n     * @param interpolator - Interpolator identifier to classify.\n     * @returns `true` for categorical schemes, otherwise `false`.\n     * @throws Never throws.\n     * @example\n     * ColorMap.isCategorical(ColorMapInterpolator.CAT_SET1);  // true\n     * ColorMap.isCategorical(ColorMapInterpolator.SEQ_VIRIDIS);  // false\n     */\n    public static isCategorical(interpolator: ColorMapInterpolator): boolean {\n        return CATEGORICAL_INTERPOLATORS.has(interpolator);\n    }\n    \n    /**\n     * Returns `true` when an interpolator uses a diverging continuous scale.\n     *\n     * @param interpolator - Interpolator identifier to classify.\n     * @returns `true` for diverging interpolators, otherwise `false`.\n     * @throws Never throws.\n     */\n    private static isDiverging(interpolator: ColorMapInterpolator): boolean {\n        return DIVERGING_INTERPOLATORS.has(interpolator);\n    }\n\n    /**\n     * Returns the number of colors in a categorical color scheme.\n     *\n     * @param interpolator - Interpolator identifier to inspect.\n     * @returns Scheme size for categorical interpolators, or `null` otherwise.\n     * @throws Never throws.\n     * @example\n     * ColorMap.getCategoricalSchemeSize(ColorMapInterpolator.CAT_SET1);  // 9\n     * ColorMap.getCategoricalSchemeSize(ColorMapInterpolator.SEQ_VIRIDIS);  // null\n     */\n    public static getCategoricalSchemeSize(interpolator: ColorMapInterpolator): number | null {\n        if (!ColorMap.isCategorical(interpolator)) return null;\n        return (d3_scheme[interpolator] as string[]).length;\n    }\n\n\n    /**\n     * Resolves a numeric domain from data and color-map configuration.\n     *\n     * USER domains must contain finite numbers and must match the interpolator\n     * shape: sequential schemes require at least two values, while diverging\n     * schemes accept either two endpoints or an explicit three-point domain.\n     * Percentile resolution ignores non-finite values. When no finite values are\n     * available, sequential schemes fall back to `[0, 0]` and diverging schemes\n     * fall back to `[0, 0, 0]`.\n     *\n     * @param values - Numeric input values used to derive the domain.\n     * @param config - Color-map configuration controlling the domain strategy.\n     * @param interpolator - Interpolator used to decide sequential vs diverging behavior.\n     * @returns Resolved sequential or diverging numeric domain.\n     */\n    private static resolveNumericDomainFromConfig(\n        values: number[] | TypedArray,\n        config: ColorMapConfig,\n        interpolator: ColorMapInterpolator,\n    ): SequentialDomain | DivergingDomain {\n        const mode = config.domainSpec.type;\n\n        if (mode === ColorMapDomainStrategy.USER) {\n            const params = config.domainSpec.params;\n            if (!params.length || params.some(v => typeof v !== 'number' || !Number.isFinite(v))) {\n                throw new Error('ColorMap USER domain for numeric interpolators must be number[].');\n            }\n            const numeric = params as number[];\n            if (ColorMap.isDiverging(interpolator)) {\n                if (numeric.length === 3) return [numeric[0], numeric[1], numeric[2]];\n                if (numeric.length === 2) {\n                    const center = (numeric[0] + numeric[1]) / 2;\n                    return [numeric[0], center, numeric[1]];\n                }\n                throw new Error('Diverging USER domain must have 2 or 3 numeric values.');\n            }\n            if (numeric.length < 2) {\n                throw new Error('Sequential USER domain must have at least 2 numeric values.');\n            }\n            return [numeric[0], numeric[numeric.length - 1]];\n        }\n\n        const finiteValues = (ArrayBuffer.isView(values) ? Array.from(values) : values)\n            .filter((value) => Number.isFinite(value));\n\n        if (finiteValues.length === 0) {\n            return ColorMap.isDiverging(interpolator) ? [0, 0, 0] : [0, 0];\n        }\n\n        if (mode === ColorMapDomainStrategy.PERCENTILE) {\n            const [lowerPercentile, upperPercentile] = config.domainSpec.params ?? [2, 98];\n            const low = ColorMap.computePercentile(finiteValues, lowerPercentile / 100);\n            const high = ColorMap.computePercentile(finiteValues, upperPercentile / 100);\n            if (ColorMap.isDiverging(interpolator)) {\n                const center = ColorMap.computePercentile(finiteValues, 50 / 100);\n                return [low, center, high];\n            }\n            return [low, high];\n        }\n\n        const [min, max] = ColorMap.computeMinMaxRange(finiteValues);\n        if (ColorMap.isDiverging(interpolator)) {\n            const center = (min + max) / 2;\n            return [min, center, max];\n        }\n        return [min, max];\n    }\n\n    /**\n     * Resolves a categorical domain from a color-map configuration.\n     *\n     * USER domains are used verbatim after string conversion. Data-derived\n     * domains preserve first-seen order and remove duplicates.\n     *\n     * @param values - Input category values.\n     * @param config - Color-map configuration controlling the domain strategy.\n     * @returns Ordered categorical domain labels.\n     */\n    private static resolveCategoricalDomainFromConfig(\n        values: string[],\n        config: ColorMapConfig,\n    ): CategoricalDomain {\n        if (config.domainSpec.type === ColorMapDomainStrategy.USER) {\n            return config.domainSpec.params.map(v => String(v));\n        }\n        return Array.from(new Set(values.map(v => String(v))));\n    }\n\n    /**\n     * Derives human-readable legend labels from a domain.\n     *\n     * Categorical domains are returned as-is. Numeric domains are formatted\n     * with a magnitude-aware d3 formatter so legend labels remain compact for\n     * large values and readable for small decimals.\n     *\n     * @param domain Any supported color-scale domain.\n     * @returns Ordered label strings suitable for a legend.\n     * @throws Never throws.\n     * @example\n     * ColorMap.computeLabels([0, 500000, 1000000]); // ['0', '500,000', '1M']\n     * ColorMap.computeLabels(['low', 'mid', 'high']); // ['low', 'mid', 'high']\n     */\n    public static computeLabels(\n        domain: ResolvedDomain,\n    ): string[] {\n        if (typeof domain[0] === 'string') return domain as string[];\n\n        const numeric = domain as number[];\n        const maxAbs = numeric.reduce((acc, v) => Math.max(acc, Math.abs(v)), 0);\n        const formatter = maxAbs >= 1_000_000\n            ? d3_format.format('.3s')\n            : maxAbs >= 1\n                ? d3_format.format(',.2f')\n                : d3_format.format('.3~g');\n\n        return numeric.map(v => formatter(v));\n    }\n\n    /**\n     * Resolves a color domain from data and configuration.\n     *\n     * The method infers categorical handling when the selected interpolator is\n     * categorical, when a USER domain contains string values, or when the input\n     * array contains non-numeric strings. Numeric-looking strings in normal\n     * arrays are still treated as numeric values. Unsupported domain shapes are\n     * not coerced beyond this inference.\n     *\n     * @param values - Source values used to derive the domain.\n     * @param config - Color-map configuration controlling the resolution mode.\n     * @returns Resolved categorical or numeric domain.\n     * @throws {Error} When USER domain has invalid shape for the selected\n     * interpolator (e.g. non-numeric values for a sequential interpolator).\n     * @example\n     * const domain = ColorMap.resolveDomainFromData(\n     *   [10, 50, 30, 80, 20],\n     *   { interpolator: ColorMapInterpolator.SEQ_VIRIDIS, domainSpec: { type: ColorMapDomainStrategy.MIN_MAX } }\n     * );\n     * // domain → [10, 80]\n     */\n    public static resolveDomainFromData(\n        values: number[] | string[] | TypedArray,\n        config: ColorMapConfig,\n    ): ResolvedDomain {\n        const isCategorical = ColorMap.isCategorical(config.interpolator)\n            || (config.domainSpec.type === ColorMapDomainStrategy.USER && config.domainSpec.params.some(v => typeof v === 'string'))\n            || (!ArrayBuffer.isView(values) && (values as Array<number|string>).some(v => typeof v === 'string' && isNaN(Number(v))));\n\n        if (isCategorical) {\n            return ColorMap.resolveCategoricalDomainFromConfig(values as string[], config);\n        } else {\n            return ColorMap.resolveNumericDomainFromConfig(values as number[] | TypedArray, config, config.interpolator);\n        }\n    }\n\n    /**\n     * Builds a d3-compatible interpolator function for the requested color scheme.\n     *\n     * Categorical schemes map values by index into the underlying d3 scheme.\n     * When no domain is provided, the full categorical scheme length is used.\n     * Diverging scales default to `[0, 0.5, 1]` and sequential scales default to\n     * `[0, 1]`.\n     *\n     * @param color - Interpolator identifier to build.\n     * @param domain - Optional explicit domain used to parameterize the scale.\n     * @returns Function that maps normalized scalar values to CSS color strings.\n     */\n    private static buildInterpolator(\n        color: ColorMapInterpolator,\n        domain?: SequentialDomain | DivergingDomain | CategoricalDomain,\n    ): (t: number) => string {\n        if (ColorMap.isCategorical(color)) {\n            const scheme = d3_scheme[color] as string[];\n            const n = domain?.length ?? scheme.length;\n            return (t: number) => {\n                const idx = Math.min(Math.round(t * (n - 1)), scheme.length - 1);\n                return scheme[idx];\n            };\n        }\n\n        if (ColorMap.isDiverging(color)) {\n            return d3_scale.scaleDiverging(d3_scheme[color] as (t: number) => string)\n                .domain((domain as DivergingDomain) ?? [0, 0.5, 1]);\n        }\n\n        return d3_scale.scaleSequential(d3_scheme[color] as (t: number) => string)\n            .domain((domain as SequentialDomain) ?? [0, 1]);\n    }\n\n    /**\n     * Computes a percentile value from a numeric array.\n     *\n     * @param values - Numeric values to sample.\n     * @param p - Percentile in normalized `[0, 1]` form.\n     * @returns Interpolated percentile value, or `0` for empty input.\n     */\n    private static computePercentile(values: number[] | TypedArray, p: number): number {\n        if (values.length === 0) return 0;\n        const sorted = (ArrayBuffer.isView(values) ? new Float32Array(values) : [...values]).sort((a, b) => a - b);\n        const idx = p * (sorted.length - 1);\n        const lo = Math.floor(idx);\n        const hi = Math.ceil(idx);\n        return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);\n    }\n}\n","/**\n * @module TransferFunction\n * Utilities for mapping scalar data values to opacity.\n *\n * This module defines the transfer-function configuration, resolved runtime\n * context, and alpha evaluation used by raster rendering. It resolves default\n * options once, precomputes dataset statistics, and converts scalar values into\n * 8-bit opacity values while treating `NaN` as transparent.\n */\n\n/**\n * Configures how scalar values map to opacity.\n *\n * The active mode determines which values receive higher opacity after the\n * input values are normalized against the current transfer context.\n */\nexport interface TransferFunction {\n    /**\n     * Opacity mapping mode.\n     *\n     * - `near-zero`: values closer to `zeroCenter` are more opaque.\n     * - `far-zero`: values farther from `zeroCenter` are more opaque.\n     * - `linear`: opacity increases monotonically across the dataset range.\n     */\n    mode?: 'near-zero' | 'far-zero' | 'linear';\n    /** Lower bound for output opacity in `[0, 1]`. */\n    opacityMin?: number;\n    /** Upper bound for output opacity in `[0, 1]`. */\n    opacityMax?: number;\n    /** Curve shaping factor; values `<= 0` are clamped to a tiny positive exponent at evaluation time. */\n    gamma?: number;\n    /** Reference center used by zero-distance modes (default `0`). */\n    zeroCenter?: number;\n}\n\n/**\n * Transfer-function configuration with all optional fields resolved.\n *\n * This is the shape used by `buildTransferContext` and `computeAlphaByte`\n * after user overrides have been merged with the defaults.\n */\nexport type RequiredTransferFunction = Required<TransferFunction>;\n\n/**\n * Default transfer-function configuration merged into user options before\n * evaluation.\n */\nexport const DEFAULT_TRANSFER_FUNCTION: RequiredTransferFunction = {\n    mode: 'far-zero',\n    opacityMin: 0,\n    opacityMax: 1,\n    gamma: 1,\n    zeroCenter: 0,\n};\n\n/**\n * Precomputed transfer-function context for efficient per-value alpha mapping.\n */\nexport interface TransferContext {\n    /** Minimum scalar value found among valid source values. */\n    min: number;\n    /** Maximum scalar value found among valid source values. */\n    max: number;\n    /** Difference between `max` and `min`. */\n    range: number;\n    /** Maximum absolute distance from `config.zeroCenter`. */\n    maxAbsDistance: number;\n    /** Number of valid scalar values used to build the context. */\n    validCount: number;\n    /** Fully resolved transfer-function configuration used during evaluation. */\n    config: RequiredTransferFunction;\n}\n\n/**\n * Builds a transfer-function context from valid scalar values.\n *\n * The returned context caches dataset bounds and the resolved configuration so\n * repeated alpha evaluation does not need to recompute them. When `values` is\n * empty, the context is zeroed and `validCount` is `0`; callers can still use it\n * for evaluation, but the output will fall back to the configured opacity range\n * for the selected mode.\n *\n * @param values - Valid scalar values used to derive dataset statistics.\n * @param config - Optional transfer-function overrides applied on top of defaults.\n * @returns Precomputed transfer-function context for repeated alpha evaluation.\n * @throws Never throws. Empty input produces a zeroed context.\n * @example\n * const ctx = buildTransferContext([0.1, 0.5, 0.3, 0.9], { mode: 'linear' });\n * // ctx.min → 0.1, ctx.max → 0.9, ctx.config.mode → 'linear'\n */\nexport function buildTransferContext(\n    values: number[],\n    config?: TransferFunction,\n): TransferContext {\n    const resolvedConfig: RequiredTransferFunction = {\n        ...DEFAULT_TRANSFER_FUNCTION,\n        ...config,\n    };\n\n    if (values.length === 0) {\n        return {\n            min: 0,\n            max: 0,\n            range: 0,\n            maxAbsDistance: 0,\n            validCount: 0,\n            config: resolvedConfig,\n        };\n    }\n\n    const min = values.reduce((a, b) => Math.min(a, b), Infinity);\n    const max = values.reduce((a, b) => Math.max(a, b), -Infinity);\n    const range = max - min;\n    const maxAbsDistance = values.reduce(\n        (acc, v) => Math.max(acc, Math.abs(v - resolvedConfig.zeroCenter)),\n        0,\n    );\n\n    return {\n        min,\n        max,\n        range,\n        maxAbsDistance,\n        validCount: values.length,\n        config: resolvedConfig,\n    };\n}\n\n/**\n * Computes alpha as an 8-bit channel value for a scalar value.\n *\n * `NaN` values are always mapped to `0` (transparent). The mapping uses the\n * precomputed context bounds and the resolved transfer-function configuration,\n * applies gamma shaping when `config.gamma` differs from `1`, and clamps the\n * result to the byte range `[0, 255]`.\n *\n * @param value - Scalar value to map into an alpha byte.\n * @param context - Precomputed transfer-function context from `buildTransferContext`.\n * @returns Alpha channel value in the integer range `[0, 255]`.\n * @throws Never throws. Returns `0` for `NaN` input.\n * @example\n * const ctx = buildTransferContext([0, 100], { mode: 'linear' });\n * computeAlphaByte(50, ctx);  // → 128 (midpoint)\n * computeAlphaByte(NaN, ctx); // → 0   (transparent)\n */\nexport function computeAlphaByte(value: number, context: TransferContext): number {\n    if (isNaN(value)) {\n        return 0;\n    }\n\n    const { config, range, min, maxAbsDistance } = context;\n\n    let t: number;\n    if (config.mode === 'linear') {\n        t = range > 0 ? (value - min) / range : 0;\n    }\n    else if (config.mode === 'far-zero') {\n        t = maxAbsDistance > 0 ? Math.abs(value - config.zeroCenter) / maxAbsDistance : 0;\n    }\n    else {\n        // near-zero: higher opacity for values closer to zeroCenter.\n        t = maxAbsDistance > 0 ? 1 - (Math.abs(value - config.zeroCenter) / maxAbsDistance) : 1;\n    }\n\n    const clampedT = Math.max(0, Math.min(1, t));\n    const shaped = Math.pow(clampedT, Math.max(0.0001, config.gamma));\n    const opacity = config.opacityMin + (config.opacityMax - config.opacityMin) * shaped;\n    return Math.max(0, Math.min(255, Math.round(opacity * 255)));\n}\n","/**\n * @module triangulator-points\n * Point geometry helpers for GeoJSON features.\n *\n * This module converts point-bearing GeoJSON into packed point-instance\n * centers for sprite-style rendering in `autk-map`.\n *\n * Coordinates are always shifted into local space using the shared origin.\n */\n\nimport {\n    FeatureCollection,\n    Feature,\n    GeometryCollection\n} from 'geojson';\n\nimport { LayerComponent } from './types-mesh';\n\nexport interface PointInstancesData {\n    instances: Float32Array;\n    components: LayerComponent[];\n}\n\n/**\n * Converts point-based GeoJSON features into packed point instances.\n *\n * The class walks a feature collection in order and supports `Point`,\n * `MultiPoint`, and point-bearing `GeometryCollection` geometries while\n * skipping unsupported features with a warning.\n */\nexport class TriangulatorPoints {\n    /**\n     * Builds point-instance data for a feature collection.\n     *\n     * @param geojson - Source feature collection containing point geometries.\n     * @param origin - World-space origin used to convert coordinates into local XY space.\n     * @returns Packed instance centers and per-feature component metadata.\n     * @throws Never throws. Unsupported features are skipped with a console warning.\n     */\n    static buildInstances(geojson: FeatureCollection, origin: number[]): PointInstancesData {\n        const instances: number[] = [];\n        const components: LayerComponent[] = [];\n\n        const collection: Feature[] = geojson.features;\n        for (let fId = 0; fId < collection.length; fId++) {\n            const feature = collection[fId];\n            if (!feature.geometry) {\n                TriangulatorPoints.warnSkippedFeature(fId, null);\n                continue;\n            }\n\n            const before = instances.length / 2;\n            if (feature.geometry.type === 'Point') {\n                TriangulatorPoints.pushPointInstance(instances, feature.geometry.coordinates, origin);\n            } else if (feature.geometry.type === 'MultiPoint') {\n                for (const coordinates of feature.geometry.coordinates) {\n                    TriangulatorPoints.pushPointInstance(instances, coordinates, origin);\n                }\n            } else if (feature.geometry.type === 'GeometryCollection') {\n                TriangulatorPoints.pushGeometryCollectionInstances(instances, feature, origin, fId);\n            } else {\n                TriangulatorPoints.warnSkippedFeature(fId, feature.geometry.type);\n                continue;\n            }\n\n            const instanceCount = instances.length / 2 - before;\n            if (instanceCount === 0) {\n                continue;\n            }\n\n            components.push({\n                nPoints: instanceCount,\n                nTriangles: instanceCount * 2,\n                featureIndex: fId,\n                featureId: feature.id,\n            });\n        }\n\n        return {\n            instances: new Float32Array(instances),\n            components,\n        };\n    }\n\n\n    /**\n     * Appends supported children of a `GeometryCollection` to the packed instance centers.\n     */\n    private static pushGeometryCollectionInstances(instances: number[], feature: Feature, origin: number[], featureIndex: number): void {\n        const { geometries } = <GeometryCollection>feature.geometry;\n        for (const geom of geometries) {\n            if (geom.type === 'Point') {\n                TriangulatorPoints.pushPointInstance(instances, geom.coordinates, origin);\n            } else if (geom.type === 'MultiPoint') {\n                for (const coordinates of geom.coordinates) {\n                    TriangulatorPoints.pushPointInstance(instances, coordinates, origin);\n                }\n            } else {\n                TriangulatorPoints.warnSkippedGeometryCollectionChild(featureIndex, geom.type);\n            }\n        }\n    }\n\n    /** Appends one point instance center in local coordinates. */\n    private static pushPointInstance(instances: number[], coordinates: number[], origin: number[]): void {\n        if (coordinates.length < 2) {\n            return;\n        }\n        instances.push(coordinates[0] - origin[0], coordinates[1] - origin[1]);\n    }\n\n\n    /**\n     * Emits a warning when a feature does not contain a supported point geometry.\n     *\n     * @param featureIndex - Index of the skipped feature in the source collection.\n     * @param geometryType - Encountered geometry type, or `null` when geometry is missing.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedFeature(featureIndex: number, geometryType: string | null): void {\n        console.warn(\n            `[autk-core] TriangulatorPoints skipped feature ${featureIndex}: expected Point or MultiPoint geometry, got ${geometryType ?? 'null'}.`\n        );\n    }\n\n    /**\n     * Emits a warning when a `GeometryCollection` child is not a supported point geometry.\n     *\n     * @param featureIndex - Index of the parent feature in the source collection.\n     * @param geometryType - Encountered unsupported child geometry type.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedGeometryCollectionChild(featureIndex: number, geometryType: string): void {\n        console.warn(\n            `[autk-core] TriangulatorPoints skipped GeometryCollection child in feature ${featureIndex}: expected Point or MultiPoint geometry, got ${geometryType}.`\n        );\n    }\n\n}\n","import type { FeatureCollection, Geometry, Position } from 'geojson';\nimport type { LayerComponent, LayerGeometry } from './types-mesh';\n\n/** Width-independent centerline data for shader-expanded polylines. */\nexport interface PolylineData {\n    geometry: LayerGeometry[];\n    components: LayerComponent[];\n    /** Per centerline node: previous XY and next XY. Each node owns five consecutive topology vertices. */\n    attributes: Float32Array;\n}\n\n/** Builds centerline topology without buffering polygons or resolving visual widths. */\nexport class PolylineBuilder {\n    /**\n     * Builds local XY centerlines for LineString, MultiLineString and nested GeometryCollection.\n     * Consecutive duplicate vertices are removed after float32 conversion. Invalid paths and\n     * paths with fewer than two distinct points are skipped. Components retain source IDs.\n     * Five vertices per node support segment quads and width-independent join triangles.\n     */\n    static build(geojson: FeatureCollection, origin: number[]): PolylineData {\n        const geometry: LayerGeometry[] = [];\n        const components: LayerComponent[] = [];\n        const attributes: number[] = [];\n\n        for (let featureIndex = 0; featureIndex < geojson.features.length; featureIndex++) {\n            const feature = geojson.features[featureIndex];\n            const paths: Position[][] = [];\n            PolylineBuilder.collectPaths(feature.geometry, paths);\n            let nPoints = 0;\n            let nTriangles = 0;\n\n            for (const path of paths) {\n                const points: number[][] = [];\n                let invalid = false;\n                for (const coordinate of path) {\n                    const x = Math.fround(coordinate[0] - origin[0]);\n                    const y = Math.fround(coordinate[1] - origin[1]);\n                    if (!Number.isFinite(x) || !Number.isFinite(y)) {\n                        invalid = true;\n                        break;\n                    }\n                    const last = points[points.length - 1];\n                    if (!last || last[0] !== x || last[1] !== y) {\n                        points.push([x, y]);\n                    }\n                }\n                if (invalid || points.length < 2) { continue; }\n                const closed = points.length > 2 && points[0][0] === points[points.length - 1][0]\n                    && points[0][1] === points[points.length - 1][1];\n                if (closed) { points.pop(); }\n                const count = points.length;\n                const position: number[] = [];\n                const indices: number[] = [];\n\n                for (let i = 0; i < count; i++) {\n                    const current = points[i];\n                    const previous = points[i === 0 ? (closed ? count - 1 : 0) : i - 1];\n                    const next = points[i === count - 1 ? (closed ? 0 : i) : i + 1];\n                    attributes.push(previous[0], previous[1], next[0], next[1]);\n                    // Incoming left/right, outgoing left/right, then join center.\n                    // Side/role are derived from vertex_index in the shader, not stored per vertex.\n                    for (let vertex = 0; vertex < 5; vertex++) {\n                        position.push(current[0], current[1]);\n                    }\n                    const base = i * 5;\n                    if (closed || (i > 0 && i < count - 1)) {\n                        indices.push(base, base + 2, base + 4, base + 1, base + 4, base + 3);\n                    }\n                    if (closed || i < count - 1) {\n                        const end = ((i + 1) % count) * 5;\n                        indices.push(base + 2, base + 3, end, base + 3, end + 1, end);\n                    }\n                }\n                geometry.push({ position: new Float32Array(position), indices: new Uint32Array(indices), featureIndex });\n                nPoints += position.length / 2;\n                nTriangles += indices.length / 3;\n            }\n            if (nTriangles > 0) {\n                components.push({ nPoints, nTriangles, featureIndex, featureId: feature.id });\n            }\n        }\n        return { geometry, components, attributes: new Float32Array(attributes) };\n    }\n\n    private static collectPaths(geometry: Geometry | null, paths: Position[][]): void {\n        if (!geometry) { return; }\n        switch (geometry.type) {\n            case 'LineString':\n                paths.push(geometry.coordinates);\n                break;\n            case 'MultiLineString':\n                paths.push(...geometry.coordinates);\n                break;\n            case 'GeometryCollection':\n                for (const child of geometry.geometries) {\n                    PolylineBuilder.collectPaths(child, paths);\n                }\n                break;\n            default:\n                console.warn(`[autk-core] PolylineBuilder skipped ${geometry.type}: expected line geometry.`);\n        }\n    }\n}\n","/**\n * @module GeometryUtils\n * Planar geometry helpers for triangulation and ring analysis.\n *\n * This module groups small 2D primitives used to offset local-space\n * polylines, normalize polygon rings, measure ring properties, test\n * convexity, and derive convex hulls. The helpers assume coordinates are\n * already expressed in a local planar system.\n */\n\n/**\n * Builds a closed polygon buffer around a polyline for stroke rendering.\n *\n * Input coordinates are expected to already be in a local planar system.\n * Consecutive duplicate points are skipped before the offset is computed.\n * The returned polygon includes a repeated closing vertex and is suitable for\n * triangulation with earcut.\n *\n * @param points - Ordered local-space polyline coordinates.\n * @param distance - Offset distance applied on both sides of the polyline.\n * @returns A closed polygon describing the buffered polyline footprint in\n * local planar coordinates. Returns an empty array when the input contains\n * fewer than two distinct points or when `distance` is `0`.\n * @throws Never throws. Degenerate inputs return an empty array rather than\n * raising an error.\n * @example\n * const poly = offsetPolyline([[0, 0], [10, 0], [10, 10]], 2);\n * // poly is a closed ring e.g. [[-0, 2], [10, -2], [12, 10], …]\n */\nexport function offsetPolyline(points: number[][], distance: number): [number, number][] {\n    const clean = points.filter((point, index) => {\n        if (index === 0) return true;\n        const prev = points[index - 1];\n        return point[0] !== prev[0] || point[1] !== prev[1];\n    }) as [number, number][];\n\n    if (clean.length < 2 || distance === 0) {\n        return [];\n    }\n\n    const left: [number, number][] = [];\n    const right: [number, number][] = [];\n\n    for (let i = 0; i < clean.length; i++) {\n        const prev = i > 0 ? clean[i - 1] : null;\n        const curr = clean[i];\n        const next = i < clean.length - 1 ? clean[i + 1] : null;\n\n        const prevNormal = prev ? getUnitLeftNormal(prev, curr) : null;\n        const nextNormal = next ? getUnitLeftNormal(curr, next) : null;\n\n        const leftPoint = computeOffsetPoint(prev, curr, next, prevNormal, nextNormal, distance, 1);\n        const rightPoint = computeOffsetPoint(prev, curr, next, prevNormal, nextNormal, distance, -1);\n\n        left.push(leftPoint);\n        right.push(rightPoint);\n    }\n\n    const polygon = [...left, ...right.reverse()];\n    if (polygon.length > 0) {\n        polygon.push([polygon[0][0], polygon[0][1]]);\n    }\n\n    return polygon;\n}\n\n/**\n * Returns a shallow copy of a ring without a duplicated closing vertex.\n *\n * Only the final vertex is removed, and only when it matches the first vertex\n * exactly. Rings that are already open are copied unchanged.\n *\n * @param ring - Polygon ring to normalize.\n * @returns A shallow copy of the ring without a repeated closing point.\n * @throws Never throws. Always returns a shallow copy, even for degenerate inputs.\n * @example\n * const open = normalizeRing([[0, 0], [10, 0], [10, 10], [0, 0]]);\n * // open → [[0, 0], [10, 0], [10, 10]]\n */\nexport function normalizeRing(ring: number[][]): number[][] {\n    if (ring.length < 2) return [...ring];\n    const normalized = [...ring];\n    const first = normalized[0];\n    const last = normalized[normalized.length - 1];\n    if (first[0] === last[0] && first[1] === last[1]) {\n        normalized.pop();\n    }\n    return normalized;\n}\n\n/**\n * Computes the convex hull of a 2D point set using the monotonic chain algorithm.\n *\n * Duplicate points are removed before hull computation. Collinear interior\n * points are discarded from the outer boundary. Degenerate inputs with\n * three or fewer unique points are returned as shallow copies.\n *\n * @param points - Input points to reduce to a convex hull.\n * @returns Hull points ordered around the outer boundary in CCW order.\n * @throws Never throws. Degenerate inputs are returned verbatim (limited copies).\n * @example\n * const hull = computePointConvexHull([[0, 0], [10, 0], [10, 10], [5, 5], [0, 10]]);\n * // hull → [[0, 0], [10, 0], [10, 10], [0, 10]] (interior point [5,5] discarded)\n */\nexport function computePointConvexHull(points: number[][]): number[][] {\n    const unique = Array.from(new Map(\n        normalizeRing(points).map((point) => [`${point[0]},${point[1]}`, point as [number, number]])\n    ).values());\n\n    if (unique.length <= 3) {\n        return unique.map(([x, y]) => [x, y]);\n    }\n\n    unique.sort((a, b) => (a[0] - b[0]) || (a[1] - b[1]));\n\n    const lower: Array<[number, number]> = [];\n    for (const point of unique) {\n        while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], point) <= 0) {\n            lower.pop();\n        }\n        lower.push(point);\n    }\n\n    const upper: Array<[number, number]> = [];\n    for (let i = unique.length - 1; i >= 0; i--) {\n        const point = unique[i];\n        while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], point) <= 0) {\n            upper.pop();\n        }\n        upper.push(point);\n    }\n\n    lower.pop();\n    upper.pop();\n    return [...lower, ...upper].map(([x, y]) => [x, y]);\n}\n\n/**\n * Computes the signed planar area of a polygon ring.\n *\n * Positive area indicates counterclockwise winding; negative area indicates\n * clockwise winding. The ring is automatically closed between the last and\n * first vertex.\n *\n * @param ring - Ring vertices in order around the polygon.\n * @returns Signed area of the ring. Counterclockwise rings produce positive\n * area and clockwise rings produce negative area.\n * @throws Never throws. Degenerate rings return `0`.\n * @example\n * const area = computeRingArea([[0, 0], [10, 0], [10, 10]]);\n * // area → 50 (CCW triangle)\n */\nexport function computeRingArea(ring: number[][]): number {\n    let area = 0;\n    for (let i = 0; i < ring.length; i++) {\n        const [x1, y1] = ring[i];\n        const [x2, y2] = ring[(i + 1) % ring.length];\n        area += x1 * y2 - x2 * y1;\n    }\n    return area * 0.5;\n}\n\n/**\n * Computes the total perimeter length of a polygon ring.\n *\n * The ring is traversed in order and closed automatically between the last\n * and first vertex.\n *\n * @param ring - Ring vertices in order around the polygon.\n * @returns Sum of Euclidean edge lengths around the ring.\n * @throws Never throws. Returns `0` for rings with fewer than 2 vertices.\n * @example\n * const len = polygonPerimeter([[0, 0], [10, 0], [10, 10]]);\n * // len → 10 + 10 + 14.14…\n */\nexport function polygonPerimeter(ring: number[][]): number {\n    let perimeter = 0;\n    const n = ring.length;\n    for (let i = 0, j = n - 1; i < n; j = i++) {\n        const dx = ring[i][0] - ring[j][0];\n        const dy = ring[i][1] - ring[j][1];\n        perimeter += Math.sqrt(dx * dx + dy * dy);\n    }\n    return perimeter;\n}\n\n/**\n * Returns true when a polygon ring is convex.\n *\n * Assumes the ring is already open, with no duplicated closing vertex.\n * Collinear vertices are ignored when testing turn direction consistency.\n *\n * @param ring - Open polygon ring to test.\n * @returns `true` when all non-zero cross products share the same sign,\n * otherwise `false`.\n * @throws Never throws. Rings with fewer than 3 vertices return `true`.\n * @example\n * isConvex([[0, 0], [10, 0], [10, 10], [0, 10]]); // true\n * isConvex([[0, 0], [10, 0], [5, 5], [10, 10], [0, 10]]); // false (concave)\n */\nexport function isConvex(ring: number[][]): boolean {\n    const n = ring.length;\n    let sign = 0;\n    for (let i = 0; i < n; i++) {\n        const prev = (i + n - 1) % n;\n        const next = (i + 1) % n;\n        const e1x = ring[i][0] - ring[prev][0];\n        const e1y = ring[i][1] - ring[prev][1];\n        const e2x = ring[next][0] - ring[i][0];\n        const e2y = ring[next][1] - ring[i][1];\n        const turn = e1x * e2y - e1y * e2x;\n        if (Math.abs(turn) < 1e-10) continue;\n        const currentSign = turn > 0 ? 1 : -1;\n        if (sign === 0) sign = currentSign;\n        else if (currentSign !== sign) return false;\n    }\n    return true;\n}\n\n/**\n * Computes the unit left-hand normal for a directed segment.\n *\n * The left-hand normal is the vector perpendicular to the segment direction\n * rotated 90° counterclockwise, used by `offsetPolyline` to push vertices\n * outward.\n *\n * @param a - Start point of the segment.\n * @param b - End point of the segment.\n * @returns A normalized left-hand perpendicular vector, or `null` when the\n * segment has zero length.\n */\nfunction getUnitLeftNormal(a: [number, number], b: [number, number]): [number, number] | null {\n    const dx = b[0] - a[0];\n    const dy = b[1] - a[1];\n    const length = Math.hypot(dx, dy);\n\n    if (length === 0) {\n        return null;\n    }\n\n    return [-dy / length, dx / length];\n}\n\n/**\n * Computes the offset vertex for one side of a polyline at a given vertex.\n *\n * Endpoints fall back to a single segment normal. Interior vertices are formed\n * by intersecting the adjacent offset segments when possible; when segments\n * are parallel or nearly so, the averaged normal direction is used instead.\n *\n * @param prev - Previous polyline point, or `null` when `curr` is the first point.\n * @param curr - Current polyline point being offset.\n * @param next - Next polyline point, or `null` when `curr` is the last point.\n * @param prevNormal - Unit left normal of the incoming segment, if available.\n * @param nextNormal - Unit left normal of the outgoing segment, if available.\n * @param distance - Offset distance applied away from the source polyline.\n * @param side - Offset side multiplier: `1` for the left outline, `-1` for the right outline.\n * @returns The offset point for the requested side at `curr`. Falls back to\n * `curr` itself when both normals are unavailable.\n */\nfunction computeOffsetPoint(\n    prev: [number, number] | null,\n    curr: [number, number],\n    next: [number, number] | null,\n    prevNormal: [number, number] | null,\n    nextNormal: [number, number] | null,\n    distance: number,\n    side: 1 | -1,\n): [number, number] {\n    if (!prevNormal && !nextNormal) {\n        return curr;\n    }\n\n    if (!prev || !prevNormal) {\n        return [\n            curr[0] + nextNormal![0] * distance * side,\n            curr[1] + nextNormal![1] * distance * side,\n        ];\n    }\n\n    if (!next || !nextNormal) {\n        return [\n            curr[0] + prevNormal[0] * distance * side,\n            curr[1] + prevNormal[1] * distance * side,\n        ];\n    }\n\n    const prevOffsetA: [number, number] = [\n        prev[0] + prevNormal[0] * distance * side,\n        prev[1] + prevNormal[1] * distance * side,\n    ];\n    const prevOffsetB: [number, number] = [\n        curr[0] + prevNormal[0] * distance * side,\n        curr[1] + prevNormal[1] * distance * side,\n    ];\n    const nextOffsetA: [number, number] = [\n        curr[0] + nextNormal[0] * distance * side,\n        curr[1] + nextNormal[1] * distance * side,\n    ];\n    const nextOffsetB: [number, number] = [\n        next[0] + nextNormal[0] * distance * side,\n        next[1] + nextNormal[1] * distance * side,\n    ];\n\n    const intersection = intersectLines(prevOffsetA, prevOffsetB, nextOffsetA, nextOffsetB);\n    if (intersection) {\n        return intersection;\n    }\n\n    const avgX = prevNormal[0] + nextNormal[0];\n    const avgY = prevNormal[1] + nextNormal[1];\n    const avgLength = Math.hypot(avgX, avgY);\n\n    if (avgLength === 0) {\n        return [\n            curr[0] + nextNormal[0] * distance * side,\n            curr[1] + nextNormal[1] * distance * side,\n        ];\n    }\n\n    return [\n        curr[0] + (avgX / avgLength) * distance * side,\n        curr[1] + (avgY / avgLength) * distance * side,\n    ];\n}\n\n/**\n * Computes the intersection point of two infinite 2D lines.\n *\n * The lines are defined by the point pairs `a1`-`a2` and `b1`-`b2`.\n * Parallel or nearly parallel lines (determinant < 1e-9) return `null`.\n * Used by `computeOffsetPoint` to resolve mitered corners.\n *\n * @param a1 - First point on the first line.\n * @param a2 - Second point on the first line.\n * @param b1 - First point on the second line.\n * @param b2 - Second point on the second line.\n * @returns The line intersection point, or `null` when the lines are parallel\n * or nearly so.\n */\nfunction intersectLines(\n    a1: [number, number],\n    a2: [number, number],\n    b1: [number, number],\n    b2: [number, number],\n): [number, number] | null {\n    const x1 = a1[0];\n    const y1 = a1[1];\n    const x2 = a2[0];\n    const y2 = a2[1];\n    const x3 = b1[0];\n    const y3 = b1[1];\n    const x4 = b2[0];\n    const y4 = b2[1];\n\n    const denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);\n    if (Math.abs(denom) < 1e-9) {\n        return null;\n    }\n\n    const detA = x1 * y2 - y1 * x2;\n    const detB = x3 * y4 - y3 * x4;\n\n    return [\n        (detA * (x3 - x4) - (x1 - x2) * detB) / denom,\n        (detA * (y3 - y4) - (y1 - y2) * detB) / denom,\n    ];\n}\n\n/**\n * Computes the signed cross product of the turn from `a` → `b` → `c`.\n *\n * Used by `computePointConvexHull` to test point-to-line orientation during\n * monotonic chain construction.\n *\n * @param a - First point.\n * @param b - Second point.\n * @param c - Third point.\n * @returns Positive for counterclockwise turns, negative for clockwise\n * turns, and `0` for collinear points.\n */\nfunction cross(a: [number, number], b: [number, number], c: [number, number]): number {\n    return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);\n}\n","/**\n * A vertex in a circular doubly linked list representing a polygon ring.\n * `prev`/`next` are always linked (set immediately after {@link createNode}), so they're typed\n * non-null; `prevZ`/`nextZ` are the z-order list links and are null at the ends.\n *\n * @typedef {object} Node\n * @property {number} i vertex index in the coordinates array\n * @property {number} x vertex x coordinate\n * @property {number} y vertex y coordinate\n * @property {Node} prev previous vertex node in the polygon ring\n * @property {Node} next next vertex node in the polygon ring\n * @property {number} z z-order curve value; doubles as the owning block index during eliminateHoles\n * @property {Node | null} prevZ previous node in z-order\n * @property {Node | null} nextZ next node in z-order\n */\n\n// single-vertex holes to preserve through filterPoints (steiner points); kept off the Node\n// shape since they're rare — the empty-set fast path means non-steiner inputs pay nothing\n/** @type {Set<Node>} */\nconst steiners = new Set();\n\n// set by filterPoints whenever it removes at least one node; read by earcutLinked's stall\n// handler to decide whether another clip pass is worth attempting before the costlier stages\nlet filteredOut = false;\n\n/**\n * Triangulate a polygon given as a flat array of vertex coordinates.\n *\n * @param {ArrayLike<number>} data flat array of vertex coordinates\n * @param {ArrayLike<number> | null} [holeIndices] indices (in vertices, not coordinates) where each hole ring starts\n * @param {number} [dim=2] number of coordinates per vertex in `data`\n * @returns {number[]} triangles as triplets of vertex indices into `data`\n * @example earcut([10,0, 0,50, 60,60, 70,10]); // [1,0,3, 3,2,1]\n */\nexport default function earcut(data, holeIndices, dim = 2) {\n\n    const hasHoles = holeIndices && holeIndices.length;\n    const outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n    if (steiners.size) steiners.clear();\n\n    let outerNode = linkedList(data, 0, outerLen, dim, true);\n    /** @type {number[]} */\n    const triangles = [];\n\n    if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n    let minX = 0, minY = 0, invSize = 0;\n\n    if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n    // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n    if (data.length > 80 * dim) {\n        minX = data[0];\n        minY = data[1];\n        let maxX = minX;\n        let maxY = minY;\n\n        for (let i = dim; i < outerLen; i += dim) {\n            const x = data[i];\n            const y = data[i + 1];\n            if (x < minX) minX = x;\n            if (y < minY) minY = y;\n            if (x > maxX) maxX = x;\n            if (y > maxY) maxY = y;\n        }\n\n        // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n        invSize = Math.max(maxX - minX, maxY - minY);\n        invSize = invSize !== 0 ? 32767 / invSize : 0;\n    }\n\n    earcutLinked(outerNode, triangles, minX, minY, invSize);\n\n    return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\n/** @param {ArrayLike<number>} data @param {number} start @param {number} end @param {number} dim @param {boolean} clockwise @returns {Node | null} */\nfunction linkedList(data, start, end, dim, clockwise) {\n    /** @type {Node | null} */\n    let last = null;\n\n    if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n        for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n    } else {\n        for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n    }\n\n    if (last && equals(last, last.next)) {\n        removeNode(last);\n        last = last.next;\n    }\n\n    return last;\n}\n\n// Remove collinear or coincident points; removability depends only on a node's immediate\n// neighbors, so we sweep forward and re-check the predecessor after each removal. With no `end`\n// we sweep the whole ring, lapping until nothing is removable (the fixpoint the clipper needs).\n// With an explicit `end` we heal only the dirty window around a bridge/diagonal cut, stopping at\n// `end` rather than lapping — O(window) instead of O(ring).\n/** @param {Node} start @param {Node} [end] @returns {Node} */\nfunction filterPoints(start, end = start) {\n    const full = end === start;\n\n    let p = start, again;\n    do {\n        again = false;\n        if (p !== p.next && (steiners.size === 0 || !steiners.has(p)) &&\n            (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n            if (full || p === end) end = p.prev; // pull the stop bound back past the removal\n            filteredOut = true;\n            removeNode(p);\n            p = p.prev;         // re-check the predecessor\n            again = true;\n        } else if (full || p !== end) {\n            p = p.next;\n            again = !full;      // local heal: keep looping until the sweep reaches end\n        }\n    } while (again || p !== end);\n\n    return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\n/** @param {Node} ear @param {number[]} triangles @param {number} minX @param {number} minY @param {number} invSize */\nfunction earcutLinked(ear, triangles, minX, minY, invSize) {\n    // interlink polygon nodes in z-order\n    if (invSize) indexCurve(ear, minX, minY, invSize);\n\n    let stop = ear, cured = false;\n\n    // iterate through ears, slicing them one by one\n    while (ear.prev !== ear.next) {\n        const prev = ear.prev;\n        /** @type {Node} */\n        const next = ear.next;\n\n        if (area(prev, ear, next) < 0 && (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear))) {\n            triangles.push(prev.i, ear.i, next.i); // cut off the triangle\n\n            removeNode(ear);\n            ear = next;\n            stop = next;\n            continue;\n        }\n\n        ear = next;\n\n        // if we looped through the whole remaining polygon and can't find any more ears\n        if (ear === stop) {\n            // try filtering collinear/coincident points and slicing again — repeat as long as\n            // filtering actually removes nodes, since each removal can expose new ears\n            filteredOut = false;\n            ear = filterPoints(ear);\n            if (filteredOut) { stop = ear; continue; }\n\n            // filtering is exhausted: cure small local self-intersections once, then retry\n            if (!cured) {\n                ear = cureLocalIntersections(ear, triangles);\n                stop = ear;\n                cured = true;\n                continue;\n            }\n\n            // as a last resort, try splitting the remaining polygon into two\n            splitEarcut(ear, triangles, minX, minY, invSize);\n            break;\n        }\n    }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\n/** @param {Node} ear @returns {boolean} */\nfunction isEar(ear) {\n    // reflex check (area(a, b, c) >= 0) is hoisted into the earcutLinked caller to avoid non-inlined call here\n    const a = ear.prev, b = ear, c = ear.next,\n        ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y,\n        x0 = Math.min(ax, bx, cx), // triangle bbox\n        y0 = Math.min(ay, by, cy),\n        x1 = Math.max(ax, bx, cx),\n        y1 = Math.max(ay, by, cy);\n\n    // make sure we don't have other points inside the potential ear\n    let p = c.next;\n    while (p !== a) {\n        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && !(ax === p.x && ay === p.y) &&\n            pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n        p = p.next;\n    }\n    return true;\n}\n\n/** @param {Node} ear @param {number} minX @param {number} minY @param {number} invSize @returns {boolean} */\nfunction isEarHashed(ear, minX, minY, invSize) {\n    // reflex check is hoisted into the earcutLinked caller (see isEar)\n    const a = ear.prev, b = ear, c = ear.next,\n        ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y,\n        x0 = Math.min(ax, bx, cx), // triangle bbox\n        y0 = Math.min(ay, by, cy),\n        x1 = Math.max(ax, bx, cx),\n        y1 = Math.max(ay, by, cy),\n        minZ = zOrder(x0, y0, minX, minY, invSize), // z-order range for the current triangle bbox;\n        maxZ = zOrder(x1, y1, minX, minY, invSize);\n\n    let p = ear.prevZ;\n    while (p && p.z >= minZ) { // look for points inside the triangle in decreasing z-order\n        if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== c && !(ax === p.x && ay === p.y) &&\n            pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n        p = p.prevZ;\n    }\n    let n = ear.nextZ;\n    while (n && n.z <= maxZ) { // look for points in increasing z-order\n        if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== c && !(ax === n.x && ay === n.y) &&\n            pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;\n        n = n.nextZ;\n    }\n    return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\n/** @param {Node} start @param {number[]} triangles @returns {Node} */\nfunction cureLocalIntersections(start, triangles) {\n    let p = start;\n    let cured = false;\n    do {\n        const a = p.prev,\n            b = p.next.next;\n\n        if (intersects(a, p, p.next, b, false) && locallyInside(a, b) && locallyInside(b, a)) {\n\n            triangles.push(a.i, p.i, b.i);\n\n            // remove two nodes involved\n            removeNode(p);\n            removeNode(p.next);\n\n            p = start = b;\n            cured = true;\n        }\n        p = p.next;\n    } while (p !== start);\n\n    return cured ? filterPoints(p) : p;\n}\n\n// try splitting polygon into two and triangulate them independently\n/** @param {Node} start @param {number[]} triangles @param {number} minX @param {number} minY @param {number} invSize */\nfunction splitEarcut(start, triangles, minX, minY, invSize) {\n    // look for a valid diagonal that divides the polygon into two\n    let a = start;\n    do {\n        let b = a.next.next;\n        while (b !== a.prev) {\n            if (a.i !== b.i && isValidDiagonal(a, b)) {\n                // split the polygon in two by the diagonal\n                let c = splitPolygon(a, b);\n\n                // filter colinear points around the cuts\n                a = filterPoints(a, a.next);\n                c = filterPoints(c, c.next);\n\n                // run earcut on each half\n                earcutLinked(a, triangles, minX, minY, invSize);\n                earcutLinked(c, triangles, minX, minY, invSize);\n                return;\n            }\n            b = b.next;\n        }\n        a = a.next;\n    } while (a !== start);\n}\n\n// true only while eliminateHoles merges holes, so removeNode keeps the block index live (growBlock)\nlet indexActive = false;\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\n/** @param {ArrayLike<number>} data @param {ArrayLike<number>} holeIndices @param {Node} outerNode @param {number} dim @returns {Node} */\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n    const queue = [];\n\n    for (let i = 0, len = holeIndices.length; i < len; i++) {\n        const start = holeIndices[i] * dim;\n        const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n        const list = /** @type {Node} */ (linkedList(data, start, end, dim, false));\n        if (list === list.next) steiners.add(list);\n        queue.push(getLeftmost(list));\n    }\n\n    queue.sort(compareXYSlope);\n\n    // block-bbox index for findHoleBridge, grown append-only as holes merge (see notes\n    // above buildBlockIndex). Seed it with the outer ring, then append each merged hole.\n    buildBlockIndex(data.length / dim, holeIndices.length);\n    indexSegment(outerNode, outerNode);\n\n    // process holes from left to right; indexActive lets removeNode keep block bboxes live as\n    // filterPoints heals edges during merges (see growBlock)\n    indexActive = true;\n    for (let i = 0; i < queue.length; i++) {\n        outerNode = eliminateHole(queue[i], outerNode);\n    }\n    indexActive = false;\n\n    // collapse collinear/coincident points across the whole merged ring once before clipping\n    return filterPoints(outerNode);\n}\n\n/** @param {Node} a @param {Node} b @returns {number} */\nfunction compareXYSlope(a, b) {\n    // when the left-most point of 2 holes meet at a vertex, sort the holes counterclockwise so that when we find\n    // the bridge to the outer shell is always the point that they meet at.\n    return a.x - b.x || a.y - b.y ||\n        (a.next.y - a.y) / (a.next.x - a.x) -\n        (b.next.y - b.y) / (b.next.x - b.x);\n}\n\n// find a bridge between vertices that connects hole with an outer ring and link it\n/** @param {Node} hole @param {Node} outerNode @returns {Node} */\nfunction eliminateHole(hole, outerNode) {\n    const bridge = findHoleBridge(hole, outerNode);\n    if (!bridge) {\n        return outerNode;\n    }\n\n    const bridgeReverse = splitPolygon(bridge, hole);\n\n    // index the merged-in segment before filtering: in ring order the splice runs\n    // bridge -> hole -> bridgeReverse -> bridge2 -> (bridge's old next), covering the\n    // hole's edges and both new slit edges. filterPoints below only drops collinear /\n    // coincident points, so these bboxes stay valid (conservative) supersets.\n    const bridge2 = bridgeReverse.next;\n    indexSegment(bridge, bridge2.next);\n\n    // heal collinear/coincident points around the two new slit edges\n    filterPoints(bridgeReverse, bridgeReverse.next);\n    return filterPoints(bridge, bridge.next);\n}\n\n// Block-bbox index for findHoleBridge (issue #183): one [minX,minY,maxX,maxY] bbox per K\n// consecutive ring edges, in a flat Float64Array, so the leftward-ray scan can skip whole\n// blocks in O(1) instead of walking the entire merged ring. Grown append-only — the outer\n// ring seeds it, then each merged hole appends a segment (head node, stop node, K-blocks\n// over head..stop); independent segments, not a ring tiling, since splices land mid-ring.\n// Buffers are sized once from the input upper bound and reused across calls.\n//\n// filterPoints only drops collinear/coincident points, so a stale bbox stays a conservative\n// superset of its live edges (never a false skip); the scan skips dead nodes (p.prev.next !==\n// p) and lazily advances a dead stop. Blocks are scanned in append (not ring) order, so the\n// chosen bridge can differ from the un-indexed code — a different but equally valid result.\nconst K = 16; // edges per block\n\nlet blockBBox = new Float64Array(0); // [minX,minY,maxX,maxY] per block\nlet numBlocks = 0;\n/** @type {Node[]} */\nconst blockHead = []; // first node of each block's segment\n/** @type {Node[]} */\nconst blockStop = []; // node just past each block's segment (exclusive walk bound)\n\n/** @param {number} maxNodes @param {number} numHoles */\nfunction buildBlockIndex(maxNodes, numHoles) {\n    // upper bound: every input node indexed once, +2 bridge nodes per hole, plus a partial\n    // trailing block per appended segment (outer ring + one per hole)\n    const maxBlocks = Math.ceil((maxNodes + 2 * numHoles) / K) + numHoles + 2;\n    if (blockBBox.length < maxBlocks * 4) blockBBox = new Float64Array(maxBlocks * 4);\n    numBlocks = 0;\n}\n\n// index the ring run head..stop (exclusive) as ceil(len / K) blocks; head === stop means\n// the whole ring. each block's bbox covers both endpoints of every edge it owns.\n/** @param {Node} head @param {Node} stop */\nfunction indexSegment(head, stop) {\n    let p = head;\n    do {\n        const b = numBlocks++;\n        blockHead[b] = p;\n        let minX = p.x, minY = p.y, maxX = p.x, maxY = p.y;\n        let k = 0;\n        do {\n            const c = p.next; // edge p->c; bbox must bound both endpoints\n            p.z = b; // reuse z as the owning block during eliminateHoles (see growBlock)\n            if (c.x < minX) minX = c.x; if (c.x > maxX) maxX = c.x;\n            if (c.y < minY) minY = c.y; if (c.y > maxY) maxY = c.y;\n            p = c;\n        } while (++k < K && p !== stop);\n        blockStop[b] = p;\n        const g = b * 4;\n        blockBBox[g] = minX; blockBBox[g + 1] = minY; blockBBox[g + 2] = maxX; blockBBox[g + 3] = maxY;\n    } while (p !== stop);\n}\n\n// when filterPoints heals an edge head->tail (removing the collinear node between them), the\n// healed edge can extend past head's frozen block bbox if its old far endpoint lived in another\n// block; grow head's block bbox to cover tail so the leftward-ray prune can't false-skip it.\n/** @param {Node} head @param {Node} tail */\nfunction growBlock(head, tail) {\n    const g = head.z * 4;\n    if (tail.x < blockBBox[g]) blockBBox[g] = tail.x;\n    if (tail.y < blockBBox[g + 1]) blockBBox[g + 1] = tail.y;\n    if (tail.x > blockBBox[g + 2]) blockBBox[g + 2] = tail.x;\n    if (tail.y > blockBBox[g + 3]) blockBBox[g + 3] = tail.y;\n}\n\n/** @param {number} b @returns {Node} */\nfunction liveBlockStop(b) {\n    let stop = blockStop[b];\n    while (stop.prev.next !== stop) stop = stop.next;\n    blockStop[b] = stop;\n    return stop;\n}\n\n// the block's head node can be removed by filterPoints during merges; advance it to the next\n// live node so the walk doesn't start on (and immediately terminate at) a dead node. For the\n// single full-ring seed block (head === stop) the same forward advance keeps them equal, so the\n// do-while still laps the whole ring instead of collapsing to an empty walk.\n/** @param {number} b @returns {Node} */\nfunction liveBlockHead(b) {\n    let head = blockHead[b];\n    while (head.prev.next !== head) head = head.next;\n    blockHead[b] = head;\n    return head;\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\n/** @param {Node} hole @param {Node} outerNode @returns {Node | null} */\nfunction findHoleBridge(hole, outerNode) {\n    let p = outerNode;\n    const hx = hole.x;\n    const hy = hole.y;\n    let qx = -Infinity;\n    /** @type {Node | undefined} */\n    let m;\n\n    // find a segment intersected by a ray from the hole's leftmost point to the left;\n    // segment's endpoint with lesser x will be potential connection point\n    // unless they intersect at a vertex, then choose the vertex\n    if (equals(hole, p)) return p;\n\n    // scan blocks; skip any whose bbox can't hold a crossing that beats qx and lies left\n    // of hx (the prune Morton order can't express — explicit per-axis [minY,maxY]/[minX,maxX])\n    for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {\n        if (hy < blockBBox[g + 1] || hy > blockBBox[g + 3] || blockBBox[g] > hx || blockBBox[g + 2] <= qx) continue;\n\n        // ensure the walk's exclusive bound is live so we don't overrun into other blocks\n        const stop = liveBlockStop(b);\n\n        p = liveBlockHead(b);\n        do {\n            if (p.prev.next === p) { // skip nodes removed by filterPoints (stale in the index)\n                if (equals(hole, p.next)) return p.next;\n                else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n                    const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n                    if (x <= hx && x > qx) {\n                        qx = x;\n                        m = p.x < p.next.x ? p : p.next;\n                        if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint\n                    }\n                }\n            }\n            p = p.next;\n        } while (p !== stop);\n    }\n\n    if (!m) return null;\n\n    // look for points inside the triangle of hole point, segment intersection and endpoint;\n    // if there are no points found, we have a valid connection;\n    // otherwise choose the point of the minimum angle with the ray as connection point\n\n    const mx = m.x;\n    const my = m.y;\n    const tminY = Math.min(hy, my); // the triangle's y span; x span is [mx, hx]\n    const tmaxY = Math.max(hy, my);\n    let tanMin = Infinity;\n\n    // scan the same blocks; skip any whose bbox can't overlap the triangle's [mx,hx]×[tminY,tmaxY] box\n    for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {\n        if (blockBBox[g + 2] < mx || blockBBox[g] > hx || blockBBox[g + 3] < tminY || blockBBox[g + 1] > tmaxY) continue;\n\n        const stop = liveBlockStop(b);\n\n        p = liveBlockHead(b);\n        do {\n            if (p.prev.next === p && hx >= p.x && p.x >= mx && hx !== p.x && // skip dead nodes\n                    pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n                const tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n                // if hole point sits on p's horizontal edge (T-junction touch): the bridge runs\n                // along that edge — locallyInside rejects it as collinear, but it's valid\n                if ((locallyInside(p, hole) || (p.y === hy && p.next.y === hy && p.next.x > hx)) &&\n                    (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n                    m = p;\n                    tanMin = tan;\n                }\n            }\n\n            p = p.next;\n        } while (p !== stop);\n    }\n\n    return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\n/** @param {Node} m @param {Node} p @returns {boolean} */\nfunction sectorContainsSector(m, p) {\n    return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// scratch buffers reused across calls and grown on demand: two node-ref arrays that\n// ping-pong during the radix passes, plus parallel z-value arrays so the passes read\n// z from contiguous memory instead of dereferencing each node. 256-entry histogram for\n// 8-bit digits; the small histogram keeps per-call setup cheap (most rings are short)\n/** @type {Node[]} */\nconst sortArr = [];\n/** @type {Node[]} */\nlet sortBuf = [];\nlet zArr = new Uint32Array(0);\nlet zBuf = new Uint32Array(0);\nconst counts = new Uint32Array(256);\n\n// interlink polygon nodes in z-order: collect into an array, sort by z, relink\n/** @param {Node} start @param {number} minX @param {number} minY @param {number} invSize */\nfunction indexCurve(start, minX, minY, invSize) {\n    let p = start;\n    let n = 0;\n    do {\n        // always (re)compute: z may still hold a block index left over from eliminateHoles\n        p.z = zOrder(p.x, p.y, minX, minY, invSize);\n        sortArr[n++] = p;\n        p = p.next;\n    } while (p !== start);\n\n    sortNodes(n);\n\n    /** @type {Node | null} */\n    let prev = null;\n    for (let i = 0; i < n; i++) {\n        const node = sortArr[i];\n        node.prevZ = prev;\n        if (prev) prev.nextZ = node;\n        prev = node;\n    }\n    /** @type {Node} */ (prev).nextZ = null;\n\n    // drop the node refs but keep the capacity: setting length to 0 leaves sortBuf unresized\n    // (its growth is gated on zArr), so the radix scatter regrows it out of order every call\n    sortArr.fill(/** @type {Node} */ (/** @type {unknown} */ (null)), 0, n);\n    sortBuf.fill(/** @type {Node} */ (/** @type {unknown} */ (null)), 0, n);\n}\n\n// sort the first n nodes of sortArr by z, in place: insertion sort for small n (cheaper\n// than histogram setup), else LSD radix in four 8-bit passes (covering z's 30 bits)\n/** @param {number} n */\nfunction sortNodes(n) {\n    if (n <= 32) {\n        for (let i = 1; i < n; i++) {\n            const node = sortArr[i], z = node.z;\n            let j = i - 1;\n            while (j >= 0 && sortArr[j].z > z) { sortArr[j + 1] = sortArr[j]; j--; }\n            sortArr[j + 1] = node;\n        }\n        return;\n    }\n\n    if (zArr.length < n) {\n        zArr = new Uint32Array(n);\n        zBuf = new Uint32Array(n);\n        sortBuf = new Array(n);\n    }\n    for (let i = 0; i < n; i++) zArr[i] = sortArr[i].z;\n\n    // even pass count lands the sorted result back in sortArr\n    radixPass(n, sortArr, zArr, sortBuf, zBuf, 0);\n    radixPass(n, sortBuf, zBuf, sortArr, zArr, 8);\n    radixPass(n, sortArr, zArr, sortBuf, zBuf, 16);\n    radixPass(n, sortBuf, zBuf, sortArr, zArr, 24);\n}\n\n// one LSD radix pass: stably scatter the first n nodes (and their z) from src to dst,\n// bucketed by the 8-bit digit of z at the given bit shift\n/** @param {number} n @param {Node[]} src @param {Uint32Array} srcZ @param {Node[]} dst @param {Uint32Array} dstZ @param {number} shift */\nfunction radixPass(n, src, srcZ, dst, dstZ, shift) {\n    counts.fill(0);\n    for (let i = 0; i < n; i++) counts[(srcZ[i] >>> shift) & 0xff]++;\n    // turn per-bucket counts into start offsets (prefix sum)\n    let sum = 0;\n    for (let b = 0; b < 256; b++) { const c = counts[b]; counts[b] = sum; sum += c; }\n    for (let i = 0; i < n; i++) {\n        const z = srcZ[i];\n        const pos = counts[(z >>> shift) & 0xff]++;\n        dst[pos] = src[i];\n        dstZ[pos] = z;\n    }\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\n/** @param {number} x @param {number} y @param {number} minX @param {number} minY @param {number} invSize @returns {number} */\nfunction zOrder(x, y, minX, minY, invSize) {\n    // coords are transformed into non-negative 15-bit integer range\n    x = (x - minX) * invSize | 0;\n    y = (y - minY) * invSize | 0;\n\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n\n    y = (y | (y << 8)) & 0x00FF00FF;\n    y = (y | (y << 4)) & 0x0F0F0F0F;\n    y = (y | (y << 2)) & 0x33333333;\n    y = (y | (y << 1)) & 0x55555555;\n\n    return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\n/** @param {Node} start @returns {Node} */\nfunction getLeftmost(start) {\n    let p = start,\n        leftmost = start;\n    do {\n        if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n        p = p.next;\n    } while (p !== start);\n\n    return leftmost;\n}\n\n// check if a point lies within a convex triangle\n/** @param {number} ax @param {number} ay @param {number} bx @param {number} by @param {number} cx @param {number} cy @param {number} px @param {number} py @returns {boolean} */\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n    return (cx - px) * (ay - py) >= (ax - px) * (cy - py) &&\n           (ax - px) * (by - py) >= (bx - px) * (ay - py) &&\n           (bx - px) * (cy - py) >= (cx - px) * (by - py);\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\n/** @param {Node} a @param {Node} b @returns {boolean} true when the diagonal is valid */\nfunction isValidDiagonal(a, b) {\n    const zeroLength = equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0; // degenerate case\n    return a.next.i !== b.i && (zeroLength || locallyInside(a, b) && locallyInside(b, a) && // // locally visible\n        (area(a.prev, a, b.prev) !== 0 || area(a, b.prev, b) !== 0)) && // no opposite-facing sectors\n        !intersectsPolygon(a, b) && (zeroLength || middleInside(a, b)); // doesn't intersect other edges, diagonal inside polygon\n}\n\n// signed area of a triangle\n/** @param {Node} p @param {Node} q @param {Node} r @returns {number} */\nfunction area(p, q, r) {\n    return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\n/** @param {Node} p1 @param {Node} p2 @returns {boolean} */\nfunction equals(p1, p2) {\n    return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect; by default includes collinear boundary touches\n/** @param {Node} p1 @param {Node} q1 @param {Node} p2 @param {Node} q2 @param {boolean} [includeBoundary] @returns {boolean} */\nfunction intersects(p1, q1, p2, q2, includeBoundary = true) {\n    const o1 = area(p1, q1, p2);\n    const o2 = area(p1, q1, q2);\n    const o3 = area(p2, q2, p1);\n    const o4 = area(p2, q2, q1);\n\n    if (((o1 > 0 && o2 < 0) || (o1 < 0 && o2 > 0)) && ((o3 > 0 && o4 < 0) || (o3 < 0 && o4 > 0))) return true;\n\n    if (!includeBoundary) return false;\n\n    if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n    if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n    if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n    if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n    return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\n/** @param {Node} p @param {Node} q @param {Node} r @returns {boolean} */\nfunction onSegment(p, q, r) {\n    return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\n// check if a polygon diagonal intersects any polygon segments\n/** @param {Node} a @param {Node} b @returns {boolean} */\nfunction intersectsPolygon(a, b) {\n    // diagonal bbox; an edge whose bbox can't overlap it can't intersect it, so\n    // skip the orientation test for those (the common case — the diagonal is short)\n    const minX = Math.min(a.x, b.x);\n    const maxX = Math.max(a.x, b.x);\n    const minY = Math.min(a.y, b.y);\n    const maxY = Math.max(a.y, b.y);\n\n    let p = a;\n    do {\n        const n = p.next;\n        if ((p.x > maxX && n.x > maxX) || (p.x < minX && n.x < minX) ||\n            (p.y > maxY && n.y > maxY) || (p.y < minY && n.y < minY)) {\n            p = n;\n            continue;\n        }\n        if (p.i !== a.i && n.i !== a.i && p.i !== b.i && n.i !== b.i &&\n                intersects(p, n, a, b)) return true;\n        p = n;\n    } while (p !== a);\n\n    return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\n/** @param {Node} a @param {Node} b @returns {boolean} */\nfunction locallyInside(a, b) {\n    return area(a.prev, a, a.next) < 0 ?\n        area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n        area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\n/** @param {Node} a @param {Node} b @returns {boolean} */\nfunction middleInside(a, b) {\n    let p = a;\n    let inside = false;\n    const px = (a.x + b.x) / 2;\n    const py = (a.y + b.y) / 2;\n    do {\n        const n = p.next;\n        if (((p.y > py) !== (n.y > py)) && (px < (n.x - p.x) * (py - p.y) / (n.y - p.y) + p.x))\n            inside = !inside;\n        p = n;\n    } while (p !== a);\n\n    return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\n/** @param {Node} a @param {Node} b @returns {Node} */\nfunction splitPolygon(a, b) {\n    const a2 = createNode(a.i, a.x, a.y),\n        b2 = createNode(b.i, b.x, b.y),\n        an = a.next,\n        bp = b.prev;\n\n    a.next = b;\n    b.prev = a;\n\n    a2.next = an;\n    an.prev = a2;\n\n    b2.next = a2;\n    a2.prev = b2;\n\n    bp.next = b2;\n    b2.prev = bp;\n\n    return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\n/** @param {number} i @param {number} x @param {number} y @param {Node | null} last @returns {Node} */\nfunction insertNode(i, x, y, last) {\n    const p = createNode(i, x, y);\n\n    if (!last) {\n        p.prev = p;\n        p.next = p;\n\n    } else {\n        p.next = last.next;\n        p.prev = last;\n        last.next.prev = p;\n        last.next = p;\n    }\n    return p;\n}\n\n/** @param {Node} p */\nfunction removeNode(p) {\n    p.next.prev = p.prev;\n    p.prev.next = p.next;\n\n    if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n    if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n\n    // keep the hole-bridge index's block bboxes covering the healed prev->next edge\n    if (indexActive) growBlock(p.prev, p.next);\n}\n\n/** @param {number} i @param {number} x @param {number} y @returns {Node} */\nfunction createNode(i, x, y) {\n    // prev/next are assigned by the caller before any read, so the null init is cast away here\n    return /** @type {Node} */ (/** @type {unknown} */ ({\n        i, // vertex index in coordinates array\n        x, y, // vertex coordinates\n        prev: null, // previous and next vertex nodes in a polygon ring\n        next: null,\n        z: 0, // z-order curve value; doubles as owning block in the hole-bridge index during eliminateHoles\n        prevZ: null, // previous and next nodes in z-order\n        nextZ: null\n    }));\n}\n\n/**\n * Return the relative difference between the polygon area and the area of its triangulation —\n * a value near 0 means a correct triangulation. Useful for verifying output in tests.\n *\n * @param {ArrayLike<number>} data\n * @param {ArrayLike<number> | null} holeIndices\n * @param {number} dim number of coordinates per vertex in `data`\n * @param {ArrayLike<number>} triangles output of {@link earcut}\n * @returns {number}\n * @example deviation(data, holes, dim, earcut(data, holes, dim)); // ~0 if correct\n */\nexport function deviation(data, holeIndices, dim, triangles) {\n    const hasHoles = holeIndices && holeIndices.length;\n    const outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n    let polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n    if (hasHoles) {\n        for (let i = 0, len = holeIndices.length; i < len; i++) {\n            const start = holeIndices[i] * dim;\n            const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n            polygonArea -= Math.abs(signedArea(data, start, end, dim));\n        }\n    }\n\n    let trianglesArea = 0;\n    for (let i = 0; i < triangles.length; i += 3) {\n        const a = triangles[i] * dim;\n        const b = triangles[i + 1] * dim;\n        const c = triangles[i + 2] * dim;\n        trianglesArea += Math.abs(\n            (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n            (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n    }\n\n    // with no triangles, a polygon area within shoelace roundoff of zero (which scales with the\n    // squared coordinate magnitude) means the input was degenerate rather than mistriangulated\n    if (trianglesArea === 0) {\n        let max = 0;\n        for (let i = 0; i < data.length; i += dim) max = Math.max(max, Math.abs(data[i]), Math.abs(data[i + 1]));\n        return Math.abs(polygonArea) <= data.length * max * max * Number.EPSILON ? 0 : 1;\n    }\n    return Math.abs((trianglesArea - polygonArea) / polygonArea);\n}\n\n/** @param {ArrayLike<number>} data @param {number} start @param {number} end @param {number} dim @returns {number} */\nfunction signedArea(data, start, end, dim) {\n    let sum = 0;\n    for (let i = start, j = end - dim; i < end; i += dim) {\n        sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n        j = i;\n    }\n    return sum;\n}\n\n/**\n * Turn a polygon in multi-dimensional array form (e.g. as in GeoJSON) into the flat form Earcut accepts.\n *\n * @param {ReadonlyArray<ReadonlyArray<ArrayLike<number>>>} data array of rings; the first ring is the outer contour, the rest are holes\n * @returns {{vertices: number[], holes: number[], dimensions: number}}\n * @example const {vertices, holes, dimensions} = flatten(geojson.coordinates);\n */\nexport function flatten(data) {\n    const vertices = [];\n    const holes = [];\n    const dimensions = data[0][0].length;\n    let holeIndex = 0;\n    let prevLen = 0;\n\n    for (const ring of data) {\n        for (const p of ring) {\n            for (let d = 0; d < dimensions; d++) vertices.push(p[d]);\n        }\n        if (prevLen) {\n            holeIndex += prevLen;\n            holes.push(holeIndex);\n        }\n        prevLen = ring.length;\n    }\n    return {vertices, holes, dimensions};\n}\n\n// Reusable module-level scratch for refine():\n//   he      = twin half-edge of each edge, or -1 on the polygon boundary\n//   hTable  = open-addressing hash, slot -> half-edge index, valid iff hStamp[slot] === gen\n//   edgeStamp = pending-in-stack flag, cleared when the edge is popped\n/** @type {Int32Array} */ let edgeStack;\n/** @type {Int32Array} */ let he;\n/** @type {Int32Array} */ let hTable;\n/** @type {Uint32Array} */ let hStamp;\n/** @type {Uint8Array} */ let edgeStamp;\nlet hMask = 0, gen = 0;\n\n/**\n * Refine a triangulation toward the constrained Delaunay triangulation by legalizing every\n * interior edge in place with Lawson flips — maximizing the minimum angle and removing most\n * slivers. An optional post-pass for {@link earcut} output, or any manifold triangle-index array\n * indexing into `coords`. Adapted from delaunator's edge legalization.\n *\n * Uses non-robust predicates: float input is fine, and the worst case is a not-quite-Delaunay\n * edge, never an invalid mesh.\n *\n * @param {number[]} triangles triangle indices, as returned by {@link earcut}; mutated in place\n * @param {ArrayLike<number>} coords the flat vertex coordinates passed to {@link earcut}\n * @param {number} [dim=2] number of coordinates per vertex in `coords`\n * @example refine(earcut(data), data);\n */\nexport function refine(triangles, coords, dim = 2) {\n    const t = triangles;\n    const n = t.length;\n    if (n < 6) return;\n    ensureScratch(n);\n    gen++;              // bumping the generation logically empties the hash (no clearing)\n    he.fill(-1, 0, n);\n\n    // Build half-edge twins with an undirected-edge hash; consumed slots mark linked pairs. As each\n    // pair is linked we seed the stack with one representative (s, the earlier-inserted edge) — this\n    // fuses the initial \"push every interior edge\" pass into the build, saving a full O(n) scan.\n    // edgeStamp is all-zero here (balanced push/pop leaves it clean) and each pair links once, so\n    // the seed write needs no dedup guard.\n    let i = 0;\n    for (let e = 0; e < n; e++) {\n        const a = t[e], b = t[nextHE(e)];\n        const lo = a < b ? a : b, hi = a < b ? b : a;\n        let h = (Math.imul(lo, 0x9e3779b1) ^ Math.imul(hi, 0x85ebca6b)) & hMask;\n        while (hStamp[h] === gen) {\n            const s = hTable[h];\n            // s === -1 marks a consumed slot (a pair already linked) — skip past it\n            if (s !== -1) {\n                const sa = t[s], sb = t[nextHE(s)];\n                if ((sa === lo && sb === hi) || (sa === hi && sb === lo)) {\n                    he[e] = s; he[s] = e; hTable[h] = -1; // link, then consume the slot\n                    edgeStamp[s] = 1; edgeStack[i++] = s; // seed the interior edge for the cascade\n                    break;\n                }\n            }\n            h = (h + 1) & hMask;\n        }\n        if (hStamp[h] !== gen) { hTable[h] = e; hStamp[h] = gen; } // first occurrence: insert\n    }\n\n    while (i > 0) {\n        const a = edgeStack[--i];\n        edgeStamp[a] = 0;\n        const b = he[a];\n        if (b === -1) continue;\n\n        const a0 = a - a % 3;\n        const b0 = b - b % 3;\n        const ar = a0 + (a + 2) % 3;\n        const al = a0 + (a + 1) % 3;\n        const bl = b0 + (b + 2) % 3;\n        const br = b0 + (b + 1) % 3;\n        const p0 = t[ar], pr = t[a], pl = t[al], p1 = t[bl];\n\n        const x0 = coords[p0 * dim], y0 = coords[p0 * dim + 1];\n        const xr = coords[pr * dim], yr = coords[pr * dim + 1];\n        const xl = coords[pl * dim], yl = coords[pl * dim + 1];\n        const x1 = coords[p1 * dim], y1 = coords[p1 * dim + 1];\n\n        // Test inCircle first: most interior edges are already Delaunay (inCircle true → no flip),\n        // so this short-circuits before the two convexity orients on the common path. The quad must\n        // also be convex (both new triangles CCW) — flipping a reflex quad would push a triangle\n        // outside the polygon. Boundary/hole edges need no guard — they self-protect via he === -1.\n        if (!inCircle(x0, y0, xr, yr, xl, yl, x1, y1) &&\n            orient(x0, y0, xr, yr, x1, y1) > 0 && orient(x0, y0, x1, y1, xl, yl) > 0) {\n            t[a] = p1; t[b] = p0;\n            const hbl = he[bl], har = he[ar];\n            he[a] = hbl; if (hbl !== -1) he[hbl] = a;\n            he[b] = har; if (har !== -1) he[har] = b;\n            he[ar] = bl; he[bl] = ar;\n\n            // re-check the quad's four outer edges; skip boundary edges (he === -1) and any\n            // already queued (edgeStamp), which also keeps the stack bounded by n.\n            if (hbl    !== -1 && edgeStamp[a]  === 0) { edgeStamp[a]  = 1; edgeStack[i++] = a; }\n            if (har    !== -1 && edgeStamp[b]  === 0) { edgeStamp[b]  = 1; edgeStack[i++] = b; }\n            if (he[al] !== -1 && edgeStamp[al] === 0) { edgeStamp[al] = 1; edgeStack[i++] = al; }\n            if (he[br] !== -1 && edgeStamp[br] === 0) { edgeStamp[br] = 1; edgeStack[i++] = br; }\n        }\n    }\n}\n\n/** @param {number} ax @param {number} ay @param {number} bx @param {number} by @param {number} cx @param {number} cy */\nfunction orient(ax, ay, bx, by, cx, cy) {\n    return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);\n}\n\n// Whether p is inside or exactly on the circumcircle of triangle (a, b, c). Sign is negated vs the\n// usual predicate to match earcut's CCW winding — the standard sign would build the anti-Delaunay\n// mesh. Cocircular quads are legal ties, so refine only flips when this returns false.\n/** @param {number} ax @param {number} ay @param {number} bx @param {number} by @param {number} cx @param {number} cy @param {number} px @param {number} py */\nfunction inCircle(ax, ay, bx, by, cx, cy, px, py) {\n    const dx = ax - px, dy = ay - py, ex = bx - px, ey = by - py, fx = cx - px, fy = cy - py;\n    const ap = dx * dx + dy * dy, bp = ex * ex + ey * ey, cp = fx * fx + fy * fy;\n    // A near-cocircular quad is a legal Delaunay tie, but roundoff can flag both an edge and its\n    // flip as illegal, cascading into an endless flip loop (#205) — so treat a determinant within\n    // a small margin of zero as a tie. The determinant's worst-case roundoff error is provably\n    // below 9e-16·(ap + bp + cp)² (Shewchuk-style bound), so the margin guarantees every executed\n    // flip is illegal in exact arithmetic, and Lawson flipping always terminates.\n    const s = ap + bp + cp;\n    return dx * (ey * cp - bp * fy) - dy * (ex * cp - bp * fx) + ap * (ex * fy - ey * fx) <= 1e-13 * s * s;\n}\n\n/** @param {number} e */\nfunction nextHE(e) { // next half-edge within the same triangle\n    return e - e % 3 + (e + 1) % 3;\n}\n\n// Grow the scratch arrays on demand (like earcut's z-order arrays). Allocating lazily here rather\n// than at module load lets the whole refine() block tree-shake away for callers who don't use it.\n/** @param {number} n */\nfunction ensureScratch(n) {\n    // edgeStack holds at most one entry per half-edge (edgeStamp dedups), so n is a safe cap —\n    // sizing it up front lets the cascade push without a bounds/grow check.\n    if (!edgeStack || edgeStack.length < n) edgeStack = new Int32Array(n);\n    if (!he || he.length < n) he = new Int32Array(n);\n    if (!edgeStamp || edgeStamp.length < n) edgeStamp = new Uint8Array(n);\n    let size = 1;\n    while (size < n * 4) size <<= 1; // power-of-two table, load factor <= 0.25\n    if (!hTable || hTable.length < size) { hTable = new Int32Array(size); hStamp = new Uint32Array(size); }\n    hMask = size - 1;\n}\n","import { FeatureCollection, Feature, LineString, MultiLineString, GeometryCollection } from 'geojson';\n\nimport { LayerGeometry, LayerComponent } from './types-mesh';\n\nimport { offsetPolyline } from './utils-geometry';\nimport earcut from 'earcut';\n\n/**\n * @module triangulator-polylines\n * Polyline triangulation helpers for GeoJSON line geometries.\n *\n * This module converts `LineString`, `MultiLineString`, and supported\n * `GeometryCollection` children into closed buffered polygons in local planar\n * coordinates, then triangulates the resulting rings with `earcut` for mesh\n * rendering.\n */\nexport class TriangulatorPolylines {\n    /** Default half-width, in local planar units, used when buffering source polylines. */\n    static offset: number = 5;\n\n    /** OSM road half-widths, in local planar units, keyed by normalized `highway` tag value. */\n    static readonly ROAD_HALF_WIDTH_BY_HIGHWAY: Record<string, number> = {\n        motorway: 10,\n        motorway_link: 3.5,\n        trunk: 8,\n        trunk_link: 3.5,\n        primary: 6,\n        primary_link: 3,\n        secondary: 5,\n        secondary_link: 2.5,\n        tertiary: 4,\n        tertiary_link: 2,\n        unclassified: 3.5,\n        residential: 3.5,\n        service: 2.5,\n        living_street: 2.5,\n        road: 3.5,\n        track: 1.5,\n        path: 0.75,\n    };\n\n    /** Default road half-width used when no known `highway` tag value is available. */\n    static readonly DEFAULT_ROAD_HALF_WIDTH: number = 3.5;\n\n    /** Optional callback used to resolve a per-feature polyline half-width. */\n    static readonly defaultOffsetResolver = (_feature: Feature, _featureIndex: number): number => TriangulatorPolylines.offset;\n\n    /**\n     * Builds triangulated polyline geometry for a GeoJSON feature collection.\n     *\n     * @param geojson Source feature collection containing polyline geometries.\n     * @param origin World-space origin subtracted before converting to local planar space.\n     * @param resolveOffset Optional per-feature half-width resolver.\n     * @returns A tuple of triangulated geometry chunks and per-feature component metadata.\n     * @throws Never throws. Unsupported or degenerate features are skipped.\n     * @example\n     * const [meshes, comps] = TriangulatorPolylines.buildMesh(lineFC, origin);\n     */\n    static buildMesh(\n        geojson: FeatureCollection,\n        origin: number[],\n        resolveOffset: (feature: Feature, featureIndex: number) => number = TriangulatorPolylines.defaultOffsetResolver,\n    ): [LayerGeometry[], LayerComponent[]] {\n        const mesh: LayerGeometry[] = [];\n        const comps: LayerComponent[] = [];\n\n        const collection: Feature[] = geojson['features'];\n\n        let meshes: { flatCoords: number[], flatIds: number[] }[];\n        for (let fId = 0; fId < collection.length; fId++) {\n            const feature = collection[fId];\n            if (!feature.geometry) {\n                TriangulatorPolylines.warnSkippedFeature(fId, null);\n                continue;\n            }\n\n            const resolvedOffset = resolveOffset(feature, fId);\n            const offset = Number.isFinite(resolvedOffset) && resolvedOffset > 0\n                ? resolvedOffset\n                : TriangulatorPolylines.offset;\n\n            if (feature.geometry.type === 'LineString') {\n                meshes = TriangulatorPolylines.lineStringToPolyline(feature, origin, offset);\n            } else if (feature.geometry.type === 'MultiLineString') {\n                meshes = TriangulatorPolylines.multiLineStringToPolyline(feature, origin, offset);\n            } else if (feature.geometry.type === 'GeometryCollection') {\n                meshes = TriangulatorPolylines.geometryCollectionToPolyline(feature, origin, offset, fId);\n            } else {\n                TriangulatorPolylines.warnSkippedFeature(fId, feature.geometry.type);\n                continue;\n            }\n\n            let nPoints = 0;\n            let nTriangles = 0;\n\n            for (const triangulation of meshes) {\n                mesh.push({ \n                    position: new Float32Array(triangulation.flatCoords), \n                    indices: new Uint32Array(triangulation.flatIds),\n                    featureIndex: fId,\n                });\n                nPoints += triangulation.flatCoords.length / 2;\n                nTriangles += triangulation.flatIds.length / 3;\n            }\n            comps.push({ nPoints, nTriangles, featureIndex: fId, featureId: feature.id });\n        }\n        return [mesh, comps];\n    }\n\n    /**\n     * Converts a single `LineString` feature into triangulated polyline mesh data.\n     *\n     * @param feature Source feature with `LineString` geometry.\n     * @param origin World-space origin subtracted before buffering.\n     * @param offset Polyline half-width used for planar buffering.\n     * @returns One triangulated polygon mesh, or an empty array when buffering fails.\n     * @throws Never throws. Degenerate buffers return an empty array.\n     * @example\n     * const [mesh] = TriangulatorPolylines.lineStringToPolyline(feature, origin, 5);\n     */\n    static lineStringToPolyline(feature: Feature, origin: number[], offset: number): { flatCoords: number[], flatIds: number[] }[] {\n        const base = <LineString>feature.geometry;\n        const localCoords = base.coordinates.map((coord: number[]) => [coord[0] - origin[0], coord[1] - origin[1]]);\n        const polygon = offsetPolyline(localCoords, offset);\n        if (polygon.length < 4) {\n            return [];\n        }\n\n        const flatIds = earcut(polygon.flat());\n        const flatCoords = polygon.map((coord: number[]) => [coord[0], coord[1]]).flat();\n\n        return [{ flatCoords, flatIds }];\n    }\n\n    /**\n     * Converts a `MultiLineString` feature into triangulated polyline meshes.\n     *\n     * @param feature Source feature with `MultiLineString` geometry.\n     * @param origin World-space origin subtracted before buffering.\n     * @param offset Polyline half-width used for planar buffering.\n     * @returns Triangulated meshes for each valid buffered line string.\n     * @throws Never throws. Invalid buffered lines are silently ignored.\n     * @example\n     * const meshes = TriangulatorPolylines.multiLineStringToPolyline(feature, origin, 5);\n     */\n    static multiLineStringToPolyline(feature: Feature, origin: number[], offset: number): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <MultiLineString>feature.geometry;\n\n        const meshes = [];\n        for (const ls of coordinates) {\n            const localCoords = ls.map((coord: number[]) => [coord[0] - origin[0], coord[1] - origin[1]]);\n            const polygon = offsetPolyline(localCoords, offset);\n            if (polygon.length < 4) {\n                continue;\n            }\n\n            const flatIds = earcut(polygon.flat());\n            const flatCoords = polygon.map((coord: number[]) => [coord[0], coord[1]]).flat();\n\n            meshes.push({ flatCoords, flatIds });\n        }\n\n        return meshes;\n    }\n\n    /**\n     * Flattens supported children of a `GeometryCollection` into polyline meshes.\n     *\n     * @param feature Source feature with `GeometryCollection` geometry.\n     * @param origin World-space origin subtracted before buffering.\n     * @param offset Polyline half-width used for planar buffering.\n     * @param featureIndex Index of the parent feature in the source collection.\n     * @returns Triangulated meshes for all supported child geometries.\n     * @throws Never throws. Unsupported children are skipped with a console warning.\n     * @example\n     * const meshes = TriangulatorPolylines.geometryCollectionToPolyline(feature, origin, 5, 0);\n     */\n    static geometryCollectionToPolyline(feature: Feature, origin: number[], offset: number, featureIndex: number): { flatCoords: number[], flatIds: number[] }[] {\n        const { geometries } = <GeometryCollection>feature.geometry;\n        const meshes = [];\n        for (const geom of geometries) {\n            const syntheticFeature = { ...feature, geometry: geom } as Feature;\n            if (geom.type === 'LineString') {\n                meshes.push(...TriangulatorPolylines.lineStringToPolyline(syntheticFeature, origin, offset));\n            } else if (geom.type === 'MultiLineString') {\n                meshes.push(...TriangulatorPolylines.multiLineStringToPolyline(syntheticFeature, origin, offset));\n            } else {\n                TriangulatorPolylines.warnSkippedGeometryCollectionChild(featureIndex, geom.type);\n            }\n        }\n        return meshes;\n    }\n\n    /**\n     * Resolves a road polyline half-width from OSM `highway` tag semantics.\n     *\n     * @param feature Source road feature with `highway` property.\n     * @returns Polyline half-width in local planar units.\n     * @throws Never throws. Falls back to `DEFAULT_ROAD_HALF_WIDTH`.\n     * @example\n     * const hw = TriangulatorPolylines.resolveRoadHalfWidth(roadFeature);\n     * // hw → 10 for motorway, 6 for primary, 3.5 for unknown\n     */\n    static resolveRoadHalfWidth(feature: Feature): number {\n        const highway = TriangulatorPolylines.normalizeRoadHighwayValue(feature.properties?.highway);\n        return highway\n            ? (TriangulatorPolylines.ROAD_HALF_WIDTH_BY_HIGHWAY[highway] ?? TriangulatorPolylines.DEFAULT_ROAD_HALF_WIDTH)\n            : TriangulatorPolylines.DEFAULT_ROAD_HALF_WIDTH;\n    }\n\n    /**\n     * Normalizes an OSM `highway` tag value for road-width lookup.\n     *\n     * @param highway Raw `highway` property value (string, semicolon-delimited, or array).\n     * @returns Normalized highway token, or `null` when unavailable.\n     * @throws Never throws.\n     * @example\n     * TriangulatorPolylines.normalizeRoadHighwayValue('motorway');  // 'motorway'\n     * TriangulatorPolylines.normalizeRoadHighwayValue('primary;secondary');  // 'primary'\n     */\n    static normalizeRoadHighwayValue(highway: unknown): string | null {\n        const values = Array.isArray(highway)\n            ? highway\n            : typeof highway === 'string'\n                ? highway.split(';')\n                : [];\n\n        for (const value of values) {\n            if (typeof value !== 'string') {\n                continue;\n            }\n\n            const normalized = value.trim().toLowerCase();\n            if (normalized.length > 0) {\n                return normalized;\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Emits a warning when a feature does not contain a supported polyline geometry.\n     *\n     * @param featureIndex Index of the skipped feature in the source collection.\n     * @param geometryType Encountered geometry type, or `null` when geometry is missing.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedFeature(featureIndex: number, geometryType: string | null): void {\n        console.warn(\n            `[autk-core] TriangulatorPolylines skipped feature ${featureIndex}: expected LineString or MultiLineString geometry, got ${geometryType ?? 'null'}.`\n        );\n    }\n\n    /**\n     * Emits a warning when a `GeometryCollection` child is not a supported polyline geometry.\n     *\n     * @param featureIndex Index of the parent feature in the source collection.\n     * @param geometryType Encountered unsupported child geometry type.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedGeometryCollectionChild(featureIndex: number, geometryType: string): void {\n        console.warn(\n            `[autk-core] TriangulatorPolylines skipped GeometryCollection child in feature ${featureIndex}: expected LineString or MultiLineString geometry, got ${geometryType}.`\n        );\n    }\n}\n","/**\n * @module triangulator-polygons\n * GeoJSON polygon triangulation and border mesh generation.\n *\n * This module converts supported GeoJSON geometries into local-space mesh data\n * for fill and outline rendering. Coordinates are translated by the supplied\n * origin before triangulation so the generated buffers can be consumed in the\n * map's shared local coordinate space. Polygon and multipolygon holes are\n * flattened into a single vertex list and passed to `earcut` with hole offsets;\n * line geometries are emitted as per-vertex border index pairs.\n */\n\nimport { \n    FeatureCollection,\n    Feature,\n    LineString,\n    MultiLineString,\n    MultiPolygon,\n    Polygon,\n    GeometryCollection\n} from \"geojson\";\n\nimport { \n    LayerBorder,\n    LayerBorderComponent,\n    LayerComponent,\n    LayerGeometry\n} from \"./types-mesh\";\n\nimport earcut from \"earcut\";\n\n/**\n * Triangulates polygonal GeoJSON features into fill and border mesh chunks.\n *\n * `TriangulatorPolygons` accepts `LineString`, `MultiLineString`, `Polygon`,\n * `MultiPolygon`, and `GeometryCollection` features containing those geometry\n * types. Fill meshes are triangulated with `earcut` after translating vertices\n * into local coordinates relative to the supplied origin. Border meshes are\n * generated as line-index pairs, with open borders for line strings and closed\n * rings for polygon outlines and holes. Unsupported or missing geometries are\n * skipped with a warning.\n */\nexport class TriangulatorPolygons {\n    /**\n     * Builds triangulated fill geometry for a feature collection.\n     *\n     * @param geojson Source feature collection.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns A tuple of mesh chunks and per-feature component counts.\n     * @throws Never throws. Unsupported features are skipped with a console warning.\n     * @example\n     * const [meshes, comps] = TriangulatorPolygons.buildMesh(polyFC, origin);\n     */\n    static buildMesh(geojson: FeatureCollection, origin: number[]): [LayerGeometry[], LayerComponent[]] {\n        const mesh: LayerGeometry[] = [];\n        const comps: LayerComponent[] = [];\n\n        const collection: Feature[] = geojson['features'];\n\n        let meshes: { flatCoords: number[], flatIds: number[] }[];\n        for (let fId=0; fId<collection.length; fId++) {\n            const feature = collection[fId];\n            if (!feature.geometry) {\n                TriangulatorPolygons.warnSkippedFeature(fId, null);\n                continue;\n            }\n\n            if (feature.geometry.type === 'LineString') {\n                meshes = TriangulatorPolygons.lineStringToMesh(feature, origin);\n            } else if (feature.geometry.type === 'MultiLineString') {\n                meshes = TriangulatorPolygons.multiLineStringToMesh(feature, origin);\n            } else if (feature.geometry.type === 'Polygon') {\n                meshes = TriangulatorPolygons.polygonToMesh(feature, origin);\n            } else if (feature.geometry.type === 'MultiPolygon') {\n                meshes = TriangulatorPolygons.multiPolygonToMesh(feature, origin);\n            } else if (feature.geometry.type === 'GeometryCollection') {\n                meshes = TriangulatorPolygons.geometryCollectionToMesh(feature, origin, fId);\n            } else {\n                TriangulatorPolygons.warnSkippedFeature(fId, feature.geometry.type);\n                continue;\n            }\n\n            let nPoints = 0;\n            let nTriangles = 0;\n\n            for (const triangulation of meshes) {\n                mesh.push({ \n                    position: new Float32Array(triangulation.flatCoords), \n                    indices: new Uint32Array(triangulation.flatIds),\n                    featureIndex: fId,\n                });\n                nPoints += triangulation.flatCoords.length / 2;\n                nTriangles += triangulation.flatIds.length / 3;\n            }\n\n            comps.push({ nPoints, nTriangles, featureIndex: fId, featureId: feature.id });\n        }\n\n        return [mesh, comps];\n    }\n\n    /**\n     * Builds border line geometry for a feature collection.\n     *\n     * @param geojson Source feature collection.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns A tuple of border chunks and per-feature border counts.\n     * @throws Never throws. Unsupported features are skipped with a console warning.\n     * @example\n     * const [borders, borderComps] = TriangulatorPolygons.buildBorder(polyFC, origin);\n     */\n    static buildBorder(geojson: FeatureCollection, origin: number[]): [LayerBorder[], LayerBorderComponent[]] {\n        const border: LayerBorder[] = [];\n        const comps: LayerBorderComponent[] = [];\n\n        const collection: Feature[] = geojson['features'];\n\n        let borders: { flatCoords: number[], flatIds: number[] }[];\n\n        for (let fId=0; fId<collection.length; fId++) {\n            const feature = collection[fId];\n            if (!feature.geometry) {\n                TriangulatorPolygons.warnSkippedFeature(fId, null);\n                continue;\n            }\n\n            if (feature.geometry.type === 'LineString') {\n                borders = TriangulatorPolygons.lineStringToBorderMesh(feature, origin);\n            } else if (feature.geometry.type === 'MultiLineString') {\n                borders = TriangulatorPolygons.multiLineStringToBorderMesh(feature, origin);\n            } else if (feature.geometry.type === 'Polygon') {\n                borders = TriangulatorPolygons.polygonToBorderMesh(feature, origin);\n            } else if (feature.geometry.type === 'MultiPolygon') {\n                borders = TriangulatorPolygons.multiPolygonToBorderMesh(feature, origin);\n            } else if (feature.geometry.type === 'GeometryCollection') {\n                borders = TriangulatorPolygons.geometryCollectionToBorderMesh(feature, origin, fId);\n            } else {\n                TriangulatorPolygons.warnSkippedFeature(fId, feature.geometry.type);\n                continue;\n            }\n\n            let nPoints = 0;\n            let nLines = 0;\n\n            for (const polyline of borders) {\n                border.push({ \n                    position: new Float32Array(polyline.flatCoords), \n                    indices: new Uint32Array(polyline.flatIds) \n                });\n                nPoints += polyline.flatCoords.length / 2;\n                nLines += polyline.flatIds.length / 2;\n            }\n\n            comps.push({nPoints, nLines});\n        }\n\n        return [border, comps];\n    }\n\n    /**\n     * Converts a `LineString` feature into triangulated fill geometry.\n     *\n     * @param feature Source feature with `LineString` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Triangulated fill meshes for the feature.\n     * @throws Never throws.\n     * @example\n     * const [mesh] = TriangulatorPolygons.lineStringToMesh(lineFeature, origin);\n     */\n    static lineStringToMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <LineString>feature.geometry;\n        const flatCoords = coordinates.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n        const flatIds = earcut(flatCoords);\n        return [{ flatCoords, flatIds }];\n    }\n\n    /**\n     * Converts a `LineString` feature into open border line geometry.\n     *\n     * @param feature Source feature with `LineString` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Border line meshes for the feature.\n     * @throws Never throws.\n     * @example\n     * const [border] = TriangulatorPolygons.lineStringToBorderMesh(lineFeature, origin);\n     */\n    static lineStringToBorderMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <LineString>feature.geometry;\n        const flatCoords = coordinates.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n        const flatIds = TriangulatorPolygons.generateOpenBorderIds(flatCoords.length / 2);\n        return [{ flatCoords, flatIds }];\n    }\n\n    /**\n     * Converts a `MultiLineString` feature into triangulated fill geometry.\n     *\n     * @param feature Source feature with `MultiLineString` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Triangulated fill meshes for each constituent line string.\n     * @throws Never throws.\n     * @example\n     * const meshes = TriangulatorPolygons.multiLineStringToMesh(mlsFeature, origin);\n     */\n    static multiLineStringToMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <MultiLineString>feature.geometry;\n        const meshes = [];\n        for (const lineString of coordinates) {\n            const flatCoords = lineString.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n            const flatIds = earcut(flatCoords);\n            meshes.push({ flatCoords, flatIds });\n        }\n        return meshes;\n    }\n\n    /**\n     * Converts a `MultiLineString` feature into border line geometry.\n     *\n     * @param feature Source feature with `MultiLineString` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Border line meshes for each constituent line string.\n     * @throws Never throws.\n     * @example\n     * const borders = TriangulatorPolygons.multiLineStringToBorderMesh(mlsFeature, origin);\n     */\n    static multiLineStringToBorderMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <MultiLineString>feature.geometry;\n        const borders = [];\n        for (const lineString of coordinates) {\n            const flatCoords = lineString.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n            const flatIds = TriangulatorPolygons.generateOpenBorderIds(flatCoords.length / 2);\n            borders.push({ flatCoords, flatIds });\n        }\n        return borders;\n    }\n\n    /**\n     * Converts a `Polygon` feature into triangulated fill geometry with hole support.\n     *\n     * @param feature Source feature with `Polygon` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Triangulated fill meshes for the polygon, including holes.\n     * @throws Never throws.\n     * @example\n     * const [mesh] = TriangulatorPolygons.polygonToMesh(polyFeature, origin);\n     */\n    static polygonToMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <Polygon>feature.geometry;\n        const coords = coordinates[0].map((cord: number[]) => cord);\n        const holes: number[] = [];\n        for (let i = 1; i < coordinates.length; i++) {\n            holes.push(coords.length);\n            coordinates[i].forEach((cord: number[]) => coords.push(cord));\n        }\n\n        const flatCoords = coords.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n        const flatIds = earcut(flatCoords, holes.length > 0 ? holes : undefined);\n        return [{ flatCoords, flatIds }];\n    }\n\n    /**\n     * Converts a `Polygon` feature into closed border line geometry.\n     *\n     * @param feature Source feature with `Polygon` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Border line meshes for all polygon rings.\n     * @throws Never throws.\n     * @example\n     * const borders = TriangulatorPolygons.polygonToBorderMesh(polyFeature, origin);\n     */\n    static polygonToBorderMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const { coordinates } = <Polygon>feature.geometry;\n        return coordinates.map((ring: number[][]) => {\n            const flatCoords = ring.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n            const flatIds = TriangulatorPolygons.generateClosedBorderIds(ring);\n            return { flatCoords, flatIds };\n        });\n    }\n\n    /**\n     * Converts a `MultiPolygon` feature into triangulated fill geometry.\n     *\n     * @param feature Source feature with `MultiPolygon` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Triangulated fill meshes for each polygon in the collection.\n     * @throws Never throws.\n     * @example\n     * const meshes = TriangulatorPolygons.multiPolygonToMesh(mpFeature, origin);\n     */\n    static multiPolygonToMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const meshes = [];\n        const { coordinates } = <MultiPolygon>feature.geometry;\n        for (const polygon of coordinates) {\n            const coords = polygon[0].map((cord: number[]) => cord);\n            const holes: number[] = [];\n            for (let i = 1; i < polygon.length; i++) {\n                holes.push(coords.length);\n                polygon[i].forEach((cord: number[]) => coords.push(cord));\n            }\n            \n            const flatCoords = coords.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n            const flatIds = earcut(flatCoords, holes.length > 0 ? holes : undefined);\n            meshes.push({ flatCoords, flatIds });\n        }\n        return meshes;\n    }\n\n    /**\n     * Converts a `MultiPolygon` feature into border line geometry.\n     *\n     * @param feature Source feature with `MultiPolygon` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @returns Border line meshes for all rings in all polygons.\n     * @throws Never throws.\n     * @example\n     * const borders = TriangulatorPolygons.multiPolygonToBorderMesh(mpFeature, origin);\n     */\n    static multiPolygonToBorderMesh(feature: Feature, origin: number[]): { flatCoords: number[], flatIds: number[] }[] {\n        const borders = [];\n        const { coordinates } = <MultiPolygon>feature.geometry;\n        for (const polygon of coordinates) {\n            for (const ring of polygon) {\n                const flatCoords = ring.map((cord: number[]) => [cord[0] - origin[0], cord[1] - origin[1]]).flat();\n                const flatIds = TriangulatorPolygons.generateClosedBorderIds(ring);\n                borders.push({ flatCoords, flatIds });\n            }\n        }\n        return borders;\n    }\n\n    /**\n     * Flattens supported children of a `GeometryCollection` into fill meshes.\n     *\n     * @param feature Source feature with `GeometryCollection` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @param featureIndex Index of the parent feature in the source collection.\n     * @returns Triangulated fill meshes for all supported child geometries.\n     * @throws Never throws. Unsupported children are skipped with a console warning.\n     * @example\n     * const meshes = TriangulatorPolygons.geometryCollectionToMesh(gcFeature, origin, 0);\n     */\n    static geometryCollectionToMesh(feature: Feature, origin: number[], featureIndex: number): { flatCoords: number[], flatIds: number[] }[] {\n        const { geometries } = <GeometryCollection>feature.geometry;\n        const meshes = [];\n        for (const geom of geometries) {\n            const syntheticFeature = { ...feature, geometry: geom } as Feature;\n            if (geom.type === 'LineString') meshes.push(...TriangulatorPolygons.lineStringToMesh(syntheticFeature, origin));\n            else if (geom.type === 'MultiLineString') meshes.push(...TriangulatorPolygons.multiLineStringToMesh(syntheticFeature, origin));\n            else if (geom.type === 'Polygon') meshes.push(...TriangulatorPolygons.polygonToMesh(syntheticFeature, origin));\n            else if (geom.type === 'MultiPolygon') meshes.push(...TriangulatorPolygons.multiPolygonToMesh(syntheticFeature, origin));\n            else TriangulatorPolygons.warnSkippedGeometryCollectionChild(featureIndex, geom.type);\n        }\n        return meshes;\n    }\n\n    /**\n     * Flattens supported children of a `GeometryCollection` into border meshes.\n     *\n     * @param feature Source feature with `GeometryCollection` geometry.\n     * @param origin World-space origin used to derive local XY coordinates.\n     * @param featureIndex Index of the parent feature in the source collection.\n     * @returns Border line meshes for all supported child geometries.\n     * @throws Never throws. Unsupported children are skipped with a console warning.\n     * @example\n     * const borders = TriangulatorPolygons.geometryCollectionToBorderMesh(gcFeature, origin, 0);\n     */\n    static geometryCollectionToBorderMesh(feature: Feature, origin: number[], featureIndex: number): { flatCoords: number[], flatIds: number[] }[] {\n        const { geometries } = <GeometryCollection>feature.geometry;\n        const borders = [];\n        for (const geom of geometries) {\n            const syntheticFeature = { ...feature, geometry: geom } as Feature;\n            if (geom.type === 'LineString') borders.push(...TriangulatorPolygons.lineStringToBorderMesh(syntheticFeature, origin));\n            else if (geom.type === 'MultiLineString') borders.push(...TriangulatorPolygons.multiLineStringToBorderMesh(syntheticFeature, origin));\n            else if (geom.type === 'Polygon') borders.push(...TriangulatorPolygons.polygonToBorderMesh(syntheticFeature, origin));\n            else if (geom.type === 'MultiPolygon') borders.push(...TriangulatorPolygons.multiPolygonToBorderMesh(syntheticFeature, origin));\n            else TriangulatorPolygons.warnSkippedGeometryCollectionChild(featureIndex, geom.type);\n        }\n        return borders;\n    }\n\n    /**\n     * Emits a warning when a feature does not contain a supported geometry type.\n     *\n     * @param featureIndex Index of the skipped feature in the source collection.\n     * @param geometryType Encountered geometry type, or `null` when geometry is missing.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedFeature(featureIndex: number, geometryType: string | null): void {\n        console.warn(\n            `[autk-core] TriangulatorPolygons skipped feature ${featureIndex}: expected LineString, MultiLineString, Polygon, or MultiPolygon geometry, got ${geometryType ?? 'null'}.`\n        );\n    }\n\n    /**\n     * Emits a warning when a `GeometryCollection` child is not a supported geometry type.\n     *\n     * @param featureIndex Index of the parent feature in the source collection.\n     * @param geometryType Encountered unsupported child geometry type.\n     * @returns Nothing. A warning is written to the console.\n     */\n    private static warnSkippedGeometryCollectionChild(featureIndex: number, geometryType: string): void {\n        console.warn(\n            `[autk-core] TriangulatorPolygons skipped GeometryCollection child in feature ${featureIndex}: expected LineString, MultiLineString, Polygon, or MultiPolygon geometry, got ${geometryType}.`\n        );\n    }\n\n    /**\n     * Generates line index pairs for an open polyline border.\n     *\n     * @param nCoords Number of vertices in the border polyline.\n     * @returns Sequential line index pairs `[0,1, 1,2, ...]`.\n     * @throws Never throws.\n     * @example\n     * generateOpenBorderIds(3);  // [0, 1, 1, 2]\n     */\n    protected static generateOpenBorderIds(nCoords: number): number[] {\n        const ids = [];\n        for (let i = 0; i < nCoords - 1; i++) ids.push(i, i + 1);\n        return ids;\n    }\n\n    /**\n     * Generates line index pairs for a closed polygon-ring border.\n     *\n     * @param ring Polygon ring used to derive closed border connectivity.\n     * @returns Line index pairs including the closing edge back to the first vertex.\n     * @throws Never throws. Rings with fewer than 2 vertices return an empty array.\n     * @example\n     * generateClosedBorderIds([[0,0], [10,0], [10,10], [0,10], [0,0]]);\n     * // → [0, 1, 1, 2, 2, 3, 3, 0]\n     */\n    protected static generateClosedBorderIds(ring: number[][]): number[] {\n        const pointCount = ring.length;\n        if (pointCount < 2) {\n            return [];\n        }\n\n        const isExplicitlyClosed = pointCount > 1\n            && ring[0][0] === ring[pointCount - 1][0]\n            && ring[0][1] === ring[pointCount - 1][1]\n            && (ring[0][2] ?? 0) === (ring[pointCount - 1][2] ?? 0);\n        const uniquePointCount = isExplicitlyClosed ? pointCount - 1 : pointCount;\n        const ids = TriangulatorPolygons.generateOpenBorderIds(uniquePointCount);\n\n        if (uniquePointCount > 1) {\n            ids.push(uniquePointCount - 1, 0);\n        }\n\n        return ids;\n    }\n}\n","/**\n * @module triangulator-roofs\n * Roof geometry generation for OSM building footprints.\n *\n * This module turns footprint rings plus OSM roof tags into mesh buffers for\n * walls, floors, flat caps, and several roof styles. It supports direct cap\n * generation for flat, cone/pyramid, dome, round, and skillion roofs, and uses an\n * iterative straight-skeleton solve for hipped, gabled, half-hipped, mansard,\n * and saltbox roofs. When the skeleton solve cannot complete, callers fall\n * back to a flat roof cap.\n */\n\nimport earcut from \"earcut\";\n\nimport { GeoJsonProperties } from \"geojson\";\n\nimport { \n    computeRingArea, \n    isConvex, \n    normalizeRing, \n    polygonPerimeter \n} from './utils-geometry';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\n/** Local 2D point representation used by roof geometry helpers. */\ntype Vec2 = [number, number];\n\n/**\n * Flat mesh buffers produced by roof and wall triangulation helpers.\n */\nexport interface MeshData {\n    /** Flat vertex position buffer packed as consecutive XYZ triples. */\n    flatCoords: number[];\n    /** Triangle index buffer referencing vertices in `flatCoords`. */\n    flatIds: number[];\n}\n\n/**\n * Parsed OSM roof attributes used to select and parameterize roof generation.\n *\n * `shape` drives the roof generator selection, while `height`, `angle`, and\n * `direction` provide the numeric parameters used by the active roof style.\n */\nexport interface RoofInfo {\n    /** Roof shape identifier derived from `roof:shape`. */\n    shape: string;\n    /** Explicit roof height above wall top (0 = derive from angle/geometry). */\n    height: number;\n    /** Roof pitch angle in degrees. */\n    angle: number;\n    /** Compass bearing of the downslope direction (0 = N, 90 = E). Skillion only. */\n    direction: number;\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\n/** Default roof pitch angle used when no explicit OSM roof angle is provided. */\nconst DEFAULT_ROOF_ANGLE = 30;\n/** Merge tolerance used when collapsing nearly coincident skeleton vertices. */\nconst MERGE_EPS = 0.05; // 5 cm to aggressively merge coincident vertices\n/** Maximum allowed straight-skeleton bisector speed before treating the solve as unstable. */\nconst MAX_BISECTOR_SPEED = 10.0;\n\n// ─── Polygon helpers ──────────────────────────────────────────────────────────\n\n/**\n * Estimates roof height from a footprint and pitch angle.\n *\n * The height estimate uses the footprint inradius approximation `2A / P` and\n * converts the pitch angle into a vertical rise above the wall top.\n *\n * @param ring - Open roof footprint ring in local planar coordinates.\n * @param angleDeg - Roof pitch angle in degrees.\n * @returns Estimated roof height above the wall top.\n */\nfunction heightFromAngle(ring: Vec2[], angleDeg: number): number {\n    const area = Math.abs(computeRingArea(ring));\n    const perim = polygonPerimeter(ring);\n    return perim > 1e-9 ? (2 * area / perim) * Math.tan((angleDeg * Math.PI) / 180) : 0;\n}\n\n// ─── Wall generation ──────────────────────────────────────────────────────────\n\n/**\n * Generates vertical wall quads for a footprint between two elevations.\n *\n * `rings[0]` is treated as the outer footprint (CCW) and subsequent rings are\n * hole boundaries (CW). Each ring segment becomes one outward-facing quad\n * strip with CCW winding for correct face normals.\n *\n * @param rings - Polygon rings in local planar coordinates.\n * @param minH - Wall base elevation.\n * @param maxH - Wall top elevation.\n * @returns Wall mesh buffers for all ring segments.\n * @throws Never throws. Returns empty buffers for empty or degenerate rings.\n * @example\n * const walls = buildWalls([[[0, 0], [10, 0], [10, 5], [0, 5]]], 0, 20);\n * // walls.flatIds.length / 3 → 8 (4 quads × 2 triangles)\n */\nexport function buildWalls(rings: Vec2[][], minH: number, maxH: number): MeshData {\n    const flatCoords: number[] = [];\n    const flatIds: number[] = [];\n\n    for (let ri = 0; ri < rings.length; ri++) {\n        // Outer ring must be CCW (outward normals); inner rings (holes) must be CW.\n        let open = normalizeRing(rings[ri]) as Vec2[];\n        const area = computeRingArea(open);\n        if (ri === 0 && area < 0) open = [...open].reverse();\n        if (ri > 0 && area > 0) open = [...open].reverse();\n        const n = open.length;\n        for (let i = 0; i < n; i++) {\n            const j = (i + 1) % n;\n            const [x0, y0] = open[i];\n            const [x1, y1] = open[j];\n            const base = flatCoords.length / 3;\n            // v0=BL, v1=BR, v2=TR, v3=TL\n            flatCoords.push(\n                x0, y0, minH,\n                x1, y1, minH,\n                x1, y1, maxH,\n                x0, y0, maxH,\n            );\n            // Two triangles, CCW winding gives outward face normals for CCW outer rings.\n            flatIds.push(base, base + 1, base + 2, base, base + 2, base + 3);\n        }\n    }\n\n    return { flatCoords, flatIds };\n}\n\n// ─── Flat roof ────────────────────────────────────────────────────────────────\n\n/**\n * Builds a flat triangulated roof cap, including hole support.\n *\n * The cap follows the full footprint at a constant Z elevation. The outer\n * ring is enforced to CCW winding so earcut produces upward-facing triangles;\n * holes are preserved via hole-start offsets.\n *\n * @param rings - Polygon rings in local planar coordinates.\n * @param height - Z elevation of the flat roof plane.\n * @returns Triangulated roof-cap mesh buffers.\n * @throws Never throws. Degenerate rings produce empty or degenerate mesh buffers.\n * @example\n * const cap = flatRoof([[[0, 0], [10, 0], [10, 10], [0, 10]]], 25);\n * // cap is a triangulated quad at z=25\n */\nexport function flatRoof(rings: Vec2[][], height: number): MeshData {\n    let outer = normalizeRing(rings[0]) as Vec2[];\n    // Enforce CCW so earcut produces outward-facing (upward) triangles.\n    if (computeRingArea(outer) < 0) outer = [...outer].reverse();\n    const allVerts: Vec2[] = [...outer];\n    const holeStarts: number[] = [];\n    for (let i = 1; i < rings.length; i++) {\n        holeStarts.push(allVerts.length);\n        allVerts.push(...(normalizeRing(rings[i]) as Vec2[]));\n    }\n    const flat2D = allVerts.flatMap(v => v);\n    const triIds = earcut(flat2D, holeStarts.length > 0 ? holeStarts : undefined);\n    const flatCoords = allVerts.flatMap(([x, y]) => [x, y, height]);\n    return { flatCoords, flatIds: triIds };\n}\n\n/**\n * Builds a flat downward-facing floor cap for floating building parts.\n *\n * The floor uses the same footprint topology as the roof cap but enforces CW\n * winding on the outer ring so earcut produces downward-facing (-Z) triangles.\n * Holes are reversed to CCW for correct punch-through.\n *\n * @param rings - Polygon rings in local planar coordinates.\n * @param height - Z elevation of the floor plane.\n * @returns Triangulated floor-cap mesh buffers.\n * @throws Never throws. Degenerate rings produce empty or degenerate mesh buffers.\n * @example\n * const floor = flatFloor([[[0, 0], [10, 0], [10, 10], [0, 10]]], 5);\n * // floor is a triangulated quad at z=5 facing downward\n */\nexport function flatFloor(rings: Vec2[][], height: number): MeshData {\n    let outer = normalizeRing(rings[0]) as Vec2[];\n    // Enforce CW so earcut produces downward-facing (-Z) triangles.\n    if (computeRingArea(outer) > 0) outer = [...outer].reverse();\n    const allVerts: Vec2[] = [...outer];\n    const holeStarts: number[] = [];\n    for (let i = 1; i < rings.length; i++) {\n        holeStarts.push(allVerts.length);\n        // Holes inside CW outer ring must be CCW to punch correctly in earcut.\n        let hole = normalizeRing(rings[i]) as Vec2[];\n        if (computeRingArea(hole) < 0) hole = [...hole].reverse();\n        allVerts.push(...hole);\n    }\n    const flat2D = allVerts.flatMap(v => v);\n    const triIds = earcut(flat2D, holeStarts.length > 0 ? holeStarts : undefined);\n    const flatCoords = allVerts.flatMap(([x, y]) => [x, y, height]);\n    return { flatCoords, flatIds: triIds };\n}\n\n// ─── Pyramid roof ─────────────────────────────────────────────────────────────\n\n/**\n * Builds a pyramid (cone) roof by fan-triangulating the outer footprint to an apex.\n *\n * Only the outer ring is used; holes are ignored. The apex is placed at the\n * centroid of the footprint. Each edge becomes a triangle fan segment.\n *\n * @param ring - Outer roof footprint ring in local planar coordinates.\n * @param baseH - Wall top elevation.\n * @param roofH - Additional height of the roof apex above `baseH`.\n * @returns Triangulated pyramid-roof mesh buffers.\n * @throws Never throws. Rings with fewer than 3 vertices produce empty buffers.\n * @example\n * const roof = pyramidRoof([[0, 0], [10, 0], [10, 10], [0, 10]], 20, 5);\n * // roof is a fan of 4 triangles meeting at the centroid at z=25\n */\nexport function pyramidRoof(ring: Vec2[], baseH: number, roofH: number): MeshData {\n    let open = normalizeRing(ring) as Vec2[];\n    // Enforce CCW so all face normals point outward.\n    if (computeRingArea(open) < 0) open = [...open].reverse();\n    const n = open.length;\n    const cx = open.reduce((s, v) => s + v[0], 0) / n;\n    const cy = open.reduce((s, v) => s + v[1], 0) / n;\n\n    const flatCoords: number[] = [];\n    const flatIds: number[] = [];\n\n    for (let i = 0; i < n; i++) {\n        const j = (i + 1) % n;\n        const base = flatCoords.length / 3;\n        \n        flatCoords.push(\n            open[i][0], open[i][1], baseH,\n            open[j][0], open[j][1], baseH,\n            cx, cy, baseH + roofH\n        );\n        \n        flatIds.push(base, base + 1, base + 2);\n    }\n\n    return { flatCoords, flatIds };\n}\n\n// ─── Dome roof ────────────────────────────────────────────────────────────────\n\n/**\n * Builds a tessellated curved dome roof with 4 latitude bands.\n *\n * The outer footprint is progressively shrunk toward the center using a\n * cosine/sine profile, creating a hemispherical shell. The supplied roof\n * height sets the apex above `baseH`.\n *\n * @param ring - Outer roof footprint ring in local planar coordinates.\n * @param baseH - Wall top elevation.\n * @param roofH - Additional dome height above `baseH`.\n * @returns Tessellated dome-roof mesh buffers.\n * @throws Never throws. Rings with fewer than 3 vertices produce empty buffers.\n * @example\n * const dome = domeRoof([[0, 0], [10, 0], [10, 10], [0, 10]], 20, 8);\n * // dome is a tessellated hemisphere cap\n */\nexport function domeRoof(ring: Vec2[], baseH: number, roofH: number): MeshData {\n    let open = normalizeRing(ring) as Vec2[];\n    if (computeRingArea(open) < 0) open = [...open].reverse();\n    const n = open.length;\n    const cx = open.reduce((s, v) => s + v[0], 0) / n;\n    const cy = open.reduce((s, v) => s + v[1], 0) / n;\n\n    const flatCoords: number[] = [];\n    const flatIds: number[] = [];\n\n    const numLatitudes = 4;\n    \n    const rings3D: [number, number, number][][] = [];\n    for (let k = 0; k <= numLatitudes; k++) {\n        const alpha = (k / numLatitudes) * (Math.PI / 2);\n        const cosA = Math.cos(alpha);\n        const sinA = Math.sin(alpha);\n        \n        const currentRing: [number, number, number][] = [];\n        if (k === numLatitudes) {\n            currentRing.push([cx, cy, baseH + roofH]);\n        } else {\n            for (let i = 0; i < n; i++) {\n                const vx = cx + (open[i][0] - cx) * cosA;\n                const vy = cy + (open[i][1] - cy) * cosA;\n                const vz = baseH + roofH * sinA;\n                currentRing.push([vx, vy, vz]);\n            }\n        }\n        rings3D.push(currentRing);\n    }\n    \n    for (let k = 0; k < numLatitudes; k++) {\n        const bottomRing = rings3D[k];\n        const topRing = rings3D[k + 1];\n        \n        if (k === numLatitudes - 1) {\n            const apex = topRing[0];\n            for (let i = 0; i < n; i++) {\n                const j = (i + 1) % n;\n                const base = flatCoords.length / 3;\n                flatCoords.push(\n                    bottomRing[i][0], bottomRing[i][1], bottomRing[i][2],\n                    bottomRing[j][0], bottomRing[j][1], bottomRing[j][2],\n                    apex[0], apex[1], apex[2]\n                );\n                flatIds.push(base, base + 1, base + 2);\n            }\n        } else {\n            for (let i = 0; i < n; i++) {\n                const j = (i + 1) % n;\n                const base = flatCoords.length / 3;\n                \n                flatCoords.push(\n                    bottomRing[i][0], bottomRing[i][1], bottomRing[i][2],\n                    bottomRing[j][0], bottomRing[j][1], bottomRing[j][2],\n                    topRing[j][0], topRing[j][1], topRing[j][2],\n                    \n                    topRing[j][0], topRing[j][1], topRing[j][2],\n                    topRing[i][0], topRing[i][1], topRing[i][2],\n                    bottomRing[i][0], bottomRing[i][1], bottomRing[i][2]\n                );\n                flatIds.push(base, base + 1, base + 2, base + 3, base + 4, base + 5);\n            }\n        }\n    }\n\n    return { flatCoords, flatIds };\n}\n\n// ─── Round roof ───────────────────────────────────────────────────────────────\n\n/**\n * Subdivides each triangle in a mesh into four smaller triangles.\n *\n * Shared edge midpoints are cached so adjacent triangles reuse the same new\n * vertex instead of duplicating it.\n *\n * @param flatCoords - Input flat XYZ coordinate buffer.\n * @param flatIds - Input triangle index buffer.\n * @returns Refined mesh buffers with subdivided triangles.\n */\nfunction subdivideMesh(flatCoords: number[], flatIds: number[]): { flatCoords: number[], flatIds: number[] } {\n    const nextCoords = [...flatCoords];\n    const nextIds: number[] = [];\n    const edgeCache = new Map<string, number>();\n\n    /**\n     * Returns the index of the midpoint vertex between two mesh vertices.\n     *\n     * Midpoints are cached per undirected edge so repeated requests return the\n     * same vertex index.\n     *\n     * @param i1 - First vertex index.\n     * @param i2 - Second vertex index.\n     * @returns Index of the midpoint vertex in `nextCoords`.\n     */\n    function getMidpoint(i1: number, i2: number): number {\n        const minI = Math.min(i1, i2);\n        const maxI = Math.max(i1, i2);\n        const key = `${minI}_${maxI}`;\n        if (edgeCache.has(key)) return edgeCache.get(key)!;\n\n        const x = (flatCoords[i1 * 3] + flatCoords[i2 * 3]) / 2;\n        const y = (flatCoords[i1 * 3 + 1] + flatCoords[i2 * 3 + 1]) / 2;\n        const z = (flatCoords[i1 * 3 + 2] + flatCoords[i2 * 3 + 2]) / 2;\n        const idx = nextCoords.length / 3;\n        nextCoords.push(x, y, z);\n        edgeCache.set(key, idx);\n        return idx;\n    }\n\n    for (let i = 0; i < flatIds.length; i += 3) {\n        const i0 = flatIds[i];\n        const i1 = flatIds[i + 1];\n        const i2 = flatIds[i + 2];\n\n        const m01 = getMidpoint(i0, i1);\n        const m12 = getMidpoint(i1, i2);\n        const m20 = getMidpoint(i2, i0);\n\n        nextIds.push(\n            i0, m01, m20,\n            i1, m12, m01,\n            i2, m20, m12,\n            m01, m12, m20\n        );\n    }\n\n    return { flatCoords: nextCoords, flatIds: nextIds };\n}\n\n/**\n * Builds a half-cylinder (barrel vault) roof.\n *\n * The longest footprint edge defines the barrel axis; the footprint is then\n * projected into a rounded profile using 3 levels of subdivision. Boundary\n * edges without a neighbor are capped with vertical skirt quads.\n *\n * @param ring - Outer roof footprint ring in local planar coordinates.\n * @param baseH - Wall top elevation.\n * @param roofH - Additional roof height above `baseH`.\n * @returns Barrel-vault roof mesh buffers including skirt geometry.\n * @throws Never throws. Degenerate footprints produce empty or minimal buffers.\n * @example\n * const barrel = roundRoof([[0, 0], [20, 0], [20, 8], [0, 8]], 15, 4);\n * // barrel is a subdivided half-cylinder + skirt caps\n */\nexport function roundRoof(ring: Vec2[], baseH: number, roofH: number): MeshData {\n    let open = normalizeRing(ring) as Vec2[];\n    if (computeRingArea(open) < 0) open = [...open].reverse();\n    \n    let maxLen = 0;\n    let dx = 1, dy = 0;\n    const n = open.length;\n    for (let i = 0; i < n; i++) {\n        const j = (i + 1) % n;\n        const ex = open[j][0] - open[i][0];\n        const ey = open[j][1] - open[i][1];\n        const len = Math.sqrt(ex * ex + ey * ey);\n        if (len > maxLen) {\n            maxLen = len;\n            dx = ex / len;\n            dy = ey / len;\n        }\n    }\n    \n    // Transverse axis\n    const tx = -dy;\n    const ty = dx;\n    \n    const projs = open.map(([x, y]) => x * tx + y * ty);\n    const minT = Math.min(...projs);\n    const maxT = Math.max(...projs);\n    const centerT = (minT + maxT) / 2;\n    const radiusT = (maxT - minT) / 2;\n\n    const flat2D = open.flatMap(v => v);\n    let triIds = earcut(flat2D);\n    let flatCoords = open.flatMap(([x, y]) => [x, y, baseH]);\n    \n    let mesh = { flatCoords, flatIds: triIds };\n    \n    // Subdivide mesh (3 iterations = 64 triangles per original triangle)\n    mesh = subdivideMesh(mesh.flatCoords, mesh.flatIds);\n    mesh = subdivideMesh(mesh.flatCoords, mesh.flatIds);\n    mesh = subdivideMesh(mesh.flatCoords, mesh.flatIds);\n    \n    for (let i = 0; i < mesh.flatCoords.length; i += 3) {\n        const x = mesh.flatCoords[i];\n        const y = mesh.flatCoords[i + 1];\n        const t = x * tx + y * ty;\n        let norm = radiusT > 1e-5 ? (t - centerT) / radiusT : 0;\n        norm = Math.max(-1, Math.min(1, norm));\n        mesh.flatCoords[i + 2] = baseH + roofH * Math.sqrt(1 - norm * norm);\n    }\n    \n    const edgeCounts = new Map<string, number>();\n    for (let i = 0; i < mesh.flatIds.length; i += 3) {\n        for (let j = 0; j < 3; j++) {\n            const v1 = mesh.flatIds[i + j];\n            const v2 = mesh.flatIds[i + ((j + 1) % 3)];\n            const minV = Math.min(v1, v2);\n            const maxV = Math.max(v1, v2);\n            const key = `${minV}_${maxV}`;\n            edgeCounts.set(key, (edgeCounts.get(key) || 0) + 1);\n        }\n    }\n    \n    const outCoords: number[] = [];\n    const outIds: number[] = [];\n    \n    // Unroll cap\n    for (let i = 0; i < mesh.flatIds.length; i += 3) {\n        const i0 = mesh.flatIds[i] * 3;\n        const i1 = mesh.flatIds[i + 1] * 3;\n        const i2 = mesh.flatIds[i + 2] * 3;\n        \n        const base = outCoords.length / 3;\n        outCoords.push(\n            mesh.flatCoords[i0], mesh.flatCoords[i0 + 1], mesh.flatCoords[i0 + 2],\n            mesh.flatCoords[i1], mesh.flatCoords[i1 + 1], mesh.flatCoords[i1 + 2],\n            mesh.flatCoords[i2], mesh.flatCoords[i2 + 1], mesh.flatCoords[i2 + 2]\n        );\n        outIds.push(base, base + 1, base + 2);\n    }\n    \n    // Unroll skirt\n    for (let i = 0; i < mesh.flatIds.length; i += 3) {\n        for (let j = 0; j < 3; j++) {\n            const v1 = mesh.flatIds[i + j];\n            const v2 = mesh.flatIds[i + ((j + 1) % 3)];\n            const minV = Math.min(v1, v2);\n            const maxV = Math.max(v1, v2);\n            if (edgeCounts.get(`${minV}_${maxV}`) === 1) {\n                const x1 = mesh.flatCoords[v1 * 3];\n                const y1 = mesh.flatCoords[v1 * 3 + 1];\n                const z1 = mesh.flatCoords[v1 * 3 + 2];\n                const x2 = mesh.flatCoords[v2 * 3];\n                const y2 = mesh.flatCoords[v2 * 3 + 1];\n                const z2 = mesh.flatCoords[v2 * 3 + 2];\n                \n                // Skip if gap is negligible\n                if (z1 - baseH < 1e-5 && z2 - baseH < 1e-5) continue;\n                \n                const base = outCoords.length / 3;\n                outCoords.push(\n                    x1, y1, baseH,\n                    x2, y2, baseH,\n                    x2, y2, z2,\n                    x1, y1, z1\n                );\n                outIds.push(base, base + 1, base + 2, base + 2, base + 3, base);\n            }\n        }\n    }\n    \n    return { flatCoords: outCoords, flatIds: outIds };\n}\n\n// ─── Skillion roof ────────────────────────────────────────────────────────────\n\n/**\n * Builds a single-plane sloped (skillion) roof.\n *\n * `directionDeg` controls the downslope bearing (0° = N, 90° = E). The\n * footprint is lifted into a plane where the upslope end reaches full roof\n * height and the downslope end stays at base elevation. Vertical skirt quads\n * fill any gaps between the base and the elevated edges.\n *\n * @param ring - Outer roof footprint ring in local planar coordinates.\n * @param baseH - Wall top elevation.\n * @param roofH - Additional roof height above `baseH` at the upslope end.\n * @param directionDeg - Compass bearing of the downslope direction (0 = N, 90 = E).\n * @returns Skillion-roof mesh buffers including skirt geometry.\n * @throws Never throws. Degenerate footprints produce empty or minimal buffers.\n * @example\n * const skillion = skillionRoof([[0, 0], [10, 0], [10, 10], [0, 10]], 20, 5, 180);\n * // skillion slopes south; north edge at z=25, south edge at z=20\n */\nexport function skillionRoof(ring: Vec2[], baseH: number, roofH: number, directionDeg: number): MeshData {\n    let open = normalizeRing(ring) as Vec2[];\n    if (computeRingArea(open) < 0) open = [...open].reverse();\n    const rad = (directionDeg * Math.PI) / 180;\n    const dx = Math.sin(rad);\n    const dy = Math.cos(rad);\n\n    const projs = open.map(([x, y]) => x * dx + y * dy);\n    const minP = Math.min(...projs);\n    const maxP = Math.max(...projs);\n    const range = maxP - minP;\n\n    // maxP end is downslope (low elevation); minP end is high.\n    const elevs = projs.map(p => range > 1e-9 ? ((maxP - p) / range) * roofH : 0);\n\n    const flat2D = open.flatMap(v => v);\n    const triIds = earcut(flat2D);\n    \n    const flatCoords: number[] = [];\n    const flatIds: number[] = [];\n    \n    // Add roof cap (unrolled)\n    for (let i = 0; i < triIds.length; i += 3) {\n        const i0 = triIds[i];\n        const i1 = triIds[i + 1];\n        const i2 = triIds[i + 2];\n        \n        const base = flatCoords.length / 3;\n        flatCoords.push(\n            open[i0][0], open[i0][1], baseH + elevs[i0],\n            open[i1][0], open[i1][1], baseH + elevs[i1],\n            open[i2][0], open[i2][1], baseH + elevs[i2]\n        );\n        flatIds.push(base, base + 1, base + 2);\n    }\n\n    // Add walls (skirt) to fill the gap from baseH to baseH + elevs[i]\n    const n = open.length;\n    for (let i = 0; i < n; i++) {\n        const j = (i + 1) % n;\n        const eI = elevs[i];\n        const eJ = elevs[j];\n        if (eI < 1e-5 && eJ < 1e-5) continue; // no gap to fill on this edge\n\n        const base = flatCoords.length / 3;\n        // Vertices: bottom-left(i, base), bottom-right(j, base), top-right(j, roof), top-left(i, roof)\n        flatCoords.push(\n            open[i][0], open[i][1], baseH,\n            open[j][0], open[j][1], baseH,\n            open[j][0], open[j][1], baseH + eJ,\n            open[i][0], open[i][1], baseH + eI\n        );\n        // CCW outward normal\n        flatIds.push(base, base + 1, base + 2, base + 2, base + 3, base);\n    }\n\n    return { flatCoords, flatIds };\n}\n\n// ─── Straight skeleton (hipped / gabled) ─────────────────────────────────────\n\n/** Vertex state used during straight-skeleton simulation. */\ninterface SkelVert {\n    /** Current 2D vertex position. */\n    pos: Vec2;\n    /** Current propagated roof height at this vertex. */\n    h: number;\n    /** Index of the source edge currently associated with the vertex. */\n    edgeIdx: number;\n}\n\n/** One straight-skeleton face described as a list of 3D vertices. */\ntype Face3D = [number, number, number][];\n\n/**\n * Computes inward unit normals for each edge of a CCW polygon.\n *\n * @param pts - CCW polygon vertices.\n * @returns Inward-facing unit normal for each polygon edge.\n */\nfunction inwardNormals(pts: Vec2[]): Vec2[] {\n    const n = pts.length;\n    return pts.map((_, i) => {\n        const j = (i + 1) % n;\n        const dx = pts[j][0] - pts[i][0];\n        const dy = pts[j][1] - pts[i][1];\n        const len = Math.sqrt(dx * dx + dy * dy);\n        return len > 1e-10 ? ([-dy / len, dx / len] as Vec2) : ([0, 0] as Vec2);\n    });\n}\n\n/**\n * Computes vertex velocities from inward edge normals and propagation speeds.\n *\n * @param sv - Current straight-skeleton vertices.\n * @param norms - Inward unit edge normals for the current polygon state.\n * @param speeds - Per-edge propagation speeds.\n * @returns Velocity vector for each skeleton vertex.\n */\nfunction bisectorVelocities(sv: SkelVert[], norms: Vec2[], speeds: number[]): Vec2[] {\n    const n = sv.length;\n    return sv.map((vert, i) => {\n        const prev = (i + n - 1) % n;\n        const n1 = norms[prev]; \n        const n2 = norms[i];   \n        const s1 = speeds[sv[prev].edgeIdx];\n        const s2 = speeds[vert.edgeIdx];\n\n        const cross = n1[0] * n2[1] - n1[1] * n2[0];\n        if (Math.abs(cross) > 1e-8) {\n            const vx = (s1 * n2[1] - s2 * n1[1]) / cross;\n            const vy = (n1[0] * s2 - n2[0] * s1) / cross;\n            return [vx, vy] as Vec2;\n        }\n        return [n2[0] * s2, n2[1] * s2] as Vec2;\n    });\n}\n\n/**\n * Estimates the time until two moving vertices collapse together.\n *\n * @param pi - First vertex position.\n * @param pj - Second vertex position.\n * @param vi - Velocity of the first vertex.\n * @param vj - Velocity of the second vertex.\n * @returns Estimated collapse time, or `Infinity` when no collapse occurs.\n */\nfunction collapseTime(pi: Vec2, pj: Vec2, vi: Vec2, vj: Vec2): number {\n    const dPx = pj[0] - pi[0];\n    const dPy = pj[1] - pi[1];\n    const dVx = vi[0] - vj[0];\n    const dVy = vi[1] - vj[1];\n    \n    const dot = dPx * dVx + dPy * dVy;\n    if (dot <= 1e-8) return Infinity;\n    \n    const dvl2 = dVx * dVx + dVy * dVy;\n    if (dvl2 < 1e-12) return Infinity;\n    \n    const t = dot / dvl2;\n    return t;\n}\n\n/**\n * Removes adjacent near-duplicate vertices before skeleton processing begins.\n *\n * @param verts - Initial polygon vertices.\n * @param eps - Merge tolerance.\n * @returns Filtered vertex list with adjacent duplicates removed.\n */\nfunction deduplicateVertsInitial(verts: SkelVert[], eps: number): SkelVert[] {\n    const res: SkelVert[] = [];\n    const n = verts.length;\n    for (let i = 0; i < n; i++) {\n        const j = (i + 1) % n;\n        const dx = verts[i].pos[0] - verts[j].pos[0];\n        const dy = verts[i].pos[1] - verts[j].pos[1];\n        if (Math.sqrt(dx * dx + dy * dy) >= eps) {\n            res.push(verts[i]);\n        }\n    }\n    return res;\n}\n\n/**\n * Classifies polygon edges as gable candidates based on their orientation.\n *\n * @param ring - Open roof footprint ring.\n * @returns Boolean flags indicating which edges behave as gable ends.\n */\nfunction classifyGables(ring: Vec2[]): boolean[] {\n    const n = ring.length;\n    const edges = ring.map((p, i) => {\n        const next = ring[(i + 1) % n];\n        const dx = next[0] - p[0];\n        const dy = next[1] - p[1];\n        const len = Math.sqrt(dx * dx + dy * dy);\n        return { dx: dx / len, dy: dy / len, len };\n    });\n    \n    let maxLen = 0;\n    let mainDx = 0, mainDy = 0;\n    for (const e of edges) {\n        if (e.len > maxLen) {\n            maxLen = e.len;\n            mainDx = e.dx;\n            mainDy = e.dy;\n        }\n    }\n    \n    return edges.map(e => {\n        const dot = Math.abs(e.dx * mainDx + e.dy * mainDy);\n        return dot < 0.8;\n    });\n}\n\n/**\n * Derives straight-skeleton edge speeds from roof-shape metadata.\n *\n * `gabled`, `half-hipped`, and `saltbox` adjust speeds on edges classified as\n * gable ends; other supported skeleton roofs use uniform propagation.\n *\n * @param ring - Open roof footprint ring.\n * @param info - Parsed roof configuration.\n * @returns Per-edge propagation speeds used by the skeleton solver.\n */\nfunction getEdgeSpeeds(ring: Vec2[], info: RoofInfo): number[] {\n    const n = ring.length;\n    const defaultSpeeds = new Array(n).fill(1.0);\n    \n    if (info.shape === 'hipped' || info.shape === 'pyramidal' || info.shape === 'pyramid' || info.shape === 'mansard') {\n        return defaultSpeeds;\n    }\n\n    const isGable = classifyGables(ring);\n    \n    if (info.shape === 'gabled') {\n        return isGable.map(g => g ? 0.0 : 1.0);\n    }\n    \n    if (info.shape === 'half-hipped') {\n        return isGable.map(g => g ? 0.3 : 1.0);\n    }\n    \n    if (info.shape === 'saltbox') {\n        let eaveCount = 0;\n        return isGable.map(g => {\n            if (g) return 0.0;\n            eaveCount++;\n            return eaveCount === 1 ? 1.0 : 2.0;\n        });\n    }\n    \n    return defaultSpeeds;\n}\n\n/**\n * Builds a straight skeleton for a convex roof footprint.\n *\n * Concave footprints, unstable bisector motion, or geometry that escapes the\n * footprint bounds abort the solve and return an empty result.\n *\n * @param ring - Open convex roof footprint ring.\n * @param speeds - Per-edge propagation speeds.\n * @param maxHCap - Maximum allowed propagated skeleton height.\n * @returns Generated skeleton faces and the maximum skeleton height reached.\n */\nfunction buildStraightSkeleton(\n    ring: Vec2[], \n    speeds: number[],\n    maxHCap: number\n): { faces: Face3D[]; maxH: number } {\n    let open = ring;\n    if (open.length < 3) return { faces: [], maxH: 0 };\n    if (!isConvex(open)) {\n        return { faces: [], maxH: 0 };\n    }\n\n    const bboxMinX = Math.min(...open.map(v => v[0]));\n    const bboxMaxX = Math.max(...open.map(v => v[0]));\n    const bboxMinY = Math.min(...open.map(v => v[1]));\n    const bboxMaxY = Math.max(...open.map(v => v[1]));\n    const bboxPad = MERGE_EPS * 10;\n\n    let initialSv: SkelVert[] = open.map((pos, i) => ({ \n        pos: [...pos] as Vec2, \n        h: 0,\n        edgeIdx: i \n    }));\n    \n    let sv: SkelVert[] = deduplicateVertsInitial(initialSv, MERGE_EPS);\n\n    const faces: Face3D[] = [];\n    let maxH = 0;\n\n    for (let iter = 0; iter < 500 && sv.length >= 3; iter++) {\n        const pts = sv.map(v => v.pos);\n        const norms = inwardNormals(pts);\n        const m = sv.length;\n        const vels = bisectorVelocities(sv, norms, speeds);\n\n        if (vels.some(v => v[0] * v[0] + v[1] * v[1] > MAX_BISECTOR_SPEED * MAX_BISECTOR_SPEED)) {\n            return { faces: [], maxH: 0 };\n        }\n\n        let tMin = Infinity;\n        for (let i = 0; i < m; i++) {\n            const j = (i + 1) % m;\n            const t = collapseTime(sv[i].pos, sv[j].pos, vels[i], vels[j]);\n            if (t < tMin) tMin = t;\n        }\n\n        let capped = false;\n        if (tMin !== Infinity && sv[0].h + tMin >= maxHCap) {\n            tMin = maxHCap - sv[0].h;\n            capped = true;\n        } else if (tMin === Infinity) {\n            tMin = maxHCap - sv[0].h;\n            capped = true;\n        }\n\n        if (tMin <= 0) break;\n\n        const newPos: Vec2[] = sv.map((v, i) => [\n            v.pos[0] + tMin * vels[i][0],\n            v.pos[1] + tMin * vels[i][1],\n        ]);\n        const newH = sv.map(v => v.h + tMin);\n        const localMax = Math.max(...newH);\n        if (localMax > maxH) maxH = localMax;\n\n        for (let i = 0; i < m; i++) {\n            const j = (i + 1) % m;\n            const oldI: [number, number, number] = [sv[i].pos[0], sv[i].pos[1], sv[i].h];\n            const oldJ: [number, number, number] = [sv[j].pos[0], sv[j].pos[1], sv[j].h];\n            const newI: [number, number, number] = [newPos[i][0], newPos[i][1], newH[i]];\n            const newJ: [number, number, number] = [newPos[j][0], newPos[j][1], newH[j]];\n\n            const dx = newPos[i][0] - newPos[j][0];\n            const dy = newPos[i][1] - newPos[j][1];\n            const collapsed = Math.sqrt(dx * dx + dy * dy) < MERGE_EPS;\n\n            if (collapsed) {\n                const mx = (newPos[i][0] + newPos[j][0]) / 2;\n                const my = (newPos[i][1] + newPos[j][1]) / 2;\n                const mh = (newH[i] + newH[j]) / 2;\n                faces.push([oldI, oldJ, [mx, my, mh]]);\n            } else {\n                faces.push([oldI, oldJ, newJ, newI]);\n            }\n        }\n\n        for (const [x, y] of newPos) {\n            if (x < bboxMinX - bboxPad || x > bboxMaxX + bboxPad ||\n                y < bboxMinY - bboxPad || y > bboxMaxY + bboxPad) {\n                return { faces: [], maxH: 0 };\n            }\n        }\n\n        if (capped) {\n            const flat2D = newPos.flatMap(v => v);\n            const ids = earcut(flat2D);\n            for (let i = 0; i < ids.length; i += 3) {\n                const a = newPos[ids[i]], b = newPos[ids[i + 1]], c = newPos[ids[i + 2]];\n                faces.push([\n                    [a[0], a[1], newH[ids[i]]],\n                    [b[0], b[1], newH[ids[i + 1]]],\n                    [c[0], c[1], newH[ids[i + 2]]],\n                ]);\n            }\n            break;\n        }\n\n        const nextSv: SkelVert[] = [];\n        for (let i = 0; i < m; i++) {\n            const j = (i + 1) % m;\n            const dx = newPos[i][0] - newPos[j][0];\n            const dy = newPos[i][1] - newPos[j][1];\n            if (Math.sqrt(dx * dx + dy * dy) >= MERGE_EPS) {\n                nextSv.push({\n                    pos: newPos[i],\n                    h: newH[i],\n                    edgeIdx: sv[i].edgeIdx\n                });\n            }\n        }\n        sv = nextSv;\n    }\n\n    return { faces, maxH };\n}\n\n/**\n * Converts straight-skeleton faces into final roof mesh buffers.\n *\n * The resulting faces are normalized so the tallest skeleton point reaches the\n * requested roof height above `baseH`.\n *\n * @param faces - Skeleton faces expressed as 3D polygons.\n * @param baseH - Wall top elevation.\n * @param roofH - Desired roof height above `baseH`.\n * @param maxSkH - Maximum skeleton height used for height normalization.\n * @returns Roof mesh buffers derived from the skeleton faces.\n */\nfunction skeletonToMesh(faces: Face3D[], baseH: number, roofH: number, maxSkH: number): MeshData {\n    const flatCoords: number[] = [];\n    const flatIds: number[] = [];\n    const scale = maxSkH > 1e-9 ? roofH / maxSkH : 1;\n\n    for (const face of faces) {\n        if (face.length < 3) continue;\n        \n        if (face.length === 3) {\n            const base = flatCoords.length / 3;\n            flatCoords.push(\n                face[0][0], face[0][1], baseH + face[0][2] * scale,\n                face[1][0], face[1][1], baseH + face[1][2] * scale,\n                face[2][0], face[2][1], baseH + face[2][2] * scale\n            );\n            flatIds.push(base, base + 1, base + 2);\n        } else if (face.length === 4) {\n            // Quad → two unrolled triangles\n            const base = flatCoords.length / 3;\n            flatCoords.push(\n                // Tri 1: 0, 1, 2\n                face[0][0], face[0][1], baseH + face[0][2] * scale,\n                face[1][0], face[1][1], baseH + face[1][2] * scale,\n                face[2][0], face[2][1], baseH + face[2][2] * scale,\n                // Tri 2: 2, 3, 0\n                face[2][0], face[2][1], baseH + face[2][2] * scale,\n                face[3][0], face[3][1], baseH + face[3][2] * scale,\n                face[0][0], face[0][1], baseH + face[0][2] * scale\n            );\n            flatIds.push(base, base + 1, base + 2, base + 3, base + 4, base + 5);\n        } else {\n            const flat2D = face.flatMap(([x, y]) => [x, y]);\n            const ids = earcut(flat2D);\n            for (let i = 0; i < ids.length; i += 3) {\n                const i0 = ids[i];\n                const i1 = ids[i + 1];\n                const i2 = ids[i + 2];\n                const base = flatCoords.length / 3;\n                flatCoords.push(\n                    face[i0][0], face[i0][1], baseH + face[i0][2] * scale,\n                    face[i1][0], face[i1][1], baseH + face[i1][2] * scale,\n                    face[i2][0], face[i2][1], baseH + face[i2][2] * scale\n                );\n                flatIds.push(base, base + 1, base + 2);\n            }\n        }\n    }\n\n    return { flatCoords, flatIds };\n}\n\n/**\n * Builds hipped, gabled, half-hipped, mansard, and saltbox roofs via straight skeleton.\n *\n * These roof styles use the outer footprint and a straight-skeleton solve to\n * propagate slopes inward. Mansard roofs additionally cap the skeleton height\n * from the footprint inradius. When the solve cannot complete (concave\n * footprint, unstable bisector, or escaped geometry), the function returns\n * `null` so the caller can fall back to a flat cap.\n *\n * @param ring - Outer roof footprint ring in local planar coordinates.\n * @param baseH - Wall top elevation.\n * @param roofH - Desired roof height above `baseH`.\n * @param info - Parsed roof configuration (shape controls gable/speed behavior).\n * @param _allRings - Full polygon rings passed through by the caller (unused).\n * @returns Roof mesh buffers, or `null` when the skeleton solve fails.\n * @throws Never throws. Returns `null` on failure rather than raising.\n * @example\n * const hipped = skeletonRoof(\n *   [[0, 0], [10, 0], [10, 10], [0, 10]],\n *   20, 5,\n *   { shape: 'hipped', height: 0, angle: 30, direction: 0 }\n * );\n * // hipped is a straight-skeleton roof cap, or null if solve fails\n */\nexport function skeletonRoof(ring: Vec2[], baseH: number, roofH: number, info: RoofInfo, _allRings?: Vec2[][]): MeshData | null {\n    let outer = normalizeRing(ring) as Vec2[];\n    if (computeRingArea(outer) < 0) outer = [...outer].reverse();\n    \n    const speeds = getEdgeSpeeds(outer, info);\n    \n    let maxHCap = Infinity;\n    if (info.shape === 'mansard') {\n        const area = Math.abs(computeRingArea(outer));\n        const perim = polygonPerimeter(outer);\n        const inradius = perim > 0 ? (2 * area / perim) : 0;\n        maxHCap = inradius * 0.7; \n    }\n\n    const { faces, maxH } = buildStraightSkeleton(outer, speeds, maxHCap);\n    if (faces.length === 0) return null;\n    return skeletonToMesh(faces, baseH, roofH, maxH);\n}\n\n// ─── Property extraction ──────────────────────────────────────────────────────\n\n/**\n * Extracts roof-generation parameters from OSM-style building properties.\n *\n * Missing or unparseable tags fall back to `flat`, zero height, a 30° pitch,\n * and a zero direction. Pitch angle is clamped to [5°, 75°] to prevent\n * degenerate geometry from extreme values. Numeric values are parsed from\n * stringified property values.\n *\n * @param props - GeoJSON properties containing roof-related OSM tags\n * (`roof:shape`, `roof:height`, `roof:angle`, `roof:direction`).\n * @returns Normalized roof configuration with safe defaults applied.\n * @throws Never throws. Always returns a valid `RoofInfo` with fallback values.\n * @example\n * const info = extractRoofInfo({ 'roof:shape': 'gabled', 'roof:angle': '45' });\n * // info → { shape: 'gabled', height: 0, angle: 45, direction: 0 }\n */\nexport function extractRoofInfo(props: GeoJsonProperties): RoofInfo {\n    if (!props) return { shape: 'flat', height: 0, angle: DEFAULT_ROOF_ANGLE, direction: 0 };\n    const rawAngle = parseFloat(String(props['roof:angle'] ?? String(DEFAULT_ROOF_ANGLE))) || DEFAULT_ROOF_ANGLE;\n    return {\n        shape: String(props['roof:shape'] ?? 'flat'),\n        height: parseFloat(String(props['roof:height'] ?? '0')) || 0,\n        // Clamp pitch angle to [5°, 75°] — prevents tan(90°) → Infinity and degenerate geometry.\n        angle: Math.min(75, Math.max(5, rawAngle)),\n        direction: parseFloat(String(props['roof:direction'] ?? '0')) || 0,\n    };\n}\n\n// ─── Main entry point ─────────────────────────────────────────────────────────\n\n/**\n * Builds the complete mesh for one building-part polygon (walls + floor + roof).\n *\n * The footprint first becomes wall geometry, then a floor cap is added when\n * `minH > 0`, and finally the roof style is selected from OSM tags. Flat,\n * cone, pyramidal, pyramid, dome, round, and skillion roofs are generated\n * directly from the outer footprint; hipped, gabled, half-hipped, mansard,\n * and saltbox roofs attempt a straight-skeleton solve and fall back to a flat\n * cap when that solve fails. Roof height comes from `roof:height` when\n * present, otherwise it is derived from `roof:angle` for non-flat roofs and\n * clamped to a steepness equivalent to 60°.\n *\n * @param rings - `[outerRing, ...holes]` coordinates already relative to the origin.\n * @param minH - Bottom of the walls (`min_height`).\n * @param maxH - Top of the walls (`height`).\n * @param props - OSM properties for this building part.\n * @returns Array of mesh chunks (walls, optional floor, roof) to be merged\n * into one `LayerGeometry`.\n * @throws Never throws. Degenerate inputs produce minimal or empty mesh data.\n * @example\n * const meshes = buildBuildingPartMesh(\n *   [[[0, 0], [10, 0], [10, 10], [0, 10]]],\n *   0, 20,\n *   { 'roof:shape': 'pyramid', 'roof:height': '5' }\n * );\n * // meshes.length → 2 (walls + pyramid roof)\n */\nexport function buildBuildingPartMesh(\n    rings: Vec2[][],\n    minH: number,\n    maxH: number,\n    props: GeoJsonProperties,\n): MeshData[] {\n    const info = extractRoofInfo(props);\n\n    let roofH = info.height;\n    if (roofH <= 0 && info.shape !== 'flat') {\n        roofH = heightFromAngle(normalizeRing(rings[0]) as Vec2[], info.angle);\n    }\n\n    // Cap roof height: a 60° pitch is already very steep; anything beyond that\n    // indicates a bad OSM tag (e.g. roof:height set to the building's full height).\n    if (info.shape !== 'flat') {\n        const maxRoofH = heightFromAngle(normalizeRing(rings[0]) as Vec2[], 60);\n        if (maxRoofH > 0 && roofH > maxRoofH) roofH = maxRoofH;\n    }\n\n    const outer = normalizeRing(rings[0]) as Vec2[];\n\n    const meshes: MeshData[] = [];\n    meshes.push(buildWalls(rings, minH, maxH));\n\n    if (minH > 0) {\n        meshes.push(flatFloor(rings, minH));\n    }\n\n    let roof: MeshData;\n\n    switch (info.shape) {\n        case 'round':\n            roof = roundRoof(outer, maxH, roofH);\n            break;\n        case 'cone':\n        case 'pyramidal':\n        case 'pyramid':\n            roof = pyramidRoof(outer, maxH, roofH);\n            break;\n        case 'dome':\n            roof = domeRoof(outer, maxH, roofH);\n            break;\n        case 'skillion':\n            roof = skillionRoof(outer, maxH, roofH, info.direction);\n            break;\n        case 'gabled':\n        case 'hipped':\n        case 'half-hipped':\n        case 'mansard':\n        case 'saltbox': {\n            const result = skeletonRoof(outer, maxH, roofH, info, rings);\n            if (result) {\n                roof = result;\n            } else {\n                roof = flatRoof(rings, maxH);\n            }\n            break;\n        }\n        case 'flat':\n        default:\n            roof = flatRoof(rings, maxH);\n            break;\n    }\n\n    meshes.push(roof);\n    return meshes;\n}\n","import type { Feature, Geometry, GeometryCollection } from 'geojson';\n\n/** Attributes of one building part; coordinates exist only in the feature geometry. */\nexport interface BuildingPartProperties {\n    geometryIndex: number;\n    [key: string]: unknown;\n}\n\n/**\n * Normalizes one building to its original component geometries and explicit part indices.\n * Does not union, repair, clone coordinates, or group independent features.\n * Legacy positional `parts` metadata is accepted, but cannot be mixed with indexed metadata.\n *\n * @param feature A building feature with polygonal or ring geometry.\n * @returns A new feature/properties object; component geometries retain their original references.\n * @throws If geometry, metadata or component indices are unsupported or ambiguous.\n */\nexport function normalizeBuildingFeature(feature: Feature<Geometry | null>): Feature<GeometryCollection> {\n    const geometry = feature.geometry;\n    const context = `Building ${String(feature.id ?? '(without id)')}`;\n    if (!geometry) throw new Error(`${context}: missing geometry`);\n    const geometries = geometry.type === 'GeometryCollection' ? geometry.geometries : [geometry];\n    for (const part of geometries) {\n        if (part.type === 'GeometryCollection') throw new Error(`${context}: nested GeometryCollection is not supported`);\n        if (!['Polygon', 'MultiPolygon', 'LineString', 'MultiLineString'].includes(part.type)) {\n            throw new Error(`${context}: unsupported part geometry ${part.type}`);\n        }\n    }\n\n    const metadata = feature.properties?.parts ?? [];\n    if (!Array.isArray(metadata)) throw new Error(`${context}: parts must be an array`);\n    const indexed = metadata.some(part => part && typeof part === 'object' && 'geometryIndex' in part);\n    const seen = new Set<number>();\n    const parts: BuildingPartProperties[] = metadata.map((part, i) => {\n        if (!part || typeof part !== 'object' || Array.isArray(part)) {\n            throw new Error(`${context}: invalid part metadata at index ${i}`);\n        }\n        const index = indexed ? part.geometryIndex : i;\n        if (!Number.isInteger(index) || index < 0 || index >= geometries.length || seen.has(index)) {\n            throw new Error(`${context}: invalid or duplicate geometryIndex ${String(index)}`);\n        }\n        seen.add(index);\n        return { ...part, geometryIndex: index };\n    });\n\n    return {\n        ...feature,\n        geometry: { type: 'GeometryCollection', geometries },\n        properties: { ...feature.properties, parts },\n    };\n}\n\n/**\n * Resolves original building components and their effective rendering attributes.\n * Parts inherit common attributes; alternative height/level tags override as a group.\n * Coordinates remain referenced, not copied. All renderers use the same association.\n */\nexport function getBuildingParts(feature: Feature<Geometry | null>): Array<{\n    geometry: Geometry;\n    geometryIndex: number;\n    properties: Record<string, unknown>;\n}> {\n    const normalized = normalizeBuildingFeature(feature);\n    const { parts, ...buildingProps } = normalized.properties!;\n    const byIndex = new Map<number, BuildingPartProperties>(parts.map((part: BuildingPartProperties) => [part.geometryIndex, part]));\n    return normalized.geometry.geometries.map((geometry, geometryIndex) => {\n        const attributes = byIndex.get(geometryIndex) ?? {};\n        const properties: Record<string, unknown> = { ...buildingProps, ...attributes };\n        for (const keys of [\n            ['height', 'building:height', 'levels', 'building:levels'],\n            ['min_height', 'min_level', 'building:min_level'],\n        ]) {\n            if (keys.some(key => Object.prototype.hasOwnProperty.call(attributes, key))) {\n                for (const key of keys) {\n                    if (!Object.prototype.hasOwnProperty.call(attributes, key)) delete properties[key];\n                }\n            }\n        }\n        return { geometry, geometryIndex, properties };\n    });\n}\n","/**\n * @module triangulator-buildings\n * Triangulates OSM-style building features into extruded mesh geometry.\n *\n * This module converts building `GeometryCollection` features into local-space\n * mesh chunks that can be consumed by the WebGPU layer pipeline. It aligns\n * part geometries with `feature.properties.parts`, resolves wall base and top\n * heights from common OSM tags, and delegates roof generation to\n * `triangulator-roofs`.\n */\n\nimport { \n    FeatureCollection,\n    Feature, \n    LineString, \n    MultiLineString, \n    MultiPolygon, \n    Polygon, \n    GeoJsonProperties \n} from \"geojson\";\n\nimport { LayerComponent, LayerGeometry } from \"./types-mesh\";\n\nimport { buildBuildingPartMesh, MeshData } from \"./triangulator-roofs\";\nimport { getBuildingParts } from './building-feature';\n\n/**\n * Builds extruded mesh geometry for OSM-style buildings.\n *\n * Each feature contains original component geometries associated with\n * `properties.parts[].geometryIndex` (legacy positional metadata is accepted).\n * Parts inherit building attributes and override them individually. For every supported part\n * geometry, the triangulator converts world coordinates into local XY space,\n * resolves wall heights from part metadata, and emits mesh chunks with feature\n * component counts. Roof geometry is delegated to `triangulator-roofs`.\n *\n * @example\n * const [mesh, components] = TriangulatorBuildings.buildMesh(buildings, origin);\n */\nexport class TriangulatorBuildings {\n    /**\n     * Builds extruded building geometry for an OSM-style building collection.\n     *\n     * @param geojson Source building feature collection.\n     * @param origin World-space origin used to convert coordinates into local XY space.\n     * @param allowZeroHeightBuildings When `true`, parts with missing height tags get a random fallback height.\n     * Explicit zero or invalid height tags are never replaced by that fallback.\n     * @returns A tuple of mesh chunks and per-feature component metadata.\n     * @throws If building geometries or part indices are unsupported or ambiguous.\n     * Parts without height metadata are skipped (or given fallback height).\n     * @example\n     * const [meshes, comps] = TriangulatorBuildings.buildMesh(buildingsFC, origin);\n     */\n    static buildMesh(geojson: FeatureCollection, origin: number[], allowZeroHeightBuildings: boolean = false): [LayerGeometry[], LayerComponent[]] {\n        const mesh: LayerGeometry[] = [];\n        const comps: LayerComponent[] = [];\n        let skippedNoHeight = 0;\n\n        for (let fId = 0; fId < geojson.features.length; fId++) {\n            const feature = geojson.features[fId];\n            const parts = getBuildingParts(feature);\n\n            let nPoints = 0;\n            let nTriangles = 0;\n\n            for (const part of parts) {\n                const partGeom = part.geometry;\n                const partProps = part.properties;\n\n                let heightInfo = TriangulatorBuildings.computeBuildingHeights(partProps);\n                if (!heightInfo.length) { \n                    skippedNoHeight++;\n                    const hasHeightTag = ['height', 'building:height', 'levels', 'building:levels'].some(key => key in partProps);\n                    if (!allowZeroHeightBuildings || hasHeightTag) continue;\n                    heightInfo = [0, (3 + 4 * Math.random()) * 3.4]; // Fallback only when height metadata is missing\n                }\n\n                const partFeature: Feature = { type: 'Feature', geometry: partGeom, properties: partProps };\n                let chunks: MeshData[] = [];\n\n                if (partGeom.type === 'LineString') {\n                    const { coordinates } = <LineString>partFeature.geometry;\n                    const ring: [number, number][] = coordinates.map(c => TriangulatorBuildings.toLocal(c, origin));\n                    chunks = buildBuildingPartMesh([ring], heightInfo[0], heightInfo[1], partFeature.properties);\n                } else if (partGeom.type === 'MultiLineString') {\n                    const { coordinates } = <MultiLineString>partFeature.geometry;\n                    for (const lineString of coordinates) {\n                        const ring: [number, number][] = lineString.map(c => TriangulatorBuildings.toLocal(c, origin));\n                        chunks.push(...buildBuildingPartMesh([ring], heightInfo[0], heightInfo[1], partFeature.properties));\n                    }\n                } else if (partGeom.type === 'Polygon') {\n                    const { coordinates } = <Polygon>partFeature.geometry;\n                    const rings: [number, number][][] = coordinates.map(ring =>\n                        ring.map(c => TriangulatorBuildings.toLocal(c, origin))\n                    );\n                    chunks = buildBuildingPartMesh(rings, heightInfo[0], heightInfo[1], partFeature.properties);\n                } else if (partGeom.type === 'MultiPolygon') {\n                    const { coordinates } = <MultiPolygon>partFeature.geometry;\n                    for (const polygon of coordinates) {\n                        const rings: [number, number][][] = polygon.map(ring =>\n                            ring.map(c => TriangulatorBuildings.toLocal(c, origin))\n                        );\n                        chunks.push(...buildBuildingPartMesh(rings, heightInfo[0], heightInfo[1], partFeature.properties));\n                    }\n                } else {\n                    console.warn('Unsupported geometry type in building part:', partGeom.type);\n                    continue;\n                }\n\n                for (const chunk of chunks) {\n                    mesh.push({ \n                        position: new Float32Array(chunk.flatCoords), \n                        indices: new Uint32Array(chunk.flatIds),\n                        featureIndex: fId,\n                    });\n                    nPoints += chunk.flatCoords.length / 3;\n                    nTriangles += chunk.flatIds.length / 3;\n                }\n            }\n\n            comps.push({ nPoints, nTriangles, featureIndex: fId, featureId: feature.id });\n        }\n\n        if (skippedNoHeight > 0) {\n            console.warn(`[TriangulatorBuildings] ${skippedNoHeight} parts: no valid height metadata`);\n        }\n\n        return [mesh, comps];\n    }\n\n    /**\n     * Resolves wall base and top heights from OSM-style building properties.\n     *\n     * @param props Building-part properties to inspect (`height`, `min_height`, `levels`, etc.).\n     * @returns A two-element array `[minHeight, height]`, or an empty array when\n     * no valid height range can be derived.\n     * @throws Never throws. Degenerate ranges return an empty array.\n     */\n    private static computeBuildingHeights(props: GeoJsonProperties): number[] {\n        const FLOOR_HEIGHT = 3.4;\n\n        if (props === null) return [];\n\n        const num = (v: unknown): number => parseFloat(String(v)) || 0;\n\n        let height = 0;\n        if ('height' in props) height = num(props['height']);\n        else if ('building:height' in props) height = num(props['building:height']);\n        else if ('levels' in props) height = FLOOR_HEIGHT * num(props['levels']);\n        else if ('building:levels' in props) height = FLOOR_HEIGHT * num(props['building:levels']);\n\n        let min_height = 0;\n        if ('min_height' in props) min_height = num(props['min_height']);\n        else if ('min_level' in props && num(props['min_level']) >= 0) min_height = FLOOR_HEIGHT * num(props['min_level']);\n        else if ('building:min_level' in props) min_height = FLOOR_HEIGHT * num(props['building:min_level']);\n\n        if (height <= min_height) return [];\n        return [min_height, height];\n    }\n\n    /**\n     * Converts a world-space coordinate into local planar coordinates.\n     *\n     * @param coord World-space coordinate with at least XY components.\n     * @param origin World-space origin used as the local offset basis.\n     * @returns Local planar coordinate `[x, y]` relative to `origin`.\n     * @throws Never throws.\n     */\n    private static toLocal(coord: number[], origin: number[]): [number, number] {\n        return [coord[0] - origin[0], coord[1] - origin[1]];\n    }\n}\n","/**\n * @module triangulator-raster\n * Triangulation helpers for raster feature collections.\n *\n * This module converts a GeoTIFF-backed `FeatureCollection` into a single quad\n * mesh that can be textured by the raster sampler. The quad is derived from the\n * collection bounding box, translated into the map's local coordinate space by\n * subtracting the shared origin, and assigned normalized UV coordinates for GPU\n * texture lookup.\n */\n\nimport { FeatureCollection, Geometry } from 'geojson';\n\nimport { LayerGeometry, LayerComponent } from './types-mesh';\n\n/**\n * Builds textured mesh geometry for GeoTIFF raster layers.\n *\n * `TriangulatorRaster` turns the source collection `bbox` into a single quad in\n * local XY space. The four corners are shifted by the supplied origin so the\n * raster aligns with the rest of the layer stack, and the quad is emitted with\n * UVs spanning `[0, 1]` to match normalized texture coordinates.\n */\nexport class TriangulatorRaster {\n    /**\n     * Builds a single textured quad covering the raster bounding box.\n     *\n     * @param geotiff Raster feature collection whose `bbox` defines the quad extent.\n     * @param origin World-space origin subtracted from each corner to form local coordinates.\n     * @returns A tuple of quad geometry and matching component metadata.\n     * @throws Never throws. When `bbox` is missing, returns empty arrays with a console warning.\n     * @example\n     * const [meshes, comps] = TriangulatorRaster.buildMesh(rasterFC, origin);\n     */\n    static buildMesh(geotiff: FeatureCollection<Geometry | null>, origin: number[]): [LayerGeometry[], LayerComponent[]] {\n        const mesh: LayerGeometry[] = [];\n        const comps: LayerComponent[] = [];\n\n        const bbox = geotiff.bbox;\n\n        if (!bbox) {\n            console.warn('GeoTIFF feature collection does not have a bounding box.');\n            return [mesh, comps];\n        }\n\n        const p0 = [bbox[0] - origin[0], bbox[1] - origin[1]];\n        const p1 = [bbox[2] - origin[0], bbox[1] - origin[1]];\n        const p2 = [bbox[2] - origin[0], bbox[3] - origin[1]];\n        const p3 = [bbox[0] - origin[0], bbox[3] - origin[1]];\n\n        const flatCoords = [p0[0], p0[1], p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]];\n        const texCoords = [0, 0, 1, 0, 1, 1, 0, 1];\n        const flatIds = [0, 1, 2, 0, 2, 3];\n\n        mesh.push({ \n            position: new Float32Array(flatCoords), \n            texCoord: new Float32Array(texCoords), \n            indices: new Uint32Array(flatIds) \n        });\n\n        comps.push({ nPoints: flatCoords.length / 2, nTriangles: flatIds.length / 3, featureIndex: 0 });\n\n        return [mesh, comps];\n    }\n}\n","/**\n * @module DataUtils\n * Data-access and scalar-validation helpers for loosely typed values.\n *\n * This module provides small utilities for reading nested properties from\n * unknown record-like values and for checking whether inputs can participate\n * in finite numeric processing.\n */\n\n/**\n * Resolves a dot-delimited property path, including literal dotted leaf keys.\n *\n * Fully traversable nested paths take precedence. If traversal fails, an own key\n * may match the remaining suffix, such as `shadows.jun` in spatial-join output.\n *\n * @param item - Source value to traverse.\n * @param path - Dot-delimited property path, for example `properties.area`.\n * @returns The resolved nested value, or `undefined` when the path cannot be\n * fully resolved.\n * @throws Never throws.\n * @example\n * valueAtPath({ a: { b: 42 } }, 'a.b');  // 42\n * valueAtPath({ a: null }, 'a.b');       // undefined\n * valueAtPath({ sjoin: { avg: { 'shadows.jun': 12 } } }, 'sjoin.avg.shadows.jun'); // 12\n */\nexport function valueAtPath(item: unknown, path: string): unknown {\n    const keys = path.split('.');\n    let value = item;\n    let resolved = true;\n    for (const key of keys) {\n        if (value == null || typeof value !== 'object' || !(key in value)) {\n            resolved = false;\n            break;\n        }\n        value = (value as Record<string, unknown>)[key];\n    }\n    if (resolved) return value;\n\n    value = item;\n    for (let i = 0; i < keys.length; i++) {\n        if (value == null || typeof value !== 'object') return undefined;\n        const record = value as Record<string, unknown>;\n        const suffix = keys.slice(i).join('.');\n        if (Object.prototype.hasOwnProperty.call(record, suffix)) return record[suffix];\n        value = record[keys[i]];\n    }\n    return value;\n}\n\n/**\n * Returns `true` when the value can be treated as a finite numeric scalar.\n *\n * @param value - Value to test for numeric scalar compatibility.\n * @returns `true` when the value is a finite number or numeric string.\n * @throws Never throws.\n * @example\n * isNumericLike(42);       // true\n * isNumericLike('3.14');   // true\n * isNumericLike('');       // false\n * isNumericLike(NaN);      // false\n */\nexport function isNumericLike(value: unknown): boolean {\n    if (typeof value === 'number') {\n        return Number.isFinite(value);\n    }\n    if (typeof value === 'string') {\n        const trimmed = value.trim();\n        return trimmed !== '' && Number.isFinite(Number(trimmed));\n    }\n    return false;\n}\n","/**\n * @module heightfield\n * Heightfield conversion helpers for raster-backed elevation data.\n *\n * This module converts Autark raster `FeatureCollection` payloads into a\n * compact local-space heightfield used by terrain rendering and other elevation\n * workflows. The source collection must provide a `bbox`, `rasterResX`,\n * `rasterResY`, and a numeric raster band selected by property path.\n */\n\nimport type { FeatureCollection, Geometry } from 'geojson';\nimport { valueAtPath } from './utils-data';\n\n/**\n * Local-space grid of scalar height samples.\n *\n * The grid is stored row-major in `data` and aligned to `bounds`, whose\n * coordinates are already shifted by the supplied map origin.\n */\nexport interface Heightfield {\n    /** Number of grid samples along the X axis. */\n    width: number;\n    /** Number of grid samples along the Y axis. */\n    height: number;\n    /** Local-space X coordinate of the first grid sample. */\n    originX: number;\n    /** Local-space Y coordinate of the first grid sample. */\n    originY: number;\n    /** Local-space distance between adjacent samples along X. */\n    cellSizeX: number;\n    /** Local-space distance between adjacent samples along Y. */\n    cellSizeY: number;\n    /** Smallest finite height value found in the source data. */\n    minHeight: number;\n    /** Largest finite height value found in the source data. */\n    maxHeight: number;\n    /** Row-major scalar height samples. Non-finite source values are replaced with `0`. */\n    data: Float32Array;\n    /** Local-space bounds as `[minX, minY, maxX, maxY]`. */\n    bounds: [number, number, number, number];\n}\n\n/**\n * Builds a local-space heightfield from a raster feature collection.\n *\n * The raster band is read from the first feature properties using `property`,\n * and the returned bounds subtract `origin` from the source bbox.\n *\n * @param collection Raster feature collection containing `bbox` and raster metadata.\n * @param property Dot-path to the raster band values in the first feature properties.\n * @param origin World-space origin to subtract from the raster bbox.\n * @returns Heightfield with local bounds, cell sizes, min/max height, and sample data.\n * @throws {Error} If bbox, raster metadata, raster values, or finite heights are missing or invalid.\n * @example\n * const heightfield = heightfieldFromRaster(collection, 'bands.elevation', origin);\n * console.log(heightfield.width, heightfield.bounds);\n */\nexport function heightfieldFromRaster(\n    collection: FeatureCollection<Geometry | null>,\n    property: string,\n    origin: readonly number[],\n): Heightfield {\n    const feature = collection.features[0];\n    const props = feature?.properties as Record<string, unknown> | undefined;\n\n    const rasterValues = props ? valueAtPath(props, property) : undefined;\n\n    if (!props || !isArrayLike(rasterValues) || !collection.bbox) {\n        throw new Error(`Heightfield requires a raster FeatureCollection with bbox and '${property}' band values.`);\n    }\n\n    const width = Number(props.rasterResX);\n    const height = Number(props.rasterResY);\n    if (!Number.isInteger(width) || !Number.isInteger(height) || width < 2 || height < 2) {\n        throw new Error('Heightfield raster resolution must be at least 2x2.');\n    }\n\n    const values = Array.from(rasterValues, Number);\n    if (values.length !== width * height) {\n        throw new Error(`Heightfield has ${values.length} cells; expected ${width * height}.`);\n    }\n\n    const data = new Float32Array(values);\n    let minHeight = Number.POSITIVE_INFINITY;\n    let maxHeight = Number.NEGATIVE_INFINITY;\n    let nonFinite = 0;\n    for (let i = 0; i < data.length; i++) {\n        const value = data[i];\n        if (Number.isFinite(value)) {\n            minHeight = Math.min(minHeight, value);\n            maxHeight = Math.max(maxHeight, value);\n        } else {\n            data[i] = 0;\n            nonFinite++;\n        }\n    }\n\n    if (!Number.isFinite(minHeight) || !Number.isFinite(maxHeight)) {\n        throw new Error('Heightfield does not contain finite elevation values.');\n    }\n    if (nonFinite > 0) {\n        console.warn(`Heightfield contains ${nonFinite} non-finite elevation values. These were set to 0.`);\n    }\n\n    const bounds: [number, number, number, number] = [\n        Number(collection.bbox[0]) - origin[0],\n        Number(collection.bbox[1]) - origin[1],\n        Number(collection.bbox[2]) - origin[0],\n        Number(collection.bbox[3]) - origin[1],\n    ];\n\n    return {\n        width,\n        height,\n        originX: bounds[0],\n        originY: bounds[1],\n        cellSizeX: (bounds[2] - bounds[0]) / Math.max(1, width - 1),\n        cellSizeY: (bounds[3] - bounds[1]) / Math.max(1, height - 1),\n        minHeight,\n        maxHeight,\n        data,\n        bounds,\n    };\n}\n\n/**\n * Checks whether a value can be copied with `Array.from` as raster samples.\n *\n * @param value Candidate raster band payload.\n * @returns `true` when the value is an array or typed-array view.\n * @throws Never throws.\n * @example\n * isArrayLike(new Float32Array([1, 2])); // true\n */\nfunction isArrayLike(value: unknown): value is ArrayLike<unknown> {\n    return Array.isArray(value) || ArrayBuffer.isView(value);\n}\n","/**\n * Common utilities\n * @module glMatrix\n */\n\n// Configuration Constants\nexport var EPSILON = 0.000001;\nexport var ARRAY_TYPE = typeof Float32Array !== \"undefined\" ? Float32Array : Array;\nexport var RANDOM = Math.random;\nexport var ANGLE_ORDER = \"zyx\";\n\n/**\n * Symmetric round\n * see https://www.npmjs.com/package/round-half-up-symmetric#user-content-detailed-background\n *\n * @param {Number} a value to round\n */\nexport function round(a) {\n  if (a >= 0) return Math.round(a);\n  return a % 0.5 === 0 ? Math.floor(a) : Math.round(a);\n}\n\n/**\n * Sets the type of array used when creating new vectors and matrices\n *\n * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array\n */\nexport function setMatrixArrayType(type) {\n  ARRAY_TYPE = type;\n}\nvar degree = Math.PI / 180;\nvar radian = 180 / Math.PI;\n\n/**\n * Convert Degree To Radian\n *\n * @param {Number} a Angle in Degrees\n */\nexport function toRadian(a) {\n  return a * degree;\n}\n\n/**\n * Convert Radian To Degree\n *\n * @param {Number} a Angle in Radians\n */\nexport function toDegree(a) {\n  return a * radian;\n}\n\n/**\n * Tests whether or not the arguments have approximately the same value, within an absolute\n * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less\n * than or equal to 1.0, and a relative tolerance is used for larger values)\n *\n * @param {Number} a          The first number to test.\n * @param {Number} b          The second number to test.\n * @param {Number} tolerance  Absolute or relative tolerance (default glMatrix.EPSILON)\n * @returns {Boolean} True if the numbers are approximately equal, false otherwise.\n */\nexport function equals(a, b) {\n  var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EPSILON;\n  return Math.abs(a - b) <= tolerance * Math.max(1, Math.abs(a), Math.abs(b));\n}","import * as glMatrix from \"./common.js\";\n\n/**\n * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.\n * @module mat4\n */\n\n/**\n * Creates a new identity mat4\n *\n * @returns {mat4} a new 4x4 matrix\n */\nexport function create() {\n  var out = new glMatrix.ARRAY_TYPE(16);\n  if (glMatrix.ARRAY_TYPE != Float32Array) {\n    out[1] = 0;\n    out[2] = 0;\n    out[3] = 0;\n    out[4] = 0;\n    out[6] = 0;\n    out[7] = 0;\n    out[8] = 0;\n    out[9] = 0;\n    out[11] = 0;\n    out[12] = 0;\n    out[13] = 0;\n    out[14] = 0;\n  }\n  out[0] = 1;\n  out[5] = 1;\n  out[10] = 1;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a new mat4 initialized with values from an existing matrix\n *\n * @param {ReadonlyMat4} a matrix to clone\n * @returns {mat4} a new 4x4 matrix\n */\nexport function clone(a) {\n  var out = new glMatrix.ARRAY_TYPE(16);\n  out[0] = a[0];\n  out[1] = a[1];\n  out[2] = a[2];\n  out[3] = a[3];\n  out[4] = a[4];\n  out[5] = a[5];\n  out[6] = a[6];\n  out[7] = a[7];\n  out[8] = a[8];\n  out[9] = a[9];\n  out[10] = a[10];\n  out[11] = a[11];\n  out[12] = a[12];\n  out[13] = a[13];\n  out[14] = a[14];\n  out[15] = a[15];\n  return out;\n}\n\n/**\n * Copy the values from one mat4 to another\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function copy(out, a) {\n  out[0] = a[0];\n  out[1] = a[1];\n  out[2] = a[2];\n  out[3] = a[3];\n  out[4] = a[4];\n  out[5] = a[5];\n  out[6] = a[6];\n  out[7] = a[7];\n  out[8] = a[8];\n  out[9] = a[9];\n  out[10] = a[10];\n  out[11] = a[11];\n  out[12] = a[12];\n  out[13] = a[13];\n  out[14] = a[14];\n  out[15] = a[15];\n  return out;\n}\n\n/**\n * Create a new mat4 with the given values\n *\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} A new mat4\n */\nexport function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n  var out = new glMatrix.ARRAY_TYPE(16);\n  out[0] = m00;\n  out[1] = m01;\n  out[2] = m02;\n  out[3] = m03;\n  out[4] = m10;\n  out[5] = m11;\n  out[6] = m12;\n  out[7] = m13;\n  out[8] = m20;\n  out[9] = m21;\n  out[10] = m22;\n  out[11] = m23;\n  out[12] = m30;\n  out[13] = m31;\n  out[14] = m32;\n  out[15] = m33;\n  return out;\n}\n\n/**\n * Set the components of a mat4 to the given values\n *\n * @param {mat4} out the receiving matrix\n * @param {Number} m00 Component in column 0, row 0 position (index 0)\n * @param {Number} m01 Component in column 0, row 1 position (index 1)\n * @param {Number} m02 Component in column 0, row 2 position (index 2)\n * @param {Number} m03 Component in column 0, row 3 position (index 3)\n * @param {Number} m10 Component in column 1, row 0 position (index 4)\n * @param {Number} m11 Component in column 1, row 1 position (index 5)\n * @param {Number} m12 Component in column 1, row 2 position (index 6)\n * @param {Number} m13 Component in column 1, row 3 position (index 7)\n * @param {Number} m20 Component in column 2, row 0 position (index 8)\n * @param {Number} m21 Component in column 2, row 1 position (index 9)\n * @param {Number} m22 Component in column 2, row 2 position (index 10)\n * @param {Number} m23 Component in column 2, row 3 position (index 11)\n * @param {Number} m30 Component in column 3, row 0 position (index 12)\n * @param {Number} m31 Component in column 3, row 1 position (index 13)\n * @param {Number} m32 Component in column 3, row 2 position (index 14)\n * @param {Number} m33 Component in column 3, row 3 position (index 15)\n * @returns {mat4} out\n */\nexport function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {\n  out[0] = m00;\n  out[1] = m01;\n  out[2] = m02;\n  out[3] = m03;\n  out[4] = m10;\n  out[5] = m11;\n  out[6] = m12;\n  out[7] = m13;\n  out[8] = m20;\n  out[9] = m21;\n  out[10] = m22;\n  out[11] = m23;\n  out[12] = m30;\n  out[13] = m31;\n  out[14] = m32;\n  out[15] = m33;\n  return out;\n}\n\n/**\n * Set a mat4 to the identity matrix\n *\n * @param {mat4} out the receiving matrix\n * @returns {mat4} out\n */\nexport function identity(out) {\n  out[0] = 1;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = 1;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = 1;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Transpose the values of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function transpose(out, a) {\n  // If we are transposing ourselves we can skip a few steps but have to cache some values\n  if (out === a) {\n    var a01 = a[1],\n      a02 = a[2],\n      a03 = a[3];\n    var a12 = a[6],\n      a13 = a[7];\n    var a23 = a[11];\n    out[1] = a[4];\n    out[2] = a[8];\n    out[3] = a[12];\n    out[4] = a01;\n    out[6] = a[9];\n    out[7] = a[13];\n    out[8] = a02;\n    out[9] = a12;\n    out[11] = a[14];\n    out[12] = a03;\n    out[13] = a13;\n    out[14] = a23;\n  } else {\n    out[0] = a[0];\n    out[1] = a[4];\n    out[2] = a[8];\n    out[3] = a[12];\n    out[4] = a[1];\n    out[5] = a[5];\n    out[6] = a[9];\n    out[7] = a[13];\n    out[8] = a[2];\n    out[9] = a[6];\n    out[10] = a[10];\n    out[11] = a[14];\n    out[12] = a[3];\n    out[13] = a[7];\n    out[14] = a[11];\n    out[15] = a[15];\n  }\n  return out;\n}\n\n/**\n * Inverts a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4 | null} out, or null if source matrix is not invertible\n */\nexport function invert(out, a) {\n  var a00 = a[0],\n    a01 = a[1],\n    a02 = a[2],\n    a03 = a[3];\n  var a10 = a[4],\n    a11 = a[5],\n    a12 = a[6],\n    a13 = a[7];\n  var a20 = a[8],\n    a21 = a[9],\n    a22 = a[10],\n    a23 = a[11];\n  var a30 = a[12],\n    a31 = a[13],\n    a32 = a[14],\n    a33 = a[15];\n  var b00 = a00 * a11 - a01 * a10;\n  var b01 = a00 * a12 - a02 * a10;\n  var b02 = a00 * a13 - a03 * a10;\n  var b03 = a01 * a12 - a02 * a11;\n  var b04 = a01 * a13 - a03 * a11;\n  var b05 = a02 * a13 - a03 * a12;\n  var b06 = a20 * a31 - a21 * a30;\n  var b07 = a20 * a32 - a22 * a30;\n  var b08 = a20 * a33 - a23 * a30;\n  var b09 = a21 * a32 - a22 * a31;\n  var b10 = a21 * a33 - a23 * a31;\n  var b11 = a22 * a33 - a23 * a32;\n\n  // Calculate the determinant\n  var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\n  if (!det) {\n    return null;\n  }\n  det = 1.0 / det;\n  out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;\n  out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;\n  out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;\n  out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;\n  out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;\n  out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;\n  out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;\n  out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;\n  out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;\n  out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;\n  out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;\n  out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;\n  out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;\n  out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;\n  out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;\n  out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;\n  return out;\n}\n\n/**\n * Calculates the adjugate of a mat4\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the source matrix\n * @returns {mat4} out\n */\nexport function adjoint(out, a) {\n  var a00 = a[0],\n    a01 = a[1],\n    a02 = a[2],\n    a03 = a[3];\n  var a10 = a[4],\n    a11 = a[5],\n    a12 = a[6],\n    a13 = a[7];\n  var a20 = a[8],\n    a21 = a[9],\n    a22 = a[10],\n    a23 = a[11];\n  var a30 = a[12],\n    a31 = a[13],\n    a32 = a[14],\n    a33 = a[15];\n  var b00 = a00 * a11 - a01 * a10;\n  var b01 = a00 * a12 - a02 * a10;\n  var b02 = a00 * a13 - a03 * a10;\n  var b03 = a01 * a12 - a02 * a11;\n  var b04 = a01 * a13 - a03 * a11;\n  var b05 = a02 * a13 - a03 * a12;\n  var b06 = a20 * a31 - a21 * a30;\n  var b07 = a20 * a32 - a22 * a30;\n  var b08 = a20 * a33 - a23 * a30;\n  var b09 = a21 * a32 - a22 * a31;\n  var b10 = a21 * a33 - a23 * a31;\n  var b11 = a22 * a33 - a23 * a32;\n  out[0] = a11 * b11 - a12 * b10 + a13 * b09;\n  out[1] = a02 * b10 - a01 * b11 - a03 * b09;\n  out[2] = a31 * b05 - a32 * b04 + a33 * b03;\n  out[3] = a22 * b04 - a21 * b05 - a23 * b03;\n  out[4] = a12 * b08 - a10 * b11 - a13 * b07;\n  out[5] = a00 * b11 - a02 * b08 + a03 * b07;\n  out[6] = a32 * b02 - a30 * b05 - a33 * b01;\n  out[7] = a20 * b05 - a22 * b02 + a23 * b01;\n  out[8] = a10 * b10 - a11 * b08 + a13 * b06;\n  out[9] = a01 * b08 - a00 * b10 - a03 * b06;\n  out[10] = a30 * b04 - a31 * b02 + a33 * b00;\n  out[11] = a21 * b02 - a20 * b04 - a23 * b00;\n  out[12] = a11 * b07 - a10 * b09 - a12 * b06;\n  out[13] = a00 * b09 - a01 * b07 + a02 * b06;\n  out[14] = a31 * b01 - a30 * b03 - a32 * b00;\n  out[15] = a20 * b03 - a21 * b01 + a22 * b00;\n  return out;\n}\n\n/**\n * Calculates the determinant of a mat4\n *\n * @param {ReadonlyMat4} a the source matrix\n * @returns {Number} determinant of a\n */\nexport function determinant(a) {\n  var a00 = a[0],\n    a01 = a[1],\n    a02 = a[2],\n    a03 = a[3];\n  var a10 = a[4],\n    a11 = a[5],\n    a12 = a[6],\n    a13 = a[7];\n  var a20 = a[8],\n    a21 = a[9],\n    a22 = a[10],\n    a23 = a[11];\n  var a30 = a[12],\n    a31 = a[13],\n    a32 = a[14],\n    a33 = a[15];\n  var b0 = a00 * a11 - a01 * a10;\n  var b1 = a00 * a12 - a02 * a10;\n  var b2 = a01 * a12 - a02 * a11;\n  var b3 = a20 * a31 - a21 * a30;\n  var b4 = a20 * a32 - a22 * a30;\n  var b5 = a21 * a32 - a22 * a31;\n  var b6 = a00 * b5 - a01 * b4 + a02 * b3;\n  var b7 = a10 * b5 - a11 * b4 + a12 * b3;\n  var b8 = a20 * b2 - a21 * b1 + a22 * b0;\n  var b9 = a30 * b2 - a31 * b1 + a32 * b0;\n\n  // Calculate the determinant\n  return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9;\n}\n\n/**\n * Multiplies two mat4s\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function multiply(out, a, b) {\n  var a00 = a[0],\n    a01 = a[1],\n    a02 = a[2],\n    a03 = a[3];\n  var a10 = a[4],\n    a11 = a[5],\n    a12 = a[6],\n    a13 = a[7];\n  var a20 = a[8],\n    a21 = a[9],\n    a22 = a[10],\n    a23 = a[11];\n  var a30 = a[12],\n    a31 = a[13],\n    a32 = a[14],\n    a33 = a[15];\n\n  // Cache only the current line of the second matrix\n  var b0 = b[0],\n    b1 = b[1],\n    b2 = b[2],\n    b3 = b[3];\n  out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n  out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n  out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n  out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n  b0 = b[4];\n  b1 = b[5];\n  b2 = b[6];\n  b3 = b[7];\n  out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n  out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n  out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n  out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n  b0 = b[8];\n  b1 = b[9];\n  b2 = b[10];\n  b3 = b[11];\n  out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n  out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n  out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n  out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n  b0 = b[12];\n  b1 = b[13];\n  b2 = b[14];\n  b3 = b[15];\n  out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;\n  out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;\n  out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;\n  out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;\n  return out;\n}\n\n/**\n * Translate a mat4 by the given vector\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to translate\n * @param {ReadonlyVec3} v vector to translate by\n * @returns {mat4} out\n */\nexport function translate(out, a, v) {\n  var x = v[0],\n    y = v[1],\n    z = v[2];\n  var a00, a01, a02, a03;\n  var a10, a11, a12, a13;\n  var a20, a21, a22, a23;\n  if (a === out) {\n    out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];\n    out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];\n    out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];\n    out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];\n  } else {\n    a00 = a[0];\n    a01 = a[1];\n    a02 = a[2];\n    a03 = a[3];\n    a10 = a[4];\n    a11 = a[5];\n    a12 = a[6];\n    a13 = a[7];\n    a20 = a[8];\n    a21 = a[9];\n    a22 = a[10];\n    a23 = a[11];\n    out[0] = a00;\n    out[1] = a01;\n    out[2] = a02;\n    out[3] = a03;\n    out[4] = a10;\n    out[5] = a11;\n    out[6] = a12;\n    out[7] = a13;\n    out[8] = a20;\n    out[9] = a21;\n    out[10] = a22;\n    out[11] = a23;\n    out[12] = a00 * x + a10 * y + a20 * z + a[12];\n    out[13] = a01 * x + a11 * y + a21 * z + a[13];\n    out[14] = a02 * x + a12 * y + a22 * z + a[14];\n    out[15] = a03 * x + a13 * y + a23 * z + a[15];\n  }\n  return out;\n}\n\n/**\n * Scales the mat4 by the dimensions in the given vec3 not using vectorization\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {ReadonlyVec3} v the vec3 to scale the matrix by\n * @returns {mat4} out\n **/\nexport function scale(out, a, v) {\n  var x = v[0],\n    y = v[1],\n    z = v[2];\n  out[0] = a[0] * x;\n  out[1] = a[1] * x;\n  out[2] = a[2] * x;\n  out[3] = a[3] * x;\n  out[4] = a[4] * y;\n  out[5] = a[5] * y;\n  out[6] = a[6] * y;\n  out[7] = a[7] * y;\n  out[8] = a[8] * z;\n  out[9] = a[9] * z;\n  out[10] = a[10] * z;\n  out[11] = a[11] * z;\n  out[12] = a[12];\n  out[13] = a[13];\n  out[14] = a[14];\n  out[15] = a[15];\n  return out;\n}\n\n/**\n * Rotates a mat4 by the given angle around the given axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\nexport function rotate(out, a, rad, axis) {\n  var x = axis[0],\n    y = axis[1],\n    z = axis[2];\n  var len = Math.sqrt(x * x + y * y + z * z);\n  var s, c, t;\n  var a00, a01, a02, a03;\n  var a10, a11, a12, a13;\n  var a20, a21, a22, a23;\n  var b00, b01, b02;\n  var b10, b11, b12;\n  var b20, b21, b22;\n  if (len < glMatrix.EPSILON) {\n    return null;\n  }\n  len = 1 / len;\n  x *= len;\n  y *= len;\n  z *= len;\n  s = Math.sin(rad);\n  c = Math.cos(rad);\n  t = 1 - c;\n  a00 = a[0];\n  a01 = a[1];\n  a02 = a[2];\n  a03 = a[3];\n  a10 = a[4];\n  a11 = a[5];\n  a12 = a[6];\n  a13 = a[7];\n  a20 = a[8];\n  a21 = a[9];\n  a22 = a[10];\n  a23 = a[11];\n\n  // Construct the elements of the rotation matrix\n  b00 = x * x * t + c;\n  b01 = y * x * t + z * s;\n  b02 = z * x * t - y * s;\n  b10 = x * y * t - z * s;\n  b11 = y * y * t + c;\n  b12 = z * y * t + x * s;\n  b20 = x * z * t + y * s;\n  b21 = y * z * t - x * s;\n  b22 = z * z * t + c;\n\n  // Perform rotation-specific matrix multiplication\n  out[0] = a00 * b00 + a10 * b01 + a20 * b02;\n  out[1] = a01 * b00 + a11 * b01 + a21 * b02;\n  out[2] = a02 * b00 + a12 * b01 + a22 * b02;\n  out[3] = a03 * b00 + a13 * b01 + a23 * b02;\n  out[4] = a00 * b10 + a10 * b11 + a20 * b12;\n  out[5] = a01 * b10 + a11 * b11 + a21 * b12;\n  out[6] = a02 * b10 + a12 * b11 + a22 * b12;\n  out[7] = a03 * b10 + a13 * b11 + a23 * b12;\n  out[8] = a00 * b20 + a10 * b21 + a20 * b22;\n  out[9] = a01 * b20 + a11 * b21 + a21 * b22;\n  out[10] = a02 * b20 + a12 * b21 + a22 * b22;\n  out[11] = a03 * b20 + a13 * b21 + a23 * b22;\n  if (a !== out) {\n    // If the source and destination differ, copy the unchanged last row\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n  }\n  return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the X axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateX(out, a, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n  var a10 = a[4];\n  var a11 = a[5];\n  var a12 = a[6];\n  var a13 = a[7];\n  var a20 = a[8];\n  var a21 = a[9];\n  var a22 = a[10];\n  var a23 = a[11];\n  if (a !== out) {\n    // If the source and destination differ, copy the unchanged rows\n    out[0] = a[0];\n    out[1] = a[1];\n    out[2] = a[2];\n    out[3] = a[3];\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n  }\n\n  // Perform axis-specific matrix multiplication\n  out[4] = a10 * c + a20 * s;\n  out[5] = a11 * c + a21 * s;\n  out[6] = a12 * c + a22 * s;\n  out[7] = a13 * c + a23 * s;\n  out[8] = a20 * c - a10 * s;\n  out[9] = a21 * c - a11 * s;\n  out[10] = a22 * c - a12 * s;\n  out[11] = a23 * c - a13 * s;\n  return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the Y axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateY(out, a, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n  var a00 = a[0];\n  var a01 = a[1];\n  var a02 = a[2];\n  var a03 = a[3];\n  var a20 = a[8];\n  var a21 = a[9];\n  var a22 = a[10];\n  var a23 = a[11];\n  if (a !== out) {\n    // If the source and destination differ, copy the unchanged rows\n    out[4] = a[4];\n    out[5] = a[5];\n    out[6] = a[6];\n    out[7] = a[7];\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n  }\n\n  // Perform axis-specific matrix multiplication\n  out[0] = a00 * c - a20 * s;\n  out[1] = a01 * c - a21 * s;\n  out[2] = a02 * c - a22 * s;\n  out[3] = a03 * c - a23 * s;\n  out[8] = a00 * s + a20 * c;\n  out[9] = a01 * s + a21 * c;\n  out[10] = a02 * s + a22 * c;\n  out[11] = a03 * s + a23 * c;\n  return out;\n}\n\n/**\n * Rotates a matrix by the given angle around the Z axis\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to rotate\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function rotateZ(out, a, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n  var a00 = a[0];\n  var a01 = a[1];\n  var a02 = a[2];\n  var a03 = a[3];\n  var a10 = a[4];\n  var a11 = a[5];\n  var a12 = a[6];\n  var a13 = a[7];\n  if (a !== out) {\n    // If the source and destination differ, copy the unchanged last row\n    out[8] = a[8];\n    out[9] = a[9];\n    out[10] = a[10];\n    out[11] = a[11];\n    out[12] = a[12];\n    out[13] = a[13];\n    out[14] = a[14];\n    out[15] = a[15];\n  }\n\n  // Perform axis-specific matrix multiplication\n  out[0] = a00 * c + a10 * s;\n  out[1] = a01 * c + a11 * s;\n  out[2] = a02 * c + a12 * s;\n  out[3] = a03 * c + a13 * s;\n  out[4] = a10 * c - a00 * s;\n  out[5] = a11 * c - a01 * s;\n  out[6] = a12 * c - a02 * s;\n  out[7] = a13 * c - a03 * s;\n  return out;\n}\n\n/**\n * Creates a matrix from a vector translation\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.translate(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\nexport function fromTranslation(out, v) {\n  out[0] = 1;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = 1;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = 1;\n  out[11] = 0;\n  out[12] = v[0];\n  out[13] = v[1];\n  out[14] = v[2];\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from a vector scaling\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.scale(dest, dest, vec);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyVec3} v Scaling vector\n * @returns {mat4} out\n */\nexport function fromScaling(out, v) {\n  out[0] = v[0];\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = v[1];\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = v[2];\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from a given angle around a given axis\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.rotate(dest, dest, rad, axis);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @param {ReadonlyVec3} axis the axis to rotate around\n * @returns {mat4} out\n */\nexport function fromRotation(out, rad, axis) {\n  var x = axis[0],\n    y = axis[1],\n    z = axis[2];\n  var len = Math.sqrt(x * x + y * y + z * z);\n  var s, c, t;\n  if (len < glMatrix.EPSILON) {\n    return null;\n  }\n  len = 1 / len;\n  x *= len;\n  y *= len;\n  z *= len;\n  s = Math.sin(rad);\n  c = Math.cos(rad);\n  t = 1 - c;\n\n  // Perform rotation-specific matrix multiplication\n  out[0] = x * x * t + c;\n  out[1] = y * x * t + z * s;\n  out[2] = z * x * t - y * s;\n  out[3] = 0;\n  out[4] = x * y * t - z * s;\n  out[5] = y * y * t + c;\n  out[6] = z * y * t + x * s;\n  out[7] = 0;\n  out[8] = x * z * t + y * s;\n  out[9] = y * z * t - x * s;\n  out[10] = z * z * t + c;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from the given angle around the X axis\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.rotateX(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromXRotation(out, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n\n  // Perform axis-specific matrix multiplication\n  out[0] = 1;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = c;\n  out[6] = s;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = -s;\n  out[10] = c;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from the given angle around the Y axis\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.rotateY(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromYRotation(out, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n\n  // Perform axis-specific matrix multiplication\n  out[0] = c;\n  out[1] = 0;\n  out[2] = -s;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = 1;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = s;\n  out[9] = 0;\n  out[10] = c;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from the given angle around the Z axis\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.rotateZ(dest, dest, rad);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {Number} rad the angle to rotate the matrix by\n * @returns {mat4} out\n */\nexport function fromZRotation(out, rad) {\n  var s = Math.sin(rad);\n  var c = Math.cos(rad);\n\n  // Perform axis-specific matrix multiplication\n  out[0] = c;\n  out[1] = s;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = -s;\n  out[5] = c;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = 1;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from a quaternion rotation and vector translation\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.translate(dest, dest, vec);\n *     let quatMat = mat4.create();\n *     mat4.fromQuat(quatMat, quat);\n *     mat4.multiply(dest, dest, quatMat);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @returns {mat4} out\n */\nexport function fromRotationTranslation(out, q, v) {\n  // Quaternion math\n  var x = q[0],\n    y = q[1],\n    z = q[2],\n    w = q[3];\n  var x2 = x + x;\n  var y2 = y + y;\n  var z2 = z + z;\n  var xx = x * x2;\n  var xy = x * y2;\n  var xz = x * z2;\n  var yy = y * y2;\n  var yz = y * z2;\n  var zz = z * z2;\n  var wx = w * x2;\n  var wy = w * y2;\n  var wz = w * z2;\n  out[0] = 1 - (yy + zz);\n  out[1] = xy + wz;\n  out[2] = xz - wy;\n  out[3] = 0;\n  out[4] = xy - wz;\n  out[5] = 1 - (xx + zz);\n  out[6] = yz + wx;\n  out[7] = 0;\n  out[8] = xz + wy;\n  out[9] = yz - wx;\n  out[10] = 1 - (xx + yy);\n  out[11] = 0;\n  out[12] = v[0];\n  out[13] = v[1];\n  out[14] = v[2];\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a new mat4 from a dual quat.\n *\n * @param {mat4} out Matrix\n * @param {ReadonlyQuat2} a Dual Quaternion\n * @returns {mat4} mat4 receiving operation result\n */\nexport function fromQuat2(out, a) {\n  var translation = new glMatrix.ARRAY_TYPE(3);\n  var bx = -a[0],\n    by = -a[1],\n    bz = -a[2],\n    bw = a[3],\n    ax = a[4],\n    ay = a[5],\n    az = a[6],\n    aw = a[7];\n  var magnitude = bx * bx + by * by + bz * bz + bw * bw;\n  //Only scale if it makes sense\n  if (magnitude > 0) {\n    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;\n    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;\n    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;\n  } else {\n    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;\n    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;\n    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;\n  }\n  fromRotationTranslation(out, a, translation);\n  return out;\n}\n\n/**\n * Returns the translation vector component of a transformation\n *  matrix. If a matrix is built with fromRotationTranslation,\n *  the returned vector will be the same as the translation vector\n *  originally supplied.\n * @param  {vec3} out Vector to receive translation component\n * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getTranslation(out, mat) {\n  out[0] = mat[12];\n  out[1] = mat[13];\n  out[2] = mat[14];\n  return out;\n}\n\n/**\n * Returns the scaling factor component of a transformation\n *  matrix. If a matrix is built with fromRotationTranslationScale\n *  with a normalized Quaternion parameter, the returned vector will be\n *  the same as the scaling vector\n *  originally supplied.\n * @param  {vec3} out Vector to receive scaling factor component\n * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {vec3} out\n */\nexport function getScaling(out, mat) {\n  var m11 = mat[0];\n  var m12 = mat[1];\n  var m13 = mat[2];\n  var m21 = mat[4];\n  var m22 = mat[5];\n  var m23 = mat[6];\n  var m31 = mat[8];\n  var m32 = mat[9];\n  var m33 = mat[10];\n  out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);\n  out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);\n  out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);\n  return out;\n}\n\n/**\n * Returns a quaternion representing the rotational component\n *  of a transformation matrix. If a matrix is built with\n *  fromRotationTranslation, the returned quaternion will be the\n *  same as the quaternion originally supplied.\n * @param {quat} out Quaternion to receive the rotation component\n * @param {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @return {quat} out\n */\nexport function getRotation(out, mat) {\n  var scaling = new glMatrix.ARRAY_TYPE(3);\n  getScaling(scaling, mat);\n  var is1 = 1 / scaling[0];\n  var is2 = 1 / scaling[1];\n  var is3 = 1 / scaling[2];\n  var sm11 = mat[0] * is1;\n  var sm12 = mat[1] * is2;\n  var sm13 = mat[2] * is3;\n  var sm21 = mat[4] * is1;\n  var sm22 = mat[5] * is2;\n  var sm23 = mat[6] * is3;\n  var sm31 = mat[8] * is1;\n  var sm32 = mat[9] * is2;\n  var sm33 = mat[10] * is3;\n  var trace = sm11 + sm22 + sm33;\n  var S = 0;\n  if (trace > 0) {\n    S = Math.sqrt(trace + 1.0) * 2;\n    out[3] = 0.25 * S;\n    out[0] = (sm23 - sm32) / S;\n    out[1] = (sm31 - sm13) / S;\n    out[2] = (sm12 - sm21) / S;\n  } else if (sm11 > sm22 && sm11 > sm33) {\n    S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n    out[3] = (sm23 - sm32) / S;\n    out[0] = 0.25 * S;\n    out[1] = (sm12 + sm21) / S;\n    out[2] = (sm31 + sm13) / S;\n  } else if (sm22 > sm33) {\n    S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n    out[3] = (sm31 - sm13) / S;\n    out[0] = (sm12 + sm21) / S;\n    out[1] = 0.25 * S;\n    out[2] = (sm23 + sm32) / S;\n  } else {\n    S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n    out[3] = (sm12 - sm21) / S;\n    out[0] = (sm31 + sm13) / S;\n    out[1] = (sm23 + sm32) / S;\n    out[2] = 0.25 * S;\n  }\n  return out;\n}\n\n/**\n * Decomposes a transformation matrix into its rotation, translation\n * and scale components. Returns only the rotation component\n * @param  {quat} out_r Quaternion to receive the rotation component\n * @param  {vec3} out_t Vector to receive the translation vector\n * @param  {vec3} out_s Vector to receive the scaling factor\n * @param  {ReadonlyMat4} mat Matrix to be decomposed (input)\n * @returns {quat} out_r\n */\nexport function decompose(out_r, out_t, out_s, mat) {\n  out_t[0] = mat[12];\n  out_t[1] = mat[13];\n  out_t[2] = mat[14];\n  var m11 = mat[0];\n  var m12 = mat[1];\n  var m13 = mat[2];\n  var m21 = mat[4];\n  var m22 = mat[5];\n  var m23 = mat[6];\n  var m31 = mat[8];\n  var m32 = mat[9];\n  var m33 = mat[10];\n  out_s[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);\n  out_s[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);\n  out_s[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);\n  var is1 = 1 / out_s[0];\n  var is2 = 1 / out_s[1];\n  var is3 = 1 / out_s[2];\n  var sm11 = m11 * is1;\n  var sm12 = m12 * is2;\n  var sm13 = m13 * is3;\n  var sm21 = m21 * is1;\n  var sm22 = m22 * is2;\n  var sm23 = m23 * is3;\n  var sm31 = m31 * is1;\n  var sm32 = m32 * is2;\n  var sm33 = m33 * is3;\n  var trace = sm11 + sm22 + sm33;\n  var S = 0;\n  if (trace > 0) {\n    S = Math.sqrt(trace + 1.0) * 2;\n    out_r[3] = 0.25 * S;\n    out_r[0] = (sm23 - sm32) / S;\n    out_r[1] = (sm31 - sm13) / S;\n    out_r[2] = (sm12 - sm21) / S;\n  } else if (sm11 > sm22 && sm11 > sm33) {\n    S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;\n    out_r[3] = (sm23 - sm32) / S;\n    out_r[0] = 0.25 * S;\n    out_r[1] = (sm12 + sm21) / S;\n    out_r[2] = (sm31 + sm13) / S;\n  } else if (sm22 > sm33) {\n    S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;\n    out_r[3] = (sm31 - sm13) / S;\n    out_r[0] = (sm12 + sm21) / S;\n    out_r[1] = 0.25 * S;\n    out_r[2] = (sm23 + sm32) / S;\n  } else {\n    S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;\n    out_r[3] = (sm12 - sm21) / S;\n    out_r[0] = (sm31 + sm13) / S;\n    out_r[1] = (sm23 + sm32) / S;\n    out_r[2] = 0.25 * S;\n  }\n  return out_r;\n}\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.translate(dest, dest, vec);\n *     let quatMat = mat4.create();\n *     mat4.fromQuat(quatMat, quat);\n *     mat4.multiply(dest, dest, quatMat);\n *     mat4.scale(dest, dest, scale)\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @returns {mat4} out\n */\nexport function fromRotationTranslationScale(out, q, v, s) {\n  // Quaternion math\n  var x = q[0],\n    y = q[1],\n    z = q[2],\n    w = q[3];\n  var x2 = x + x;\n  var y2 = y + y;\n  var z2 = z + z;\n  var xx = x * x2;\n  var xy = x * y2;\n  var xz = x * z2;\n  var yy = y * y2;\n  var yz = y * z2;\n  var zz = z * z2;\n  var wx = w * x2;\n  var wy = w * y2;\n  var wz = w * z2;\n  var sx = s[0];\n  var sy = s[1];\n  var sz = s[2];\n  out[0] = (1 - (yy + zz)) * sx;\n  out[1] = (xy + wz) * sx;\n  out[2] = (xz - wy) * sx;\n  out[3] = 0;\n  out[4] = (xy - wz) * sy;\n  out[5] = (1 - (xx + zz)) * sy;\n  out[6] = (yz + wx) * sy;\n  out[7] = 0;\n  out[8] = (xz + wy) * sz;\n  out[9] = (yz - wx) * sz;\n  out[10] = (1 - (xx + yy)) * sz;\n  out[11] = 0;\n  out[12] = v[0];\n  out[13] = v[1];\n  out[14] = v[2];\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin\n * This is equivalent to (but much faster than):\n *\n *     mat4.identity(dest);\n *     mat4.translate(dest, dest, vec);\n *     mat4.translate(dest, dest, origin);\n *     let quatMat = mat4.create();\n *     mat4.fromQuat(quatMat, quat);\n *     mat4.multiply(dest, dest, quatMat);\n *     mat4.scale(dest, dest, scale)\n *     mat4.translate(dest, dest, negativeOrigin);\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {quat} q Rotation quaternion\n * @param {ReadonlyVec3} v Translation vector\n * @param {ReadonlyVec3} s Scaling vector\n * @param {ReadonlyVec3} o The origin vector around which to scale and rotate\n * @returns {mat4} out\n */\nexport function fromRotationTranslationScaleOrigin(out, q, v, s, o) {\n  // Quaternion math\n  var x = q[0],\n    y = q[1],\n    z = q[2],\n    w = q[3];\n  var x2 = x + x;\n  var y2 = y + y;\n  var z2 = z + z;\n  var xx = x * x2;\n  var xy = x * y2;\n  var xz = x * z2;\n  var yy = y * y2;\n  var yz = y * z2;\n  var zz = z * z2;\n  var wx = w * x2;\n  var wy = w * y2;\n  var wz = w * z2;\n  var sx = s[0];\n  var sy = s[1];\n  var sz = s[2];\n  var ox = o[0];\n  var oy = o[1];\n  var oz = o[2];\n  var out0 = (1 - (yy + zz)) * sx;\n  var out1 = (xy + wz) * sx;\n  var out2 = (xz - wy) * sx;\n  var out4 = (xy - wz) * sy;\n  var out5 = (1 - (xx + zz)) * sy;\n  var out6 = (yz + wx) * sy;\n  var out8 = (xz + wy) * sz;\n  var out9 = (yz - wx) * sz;\n  var out10 = (1 - (xx + yy)) * sz;\n  out[0] = out0;\n  out[1] = out1;\n  out[2] = out2;\n  out[3] = 0;\n  out[4] = out4;\n  out[5] = out5;\n  out[6] = out6;\n  out[7] = 0;\n  out[8] = out8;\n  out[9] = out9;\n  out[10] = out10;\n  out[11] = 0;\n  out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);\n  out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);\n  out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Calculates a 4x4 matrix from the given quaternion\n *\n * @param {mat4} out mat4 receiving operation result\n * @param {ReadonlyQuat} q Quaternion to create matrix from\n *\n * @returns {mat4} out\n */\nexport function fromQuat(out, q) {\n  var x = q[0],\n    y = q[1],\n    z = q[2],\n    w = q[3];\n  var x2 = x + x;\n  var y2 = y + y;\n  var z2 = z + z;\n  var xx = x * x2;\n  var yx = y * x2;\n  var yy = y * y2;\n  var zx = z * x2;\n  var zy = z * y2;\n  var zz = z * z2;\n  var wx = w * x2;\n  var wy = w * y2;\n  var wz = w * z2;\n  out[0] = 1 - yy - zz;\n  out[1] = yx + wz;\n  out[2] = zx - wy;\n  out[3] = 0;\n  out[4] = yx - wz;\n  out[5] = 1 - xx - zz;\n  out[6] = zy + wx;\n  out[7] = 0;\n  out[8] = zx + wy;\n  out[9] = zy - wx;\n  out[10] = 1 - xx - yy;\n  out[11] = 0;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = 0;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Generates a frustum matrix with the given bounds\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Number} left Left bound of the frustum\n * @param {Number} right Right bound of the frustum\n * @param {Number} bottom Bottom bound of the frustum\n * @param {Number} top Top bound of the frustum\n * @param {Number} near Near bound of the frustum\n * @param {Number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function frustum(out, left, right, bottom, top, near, far) {\n  var rl = 1 / (right - left);\n  var tb = 1 / (top - bottom);\n  var nf = 1 / (near - far);\n  out[0] = near * 2 * rl;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = near * 2 * tb;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = (right + left) * rl;\n  out[9] = (top + bottom) * tb;\n  out[10] = (far + near) * nf;\n  out[11] = -1;\n  out[12] = 0;\n  out[13] = 0;\n  out[14] = far * near * 2 * nf;\n  out[15] = 0;\n  return out;\n}\n\n/**\n * Generates a perspective projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL's clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\nexport function perspectiveNO(out, fovy, aspect, near, far) {\n  var f = 1.0 / Math.tan(fovy / 2);\n  out[0] = f / aspect;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = f;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[11] = -1;\n  out[12] = 0;\n  out[13] = 0;\n  out[15] = 0;\n  if (far != null && far !== Infinity) {\n    var nf = 1 / (near - far);\n    out[10] = (far + near) * nf;\n    out[14] = 2 * far * near * nf;\n  } else {\n    out[10] = -1;\n    out[14] = -2 * near;\n  }\n  return out;\n}\n\n/**\n * Alias for {@link mat4.perspectiveNO}\n * @function\n */\nexport var perspective = perspectiveNO;\n\n/**\n * Generates a perspective projection matrix suitable for WebGPU with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.\n * Passing null/undefined/no value for far will generate infinite projection matrix.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} fovy Vertical field of view in radians\n * @param {number} aspect Aspect ratio. typically viewport width/height\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum, can be null or Infinity\n * @returns {mat4} out\n */\nexport function perspectiveZO(out, fovy, aspect, near, far) {\n  var f = 1.0 / Math.tan(fovy / 2);\n  out[0] = f / aspect;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = f;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[11] = -1;\n  out[12] = 0;\n  out[13] = 0;\n  out[15] = 0;\n  if (far != null && far !== Infinity) {\n    var nf = 1 / (near - far);\n    out[10] = far * nf;\n    out[14] = far * near * nf;\n  } else {\n    out[10] = -1;\n    out[14] = -near;\n  }\n  return out;\n}\n\n/**\n * Generates a perspective projection matrix with the given field of view.\n * This is primarily useful for generating projection matrices to be used\n * with the still experiemental WebVR API.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function perspectiveFromFieldOfView(out, fov, near, far) {\n  var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);\n  var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);\n  var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);\n  var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);\n  var xScale = 2.0 / (leftTan + rightTan);\n  var yScale = 2.0 / (upTan + downTan);\n  out[0] = xScale;\n  out[1] = 0.0;\n  out[2] = 0.0;\n  out[3] = 0.0;\n  out[4] = 0.0;\n  out[5] = yScale;\n  out[6] = 0.0;\n  out[7] = 0.0;\n  out[8] = -((leftTan - rightTan) * xScale * 0.5);\n  out[9] = (upTan - downTan) * yScale * 0.5;\n  out[10] = far / (near - far);\n  out[11] = -1.0;\n  out[12] = 0.0;\n  out[13] = 0.0;\n  out[14] = far * near / (near - far);\n  out[15] = 0.0;\n  return out;\n}\n\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [-1, 1],\n * which matches WebGL/OpenGL's clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function orthoNO(out, left, right, bottom, top, near, far) {\n  var lr = 1 / (left - right);\n  var bt = 1 / (bottom - top);\n  var nf = 1 / (near - far);\n  out[0] = -2 * lr;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = -2 * bt;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = 2 * nf;\n  out[11] = 0;\n  out[12] = (left + right) * lr;\n  out[13] = (top + bottom) * bt;\n  out[14] = (far + near) * nf;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Alias for {@link mat4.orthoNO}\n * @function\n */\nexport var ortho = orthoNO;\n\n/**\n * Generates a orthogonal projection matrix with the given bounds.\n * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1],\n * which matches WebGPU/Vulkan/DirectX/Metal's clip volume.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {number} left Left bound of the frustum\n * @param {number} right Right bound of the frustum\n * @param {number} bottom Bottom bound of the frustum\n * @param {number} top Top bound of the frustum\n * @param {number} near Near bound of the frustum\n * @param {number} far Far bound of the frustum\n * @returns {mat4} out\n */\nexport function orthoZO(out, left, right, bottom, top, near, far) {\n  var lr = 1 / (left - right);\n  var bt = 1 / (bottom - top);\n  var nf = 1 / (near - far);\n  out[0] = -2 * lr;\n  out[1] = 0;\n  out[2] = 0;\n  out[3] = 0;\n  out[4] = 0;\n  out[5] = -2 * bt;\n  out[6] = 0;\n  out[7] = 0;\n  out[8] = 0;\n  out[9] = 0;\n  out[10] = nf;\n  out[11] = 0;\n  out[12] = (left + right) * lr;\n  out[13] = (top + bottom) * bt;\n  out[14] = near * nf;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Generates a look-at matrix with the given eye position, focal point, and up axis.\n * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} center Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\nexport function lookAt(out, eye, center, up) {\n  var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;\n  var eyex = eye[0];\n  var eyey = eye[1];\n  var eyez = eye[2];\n  var upx = up[0];\n  var upy = up[1];\n  var upz = up[2];\n  var centerx = center[0];\n  var centery = center[1];\n  var centerz = center[2];\n  if (Math.abs(eyex - centerx) < glMatrix.EPSILON && Math.abs(eyey - centery) < glMatrix.EPSILON && Math.abs(eyez - centerz) < glMatrix.EPSILON) {\n    return identity(out);\n  }\n  z0 = eyex - centerx;\n  z1 = eyey - centery;\n  z2 = eyez - centerz;\n  len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);\n  z0 *= len;\n  z1 *= len;\n  z2 *= len;\n  x0 = upy * z2 - upz * z1;\n  x1 = upz * z0 - upx * z2;\n  x2 = upx * z1 - upy * z0;\n  len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);\n  if (!len) {\n    x0 = 0;\n    x1 = 0;\n    x2 = 0;\n  } else {\n    len = 1 / len;\n    x0 *= len;\n    x1 *= len;\n    x2 *= len;\n  }\n  y0 = z1 * x2 - z2 * x1;\n  y1 = z2 * x0 - z0 * x2;\n  y2 = z0 * x1 - z1 * x0;\n  len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);\n  if (!len) {\n    y0 = 0;\n    y1 = 0;\n    y2 = 0;\n  } else {\n    len = 1 / len;\n    y0 *= len;\n    y1 *= len;\n    y2 *= len;\n  }\n  out[0] = x0;\n  out[1] = y0;\n  out[2] = z0;\n  out[3] = 0;\n  out[4] = x1;\n  out[5] = y1;\n  out[6] = z1;\n  out[7] = 0;\n  out[8] = x2;\n  out[9] = y2;\n  out[10] = z2;\n  out[11] = 0;\n  out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);\n  out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);\n  out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Generates a matrix that makes something look at something else.\n *\n * @param {mat4} out mat4 frustum matrix will be written into\n * @param {ReadonlyVec3} eye Position of the viewer\n * @param {ReadonlyVec3} target Point the viewer is looking at\n * @param {ReadonlyVec3} up vec3 pointing up\n * @returns {mat4} out\n */\nexport function targetTo(out, eye, target, up) {\n  var eyex = eye[0],\n    eyey = eye[1],\n    eyez = eye[2],\n    upx = up[0],\n    upy = up[1],\n    upz = up[2];\n  var z0 = eyex - target[0],\n    z1 = eyey - target[1],\n    z2 = eyez - target[2];\n  var len = z0 * z0 + z1 * z1 + z2 * z2;\n  if (len > 0) {\n    len = 1 / Math.sqrt(len);\n    z0 *= len;\n    z1 *= len;\n    z2 *= len;\n  }\n  var x0 = upy * z2 - upz * z1,\n    x1 = upz * z0 - upx * z2,\n    x2 = upx * z1 - upy * z0;\n  len = x0 * x0 + x1 * x1 + x2 * x2;\n  if (len > 0) {\n    len = 1 / Math.sqrt(len);\n    x0 *= len;\n    x1 *= len;\n    x2 *= len;\n  }\n  out[0] = x0;\n  out[1] = x1;\n  out[2] = x2;\n  out[3] = 0;\n  out[4] = z1 * x2 - z2 * x1;\n  out[5] = z2 * x0 - z0 * x2;\n  out[6] = z0 * x1 - z1 * x0;\n  out[7] = 0;\n  out[8] = z0;\n  out[9] = z1;\n  out[10] = z2;\n  out[11] = 0;\n  out[12] = eyex;\n  out[13] = eyey;\n  out[14] = eyez;\n  out[15] = 1;\n  return out;\n}\n\n/**\n * Returns a string representation of a mat4\n *\n * @param {ReadonlyMat4} a matrix to represent as a string\n * @returns {String} string representation of the matrix\n */\nexport function str(a) {\n  return \"mat4(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \", \" + a[3] + \", \" + a[4] + \", \" + a[5] + \", \" + a[6] + \", \" + a[7] + \", \" + a[8] + \", \" + a[9] + \", \" + a[10] + \", \" + a[11] + \", \" + a[12] + \", \" + a[13] + \", \" + a[14] + \", \" + a[15] + \")\";\n}\n\n/**\n * Returns Frobenius norm of a mat4\n *\n * @param {ReadonlyMat4} a the matrix to calculate Frobenius norm of\n * @returns {Number} Frobenius norm\n */\nexport function frob(a) {\n  return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3] + a[4] * a[4] + a[5] * a[5] + a[6] * a[6] + a[7] * a[7] + a[8] * a[8] + a[9] * a[9] + a[10] * a[10] + a[11] * a[11] + a[12] * a[12] + a[13] * a[13] + a[14] * a[14] + a[15] * a[15]);\n}\n\n/**\n * Adds two mat4's\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function add(out, a, b) {\n  out[0] = a[0] + b[0];\n  out[1] = a[1] + b[1];\n  out[2] = a[2] + b[2];\n  out[3] = a[3] + b[3];\n  out[4] = a[4] + b[4];\n  out[5] = a[5] + b[5];\n  out[6] = a[6] + b[6];\n  out[7] = a[7] + b[7];\n  out[8] = a[8] + b[8];\n  out[9] = a[9] + b[9];\n  out[10] = a[10] + b[10];\n  out[11] = a[11] + b[11];\n  out[12] = a[12] + b[12];\n  out[13] = a[13] + b[13];\n  out[14] = a[14] + b[14];\n  out[15] = a[15] + b[15];\n  return out;\n}\n\n/**\n * Subtracts matrix b from matrix a\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @returns {mat4} out\n */\nexport function subtract(out, a, b) {\n  out[0] = a[0] - b[0];\n  out[1] = a[1] - b[1];\n  out[2] = a[2] - b[2];\n  out[3] = a[3] - b[3];\n  out[4] = a[4] - b[4];\n  out[5] = a[5] - b[5];\n  out[6] = a[6] - b[6];\n  out[7] = a[7] - b[7];\n  out[8] = a[8] - b[8];\n  out[9] = a[9] - b[9];\n  out[10] = a[10] - b[10];\n  out[11] = a[11] - b[11];\n  out[12] = a[12] - b[12];\n  out[13] = a[13] - b[13];\n  out[14] = a[14] - b[14];\n  out[15] = a[15] - b[15];\n  return out;\n}\n\n/**\n * Multiply each element of the matrix by a scalar.\n *\n * @param {mat4} out the receiving matrix\n * @param {ReadonlyMat4} a the matrix to scale\n * @param {Number} b amount to scale the matrix's elements by\n * @returns {mat4} out\n */\nexport function multiplyScalar(out, a, b) {\n  out[0] = a[0] * b;\n  out[1] = a[1] * b;\n  out[2] = a[2] * b;\n  out[3] = a[3] * b;\n  out[4] = a[4] * b;\n  out[5] = a[5] * b;\n  out[6] = a[6] * b;\n  out[7] = a[7] * b;\n  out[8] = a[8] * b;\n  out[9] = a[9] * b;\n  out[10] = a[10] * b;\n  out[11] = a[11] * b;\n  out[12] = a[12] * b;\n  out[13] = a[13] * b;\n  out[14] = a[14] * b;\n  out[15] = a[15] * b;\n  return out;\n}\n\n/**\n * Adds two mat4's after multiplying each element of the second operand by a scalar value.\n *\n * @param {mat4} out the receiving vector\n * @param {ReadonlyMat4} a the first operand\n * @param {ReadonlyMat4} b the second operand\n * @param {Number} scale the amount to scale b's elements by before adding\n * @returns {mat4} out\n */\nexport function multiplyScalarAndAdd(out, a, b, scale) {\n  out[0] = a[0] + b[0] * scale;\n  out[1] = a[1] + b[1] * scale;\n  out[2] = a[2] + b[2] * scale;\n  out[3] = a[3] + b[3] * scale;\n  out[4] = a[4] + b[4] * scale;\n  out[5] = a[5] + b[5] * scale;\n  out[6] = a[6] + b[6] * scale;\n  out[7] = a[7] + b[7] * scale;\n  out[8] = a[8] + b[8] * scale;\n  out[9] = a[9] + b[9] * scale;\n  out[10] = a[10] + b[10] * scale;\n  out[11] = a[11] + b[11] * scale;\n  out[12] = a[12] + b[12] * scale;\n  out[13] = a[13] + b[13] * scale;\n  out[14] = a[14] + b[14] * scale;\n  out[15] = a[15] + b[15] * scale;\n  return out;\n}\n\n/**\n * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];\n}\n\n/**\n * Returns whether or not the matrices have approximately the same elements in the same position.\n *\n * @param {ReadonlyMat4} a The first matrix.\n * @param {ReadonlyMat4} b The second matrix.\n * @returns {Boolean} True if the matrices are equal, false otherwise.\n */\nexport function equals(a, b) {\n  var a0 = a[0],\n    a1 = a[1],\n    a2 = a[2],\n    a3 = a[3];\n  var a4 = a[4],\n    a5 = a[5],\n    a6 = a[6],\n    a7 = a[7];\n  var a8 = a[8],\n    a9 = a[9],\n    a10 = a[10],\n    a11 = a[11];\n  var a12 = a[12],\n    a13 = a[13],\n    a14 = a[14],\n    a15 = a[15];\n  var b0 = b[0],\n    b1 = b[1],\n    b2 = b[2],\n    b3 = b[3];\n  var b4 = b[4],\n    b5 = b[5],\n    b6 = b[6],\n    b7 = b[7];\n  var b8 = b[8],\n    b9 = b[9],\n    b10 = b[10],\n    b11 = b[11];\n  var b12 = b[12],\n    b13 = b[13],\n    b14 = b[14],\n    b15 = b[15];\n  return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));\n}\n\n/**\n * Alias for {@link mat4.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link mat4.subtract}\n * @function\n */\nexport var sub = subtract;","import * as glMatrix from \"./common.js\";\n\n/**\n * 3 Dimensional Vector\n * @module vec3\n */\n\n/**\n * Creates a new, empty vec3\n *\n * @returns {vec3} a new 3D vector\n */\nexport function create() {\n  var out = new glMatrix.ARRAY_TYPE(3);\n  if (glMatrix.ARRAY_TYPE != Float32Array) {\n    out[0] = 0;\n    out[1] = 0;\n    out[2] = 0;\n  }\n  return out;\n}\n\n/**\n * Creates a new vec3 initialized with values from an existing vector\n *\n * @param {ReadonlyVec3} a vector to clone\n * @returns {vec3} a new 3D vector\n */\nexport function clone(a) {\n  var out = new glMatrix.ARRAY_TYPE(3);\n  out[0] = a[0];\n  out[1] = a[1];\n  out[2] = a[2];\n  return out;\n}\n\n/**\n * Calculates the length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate length of\n * @returns {Number} length of a\n */\nexport function length(a) {\n  var x = a[0];\n  var y = a[1];\n  var z = a[2];\n  return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Creates a new vec3 initialized with the given values\n *\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} a new 3D vector\n */\nexport function fromValues(x, y, z) {\n  var out = new glMatrix.ARRAY_TYPE(3);\n  out[0] = x;\n  out[1] = y;\n  out[2] = z;\n  return out;\n}\n\n/**\n * Copy the values from one vec3 to another\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the source vector\n * @returns {vec3} out\n */\nexport function copy(out, a) {\n  out[0] = a[0];\n  out[1] = a[1];\n  out[2] = a[2];\n  return out;\n}\n\n/**\n * Set the components of a vec3 to the given values\n *\n * @param {vec3} out the receiving vector\n * @param {Number} x X component\n * @param {Number} y Y component\n * @param {Number} z Z component\n * @returns {vec3} out\n */\nexport function set(out, x, y, z) {\n  out[0] = x;\n  out[1] = y;\n  out[2] = z;\n  return out;\n}\n\n/**\n * Adds two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function add(out, a, b) {\n  out[0] = a[0] + b[0];\n  out[1] = a[1] + b[1];\n  out[2] = a[2] + b[2];\n  return out;\n}\n\n/**\n * Subtracts vector b from vector a\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function subtract(out, a, b) {\n  out[0] = a[0] - b[0];\n  out[1] = a[1] - b[1];\n  out[2] = a[2] - b[2];\n  return out;\n}\n\n/**\n * Multiplies two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function multiply(out, a, b) {\n  out[0] = a[0] * b[0];\n  out[1] = a[1] * b[1];\n  out[2] = a[2] * b[2];\n  return out;\n}\n\n/**\n * Divides two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function divide(out, a, b) {\n  out[0] = a[0] / b[0];\n  out[1] = a[1] / b[1];\n  out[2] = a[2] / b[2];\n  return out;\n}\n\n/**\n * Math.ceil the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to ceil\n * @returns {vec3} out\n */\nexport function ceil(out, a) {\n  out[0] = Math.ceil(a[0]);\n  out[1] = Math.ceil(a[1]);\n  out[2] = Math.ceil(a[2]);\n  return out;\n}\n\n/**\n * Math.floor the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to floor\n * @returns {vec3} out\n */\nexport function floor(out, a) {\n  out[0] = Math.floor(a[0]);\n  out[1] = Math.floor(a[1]);\n  out[2] = Math.floor(a[2]);\n  return out;\n}\n\n/**\n * Returns the minimum of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function min(out, a, b) {\n  out[0] = Math.min(a[0], b[0]);\n  out[1] = Math.min(a[1], b[1]);\n  out[2] = Math.min(a[2], b[2]);\n  return out;\n}\n\n/**\n * Returns the maximum of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function max(out, a, b) {\n  out[0] = Math.max(a[0], b[0]);\n  out[1] = Math.max(a[1], b[1]);\n  out[2] = Math.max(a[2], b[2]);\n  return out;\n}\n\n/**\n * symmetric round the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to round\n * @returns {vec3} out\n */\nexport function round(out, a) {\n  out[0] = glMatrix.round(a[0]);\n  out[1] = glMatrix.round(a[1]);\n  out[2] = glMatrix.round(a[2]);\n  return out;\n}\n\n/**\n * Scales a vec3 by a scalar number\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to scale\n * @param {Number} b amount to scale the vector by\n * @returns {vec3} out\n */\nexport function scale(out, a, b) {\n  out[0] = a[0] * b;\n  out[1] = a[1] * b;\n  out[2] = a[2] * b;\n  return out;\n}\n\n/**\n * Adds two vec3's after scaling the second operand by a scalar value\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} scale the amount to scale b by before adding\n * @returns {vec3} out\n */\nexport function scaleAndAdd(out, a, b, scale) {\n  out[0] = a[0] + b[0] * scale;\n  out[1] = a[1] + b[1] * scale;\n  out[2] = a[2] + b[2] * scale;\n  return out;\n}\n\n/**\n * Calculates the euclidian distance between two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} distance between a and b\n */\nexport function distance(a, b) {\n  var x = b[0] - a[0];\n  var y = b[1] - a[1];\n  var z = b[2] - a[2];\n  return Math.sqrt(x * x + y * y + z * z);\n}\n\n/**\n * Calculates the squared euclidian distance between two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} squared distance between a and b\n */\nexport function squaredDistance(a, b) {\n  var x = b[0] - a[0];\n  var y = b[1] - a[1];\n  var z = b[2] - a[2];\n  return x * x + y * y + z * z;\n}\n\n/**\n * Calculates the squared length of a vec3\n *\n * @param {ReadonlyVec3} a vector to calculate squared length of\n * @returns {Number} squared length of a\n */\nexport function squaredLength(a) {\n  var x = a[0];\n  var y = a[1];\n  var z = a[2];\n  return x * x + y * y + z * z;\n}\n\n/**\n * Negates the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to negate\n * @returns {vec3} out\n */\nexport function negate(out, a) {\n  out[0] = -a[0];\n  out[1] = -a[1];\n  out[2] = -a[2];\n  return out;\n}\n\n/**\n * Returns the inverse of the components of a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to invert\n * @returns {vec3} out\n */\nexport function inverse(out, a) {\n  out[0] = 1.0 / a[0];\n  out[1] = 1.0 / a[1];\n  out[2] = 1.0 / a[2];\n  return out;\n}\n\n/**\n * Normalize a vec3\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a vector to normalize\n * @returns {vec3} out\n */\nexport function normalize(out, a) {\n  var x = a[0];\n  var y = a[1];\n  var z = a[2];\n  var len = x * x + y * y + z * z;\n  if (len > 0) {\n    //TODO: evaluate use of glm_invsqrt here?\n    len = 1 / Math.sqrt(len);\n  }\n  out[0] = a[0] * len;\n  out[1] = a[1] * len;\n  out[2] = a[2] * len;\n  return out;\n}\n\n/**\n * Calculates the dot product of two vec3's\n *\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {Number} dot product of a and b\n */\nexport function dot(a, b) {\n  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\n/**\n * Computes the cross product of two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @returns {vec3} out\n */\nexport function cross(out, a, b) {\n  var ax = a[0],\n    ay = a[1],\n    az = a[2];\n  var bx = b[0],\n    by = b[1],\n    bz = b[2];\n  out[0] = ay * bz - az * by;\n  out[1] = az * bx - ax * bz;\n  out[2] = ax * by - ay * bx;\n  return out;\n}\n\n/**\n * Performs a linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function lerp(out, a, b, t) {\n  var ax = a[0];\n  var ay = a[1];\n  var az = a[2];\n  out[0] = ax + t * (b[0] - ax);\n  out[1] = ay + t * (b[1] - ay);\n  out[2] = az + t * (b[2] - az);\n  return out;\n}\n\n/**\n * Performs a spherical linear interpolation between two vec3's\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function slerp(out, a, b, t) {\n  var angle = Math.acos(Math.min(Math.max(dot(a, b), -1), 1));\n  var sinTotal = Math.sin(angle);\n  var ratioA = Math.sin((1 - t) * angle) / sinTotal;\n  var ratioB = Math.sin(t * angle) / sinTotal;\n  out[0] = ratioA * a[0] + ratioB * b[0];\n  out[1] = ratioA * a[1] + ratioB * b[1];\n  out[2] = ratioA * a[2] + ratioB * b[2];\n  return out;\n}\n\n/**\n * Performs a hermite interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function hermite(out, a, b, c, d, t) {\n  var factorTimes2 = t * t;\n  var factor1 = factorTimes2 * (2 * t - 3) + 1;\n  var factor2 = factorTimes2 * (t - 2) + t;\n  var factor3 = factorTimes2 * (t - 1);\n  var factor4 = factorTimes2 * (3 - 2 * t);\n  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n  return out;\n}\n\n/**\n * Performs a bezier interpolation with two control points\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the first operand\n * @param {ReadonlyVec3} b the second operand\n * @param {ReadonlyVec3} c the third operand\n * @param {ReadonlyVec3} d the fourth operand\n * @param {Number} t interpolation amount, in the range [0-1], between the two inputs\n * @returns {vec3} out\n */\nexport function bezier(out, a, b, c, d, t) {\n  var inverseFactor = 1 - t;\n  var inverseFactorTimesTwo = inverseFactor * inverseFactor;\n  var factorTimes2 = t * t;\n  var factor1 = inverseFactorTimesTwo * inverseFactor;\n  var factor2 = 3 * t * inverseFactorTimesTwo;\n  var factor3 = 3 * factorTimes2 * inverseFactor;\n  var factor4 = factorTimes2 * t;\n  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;\n  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;\n  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;\n  return out;\n}\n\n/**\n * Generates a random vector with the given scale\n *\n * @param {vec3} out the receiving vector\n * @param {Number} [scale] Length of the resulting vector. If omitted, a unit vector will be returned\n * @returns {vec3} out\n */\nexport function random(out, scale) {\n  scale = scale === undefined ? 1.0 : scale;\n  var r = glMatrix.RANDOM() * 2.0 * Math.PI;\n  var z = glMatrix.RANDOM() * 2.0 - 1.0;\n  var zScale = Math.sqrt(1.0 - z * z) * scale;\n  out[0] = Math.cos(r) * zScale;\n  out[1] = Math.sin(r) * zScale;\n  out[2] = z * scale;\n  return out;\n}\n\n/**\n * Transforms the vec3 with a mat4.\n * 4th vector component is implicitly '1'\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat4} m matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat4(out, a, m) {\n  var x = a[0],\n    y = a[1],\n    z = a[2];\n  var w = m[3] * x + m[7] * y + m[11] * z + m[15];\n  w = w || 1.0;\n  out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;\n  out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;\n  out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;\n  return out;\n}\n\n/**\n * Transforms the vec3 with a mat3.\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyMat3} m the 3x3 matrix to transform with\n * @returns {vec3} out\n */\nexport function transformMat3(out, a, m) {\n  var x = a[0],\n    y = a[1],\n    z = a[2];\n  out[0] = x * m[0] + y * m[3] + z * m[6];\n  out[1] = x * m[1] + y * m[4] + z * m[7];\n  out[2] = x * m[2] + y * m[5] + z * m[8];\n  return out;\n}\n\n/**\n * Transforms the vec3 with a quat\n * Can also be used for dual quaternions. (Multiply it with the real part)\n *\n * @param {vec3} out the receiving vector\n * @param {ReadonlyVec3} a the vector to transform\n * @param {ReadonlyQuat} q normalized quaternion to transform with\n * @returns {vec3} out\n */\nexport function transformQuat(out, a, q) {\n  // Fast Vector Rotation using Quaternions by Robert Eisele\n  // https://raw.org/proof/vector-rotation-using-quaternions/\n\n  var qx = q[0],\n    qy = q[1],\n    qz = q[2],\n    qw = q[3];\n  var vx = a[0],\n    vy = a[1],\n    vz = a[2];\n\n  // t = q x v\n  var tx = qy * vz - qz * vy;\n  var ty = qz * vx - qx * vz;\n  var tz = qx * vy - qy * vx;\n\n  // t = 2t\n  tx = tx + tx;\n  ty = ty + ty;\n  tz = tz + tz;\n\n  // v + w t + q x t\n  out[0] = vx + qw * tx + qy * tz - qz * ty;\n  out[1] = vy + qw * ty + qz * tx - qx * tz;\n  out[2] = vz + qw * tz + qx * ty - qy * tx;\n  return out;\n}\n\n/**\n * Rotate a 3D vector around the x-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateX(out, a, b, rad) {\n  var p = [],\n    r = [];\n  //Translate point to the origin\n  p[0] = a[0] - b[0];\n  p[1] = a[1] - b[1];\n  p[2] = a[2] - b[2];\n\n  //perform rotation\n  r[0] = p[0];\n  r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad);\n  r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad);\n\n  //translate to correct position\n  out[0] = r[0] + b[0];\n  out[1] = r[1] + b[1];\n  out[2] = r[2] + b[2];\n  return out;\n}\n\n/**\n * Rotate a 3D vector around the y-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateY(out, a, b, rad) {\n  var p = [],\n    r = [];\n  //Translate point to the origin\n  p[0] = a[0] - b[0];\n  p[1] = a[1] - b[1];\n  p[2] = a[2] - b[2];\n\n  //perform rotation\n  r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad);\n  r[1] = p[1];\n  r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad);\n\n  //translate to correct position\n  out[0] = r[0] + b[0];\n  out[1] = r[1] + b[1];\n  out[2] = r[2] + b[2];\n  return out;\n}\n\n/**\n * Rotate a 3D vector around the z-axis\n * @param {vec3} out The receiving vec3\n * @param {ReadonlyVec3} a The vec3 point to rotate\n * @param {ReadonlyVec3} b The origin of the rotation\n * @param {Number} rad The angle of rotation in radians\n * @returns {vec3} out\n */\nexport function rotateZ(out, a, b, rad) {\n  var p = [],\n    r = [];\n  //Translate point to the origin\n  p[0] = a[0] - b[0];\n  p[1] = a[1] - b[1];\n  p[2] = a[2] - b[2];\n\n  //perform rotation\n  r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad);\n  r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad);\n  r[2] = p[2];\n\n  //translate to correct position\n  out[0] = r[0] + b[0];\n  out[1] = r[1] + b[1];\n  out[2] = r[2] + b[2];\n  return out;\n}\n\n/**\n * Get the angle between two 3D vectors\n * @param {ReadonlyVec3} a The first operand\n * @param {ReadonlyVec3} b The second operand\n * @returns {Number} The angle in radians\n */\nexport function angle(a, b) {\n  var ax = a[0],\n    ay = a[1],\n    az = a[2],\n    bx = b[0],\n    by = b[1],\n    bz = b[2],\n    mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)),\n    cosine = mag && dot(a, b) / mag;\n  return Math.acos(Math.min(Math.max(cosine, -1), 1));\n}\n\n/**\n * Set the components of a vec3 to zero\n *\n * @param {vec3} out the receiving vector\n * @returns {vec3} out\n */\nexport function zero(out) {\n  out[0] = 0.0;\n  out[1] = 0.0;\n  out[2] = 0.0;\n  return out;\n}\n\n/**\n * Returns a string representation of a vector\n *\n * @param {ReadonlyVec3} a vector to represent as a string\n * @returns {String} string representation of the vector\n */\nexport function str(a) {\n  return \"vec3(\" + a[0] + \", \" + a[1] + \", \" + a[2] + \")\";\n}\n\n/**\n * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function exactEquals(a, b) {\n  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];\n}\n\n/**\n * Returns whether or not the vectors have approximately the same elements in the same position.\n *\n * @param {ReadonlyVec3} a The first vector.\n * @param {ReadonlyVec3} b The second vector.\n * @returns {Boolean} True if the vectors are equal, false otherwise.\n */\nexport function equals(a, b) {\n  var a0 = a[0],\n    a1 = a[1],\n    a2 = a[2];\n  var b0 = b[0],\n    b1 = b[1],\n    b2 = b[2];\n  return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2));\n}\n\n/**\n * Alias for {@link vec3.subtract}\n * @function\n */\nexport var sub = subtract;\n\n/**\n * Alias for {@link vec3.multiply}\n * @function\n */\nexport var mul = multiply;\n\n/**\n * Alias for {@link vec3.divide}\n * @function\n */\nexport var div = divide;\n\n/**\n * Alias for {@link vec3.distance}\n * @function\n */\nexport var dist = distance;\n\n/**\n * Alias for {@link vec3.squaredDistance}\n * @function\n */\nexport var sqrDist = squaredDistance;\n\n/**\n * Alias for {@link vec3.length}\n * @function\n */\nexport var len = length;\n\n/**\n * Alias for {@link vec3.squaredLength}\n * @function\n */\nexport var sqrLen = squaredLength;\n\n/**\n * Perform some operation over an array of vec3s.\n *\n * @param {Array} a the array of vectors to iterate over\n * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed\n * @param {Number} offset Number of elements to skip at the beginning of the array\n * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array\n * @param {Function} fn Function to call for each vector in the array\n * @param {Object} [arg] additional argument to pass to fn\n * @returns {Array} a\n * @function\n */\nexport var forEach = function () {\n  var vec = create();\n  return function (a, stride, offset, count, fn, arg) {\n    var i, l;\n    if (!stride) {\n      stride = 3;\n    }\n    if (!offset) {\n      offset = 0;\n    }\n    if (count) {\n      l = Math.min(count * stride + offset, a.length);\n    } else {\n      l = a.length;\n    }\n    for (i = offset; i < l; i += stride) {\n      vec[0] = a[i];\n      vec[1] = a[i + 1];\n      vec[2] = a[i + 2];\n      fn(vec, vec, arg);\n      a[i] = vec[0];\n      a[i + 1] = vec[1];\n      a[i + 2] = vec[2];\n    }\n    return a;\n  };\n}();","/**\n * @module Camera\n * Interactive camera primitives for WebGPU scene navigation.\n *\n * This module defines the `Camera` class, which keeps the current eye,\n * look-at, and up vectors in sync with view and projection matrices. It also\n * exposes a one-shot helper for building view-projection matrices from\n * explicit parameters when a persistent camera instance is not needed.\n */\n\nimport { vec3, mat4 } from 'gl-matrix';\n\n/**\n * Initial camera state used to seed or reset a `Camera` instance.\n */\nexport interface CameraData {\n    /** World-space up vector. */\n    up: number[];\n    /** Initial eye (camera) position in world space. */\n    eye: number[];\n    /** Point the camera looks at in world space. */\n    lookAt: number[];\n}\n\n/**\n * Explicit parameters for building a single view-projection matrix.\n */\nexport interface ViewProjectionParams {\n    /** Eye (camera) position in world space. */\n    eye:    [number, number, number];\n    /** Point the camera looks at in world space. */\n    lookAt: [number, number, number];\n    /** World-space up vector. */\n    up:     [number, number, number];\n    /** Vertical field of view in degrees. */\n    fovDeg: number;\n    /** Viewport aspect ratio (width / height). */\n    aspect: number;\n    /** Near clipping plane distance. */\n    near:   number;\n    /** Far clipping plane distance. */\n    far:    number;\n}\n\n/**\n * Interactive 3-DOF camera for orbit-style navigation.\n *\n * The camera tracks world-space eye, look-at, and up vectors together with the\n * current viewport size. Call the navigation methods to adjust state, then\n * call {@link Camera.update} to rebuild the matrices. Projection uses\n * reversed-Z depth mapping for improved precision at distance.\n *\n * @example\n * const camera = new Camera();\n * camera.resize(width, height);\n * camera.zoom(-1, 0.5, 0.5);\n * camera.update();\n */\nexport class Camera {\n    /** Eye (camera) position in world space. */\n    protected wEye: vec3 = vec3.create();\n    /** Look-at target in world space. */\n    protected wLookAt: vec3 = vec3.create();\n    /** Normalised direction vector from eye to look-at. */\n    protected wEyeDir: vec3 = vec3.create();\n    /** World-space up vector. */\n    protected wUp: vec3 = vec3.create();\n    /** Near clipping plane distance. */\n    protected wNear: number = 0;\n    /** Far clipping plane distance. */\n    protected wFar: number = 0;\n    /** Vertical field of view in radians. */\n    protected fovy = (45 * Math.PI) / 180.0;\n    /** Current projection matrix. */\n    protected mProjectionMatrix: mat4 = mat4.create();\n    /** Current view matrix. */\n    protected mViewMatrix: mat4 = mat4.create();\n    private viewportWidth: number = 0;\n    private viewportHeight: number = 0;\n\n    private static defaultParams: CameraData = {\n        up: [0, 1, 0],\n        eye: [0, 0, 10000],\n        lookAt: [0, 0, 0],\n    };\n\n    /**\n     * Creates a camera with the provided initial state.\n     *\n     * @param params - Initial camera position and orientation (defaults to `[0, 1, 0]` up, 10k units above origin).\n     * @throws Never throws.\n     * @example\n     * const camera = new Camera();\n     * const custom = new Camera({ eye: [0, 0, 500], lookAt: [0, 0, 0], up: [0, 1, 0] });\n     */\n    constructor(params: CameraData = Camera.defaultParams) {\n        this.resetCamera(params.up, params.lookAt, params.eye);\n    }\n\n    /**\n     * Resets the camera to a new position, orientation, and default projection.\n     *\n     * @param wUp - World-space up vector.\n     * @param wLookAt - Point to look at in world space.\n     * @param wEye - Eye position in world space.\n     * @throws Never throws.\n     * @example\n     * camera.resetCamera([0, 1, 0], [100, 200, 0], [100, 200, 500]);\n     * camera.update();\n     */\n    public resetCamera(wUp: number[], wLookAt: number[], wEye: number[]): void {\n        this.fovy = (45 * Math.PI) / 180.0;\n        this.mProjectionMatrix = mat4.create();\n        this.mViewMatrix = mat4.create();\n        this.wNear = 1;\n        this.wFar = 5e5;\n        this.wLookAt = vec3.fromValues(wLookAt[0], wLookAt[1], wLookAt[2]);\n        this.wEye = vec3.fromValues(wEye[0], wEye[1], wEye[2]);\n        this.updateEyeDirAndLen();\n        this.wUp = vec3.fromValues(wUp[0], wUp[1], wUp[2]);\n    }\n\n    /**\n     * Returns the current projection matrix.\n     *\n     * @returns The projection matrix in column-major `mat4`.\n     * @throws Never throws.\n     * @example\n     * camera.update();\n     * const proj = camera.getProjectionMatrix();\n     */\n    public getProjectionMatrix(): mat4 {\n        return this.mProjectionMatrix;\n    }\n\n    public getEye(): [number, number, number] {\n        return [this.wEye[0], this.wEye[1], this.wEye[2]];\n    }\n\n    public getLookAt(): [number, number, number] {\n        return [this.wLookAt[0], this.wLookAt[1], this.wLookAt[2]];\n    }\n\n    public getUp(): [number, number, number] {\n        return [this.wUp[0], this.wUp[1], this.wUp[2]];\n    }\n\n    public getFovyRadians(): number {\n        return this.fovy;\n    }\n\n    public getNear(): number {\n        return this.wNear;\n    }\n\n    public getFar(): number {\n        return this.wFar;\n    }\n\n    public getViewportHeight(): number {\n        return this.viewportHeight;\n    }\n\n    public getViewportWidth(): number {\n        return this.viewportWidth;\n    }\n\n    public getViewProjectionMatrix(): Float32Array {\n        return new Float32Array(mat4.mul(mat4.create(), this.mProjectionMatrix, this.mViewMatrix));\n    }\n\n    public getWorldRayDirection(x: number, y: number): [number, number, number] {\n        const direction = this.screenCoordToWorldDir(x, y);\n        return [direction[0], direction[1], direction[2]];\n    }\n\n    public setOrthographicBounds(left: number, right: number, bottom: number, top: number): void {\n        mat4.identity(this.mViewMatrix);\n        mat4.orthoZO(this.mProjectionMatrix, left, right, bottom, top, 0, -100);\n        this.wEye = vec3.fromValues((left + right) * 0.5, (bottom + top) * 0.5, 100);\n        this.wLookAt = vec3.fromValues((left + right) * 0.5, (bottom + top) * 0.5, 0);\n        this.wUp = vec3.fromValues(0, 1, 0);\n        this.updateEyeDirAndLen();\n    }\n\n    /**\n     * Returns the current view (model-view) matrix.\n     *\n     * @returns The view matrix in column-major `mat4`.\n     * @throws Never throws.\n     * @example\n     * camera.update();\n     * const view = camera.getModelViewMatrix();\n     */\n    public getModelViewMatrix(): mat4 {\n        return this.mViewMatrix;\n    }\n\n    /**\n     * Updates viewport size and recomputes matrices in one call.\n     *\n     * Pass drawable canvas pixel size, not CSS size.\n     *\n     * @param width - Viewport width in pixels.\n     * @param height - Viewport height in pixels.\n     * @throws Never throws.\n     * @example\n     * camera.resize(1920, 1080);  // calls update() internally\n     */\n    public resize(width: number, height: number): void {\n        this.viewportWidth = width;\n        this.viewportHeight = height;\n        this.update();\n    }\n\n    /**\n     * Zooms the camera at the cursor position, preserving it in world space.\n     *\n     * @param delta - Normalized scroll delta (positive = zoom out, negative = zoom in).\n     * @param x - Normalized cursor X position (0–1, left to right).\n     * @param y - Normalized cursor Y position (0–1, bottom to top).\n     * @throws Never throws.\n     * @example\n     * camera.zoom(-1, 0.5, 0.5);  // zoom in at screen center\n     * camera.update();\n     */\n    public zoom(delta: number, x: number, y: number): void {\n        const zoomScale = Math.max(Math.abs(this.wEye[2]), 1) * 0.2;\n        delta = -delta * zoomScale;\n        const dir = this.screenCoordToWorldDir(x, y);\n        vec3.scaleAndAdd(this.wEye, this.wEye, dir, delta);\n        vec3.scaleAndAdd(this.wLookAt, this.wEye, this.wEyeDir, vec3.length(this.wEyeDir));\n    }\n\n    /**\n     * Pans the camera in screen space, scaled by the current view distance.\n     *\n     * @param dx - Normalized horizontal drag delta (0–1).\n     * @param dy - Normalized vertical drag delta (0–1).\n     * @throws Never throws.\n     * @example\n     * camera.translate(0.1, 0);  // pan right\n     * camera.update();\n     */\n    public translate(dx: number, dy: number): void {\n        const scale = this.wEye[2];\n        const X = vec3.create();\n        vec3.normalize(X, vec3.cross(X, this.wEyeDir, this.wUp));\n        const D = vec3.add(\n            vec3.create(),\n            vec3.scale(vec3.create(), X, dx * scale),\n            vec3.scale(vec3.create(), this.wUp, dy * scale),\n        );\n        vec3.add(this.wEye, this.wEye, D);\n        vec3.scaleAndAdd(this.wLookAt, this.wEye, this.wEyeDir, vec3.length(this.wEyeDir));\n    }\n\n    /**\n     * Rotates the camera around the world Z-axis (compass bearing).\n     *\n     * @param delta - Rotation angle in radians.\n     * @throws Never throws.\n     * @example\n     * camera.yaw(Math.PI / 4);  // rotate 45° clockwise\n     * camera.update();\n     */\n    public yaw(delta: number): void {\n        vec3.rotateZ(this.wEyeDir, this.wEyeDir, vec3.fromValues(0, 0, 0), delta);\n        vec3.rotateZ(this.wUp, this.wUp, vec3.fromValues(0, 0, 0), delta);\n        vec3.scaleAndAdd(this.wLookAt, this.wEye, this.wEyeDir, vec3.length(this.wEyeDir));\n    }\n\n    /**\n     * Tilts the camera up or down (elevation angle).\n     *\n     * @param delta - Tilt angle in radians. Positive values tilt upward.\n     * @throws Never throws.\n     * @example\n     * camera.pitch(-0.3);  // tilt downward ~17°\n     * camera.update();\n     */\n    public pitch(delta: number): void {\n        delta = -delta;\n        vec3.add(\n            this.wEyeDir,\n            vec3.scale(vec3.create(), this.wUp, Math.sin(delta)),\n            vec3.scale(vec3.create(), this.wEyeDir, Math.cos(delta)),\n        );\n        vec3.normalize(this.wEyeDir, this.wEyeDir);\n        vec3.scaleAndAdd(this.wLookAt, this.wEye, this.wEyeDir, vec3.length(this.wEyeDir));\n        vec3.cross(this.wUp, vec3.cross(vec3.create(), this.wEyeDir, this.wUp), this.wEyeDir);\n        vec3.normalize(this.wUp, this.wUp);\n    }\n\n    /**\n     * Returns a scalar proportional to the current map zoom for marker sizing.\n     *\n     * This uses the camera eye height, which is the quantity changed by the map\n     * zoom interaction and therefore tracks zoom more reliably than the\n     * normalized eye-direction vector.\n     */\n    public getZoomScale(): number {\n        return Math.max(Math.abs(this.wEye[2]), 1) / 10000;\n    }\n\n    /**\n     * Rebuilds view and projection matrices from the current camera state.\n     *\n     * Uses reversed-Z depth for improved precision at long range.\n     *\n     * @throws Never throws.\n     * @example\n     * camera.zoom(-1, 0.5, 0.5);\n     * camera.update();  // rebuild matrices after navigation change\n     */\n    public update(): void {\n        const aspect = this.viewportWidth / this.viewportHeight;\n        mat4.lookAt(this.mViewMatrix, this.wEye, this.wLookAt, this.wUp);\n        // Reversed-Z: swap near/far so near→1 and far→0 in NDC.\n        // Combined with depthClearValue=0 and depthCompare='greater-equal' this\n        // distributes float32 precision logarithmically, eliminating z-fighting\n        // at distance without requiring an absurdly large far plane.\n        mat4.perspectiveZO(this.mProjectionMatrix, this.fovy, aspect, this.wFar, this.wNear);\n    }\n\n    /**\n     * Builds a stateless view-projection matrix from explicit parameters.\n     *\n     * @param p - Camera and projection parameters.\n     * @returns Column-major `Float32Array` of length 16.\n     * @throws Never throws.\n     * @example\n     * const vp = Camera.buildViewProjection({\n     *   eye: [0, 0, 500], lookAt: [0, 0, 0], up: [0, 1, 0],\n     *   fovDeg: 45, aspect: 16/9, near: 0.1, far: 10000,\n     * });\n     */\n    public static buildViewProjection(p: ViewProjectionParams): Float32Array {\n        const view = mat4.lookAt(mat4.create(), p.eye, p.lookAt, p.up);\n        const proj = mat4.perspectiveZO(mat4.create(), p.fovDeg * (Math.PI / 180), p.aspect, p.near, p.far);\n        return new Float32Array(mat4.mul(mat4.create(), proj, view));\n    }\n\n    /**\n     * Converts a normalized screen coordinate to a world-space direction ray.\n     *\n     * @param x - Normalized screen X (0–1, left to right).\n     * @param y - Normalized screen Y (0–1, bottom to top).\n     * @returns Normalized direction vector in world space.\n     * @throws Never throws.\n     */\n    protected screenCoordToWorldDir(x: number, y: number): vec3 {\n        const wRight = vec3.create();\n        vec3.normalize(wRight, vec3.cross(wRight, this.wEyeDir, this.wUp));\n        const upOffset = vec3.scale(vec3.create(), this.wUp, Math.tan(this.fovy / 2) * (y - 0.5) * 2);\n        const aspect = this.viewportWidth / this.viewportHeight;\n        const rightOffset = vec3.scale(vec3.create(), wRight, Math.tan(this.fovy / 2) * (x - 0.5) * 2 * aspect);\n        const offset = vec3.add(vec3.create(), upOffset, rightOffset);\n        const dir = vec3.add(vec3.create(), this.wEyeDir, offset);\n        vec3.normalize(dir, dir);\n        return dir;\n    }\n\n    /**\n     * Recomputes the normalized eye direction from current eye and look-at.\n     *\n     * @throws Never throws.\n     */\n    protected updateEyeDirAndLen(): void {\n        this.wEyeDir = vec3.create();\n        vec3.sub(this.wEyeDir, this.wLookAt, this.wEye);\n        vec3.normalize(this.wEyeDir, this.wEyeDir);\n    }\n}\n","/**\n * @module EventEmitter\n * A lightweight, type-safe event emitter for custom application events.\n *\n * This module provides a generic event bus keyed by an event record, along with\n * a shared selection payload used across visualization packages. It exposes the\n * minimal `on`, `off`, and `emit` lifecycle needed to register listeners,\n * remove them by reference, and dispatch typed payloads synchronously.\n */\n\n/** Listener callback for a single typed event payload. */\nexport type EventListener<T> = (event: T) => void;\n\n/**\n * Base payload shared by selection-driven visualization events.\n *\n * Packages such as `@urban-toolkit/autk-map` and `@urban-toolkit/autk-plot` extend or alias this shape so\n * selection interactions follow a consistent contract across the toolkit.\n */\nexport interface SelectionData {\n    /** Source feature indices included in the current selection. */\n    selection: number[];\n}\n\n/**\n * Type-safe event emitter keyed by an event record.\n *\n * Each event name maps to a specific payload type, and listeners are stored per\n * event key. Listener removal requires the original function reference.\n *\n * @template Events Record mapping event names to their payload types.\n *\n * @example\n * type MapEvents = { pick: { selection: number[]; layerId: string } };\n * const emitter = new EventEmitter<MapEvents>();\n * emitter.on('pick', ({ selection, layerId }) => console.log(selection, layerId));\n * emitter.emit('pick', { selection: [1, 2], layerId: 'buildings' });\n */\nexport class EventEmitter<Events extends Record<string, unknown>> {\n    private _listeners: { [K in keyof Events]?: Array<EventListener<Events[K]>> } = {};\n\n    /**\n     * Registers a listener for the given event.\n     *\n     * Multiple registrations of the same callback are allowed and treated as separate entries.\n     *\n     * @param event Event name to subscribe to.\n     * @param listener Callback invoked when the event fires.\n     * @throws Never throws.\n     * @example\n     * emitter.on('pick', ({ selection, layerId }) => console.log(selection));\n     */\n    on<K extends keyof Events>(event: K, listener: EventListener<Events[K]>): void {\n        if (!this._listeners[event]) {\n            this._listeners[event] = [];\n        }\n        this._listeners[event]!.push(listener);\n    }\n\n    /**\n     * Removes a previously registered listener by reference.\n     *\n     * @param event Event name to unsubscribe from.\n     * @param listener Exact listener reference to remove.\n     * @throws Never throws.\n     * @example\n     * const handler = (e) => console.log(e);\n     * emitter.on('pick', handler);\n     * emitter.off('pick', handler);\n     */\n    off<K extends keyof Events>(event: K, listener: EventListener<Events[K]>): void {\n        const arr = this._listeners[event];\n        if (arr) {\n            this._listeners[event] = arr.filter(l => l !== listener) as typeof arr;\n        }\n    }\n\n    /**\n     * Dispatches an event payload to all registered listeners synchronously.\n     *\n     * @param event Event name to dispatch.\n     * @param payload Payload passed to each listener.\n     * @throws Never throws. Listener errors propagate to the caller.\n     * @example\n     * emitter.emit('pick', { selection: [1, 2], layerId: 'buildings' });\n     */\n    emit<K extends keyof Events>(event: K, payload: Events[K]): void {\n        this._listeners[event]?.forEach(l => l(payload));\n    }\n}\n","/**\n * @module LayerTypes\n * Shared layer-taxonomy and geographic-bounds types used across the toolkit.\n *\n * This module centralizes the layer families understood by collection loading,\n * rendering selection, and downstream styling logic. It also defines the named\n * coordinate form used by GeoJSON utilities when they return geographic bounds.\n */\n\n/**\n * Canonical layer families recognized by collection loading and rendering.\n *\n * `LayerType` is used to route GeoJSON and other layer sources into the\n * appropriate pipeline branch, including geometry inference, renderer\n * selection, and thematic handling.\n */\nexport type LayerType =\n  | 'background'\n  | 'surface'\n  | 'parks'\n  | 'water'\n  | 'roads'\n  | 'buildings'\n  | 'points'\n  | 'polygons'\n  | 'polylines'\n  | 'raster';\n\n/** All `LayerType` values as a readonly array, in union definition order. */\nexport const LAYER_TYPE_VALUES: readonly LayerType[] = [\n  'background',\n  'surface',\n  'parks',\n  'water',\n  'roads',\n  'buildings',\n  'points',\n  'polygons',\n  'polylines',\n  'raster',\n] as const;\n\n/**\n * OSM base layer types in fixed bottom-up render order.\n *\n * Buildings are always rendered last and are not included here.\n * This order is independent of the `LayerType` union definition order.\n */\nexport const OSM_BASE_LAYER_ORDER: readonly LayerType[] = [\n  'surface',\n  'parks',\n  'water',\n  'roads',\n  'buildings'\n] as const;\n\n/**\n * Named geographic bounding box returned by GeoJSON utility helpers.\n *\n * The fields preserve the coordinate order used throughout the toolkit while\n * giving each bound an explicit longitude/latitude name.\n */\nexport interface BoundingBox {\n  /** Minimum longitude contained in the bounds. */\n  minLon: number;\n  /** Minimum latitude contained in the bounds. */\n  minLat: number;\n  /** Maximum longitude contained in the bounds. */\n  maxLon: number;\n  /** Maximum latitude contained in the bounds. */\n  maxLat: number;\n}\n","/**\n * @module GeoJsonUtils\n * GeoJSON spatial helpers for deriving bounding boxes, shared origins, and\n * centroids.\n *\n * This module provides small geometry utilities used to summarize feature\n * collections and raw geometries. It covers bounding-box derivation, origin\n * calculation from a collection extent, and geometry-aware centroid\n * aggregation across points, lines, polygons, and geometry collections.\n */\nimport { \n    FeatureCollection, \n    Geometry, \n    Position \n} from 'geojson';\n\nimport type { BoundingBox } from './types-layer';\nimport { booleanIntersects, bbox as turfBbox } from '@turf/turf';\nimport RBush from 'rbush';\n\n/**\n * Type guard that checks whether a value is a GeoJSON FeatureCollection.\n *\n * @param data - value to test.\n * @returns `true` if the value has `type: 'FeatureCollection'` and a `features` array.\n * @throws Never throws.\n * @example\n * isFeatureCollection({ type: 'FeatureCollection', features: [] }); // true\n * isFeatureCollection([{ name: 'x' }]); // false\n */\nexport function isFeatureCollection(data: unknown): data is FeatureCollection {\n    return (\n        typeof data === 'object' &&\n        data !== null &&\n        'type' in data &&\n        (data as FeatureCollection).type === 'FeatureCollection' &&\n        'features' in data &&\n        Array.isArray((data as FeatureCollection).features)\n    );\n}\n\n/**\n * Computes a spatial origin from a feature collection's bounding-box center.\n *\n * @param geojson - Feature collection to summarize.\n * @returns The `[longitude, latitude]` center, or `[0, 0]` when no usable geometry is present.\n * @throws Never throws.\n * @example\n * const origin = computeOrigin(fc);\n * // origin → [151.2, -33.8]\n */\nexport function computeOrigin(geojson: FeatureCollection): [number, number] {\n    const bbox = computeBoundingBox(geojson);\n    if (!bbox) return [0, 0];\n    return [\n        (bbox.minLon + bbox.maxLon) * 0.5,\n        (bbox.minLat + bbox.maxLat) * 0.5,\n    ];\n}\n\n/**\n * Computes the geographic bounding box of a GeoJSON collection or geometry.\n *\n * @param source - GeoJSON feature collection or geometry to inspect.\n * Pass `null` to receive a `null` result.\n * @returns A named bounding box, or `null` when the source is empty or has no coordinates.\n * @throws Never throws.\n * @example\n * const bbox = computeBoundingBox(fc);\n * // bbox → { minLon: 151.0, minLat: -34.0, maxLon: 151.5, maxLat: -33.5 }\n */\nexport function computeBoundingBox(source: FeatureCollection | Geometry | null): BoundingBox | null {\n    if (!source) {\n        return null;\n    }\n\n    let minLon = Infinity;\n    let minLat = Infinity;\n    let maxLon = -Infinity;\n    let maxLat = -Infinity;\n\n    const expand = (coord: number[]) => {\n        if (coord[0] < minLon) minLon = coord[0];\n        if (coord[0] > maxLon) maxLon = coord[0];\n        if (coord[1] < minLat) minLat = coord[1];\n        if (coord[1] > maxLat) maxLat = coord[1];\n    };\n\n    if (source.type === 'FeatureCollection') {\n        for (const feature of source.features) {\n            const geom = feature.geometry;\n            if (!geom) continue;\n            expandGeometry(geom, expand);\n        }\n    } else {\n        expandGeometry(source, expand);\n    }\n\n    if (!Number.isFinite(minLon)) {\n        return null;\n    }\n\n    return { minLon, minLat, maxLon, maxLat };\n}\n\n/**\n * Computes a geometry-aware weighted centroid for any GeoJSON geometry type.\n *\n * @param geometry - GeoJSON geometry whose centroid should be computed.\n * @returns A three-component centroid tuple `[x, y, z]`, or `null` when the\n * geometry is `null` or cannot yield a meaningful centroid.\n * @throws Never throws.\n * @example\n * const centroid = computeGeometryCentroid(polygonGeom);\n * // centroid → [151.2, -33.8, 0]\n */\nexport function computeGeometryCentroid(geometry: Geometry | null): [number, number, number] | null {\n    if (!geometry) return null;\n    const weighted = computeWeightedCentroid(geometry);\n    return weighted ? weighted.centroid : null;\n}\n\n/**\n * Visits every coordinate contained in a GeoJSON geometry.\n *\n * @param geom - Geometry whose coordinates should be traversed.\n * @param expand - Callback invoked for each coordinate position encountered.\n * @returns Nothing. The provided callback is used for side effects such as\n * updating running bounds.\n */\nfunction expandGeometry(geom: Geometry, expand: (c: number[]) => void): void {\n    switch (geom.type) {\n        case 'Point':\n            expand(geom.coordinates);\n            break;\n        case 'MultiPoint':\n        case 'LineString':\n            for (const c of geom.coordinates) expand(c);\n            break;\n        case 'MultiLineString':\n            for (const line of geom.coordinates) {\n                for (const c of line) expand(c);\n            }\n            break;\n        case 'Polygon':\n            for (const ring of geom.coordinates) {\n                for (const c of ring) expand(c);\n            }\n            break;\n        case 'MultiPolygon':\n            for (const poly of geom.coordinates) {\n                for (const ring of poly) {\n                    for (const c of ring) expand(c);\n                }\n            }\n            break;\n        case 'GeometryCollection':\n            for (const sub of geom.geometries) expandGeometry(sub, expand);\n            break;\n    }\n}\n\n/**\n * Internal weighted centroid used when combining centroid contributions from\n * multiple geometries or geometry parts.\n */\ntype WeightedCentroid = {\n    centroid: [number, number, number];\n    weight: number;\n};\n\n/**\n * Computes a geometry centroid together with the weight used to combine it\n * with other centroids.\n *\n * Point geometries contribute unit weight, line geometries contribute total\n * length, and polygon geometries contribute total area.\n *\n * @param geometry - Geometry to reduce into a weighted centroid.\n * @returns The weighted centroid and its aggregation weight, or `null` when no\n * meaningful centroid can be derived.\n */\nfunction computeWeightedCentroid(geometry: Geometry): WeightedCentroid | null {\n    switch (geometry.type) {\n        case 'Point':\n            return {\n                centroid: [geometry.coordinates[0], geometry.coordinates[1], geometry.coordinates[2] ?? 0],\n                weight: 1,\n            };\n        case 'MultiPoint':\n            return averagePositions(geometry.coordinates);\n        case 'LineString':\n            return computeLineCentroid(geometry.coordinates);\n        case 'MultiLineString':\n            return combineWeightedCentroids(geometry.coordinates.map((line) => computeLineCentroid(line)));\n        case 'Polygon':\n            return computePolygonCentroid(geometry.coordinates);\n        case 'MultiPolygon':\n            return combineWeightedCentroids(geometry.coordinates.map((polygon) => computePolygonCentroid(polygon)));\n        case 'GeometryCollection':\n            return combineWeightedCentroids(geometry.geometries.map((child) => computeWeightedCentroid(child)));\n    }\n}\n\n/**\n * Computes the arithmetic mean of a list of positions.\n *\n * Missing Z components are treated as `0`.\n *\n * @param positions - Positions to average.\n * @returns A weighted centroid whose weight equals the number of positions, or\n * `null` when the input is empty.\n */\nfunction averagePositions(positions: Position[]): WeightedCentroid | null {\n    if (positions.length === 0) return null;\n\n    let x = 0;\n    let y = 0;\n    let z = 0;\n    for (const position of positions) {\n        x += position[0];\n        y += position[1];\n        z += position[2] ?? 0;\n    }\n\n    return {\n        centroid: [x / positions.length, y / positions.length, z / positions.length],\n        weight: positions.length,\n    };\n}\n\n/**\n * Computes a length-weighted centroid for a line string.\n *\n * Each segment contributes its midpoint weighted by segment length. Degenerate\n * zero-length lines fall back to a simple average of the input positions.\n *\n * @param positions - Ordered line positions.\n * @returns A weighted centroid whose weight equals total line length, or\n * `null` when no positions are provided.\n */\nfunction computeLineCentroid(positions: Position[]): WeightedCentroid | null {\n    if (positions.length === 0) return null;\n    if (positions.length === 1) return averagePositions(positions);\n\n    let totalLength = 0;\n    let weightedX = 0;\n    let weightedY = 0;\n    let weightedZ = 0;\n\n    for (let i = 0; i < positions.length - 1; i++) {\n        const start = positions[i];\n        const end = positions[i + 1];\n        const length = Math.hypot(end[0] - start[0], end[1] - start[1], (end[2] ?? 0) - (start[2] ?? 0));\n        if (length === 0) continue;\n\n        totalLength += length;\n        weightedX += ((start[0] + end[0]) * 0.5) * length;\n        weightedY += ((start[1] + end[1]) * 0.5) * length;\n        weightedZ += (((start[2] ?? 0) + (end[2] ?? 0)) * 0.5) * length;\n    }\n\n    if (totalLength === 0) {\n        return averagePositions(positions);\n    }\n\n    return {\n        centroid: [weightedX / totalLength, weightedY / totalLength, weightedZ / totalLength],\n        weight: totalLength,\n    };\n}\n\n/**\n * Computes an area-weighted centroid for a polygon with optional holes.\n *\n * The exterior ring contributes positive area and interior rings subtract from\n * the total, matching standard polygon centroid calculations.\n *\n * @param rings - Polygon rings in GeoJSON order, with the shell first and any\n * holes following.\n * @returns A weighted centroid whose weight equals polygon area, or `null`\n * when the polygon has no usable coordinates.\n */\nfunction computePolygonCentroid(rings: Position[][]): WeightedCentroid | null {\n    const shell = rings[0];\n    if (!shell || shell.length === 0) return null;\n\n    let weightedX = 0;\n    let weightedY = 0;\n    let weightedZ = 0;\n    let totalAreaContribution = 0;\n\n    for (let ringIndex = 0; ringIndex < rings.length; ringIndex++) {\n        const ring = rings[ringIndex];\n        const ringCentroid = computeRingCentroid(ring);\n        if (!ringCentroid) continue;\n\n        const areaContribution = Math.abs(ringCentroid.signedArea) * (ringIndex === 0 ? 1 : -1);\n        weightedX += ringCentroid.centroid[0] * areaContribution;\n        weightedY += ringCentroid.centroid[1] * areaContribution;\n        weightedZ += ringCentroid.centroid[2] * areaContribution;\n        totalAreaContribution += areaContribution;\n    }\n\n    const totalArea = Math.abs(totalAreaContribution);\n    if (totalArea === 0) {\n        const flattened = rings.flat();\n        return averagePositions(flattened);\n    }\n\n    return {\n        centroid: [weightedX / totalAreaContribution, weightedY / totalAreaContribution, weightedZ / totalAreaContribution],\n        weight: totalArea,\n    };\n}\n\n/**\n * Computes the signed-area centroid for a single polygon ring.\n *\n * @param ring - Closed polygon ring to analyze.\n * @returns The ring centroid and signed area contribution, or `null` when the\n * ring has fewer than three positions or zero area.\n */\nfunction computeRingCentroid(ring: Position[]): { centroid: [number, number, number]; signedArea: number } | null {\n    if (ring.length < 3) return null;\n\n    let crossSum = 0;\n    let centroidX = 0;\n    let centroidY = 0;\n    let weightedZ = 0;\n\n    for (let i = 0; i < ring.length - 1; i++) {\n        const current = ring[i];\n        const next = ring[i + 1];\n        const cross = current[0] * next[1] - next[0] * current[1];\n        crossSum += cross;\n        centroidX += (current[0] + next[0]) * cross;\n        centroidY += (current[1] + next[1]) * cross;\n        weightedZ += (((current[2] ?? 0) + (next[2] ?? 0)) * 0.5) * cross;\n    }\n\n    const signedArea = crossSum * 0.5;\n    if (signedArea === 0) return null;\n\n    return {\n        centroid: [\n            centroidX / (6 * signedArea),\n            centroidY / (6 * signedArea),\n            weightedZ / crossSum,\n        ],\n        signedArea,\n    };\n}\n\n/**\n * Combines multiple weighted centroids into a single weighted centroid.\n *\n * @param centroids - Weighted centroid candidates to aggregate.\n * `null` entries and zero-weight centroids are ignored.\n * @returns The combined weighted centroid, or `null` when no valid weighted\n * centroids are provided.\n */\nfunction combineWeightedCentroids(\n    centroids: Array<WeightedCentroid | null>,\n): WeightedCentroid | null {\n    let totalWeight = 0;\n    let weightedX = 0;\n    let weightedY = 0;\n    let weightedZ = 0;\n\n    for (const centroid of centroids) {\n        if (!centroid || centroid.weight === 0) continue;\n        totalWeight += centroid.weight;\n        weightedX += centroid.centroid[0] * centroid.weight;\n        weightedY += centroid.centroid[1] * centroid.weight;\n        weightedZ += centroid.centroid[2] * centroid.weight;\n    }\n\n    if (totalWeight === 0) return null;\n\n    return {\n        centroid: [weightedX / totalWeight, weightedY / totalWeight, weightedZ / totalWeight],\n        weight: totalWeight,\n    };\n}\n\n/**\n * Computes connected components (clusters) of intersecting geometries and returns\n * a mapping from feature id to cluster id. The input array must contain an\n * application-level identifier for each geometry. Cluster ids are stable only\n * within a single invocation and start at 0.\n *\n * @param items - Geometries with application-level identifiers to cluster.\n * @returns Map from stringified feature id to cluster id (0-based).\n * @example\n * const clusters = computeIntersectingClusterIds(features);\n * // clusters → Map { 'building-1' → 0, 'building-2' → 0, 'building-3' → 1 }\n */\nexport function computeIntersectingClusterIds(\n    items: Array<{ id: number | string; geometry: Geometry | null | undefined }>,\n): Map<string, number> {\n    const validItems = items.map((it, idx) => ({ ...it, __idx: idx })).filter((it) => it.geometry != null) as Array<{\n        id: number | string;\n        geometry: Geometry;\n        __idx: number;\n    }>;\n\n    const n = validItems.length;\n    if (n === 0) return new Map();\n\n    // Union-find structure\n    const parent = new Array(n).fill(0).map((_, i) => i);\n    const find = (i: number): number => (parent[i] === i ? i : (parent[i] = find(parent[i])));\n    const union = (a: number, b: number) => {\n        const ra = find(a);\n        const rb = find(b);\n        if (ra !== rb) parent[rb] = ra;\n    };\n\n    // Build R-tree of bboxes\n    interface RTreeItem {\n        minX: number;\n        minY: number;\n        maxX: number;\n        maxY: number;\n        idx: number;\n    }\n    const rtree = new RBush<RTreeItem>();\n    const itemsForTree: RTreeItem[] = new Array(n);\n    for (let i = 0; i < n; i++) {\n        const [minX, minY, maxX, maxY] = turfBbox(validItems[i].geometry as any);\n        itemsForTree[i] = { minX, minY, maxX, maxY, idx: i };\n    }\n    rtree.load(itemsForTree);\n\n    // Intersections among nearby candidates\n    for (let i = 0; i < n; i++) {\n        const aItem = itemsForTree[i];\n        const candidates = rtree.search(aItem);\n        for (const cand of candidates) {\n            const j = cand.idx;\n            if (j <= i) continue;\n            try {\n                if (booleanIntersects(validItems[i].geometry as any, validItems[j].geometry as any)) {\n                    union(i, j);\n                }\n            } catch {\n                // ignore invalid geometries\n            }\n        }\n    }\n\n    // Assign compact cluster ids\n    const rootToClusterId = new Map<number, number>();\n    let nextClusterId = 0;\n    const result = new Map<string, number>();\n    for (let i = 0; i < n; i++) {\n        const root = find(i);\n        if (!rootToClusterId.has(root)) rootToClusterId.set(root, nextClusterId++);\n        const clusterId = rootToClusterId.get(root)!;\n        const appId = String(validItems[i].id);\n        result.set(appId, clusterId);\n    }\n\n    return result;\n}\n","/**\n * @module LayerUtils\n * Shared helpers for the toolkit's layer taxonomy.\n *\n * This module centralizes the canonical `LayerType` guard and the GeoJSON\n * geometry classification used by layer-loading code. It keeps layer identity\n * checks and geometry-to-layer inference consistent across packages that share\n * the same taxonomy.\n */\nimport type { Geometry } from 'geojson';\n\nimport type { LayerType } from './types-layer';\n\n/**\n * Type guard checking whether a string is a supported shared layer type.\n *\n * @param value Candidate layer identifier to validate.\n * @returns `true` when `value` is a recognized `LayerType`, narrowing the type.\n * @throws Never throws.\n * @example\n * if (isLayerType(userInput)) {\n *   // userInput is now typed as LayerType\n * }\n */\nexport function isLayerType(value: string): value is LayerType {\n    return value === 'surface'\n        || value === 'water'\n        || value === 'parks'\n        || value === 'roads'\n        || value === 'buildings'\n        || value === 'points'\n        || value === 'polygons'\n        || value === 'polylines'\n        || value === 'raster';\n}\n\n/**\n * Maps a GeoJSON geometry type to the corresponding shared layer family.\n *\n * @param geometryType GeoJSON geometry type to classify.\n * @returns One of `points`, `polylines`, or `polygons`.\n * @throws Never throws.\n * @example\n * mapGeometryTypeToLayerType('Polygon');  // 'polygons'\n * mapGeometryTypeToLayerType('Point');    // 'points'\n */\nexport function mapGeometryTypeToLayerType(\n    geometryType: Geometry['type'],\n): Extract<LayerType, 'points' | 'polygons' | 'polylines'> {\n    switch (geometryType) {\n        case 'Point':\n        case 'MultiPoint':\n            return 'points';\n        case 'LineString':\n        case 'MultiLineString':\n            return 'polylines';\n        case 'Polygon':\n        case 'MultiPolygon':\n        case 'GeometryCollection':\n            return 'polygons';\n    }\n}\n","/**\n * @module KeyEvents\n * Keyboard interaction controller for map-level shortcuts.\n *\n * This module defines the `KeyEvents` class, which binds canvas-scoped keyboard\n * listeners for an `AutkMap` instance and translates supported shortcuts into\n * map-side updates. It currently manages style-cycling behavior and triggers\n * layer render-info invalidation so visual changes are applied on the next\n * render pass.\n */\n\nimport { AutkMap } from './map';\n\n/**\n * Keyboard interaction controller for map shortcuts.\n *\n * `KeyEvents` owns the lifecycle of canvas-scoped keyboard listeners associated\n * with a map instance. Supported shortcuts update shared map presentation state\n * and may mark existing layers dirty so dependent GPU-side render\n * configuration is rebuilt.\n */\nexport class KeyEvents {\n    /** Owning map instance. */\n    private _map!: AutkMap;\n    /** Bound keyup handler reference used for safe add/remove listener calls. */\n    private _onKeyUp: (event: KeyboardEvent) => void;\n\n    /**\n     * Creates a keyboard interaction controller for a map instance.\n     *\n     * @param map Map instance whose state is updated by supported keyboard shortcuts.\n     */\n    constructor(map: AutkMap) {\n        this._map = map;\n        this._onKeyUp = this.keyUp.bind(this);\n    }\n\n    /**\n     * Registers keyboard listeners handled by this controller.\n     *\n     * Listener registration is idempotent for this instance: any previously\n     * registered `keyup` handler is removed before the current bound handler is\n     * added again. The canvas is made focusable when needed and listeners are\n     * attached directly to it.\n     *\n     * @returns Nothing. The controller starts receiving keyboard events while the canvas is focused.\n     */\n    bindEvents(): void {\n        const canvas = this._map.canvas;\n        if (canvas.tabIndex < 0) {\n            canvas.tabIndex = 0;\n        }\n        canvas.style.outline = 'none';\n\n        canvas.removeEventListener('keyup', this._onKeyUp, false);\n        canvas.addEventListener('keyup', this._onKeyUp, false);\n    }\n\n    /**\n     * Removes keyboard listeners registered by this controller.\n     *\n     * This detaches the controller's bound `keyup` listener from the canvas. It\n     * is safe to call even when listeners are not currently registered.\n     *\n     * @returns Nothing. Keyboard shortcuts handled by this controller are disabled.\n     */\n    destroyEvents(): void {\n        this._map.canvas.removeEventListener('keyup', this._onKeyUp, false);\n    }\n\n    /**\n     * Handles keyboard shortcuts on key release.\n     *\n     * Currently supported shortcuts:\n     * - `s`: cycles to the next predefined map style in the owning map style,\n     *   wrapping to the first style after the last.\n     *   After the style is changed, every existing layer is marked render-info\n     *   dirty so style-dependent rendering state is refreshed.\n     *\n     * All other keys are ignored.\n     *\n     * @param event Keyboard event fired on key release.\n     * @returns Nothing. Supported shortcuts update shared style state and layer invalidation flags.\n     */\n    keyUp(event: KeyboardEvent) {\n        if (event.key.toLowerCase() === 's') {\n            const styles: string[] = this._map.style.availableStyles;\n            const current = this._map.style.currentStyle;\n\n            const id = (styles.indexOf(current) + 1) % styles.length;\n            this._map.style.setPredefinedStyle(styles[id]);\n        }\n\n        if (event.key.toLowerCase() === 'b') {\n            this._map.toggleTerrainOverlayBoundsDebug();\n        }\n\n        if (event.key.toLowerCase() === 'r') {\n            this._map.resetCamera();\n        }\n    }\n}\n","/**\n * @module AutkMapEvents\n * Typed event definitions for `@urban-toolkit/autk-map` interaction and picking signals.\n *\n * This module defines the event names, payload shapes, and event-bus record\n * used by the map's public interaction API. It covers pointer-driven picking\n * notifications and the mouse state values used by event controllers to track\n * drag lifecycle.\n */\n\n/**\n * Event names emitted by the map interaction bus.\n */\nexport enum MapEvent {\n  /** Selection payload emitted when features are picked from a layer. */\n  PICKING = 'picking',\n}\n\n/**\n * Mouse interaction states tracked by map event handlers.\n */\nexport enum MouseStatus {\n  /** Pointer input is idle and not dragging the map. */\n  IDLE = 'mouseIdle',\n  /** Pointer input is actively dragging the map. */\n  DRAG = 'mouseDrag',\n}\n\nimport type { SelectionData } from '@urban-toolkit/autk-core';\n\n/**\n * Payload emitted for feature-picking events.\n *\n * The payload extends the shared selection data shape with the identifier of\n * the layer that produced the hit results.\n */\nexport interface MapEventData extends SelectionData {\n    /** Identifier of the layer that emitted the event. */\n    layerId: string;\n}\n\n/**\n * Typed event-bus payload map for `MapEvent` listeners.\n */\nexport type MapEventRecord = Record<MapEvent, MapEventData>;\n","/**\n * @module MouseEvents\n * Pointer and mouse interaction controller for the map canvas.\n *\n * This module defines the `MouseEvents` class, which translates DOM pointer,\n * wheel, and double-click input into camera navigation and picking behavior\n * for an `AutkMap` instance. It coordinates drag state, pointer-position\n * tracking, and event binding so map interactions continue to work even when\n * listeners are attached at the document level.\n */\n\nimport { MouseStatus } from './types-events';\nimport { AutkMap } from './map';\n\n/**\n * Handles pointer interactions for the map canvas.\n *\n * This controller binds DOM pointer, wheel, and double-click events to the\n * map camera and active picking layer. It is responsible for panning,\n * orbit-style rotation, scroll-wheel zooming, and forwarding double-click\n * positions to the currently pick-enabled layer.\n *\n * All drag-related listeners (`pointerdown`, `pointermove`, `pointerup`) are\n * registered on the document in capture phase during `bindEvents()`, before\n * any third-party script (e.g. Playwright's recorder) can be injected. This\n * guarantees our handlers fire first regardless of overlay elements or\n * injected capture listeners added later.\n */\nexport class MouseEvents {\n    /** Reference to the owning map instance. */\n    private _map!: AutkMap;\n    /** Last recorded pointer position in canvas-local CSS pixels. */\n    private _lastPoint: number[];\n    /** Current pointer interaction state. */\n    private _status: MouseStatus;\n    /** Active touch pointers keyed by pointer id, stored in canvas-local CSS pixels. */\n    private _activePointers: Map<number, number[]> = new Map();\n    /** Previous two-finger gesture center in canvas-local CSS pixels. */\n    private _lastGestureCenter: number[] | null = null;\n    /** Previous two-finger distance in canvas-local CSS pixels. */\n    private _lastGestureDistance: number | null = null;\n\n    /** Bound wheel handler reference used for safe add/remove listener calls. */\n    private _onWheel: (e: WheelEvent) => void;\n    /** Bound pointerdown handler reference used for safe add/remove listener calls. */\n    private _onPointerDown: (e: PointerEvent) => void;\n    /** Bound pointerup handler reference used for safe add/remove listener calls. */\n    private _onPointerUp: (e: PointerEvent) => void;\n    /** Bound pointercancel handler reference used for safe add/remove listener calls. */\n    private _onPointerCancel: (e: PointerEvent) => void;\n    /** Bound contextmenu handler reference used for safe add/remove listener calls. */\n    private _onContextMenu: (e: PointerEvent) => void;\n    /** Bound pointermove handler reference used for safe add/remove listener calls. */\n    private _onPointerMove: (e: PointerEvent) => void;\n    /** Bound double-click handler reference used for safe add/remove listener calls. */\n    private _onDblClick: (e: MouseEvent) => void;\n    /** Previous inline touch-action value restored during teardown. */\n    private _previousTouchAction: string = '';\n    /** Previous inline iOS touch callout value restored during teardown. */\n    private _previousWebkitTouchCallout: string = '';\n\n    /**\n     * Creates a mouse and pointer interaction controller for a map instance.\n     *\n     * @param map Map instance whose camera navigation and picking behavior are controlled by pointer input.\n     */\n    constructor(map: AutkMap) {\n        this._map = map;\n        this._lastPoint = [0, 0];\n        this._status = MouseStatus.IDLE;\n\n        this._onWheel = this.mouseWheel.bind(this);\n        this._onPointerDown = this.pointerDown.bind(this);\n        this._onPointerUp = this.pointerUp.bind(this);\n        this._onPointerCancel = this.pointerUp.bind(this);\n        this._onContextMenu = this.contextMenu.bind(this);\n        this._onPointerMove = this.pointerMove.bind(this);\n        this._onDblClick = this.mouseDoubleClick.bind(this);\n    }\n\n    /**\n     * Attaches all pointer listeners.\n     *\n     * Drag listeners are registered on the document in capture phase so they\n     * are added before Playwright's recorder (or any other injected script)\n     * and therefore fire first in the event propagation chain.\n     *\n     * Canvas-scoped listeners handle wheel, context-menu suppression, and\n     * double-click picking. Document-scoped listeners allow an active drag to\n     * continue receiving move and release events even when the pointer leaves\n     * the canvas bounds.\n     *\n     * @returns Attaches the bound event handlers to the canvas and document.\n     */\n    bindEvents(): void {\n        const canvas = this._map.renderer.canvas;\n        const canvasStyle = canvas.style;\n\n        this._previousTouchAction = canvasStyle.touchAction;\n        this._previousWebkitTouchCallout = canvasStyle.getPropertyValue('-webkit-touch-callout');\n\n        canvasStyle.touchAction = 'none';\n        canvasStyle.setProperty('-webkit-touch-callout', 'none');\n\n        canvas.addEventListener('wheel', this._onWheel, { passive: false });\n        canvas.addEventListener('contextmenu', this._onContextMenu as any, false);\n        canvas.addEventListener('dblclick', this._onDblClick, false);\n        document.addEventListener('pointerdown', this._onPointerDown, { capture: true });\n        document.addEventListener('pointermove', this._onPointerMove, { capture: true });\n        document.addEventListener('pointerup',   this._onPointerUp,   { capture: true });\n        document.addEventListener('pointercancel', this._onPointerCancel, { capture: true });\n    }\n\n    /**\n     * Removes all pointer listeners.\n     *\n     * This should be called during map teardown to prevent further pointer\n     * handling and to release the listener references registered by\n     * `bindEvents()`.\n     *\n     * @returns Detaches the registered event handlers from the canvas and document.\n     */\n    destroyEvents(): void {\n        const canvas = this._map.renderer.canvas;\n        const canvasStyle = canvas.style;\n\n        canvasStyle.touchAction = this._previousTouchAction;\n        canvasStyle.setProperty('-webkit-touch-callout', this._previousWebkitTouchCallout);\n\n        canvas.removeEventListener('wheel', this._onWheel);\n        canvas.removeEventListener('contextmenu', this._onContextMenu as any);\n        canvas.removeEventListener('dblclick', this._onDblClick);\n        document.removeEventListener('pointerdown', this._onPointerDown, { capture: true });\n        document.removeEventListener('pointermove', this._onPointerMove, { capture: true });\n        document.removeEventListener('pointerup',   this._onPointerUp,   { capture: true });\n        document.removeEventListener('pointercancel', this._onPointerCancel, { capture: true });\n    }\n\n    /**\n     * Suppresses the browser context menu over the map canvas.\n     *\n     * @param event Pointer event raised for the context-menu gesture.\n     * @returns Prevents the browser context menu from opening and stops further propagation.\n     */\n    contextMenu(event: PointerEvent): void {\n        event.preventDefault();\n        event.stopPropagation();\n    }\n\n    /**\n     * Starts a drag when the pointer goes down over the canvas.\n     *\n     * The canvas bounds check is necessary because this listener fires for\n     * all document `pointerdown` events. Clicking the canvas also gives it\n     * keyboard focus so canvas-scoped shortcuts become active. Only\n     * primary-button and middle-button presses over the map canvas begin a drag\n     * interaction.\n     *\n     * @param event Pointer event raised on press.\n     * @returns Records the drag start position and switches the interaction state to drag when the event targets the canvas.\n     */\n    pointerDown(event: PointerEvent): void {\n        const canvas = this._map.renderer.canvas;\n        if (event.target !== canvas) return;\n\n        this._map.canvas.focus({ preventScroll: true });\n\n        if (event.button === 0 || event.button === 1) {\n            event.preventDefault();\n            event.stopPropagation();\n\n            const point = this._getPoint(event);\n            this._lastPoint = point;\n            this._status = MouseStatus.DRAG;\n\n            if (event.pointerType === 'touch') {\n                this._activePointers.set(event.pointerId, point);\n                canvas.setPointerCapture?.(event.pointerId);\n                if (this._activePointers.size >= 2) {\n                    this._updateGestureState();\n                }\n            }\n        }\n    }\n\n    /**\n     * Applies camera pan or orbit while dragging.\n     *\n     * If pointerdown was deferred (e.g. by Playwright's recorder), we detect\n     * drag start here by checking `event.buttons` while in the idle state.\n     * During a drag, `Shift` + primary button rotates the camera by updating\n     * yaw and pitch; all other supported drags translate the camera.\n     *\n     * Movement deltas are normalized by the renderer's CSS width and height\n     * before being passed to the camera.\n     *\n     * @param event Pointer event raised on move.\n     * @returns Updates the camera and the stored pointer position while an active drag is in progress.\n     */\n    pointerMove(event: PointerEvent): void {\n        if (event.pointerType === 'touch' && this._activePointers.has(event.pointerId)) {\n            this._activePointers.set(event.pointerId, this._getPoint(event));\n            if (this._activePointers.size >= 2) {\n                this._handleMultiTouchMove(event);\n                return;\n            }\n        }\n\n        if (this._status === MouseStatus.IDLE && (event.buttons === 1 || event.buttons === 4)\n                && event.target === this._map.renderer.canvas) {\n            this._lastPoint = this._getPoint(event);\n            this._status = MouseStatus.DRAG;\n        }\n\n        if (this._status !== MouseStatus.DRAG) return;\n\n        const cssWidth = this._map.renderer.cssWidth;\n        const cssHeight = this._map.renderer.cssHeight;\n        event.preventDefault();\n        event.stopPropagation();\n\n        const point = this._getPoint(event);\n        const dx = -point[0] + this._lastPoint[0];\n        const dy =  point[1] - this._lastPoint[1];\n\n        if ((event.buttons & 1) === 1 && event.shiftKey) {\n            this._map.camera.yaw(dx / cssWidth);\n            this._map.camera.pitch(dy / cssHeight);\n        } else {\n            this._map.camera.translate(dx / cssWidth, dy / cssHeight);\n        }\n\n        this._lastPoint = point;\n        if (event.pointerType === 'touch') {\n            this._activePointers.set(event.pointerId, point);\n        }\n    }\n\n    /**\n     * Ends the current drag interaction.\n     *\n     * Calls received while the controller is not in drag mode are ignored.\n     *\n     * @param event Pointer event raised on release.\n     * @returns Resets the interaction state to idle and suppresses the handled release event.\n     */\n    pointerUp(event: PointerEvent): void {\n        const canvas = this._map.renderer.canvas;\n        const wasTouchPointer = this._activePointers.delete(event.pointerId);\n        if (canvas.hasPointerCapture?.(event.pointerId)) {\n            canvas.releasePointerCapture(event.pointerId);\n        }\n\n        if (wasTouchPointer) {\n            if (this._activePointers.size >= 2) {\n                this._updateGestureState();\n            } else if (this._activePointers.size === 1) {\n                this._lastPoint = Array.from(this._activePointers.values())[0];\n                this._clearGestureState();\n                this._status = MouseStatus.DRAG;\n            } else {\n                this._clearGestureState();\n                this._status = MouseStatus.IDLE;\n            }\n\n            event.preventDefault();\n            event.stopPropagation();\n            return;\n        }\n\n        if (this._status !== MouseStatus.DRAG) return;\n\n        event.preventDefault();\n        event.stopPropagation();\n        this._status = MouseStatus.IDLE;\n    }\n\n    /**\n     * Applies scroll-wheel zoom centered on the pointer position.\n     *\n     * The wheel position is converted into normalized canvas coordinates so\n     * zooming can be anchored to the current pointer location.\n     *\n     * @param event Wheel event raised over the canvas.\n     * @returns Updates the camera zoom and suppresses the browser's default scroll handling.\n     */\n    mouseWheel(event: WheelEvent) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const rect = this._map.renderer.canvas.getBoundingClientRect();\n        const x = (event.clientX - rect.left) / this._map.renderer.cssWidth;\n        const y = 1.0 - (event.clientY - rect.top) / this._map.renderer.cssHeight;\n\n        this._map.camera.zoom(event.deltaY * 0.01, x, y);\n    }\n\n    /**\n     * Triggers picking on double click for the currently active pick-enabled layer.\n     *\n     * If no active picking layer is available, or the active layer is not\n     * currently configured for picking, the event is ignored after its default\n     * browser behavior is suppressed.\n     *\n     * @param event Mouse event raised on double click.\n     * @returns Stores the canvas-relative click position on the active picking layer when picking is enabled,\n     * and requests the frame whose picking pass resolves it.\n     */\n    mouseDoubleClick(event: MouseEvent) {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const rect = this._map.renderer.canvas.getBoundingClientRect();\n\n        const mouseX = event.clientX - rect.left;\n        const mouseY = event.clientY - rect.top;\n\n        const activePickingLayer = this._map.activePickingLayer;\n        if (activePickingLayer?.layerRenderInfo.isPick) {\n            activePickingLayer.layerRenderInfo.pickedComps = [mouseX, mouseY];\n            this._map.requestRender();\n        }\n    }\n\n    /**\n     * Applies pinch zoom and two-finger orbit/tilt from active touch pointers.\n     *\n     * Distance changes drive zoom around the gesture midpoint. When the\n     * distance is stable, midpoint movement maps to the same yaw/pitch path as\n     * desktop Shift-drag.\n     *\n     * @param event Pointer move event for one of the active touch pointers.\n     * @returns Updates the camera and cached two-finger gesture state.\n     */\n    private _handleMultiTouchMove(event: PointerEvent): void {\n        event.preventDefault();\n        event.stopPropagation();\n\n        const gesture = this._getGesture();\n        if (!gesture) return;\n\n        const { center, distance } = gesture;\n        const cssWidth = this._map.renderer.cssWidth;\n        const cssHeight = this._map.renderer.cssHeight;\n\n        if (this._lastGestureCenter && this._lastGestureDistance !== null) {\n            const distanceDelta = distance - this._lastGestureDistance;\n            const centerDx = -center[0] + this._lastGestureCenter[0];\n            const centerDy = center[1] - this._lastGestureCenter[1];\n\n            if (Math.abs(distanceDelta) > 1) {\n                this._map.camera.zoom(-distanceDelta * 0.01, center[0] / cssWidth, 1.0 - center[1] / cssHeight);\n            } else {\n                this._map.camera.yaw(centerDx / cssWidth);\n                this._map.camera.pitch(centerDy / cssHeight);\n            }\n        }\n\n        this._lastGestureCenter = center;\n        this._lastGestureDistance = distance;\n    }\n\n    /**\n     * Initializes cached center and distance for the current two-finger gesture.\n     */\n    private _updateGestureState(): void {\n        const gesture = this._getGesture();\n        this._lastGestureCenter = gesture?.center ?? null;\n        this._lastGestureDistance = gesture?.distance ?? null;\n    }\n\n    /**\n     * Clears cached two-finger gesture state.\n     */\n    private _clearGestureState(): void {\n        this._lastGestureCenter = null;\n        this._lastGestureDistance = null;\n    }\n\n    /**\n     * Computes the midpoint and distance for the first two active touch pointers.\n     */\n    private _getGesture(): { center: number[], distance: number } | null {\n        const points = Array.from(this._activePointers.values());\n        if (points.length < 2) return null;\n\n        const [a, b] = points;\n        const dx = b[0] - a[0];\n        const dy = b[1] - a[1];\n\n        return {\n            center: [(a[0] + b[0]) * 0.5, (a[1] + b[1]) * 0.5],\n            distance: Math.hypot(dx, dy),\n        };\n    }\n\n    /**\n     * Computes pointer coordinates in canvas-local CSS pixels.\n     *\n     * The returned coordinates are measured from the top-left corner of the\n     * renderer canvas using the canvas's current client bounding box.\n     *\n     * @param event Pointer or mouse event containing viewport coordinates.\n     * @returns Two-element array `[x, y]` relative to the canvas bounds in CSS pixels.\n     */\n    private _getPoint(event: PointerEvent | MouseEvent): number[] {\n        const canvas = this._map.renderer.canvas;\n        const rect = canvas.getBoundingClientRect();\n        return [\n            event.clientX - rect.left,\n            event.clientY - rect.top,\n        ];\n    }\n}\n","/**\n * @module ResizeEvents\n * Window resize controller for a map instance.\n *\n * This module defines the `ResizeEvents` class, which keeps the map viewport in\n * sync with the canvas layout size. It updates the camera and renderer using the\n * canvas's current CSS dimensions and the active device pixel ratio, then notifies\n * the map UI so overlay layout can react to the new viewport size.\n */\n\nimport { AutkMap } from './map';\n\n/**\n * Window resize controller for the map viewport.\n *\n * `ResizeEvents` binds a single window-level resize listener and forwards each\n * event to the module's resize function. The resize routine reads the canvas's\n * current layout size, updates the camera and renderer to match, and then asks\n * the map UI to recompute any size-dependent layout.\n */\nexport class ResizeEvents {\n    /** Reference to the owning map instance. */\n    private _map: AutkMap;\n\n    /** Bound resize handler stored for add/remove listener symmetry. */\n    private _onResize: () => void;\n\n    /**\n     * Creates a resize interaction controller for a map instance.\n     *\n     * @param map Target map instance.\n     */\n    constructor(map: AutkMap) {\n        this._map = map;\n        this._onResize = this.resize.bind(this);\n    }\n\n    /**\n     * Attaches the resize listener to the window.\n     *\n     * Repeated calls register the same bound handler again because the method does\n     * not guard against duplicate bindings.\n     *\n     * @returns Nothing. Future window resize events are forwarded to {@link ResizeEvents.resize}.\n     */\n    bindEvents(): void {\n        window.addEventListener('resize', this._onResize);\n    }\n\n    /**\n     * Removes the resize listener from the window.\n     *\n     * This only removes the handler previously registered by\n     * {@link ResizeEvents.bindEvents}.\n     *\n     * @returns Nothing. The bound window resize listener is detached.\n     */\n    destroyEvents(): void {\n        window.removeEventListener('resize', this._onResize);\n    }\n\n    /**\n     * Synchronizes the map viewport with the canvas's current layout size.\n     *\n     * The method reads the canvas element's `offsetWidth` and `offsetHeight`,\n     * uses `window.devicePixelRatio` with a fallback of `1`, then propagates the\n     * updated dimensions to the camera, renderer, and UI. It does not modify the\n     * canvas size directly in this class; resizing is delegated to the renderer.\n     *\n     * @returns Nothing. The camera, renderer, and UI are updated for the current viewport size.\n     */\n    resize(): void {\n        const canvas = this._map.canvas;\n        const width = canvas.offsetWidth;\n        const height = canvas.offsetHeight;\n        const devicePixelRatio = window.devicePixelRatio || 1;\n\n        this._map.camera.resize(width, height);\n        this._map.renderer.resize(width, height, devicePixelRatio);\n        this._map.ui.handleResize();\n    }\n}\n","/**\n * @module Renderer\n * WebGPU renderer and render-target manager for `@urban-toolkit/autk-map`.\n *\n * This module provides the `Renderer` class, which configures the canvas\n * context, allocates the main and picking render targets, manages command\n * encoder lifetime, and handles size-dependent GPU resources. It also\n * supports picking readback buffers and CSS-to-pixel coordinate conversion for\n * input-driven readback operations.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport { MapStyle } from './map-style';\n\n/**\n * WebGPU renderer responsible for canvas setup, render-target management, and\n * frame-level GPU resource lifecycle.\n *\n * `Renderer` owns the WebGPU canvas context, allocates the multisampled main\n * pass targets and the offscreen picking targets, and exposes helpers for\n * starting render passes, submitting command buffers, and rebuilding\n * size-dependent resources after resize events.\n */\nexport class Renderer {\n    private static readonly PICK_READBACK_BYTES_PER_ROW = 256;\n    private static readonly PICK_READBACK_BUFFER_COUNT = 2;\n    private static _sharedDevicePromise: Promise<GPUDevice | null> | null = null;\n    /** HTML canvas used as the backing render surface. */\n    protected _canvas: HTMLCanvasElement;\n\n    /** Logical WebGPU device used for all allocations. */\n    protected _device!: GPUDevice;\n\n    /** Lazily configured WebGPU canvas context. */\n    protected _context!: GPUCanvasContext | null;\n\n    /** Multisampled color texture used by the main pass before resolve. */\n    protected _multisampleTexture!: GPUTexture;\n    /** Main render-pass color attachment descriptor. */\n    protected _frameBuffer!: GPURenderPassColorAttachment;\n\n    /** Depth texture used by the main render pass. */\n    protected _depthTexture!: GPUTexture;\n    /** Main render-pass depth attachment descriptor. */\n    protected _depthBuffer!: GPURenderPassDepthStencilAttachment;\n\n    /** Offscreen color attachment used by the picking pass. */\n    protected _pickingBuffer!: GPURenderPassColorAttachment;\n    /** Offscreen color texture used for picking readback. */\n    protected _pickingTexture!: GPUTexture;\n    /** Depth attachment used by the picking pass. */\n    protected _pickingDepthBuffer!: GPURenderPassDepthStencilAttachment;\n    /** Depth texture used by the picking pass. */\n    protected _pickingDepthTexture!: GPUTexture;\n\n    /** Active command encoder for the current frame. */\n    protected _commandEncoder: GPUCommandEncoder | null = null;\n\n    /** Double-buffered readback pool for picking copies. */\n    private _pickReadbackBuffers: Array<{ buffer: GPUBuffer | null; size: number; busy: boolean }> = Array.from(\n        { length: Renderer.PICK_READBACK_BUFFER_COUNT },\n        () => ({ buffer: null, size: 0, busy: false })\n    );\n\n    /** MSAA sample count for the main render pass. */\n    protected _sampleCount: number = 4;\n    /** Sample count for the picking pass. */\n    protected _pickingSampleCount: number = 1;\n    /** Preferred canvas format returned by WebGPU. */\n    protected _canvasFormat!: GPUTextureFormat;\n    /** Indicates whether WebGPU resources have been initialized. */\n    protected _isInitialized: boolean = false;\n    /** Canvas layout width in CSS pixels. */\n    protected _cssWidth: number = 1;\n    /** Canvas layout height in CSS pixels. */\n    protected _cssHeight: number = 1;\n    /** Canvas backing-store width in device pixels. */\n    protected _pixelWidth: number = 1;\n    /** Canvas backing-store height in device pixels. */\n    protected _pixelHeight: number = 1;\n    /** Device pixel ratio used to derive backing-store size. */\n    protected _devicePixelRatio: number = 1;\n    /** Color texture containing 2D layer output projected onto terrain. */\n    private _overlayTexture?: GPUTexture;\n    /** Multisampled color texture resolved into `_overlayTexture`. */\n    private _overlayMultisampleTexture?: GPUTexture;\n    /** Depth texture used while rendering terrain overlay layers. */\n    private _overlayDepthTexture?: GPUTexture;\n    /** Picking id texture containing overlay-layer picking output. */\n    private _overlayPickingTexture?: GPUTexture;\n    /** Depth texture used while rendering overlay picking ids. */\n    private _overlayPickingDepthTexture?: GPUTexture;\n    /** View for the resolved terrain overlay color texture. */\n    private _overlayTextureView?: GPUTextureView;\n    /** View for the multisampled terrain overlay color texture. */\n    private _overlayMultisampleTextureView?: GPUTextureView;\n    /** View for the terrain overlay depth texture. */\n    private _overlayDepthTextureView?: GPUTextureView;\n    /** View for the terrain overlay picking texture. */\n    private _overlayPickingTextureView?: GPUTextureView;\n    /** View for the terrain overlay picking depth texture. */\n    private _overlayPickingDepthTextureView?: GPUTextureView;\n    /** Current terrain overlay texture width in pixels. */\n    private _overlayWidth = 0;\n    /** Current terrain overlay texture height in pixels. */\n    private _overlayHeight = 0;\n    /** Depth texture used to composite 3D layers against terrain. */\n    private _terrainDepthTexture?: GPUTexture;\n    /** View for the terrain composite depth texture. */\n    private _terrainDepthTextureView?: GPUTextureView;\n    /** Current terrain depth texture width in pixels. */\n    private _terrainDepthWidth = 0;\n    /** Current terrain depth texture height in pixels. */\n    private _terrainDepthHeight = 0;\n\n    /**\n     * Creates a renderer bound to a canvas.\n     *\n     * @param canvas Target HTML canvas.\n     * @throws Never throws.\n     */\n    constructor(canvas: HTMLCanvasElement, private readonly _style: MapStyle) {\n        this._canvas = canvas;\n        this._syncCanvasMetrics(canvas.offsetWidth || canvas.width, canvas.offsetHeight || canvas.height, window.devicePixelRatio || 1);\n    }\n\n    /** Map style used by renderer-owned passes and pipelines. */\n    get style(): MapStyle {\n        return this._style;\n    }\n\n    /** Underlying render canvas. */\n    get canvas(): HTMLCanvasElement {\n        return this._canvas;\n    }\n\n    /** Canvas layout width in CSS pixels. */\n    get cssWidth(): number {\n        return this._cssWidth;\n    }\n\n    /** Canvas layout height in CSS pixels. */\n    get cssHeight(): number {\n        return this._cssHeight;\n    }\n\n    /** Canvas backing-store width in device pixels. */\n    get pixelWidth(): number {\n        return this._pixelWidth;\n    }\n\n    /** Canvas backing-store height in device pixels. */\n    get pixelHeight(): number {\n        return this._pixelHeight;\n    }\n\n    /** Terrain overlay texture width in pixels. */\n    get overlayWidth(): number {\n        return this._overlayWidth;\n    }\n\n    /** Terrain overlay texture height in pixels. */\n    get overlayHeight(): number {\n        return this._overlayHeight;\n    }\n\n    /** Terrain depth texture view used by terrain-aware building compositing. */\n    get terrainDepthTextureView(): GPUTextureView {\n        if (!this._terrainDepthTextureView) {\n            throw new Error('Terrain depth texture has not been configured.');\n        }\n        return this._terrainDepthTextureView;\n    }\n\n    /** Device pixel ratio currently applied to the render surface. */\n    get devicePixelRatio(): number {\n        return this._devicePixelRatio;\n    }\n\n    /** Preferred canvas format negotiated with WebGPU. */\n    get canvasFormat(): GPUTextureFormat {\n        return this._canvasFormat;\n    }\n\n    /** Active WebGPU canvas context, if configured. */\n    get context(): GPUCanvasContext | null {\n        return this._context;\n    }\n\n    /** Logical GPU device. */\n    get device(): GPUDevice {\n        return this._device;\n    }\n\n    /** Main color attachment used by the primary render pass. */\n    get frameBuffer(): GPURenderPassColorAttachment {\n        return this._frameBuffer;\n    }\n\n    /** Depth attachment used by the primary render pass. */\n    get depthBuffer(): GPURenderPassDepthStencilAttachment {\n        return this._depthBuffer;\n    }\n\n    /** Active command encoder for the current frame. */\n    get commandEncoder(): GPUCommandEncoder {\n        if (!this._commandEncoder) {\n            throw new Error('Renderer command encoder requested outside an active frame.');\n        }\n        return this._commandEncoder;\n    }\n\n    /** MSAA sample count used for the main pass. */\n    get sampleCount(): number {\n        return this._sampleCount;\n    }\n\n    /** Picking color texture used for object-id readback. */\n    get pickingTexture(): GPUTexture {\n        return this._pickingTexture;\n    }\n\n    /** Picking color attachment descriptor. */\n    get pickingBuffer(): GPURenderPassColorAttachment {\n        return this._pickingBuffer;\n    }\n\n    /** Picking depth attachment descriptor. */\n    get pickingDepthBuffer(): GPURenderPassDepthStencilAttachment {\n        return this._pickingDepthBuffer;\n    }\n\n    /** Main depth texture view used by render paths that need direct sampling. */\n    get depthTextureView(): GPUTextureView {\n        return this._depthBuffer.view as GPUTextureView;\n    }\n\n    /** Terrain overlay color texture view sampled by the terrain renderer. */\n    get overlayTextureView(): GPUTextureView {\n        if (!this._overlayTextureView) {\n            throw new Error('Overlay texture has not been configured.');\n        }\n        return this._overlayTextureView;\n    }\n\n    /** Terrain overlay picking texture view sampled by terrain picking. */\n    get overlayPickingTextureView(): GPUTextureView {\n        if (!this._overlayPickingTextureView) {\n            throw new Error('Overlay picking texture has not been configured.');\n        }\n        return this._overlayPickingTextureView;\n    }\n\n    /**\n     * Initializes WebGPU and creates all core render targets.\n     *\n     * @throws Never throws. Failures log to console and leave the renderer uninitialized.\n     */\n    async init(): Promise<void> {\n        const api = await this.initWebGPU();\n\n        if (api) {\n            this.configureContext();\n            this.configureFrameBuffer();\n            this.configureDepthBuffer();\n            this.configurePickingBuffer();\n            this._isInitialized = true;\n        } else {\n            this._isInitialized = false;\n            console.error('Renderer initialization failed: WebGPU is not available.');\n        }\n    }\n\n    /**\n     * Initializes the WebGPU device and preferred canvas format.\n     *\n     * @returns `true` when adapter and device acquisition succeed; otherwise `false`.\n     * @throws Never throws. Errors are caught and return `false`.\n     */\n    async initWebGPU(): Promise<boolean> {\n        try {\n            const entry: GPU = navigator.gpu;\n            if (!entry) {\n                return false;\n            }\n\n            this._canvasFormat = entry.getPreferredCanvasFormat();\n\n            if (!Renderer._sharedDevicePromise) {\n                Renderer._sharedDevicePromise = (async () => {\n                    const adapter = await entry.requestAdapter();\n                    if (adapter === null) return null;\n                    return adapter.requestDevice();\n                })();\n            }\n\n            const device = await Renderer._sharedDevicePromise;\n            if (device === null) {\n                Renderer._sharedDevicePromise = null;\n                return false;\n            }\n\n            this._device = device;\n        } catch (e) {\n            console.error(e);\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * Resizes the canvas and recreates size-dependent render targets.\n     *\n     * @param cssWidth New layout width in CSS pixels.\n     * @param cssHeight New layout height in CSS pixels.\n     * @param devicePixelRatio Backing-store scale factor.\n     * @throws Never throws.\n     */\n    resize(cssWidth: number, cssHeight: number, devicePixelRatio: number = window.devicePixelRatio || 1): void {\n        this._syncCanvasMetrics(cssWidth, cssHeight, devicePixelRatio);\n\n        if (!this._isInitialized) {\n            return;\n        }\n\n        this.configureContext();\n        this.configureFrameBuffer();\n        this.configureDepthBuffer();\n        this.configurePickingBuffer();\n    }\n\n    /**\n     * Configures the WebGPU canvas context.\n     *\n     * The context is created lazily and then configured with the negotiated\n     * canvas format and render-attachment usage.\n     */\n    configureContext(): void {\n        if (!this._device) {\n            return;\n        }\n\n        if (!this._context) {\n            this._context = this._canvas.getContext('webgpu');\n        }\n\n        if (this._context) {\n            const canvasConfig: GPUCanvasConfiguration = {\n                device: this._device,\n                format: this._canvasFormat,\n                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC | GPUTextureUsage.TEXTURE_BINDING,\n                alphaMode: 'premultiplied',\n            };\n            this._context.configure(canvasConfig);\n        }\n    }\n\n    /**\n     * Creates or recreates color and depth attachments for picking.\n     *\n     * The picking pass renders into an offscreen texture sized to the current\n     * backing store so object ids can be read back at pixel precision.\n     */\n    configurePickingBuffer(): void {\n        if (!this._device) {\n            return;\n        }\n\n        this._pickingTexture?.destroy();\n        this._pickingDepthTexture?.destroy();\n\n        const desc: GPUTextureDescriptor = {\n            size: [this._pixelWidth, this._pixelHeight],\n            format: 'rgba8unorm',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC | GPUTextureUsage.TEXTURE_BINDING,\n            sampleCount: this._pickingSampleCount,\n        };\n\n        this._pickingTexture = this._device.createTexture(desc);\n        const pickingTextureView = this._pickingTexture.createView();\n\n        this._pickingBuffer = {\n            view: pickingTextureView,\n            clearValue: { r: 0, g: 0, b: 0, a: 1 },\n            loadOp: 'clear',\n            storeOp: 'store',\n        };\n\n        const depthDesc: GPUTextureDescriptor = {\n            size: [this._pixelWidth, this._pixelHeight],\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n            sampleCount: this._pickingSampleCount,\n        };\n        this._pickingDepthTexture = this._device.createTexture(depthDesc);\n        const pickingDepthTextureView = this._pickingDepthTexture.createView();\n\n        this._pickingDepthBuffer = {\n            view: pickingDepthTextureView,\n            depthClearValue: 0.0,\n            depthLoadOp: 'clear',\n            depthStoreOp: 'store',\n        };\n    }\n\n    /**\n     * Creates or recreates the main color attachment and multisample texture.\n     *\n     * The attachment resolves into the current swap-chain texture and uses the\n     * configured background color as its clear value.\n     */\n    configureFrameBuffer(): void {\n        if (!this._device) {\n            return;\n        }\n\n        if (!this._context) {\n            console.error('GPU canvas context is null.');\n            return;\n        }\n\n        let colorTextureView: GPUTextureView;\n        try {\n            colorTextureView = this._context.getCurrentTexture().createView();\n        } catch {\n            return;\n        }\n\n        this._multisampleTexture?.destroy();\n\n        const multiSampleDesc: GPUTextureDescriptor = {\n            size: [this._pixelWidth, this._pixelHeight],\n            sampleCount: this._sampleCount,\n            format: this._canvasFormat,\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n        };\n\n        this._multisampleTexture = this._device.createTexture(multiSampleDesc);\n        const multiSampleTextureView = this._multisampleTexture.createView();\n\n        const sky = this._style.getColor('background');\n        this._frameBuffer = {\n            view: multiSampleTextureView,\n            resolveTarget: colorTextureView,\n            clearValue: { r: sky.r / 255, g: sky.g / 255, b: sky.b / 255, a: 1 },\n            loadOp: 'clear',\n            storeOp: 'store',\n        };\n    }\n\n    /**\n     * Creates or recreates the main depth attachment.\n     *\n     * The depth texture matches the current backing-store size and is used by\n     * the primary render pass.\n     */\n    configureDepthBuffer(): void {\n        if (!this._device) {\n            return;\n        }\n\n        this._depthTexture?.destroy();\n\n        const depthTextureDesc: GPUTextureDescriptor = {\n            size: [this._pixelWidth, this._pixelHeight, 1],\n            sampleCount: this._sampleCount,\n            dimension: '2d',\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC | GPUTextureUsage.TEXTURE_BINDING,\n        };\n\n        this._depthTexture = this._device.createTexture(depthTextureDesc);\n        const depthTextureView = this._depthTexture.createView();\n\n        this._depthBuffer = {\n            view: depthTextureView,\n            depthClearValue: 0.0,\n            depthLoadOp: 'clear',\n            depthStoreOp: 'store',\n        };\n    }\n\n    /**\n     * Starts the main render pass by clearing configured attachments.\n     *\n     * @throws Never throws. Silently returns when not initialized or when the\n     * canvas context has been transiently unconfigured (e.g. by a sibling\n     * renderer's destroy/recreate cycle in a multi-instance setup).\n     */\n    start(): void {\n        if (!this._isInitialized) {\n            return;\n        }\n\n        if (!this._context) {\n            console.error('GPU canvas context is null.');\n            return;\n        }\n\n        let currentTextureView: GPUTextureView;\n        try {\n            currentTextureView = this._context.getCurrentTexture().createView();\n        } catch {\n            return;\n        }\n\n        // Configure the frame buffer\n        this._frameBuffer.loadOp = 'clear';\n        this._frameBuffer.resolveTarget = currentTextureView;\n        const sky = this._style.getColor('background');\n        this._frameBuffer.clearValue = { r: sky.r / 255, g: sky.g / 255, b: sky.b / 255, a: 1 };\n\n        this._beginFrame();\n    }\n\n    /**\n     * Opens the shared main render pass for the current frame.\n     *\n     * @returns An encoder for the primary pass.\n     * @throws If the renderer has not been initialized or GPU context is null.\n     */\n    beginMainRenderPass(): GPURenderPassEncoder {\n        if (!this._isInitialized) {\n            throw new Error('Renderer main pass requested before initialization.');\n        }\n\n        if (!this._context) {\n            throw new Error('GPU canvas context is null.');\n        }\n\n        this._frameBuffer.loadOp = 'clear';\n        this._frameBuffer.resolveTarget = this._context.getCurrentTexture().createView();\n        this._depthBuffer.depthLoadOp = 'clear';\n\n        const renderPassDesc: GPURenderPassDescriptor = {\n            colorAttachments: [this._frameBuffer],\n            depthStencilAttachment: this._depthBuffer,\n        };\n\n        return this.commandEncoder.beginRenderPass(renderPassDesc);\n    }\n\n    /**\n     * Begins a main color-only render pass.\n     *\n     * @param loadOp Load operation for the main color attachment.\n     * @returns Render pass encoder targeting the current canvas color attachment.\n     * @throws If the renderer has not been initialized.\n     * @example\n     * const pass = renderer.beginMainColorRenderPass('load');\n     */\n    beginMainColorRenderPass(loadOp: GPULoadOp = 'load'): GPURenderPassEncoder {\n        if (!this._isInitialized || !this._context) {\n            throw new Error('Renderer color pass requested before initialization.');\n        }\n\n        this._frameBuffer.loadOp = loadOp;\n        this._frameBuffer.resolveTarget = this._context.getCurrentTexture().createView();\n\n        return this.commandEncoder.beginRenderPass({\n            colorAttachments: [this._frameBuffer],\n        });\n    }\n\n    /**\n     * Creates or resizes the terrain composite depth texture.\n     *\n     * @param width Requested texture width in pixels.\n     * @param height Requested texture height in pixels.\n     * @returns `true` when the texture was recreated, otherwise `false`.\n     * @throws If GPU texture creation fails.\n     * @example\n     * renderer.configureTerrainDepthTexture(width, height);\n     */\n    configureTerrainDepthTexture(width: number, height: number): boolean {\n        if (!this._device || (this._terrainDepthTexture && width === this._terrainDepthWidth && height === this._terrainDepthHeight)) {\n            return false;\n        }\n\n        this._terrainDepthTexture?.destroy();\n        this._terrainDepthWidth = width;\n        this._terrainDepthHeight = height;\n        this._terrainDepthTexture = this._device.createTexture({\n            label: 'Terrain composite depth texture',\n            size: [width, height],\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n        });\n        this._terrainDepthTextureView = this._terrainDepthTexture.createView();\n        return true;\n    }\n\n    /**\n     * Begins a depth-only pass for terrain compositing.\n     *\n     * @returns Render pass encoder writing to the terrain depth texture.\n     * @throws If the terrain depth texture has not been configured.\n     * @example\n     * const pass = renderer.beginTerrainDepthRenderPass();\n     */\n    beginTerrainDepthRenderPass(): GPURenderPassEncoder {\n        if (!this._terrainDepthTextureView) {\n            throw new Error('Renderer terrain depth pass requested before terrain depth texture configuration.');\n        }\n\n        return this.commandEncoder.beginRenderPass({\n            label: 'Terrain composite depth pass',\n            colorAttachments: [],\n            depthStencilAttachment: {\n                view: this._terrainDepthTextureView,\n                depthClearValue: 0,\n                depthLoadOp: 'clear',\n                depthStoreOp: 'store',\n            },\n        });\n    }\n\n    /**\n     * Creates or resizes terrain overlay color, depth, and picking textures.\n     *\n     * @param width Requested overlay texture width in pixels.\n     * @param height Requested overlay texture height in pixels.\n     * @returns `true` when overlay textures were recreated, otherwise `false`.\n     * @throws If GPU texture creation fails.\n     * @example\n     * renderer.configureOverlayTexture(4096, 4096);\n     */\n    configureOverlayTexture(width: number, height: number): boolean {\n        if (!this._device || (this._overlayTexture && width === this._overlayWidth && height === this._overlayHeight)) {\n            return false;\n        }\n\n        this._overlayTexture?.destroy();\n        this._overlayMultisampleTexture?.destroy();\n        this._overlayDepthTexture?.destroy();\n        this._overlayPickingTexture?.destroy();\n        this._overlayPickingDepthTexture?.destroy();\n        this._overlayWidth = width;\n        this._overlayHeight = height;\n\n        this._overlayTexture = this._device.createTexture({\n            label: 'Terrain overlay texture',\n            size: [width, height],\n            format: this._canvasFormat,\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n        });\n        this._overlayMultisampleTexture = this._device.createTexture({\n            label: 'Terrain overlay MSAA texture',\n            size: [width, height],\n            sampleCount: this._sampleCount,\n            format: this._canvasFormat,\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n        });\n        this._overlayDepthTexture = this._device.createTexture({\n            label: 'Terrain overlay depth texture',\n            size: [width, height],\n            sampleCount: this._sampleCount,\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n        });\n        this._overlayPickingTexture = this._device.createTexture({\n            label: 'Terrain overlay picking texture',\n            size: [width, height],\n            format: 'rgba8unorm',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n        });\n        this._overlayPickingDepthTexture = this._device.createTexture({\n            label: 'Terrain overlay picking depth texture',\n            size: [width, height],\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n        });\n        this._overlayTextureView = this._overlayTexture.createView();\n        this._overlayMultisampleTextureView = this._overlayMultisampleTexture.createView();\n        this._overlayDepthTextureView = this._overlayDepthTexture.createView();\n        this._overlayPickingTextureView = this._overlayPickingTexture.createView();\n        this._overlayPickingDepthTextureView = this._overlayPickingDepthTexture.createView();\n        return true;\n    }\n\n    /**\n     * Begins the terrain overlay color render pass.\n     *\n     * @returns Render pass encoder targeting the overlay color and depth textures.\n     * @throws If overlay textures have not been configured.\n     * @example\n     * const pass = renderer.beginOverlayRenderPass();\n     */\n    beginOverlayRenderPass(): GPURenderPassEncoder {\n        if (!this._overlayTextureView || !this._overlayMultisampleTextureView || !this._overlayDepthTextureView) {\n            throw new Error('Renderer overlay pass requested before overlay texture configuration.');\n        }\n\n        return this.commandEncoder.beginRenderPass({\n            label: 'Terrain overlay render pass',\n            colorAttachments: [\n                {\n                    view: this._overlayMultisampleTextureView,\n                    resolveTarget: this._overlayTextureView,\n                    clearValue: { r: 0, g: 0, b: 0, a: 0 },\n                    loadOp: 'clear',\n                    storeOp: 'store',\n                },\n            ],\n            depthStencilAttachment: {\n                view: this._overlayDepthTextureView,\n                depthClearValue: 0,\n                depthLoadOp: 'clear',\n                depthStoreOp: 'store',\n            },\n        });\n    }\n\n    /**\n     * Begins the terrain overlay picking render pass.\n     *\n     * @returns Render pass encoder targeting overlay picking and depth textures.\n     * @throws If overlay picking textures have not been configured.\n     * @example\n     * const pass = renderer.beginOverlayPickingRenderPass();\n     */\n    beginOverlayPickingRenderPass(): GPURenderPassEncoder {\n        if (!this._overlayPickingTextureView || !this._overlayPickingDepthTextureView) {\n            throw new Error('Renderer overlay picking pass requested before overlay texture configuration.');\n        }\n\n        return this.commandEncoder.beginRenderPass({\n            label: 'Terrain overlay picking render pass',\n            colorAttachments: [\n                {\n                    view: this._overlayPickingTextureView,\n                    clearValue: { r: 0, g: 0, b: 0, a: 1 },\n                    loadOp: 'clear',\n                    storeOp: 'store',\n                },\n            ],\n            depthStencilAttachment: {\n                view: this._overlayPickingDepthTextureView,\n                depthClearValue: 0,\n                depthLoadOp: 'clear',\n                depthStoreOp: 'store',\n            },\n        });\n    }\n\n    /**\n     * Submits the current command buffer and clears the active encoder.\n     *\n     * @throws Never throws. Silently returns when not initialized or no encoder exists.\n     */\n    finish(): void {\n        if (!this._isInitialized || !this._commandEncoder) {\n            return;\n        }\n        this._device.queue.submit([this._commandEncoder.finish()]);\n        this._commandEncoder = null;\n    }\n\n    /**\n     * Starts the picking render pass by clearing picking attachments.\n     *\n     * @throws Never throws. Silently returns when not initialized.\n     */\n    startPickingRenderPass(): void {\n        if (!this._isInitialized) {\n            return;\n        }\n\n        this._pickingBuffer.loadOp = 'clear';\n        this._pickingDepthBuffer.depthLoadOp = 'clear';\n\n        const renderPassDesc: GPURenderPassDescriptor = {\n            colorAttachments: [this._pickingBuffer],\n            depthStencilAttachment: this._pickingDepthBuffer,\n        };\n\n        this._beginFrame();\n        this._beginEmptyRenderPass(renderPassDesc);\n    }\n\n    /**\n     * Begins a picking render pass and returns its encoder.\n     *\n     * @param depthLoadOp Load operation for the picking depth attachment.\n     * @returns Render pass encoder targeting the main picking attachments.\n     * @throws If the renderer has not been initialized.\n     * @example\n     * const pass = renderer.beginPickingRenderPass('clear');\n     */\n    beginPickingRenderPass(depthLoadOp: GPULoadOp = 'clear'): GPURenderPassEncoder {\n        if (!this._isInitialized) {\n            throw new Error('Renderer picking pass requested before initialization.');\n        }\n\n        this._pickingBuffer.loadOp = 'clear';\n        this._pickingDepthBuffer.depthLoadOp = depthLoadOp;\n\n        return this.commandEncoder.beginRenderPass({\n            colorAttachments: [this._pickingBuffer],\n            depthStencilAttachment: this._pickingDepthBuffer,\n        });\n    }\n\n    /**\n     * Begins a depth-only pass using the picking depth attachment.\n     *\n     * @returns Render pass encoder writing only picking depth.\n     * @throws If the renderer has not been initialized.\n     * @example\n     * const pass = renderer.beginPickingDepthRenderPass();\n     */\n    beginPickingDepthRenderPass(): GPURenderPassEncoder {\n        if (!this._isInitialized) {\n            throw new Error('Renderer picking depth pass requested before initialization.');\n        }\n\n        return this.commandEncoder.beginRenderPass({\n            label: 'Picking depth render pass',\n            colorAttachments: [],\n            depthStencilAttachment: {\n                view: this._pickingDepthBuffer.view,\n                depthClearValue: 0,\n                depthLoadOp: 'clear',\n                depthStoreOp: 'store',\n            },\n        });\n    }\n\n    /**\n     * Reserves a double-buffered picking readback slot for the current frame.\n     *\n     * @param pickCount Number of single-pixel readbacks to accommodate.\n     * @returns The reserved slot index, or `null` when no slot is available.\n     * @throws Never throws.\n     */\n    reservePickingReadbackSlot(pickCount: number): number | null {\n        if (!this._isInitialized || pickCount <= 0) {\n            return null;\n        }\n\n        const bufferSize = Renderer.PICK_READBACK_BYTES_PER_ROW * pickCount;\n        for (let index = 0; index < this._pickReadbackBuffers.length; index++) {\n            const slot = this._pickReadbackBuffers[index];\n            if (slot.busy) {\n                continue;\n            }\n\n            if (!slot.buffer || slot.size < bufferSize) {\n                slot.buffer?.destroy();\n                slot.buffer = this._device.createBuffer({\n                    label: `Picking readback buffer ${index}`,\n                    size: bufferSize,\n                    usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,\n                });\n                slot.size = bufferSize;\n            }\n\n            slot.busy = true;\n            return index;\n        }\n\n        return null;\n    }\n\n    /**\n     * Queues a single-pixel picking texture readback into a reserved slot.\n     *\n     * @param slotIndex Reserved readback slot index.\n     * @param pickIndex Offset within the slot for this pick.\n     * @param x CSS-relative x coordinate.\n     * @param y CSS-relative y coordinate.\n     * @throws If the requested slot is not reserved.\n     */\n    enqueuePickingReadback(slotIndex: number, pickIndex: number, x: number, y: number): void {\n        const slot = this._pickReadbackBuffers[slotIndex];\n        if (!slot?.buffer) {\n            throw new Error(`Picking readback slot ${slotIndex} is not reserved.`);\n        }\n\n        const [px, py] = this.toPixelCoordinates(x, y);\n\n        this.commandEncoder.copyTextureToBuffer(\n            {\n                texture: this._pickingTexture,\n                origin: { x: px, y: py },\n            },\n            {\n                buffer: slot.buffer,\n                offset: pickIndex * Renderer.PICK_READBACK_BYTES_PER_ROW,\n                bytesPerRow: Renderer.PICK_READBACK_BYTES_PER_ROW,\n            },\n            { width: 1, height: 1, depthOrArrayLayers: 1 }\n        );\n    }\n\n    /**\n     * Maps a reserved readback slot and decodes all picked ids.\n     *\n     * @param slotIndex Reserved readback slot index.\n     * @param pickCount Number of copied pick records to decode.\n     * @returns Decoded object ids in copy order, or an empty array when unavailable.\n     * @throws If the buffer map operation times out or the device is lost.\n     */\n    async readPickingResults(slotIndex: number, pickCount: number): Promise<number[]> {\n        const slot = this._pickReadbackBuffers[slotIndex];\n        if (!slot?.buffer) {\n            return [];\n        }\n\n        try {\n            await slot.buffer.mapAsync(GPUMapMode.READ);\n            const arrayBuffer = slot.buffer.getMappedRange();\n            const data = new Uint8Array(arrayBuffer);\n            const ids: number[] = [];\n            for (let index = 0; index < pickCount; index++) {\n                const offset = index * Renderer.PICK_READBACK_BYTES_PER_ROW;\n                ids.push(this._decodeColorToId(data[offset], data[offset + 1], data[offset + 2]));\n            }\n            return ids;\n        } finally {\n            if (slot.buffer.mapState === 'mapped') {\n                slot.buffer.unmap();\n            }\n            slot.busy = false;\n        }\n    }\n\n    /**\n     * Releases GPU resources, unconfigures the canvas, and resets renderer state.\n     *\n     * @throws Never throws.\n     */\n    destroy(): void {\n        // Mark uninitialized first so that any tick that races with destroy()\n        // (e.g. an in-flight animation frame from a sibling renderer that\n        // shares the canvas's GPUCanvasContext) sees `_isInitialized === false`\n        // and bails out of `start()` / `beginMainRenderPass()` before touching\n        // the resources we are about to release below.\n        this._isInitialized = false;\n\n        this._multisampleTexture?.destroy();\n        this._depthTexture?.destroy();\n        this._pickingTexture?.destroy();\n        this._pickingDepthTexture?.destroy();\n        this._overlayTexture?.destroy();\n        this._overlayMultisampleTexture?.destroy();\n        this._overlayDepthTexture?.destroy();\n        this._overlayPickingTexture?.destroy();\n        this._overlayPickingDepthTexture?.destroy();\n        this._terrainDepthTexture?.destroy();\n        this._pickReadbackBuffers.forEach((slot) => slot.buffer?.destroy());\n        this._context?.unconfigure();\n\n        this._commandEncoder = null;\n    }\n\n    /** Ensures a command encoder exists for the current frame. */\n    private _beginFrame(): void {\n        if (!this._commandEncoder) {\n            this._commandEncoder = this._device.createCommandEncoder();\n        }\n    }\n\n    /**\n     * Opens and immediately closes an empty render pass to clear attachments.\n     *\n     * The pass is started on the shared command encoder so attachment clear\n     * operations are encoded without issuing draw calls.\n     *\n     * @param renderPassDesc Render pass descriptor to execute.\n     */\n    private _beginEmptyRenderPass(renderPassDesc: GPURenderPassDescriptor): void {\n        const passEncoder = this.commandEncoder.beginRenderPass(renderPassDesc);\n        passEncoder.end();\n    }\n\n    /** Decodes an RGB picking color into the original object id. */\n    private _decodeColorToId(r: number, g: number, b: number): number {\n        const id = (r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16);\n        return id - 1;\n    }\n\n    /**\n     * Converts CSS-relative coordinates into clamped backing-store pixel coordinates.\n     *\n     * @param x CSS-relative x coordinate.\n     * @param y CSS-relative y coordinate.\n     * @returns Clamped pixel coordinates `[px, py]`.\n     * @throws Never throws.\n     */\n    toPixelCoordinates(x: number, y: number): [number, number] {\n        const scaleX = this._cssWidth > 0 ? this._pixelWidth / this._cssWidth : 1;\n        const scaleY = this._cssHeight > 0 ? this._pixelHeight / this._cssHeight : 1;\n        const px = Math.max(0, Math.min(this._pixelWidth - 1, Math.floor(x * scaleX)));\n        const py = Math.max(0, Math.min(this._pixelHeight - 1, Math.floor(y * scaleY)));\n        return [px, py];\n    }\n\n    /**\n     * Synchronizes CSS and backing-store metrics before any GPU reallocation\n     * work.\n     *\n     * The canvas element is resized to the computed backing-store dimensions so\n     * subsequent render-target allocation uses the updated size.\n     */\n    private _syncCanvasMetrics(cssWidth: number, cssHeight: number, devicePixelRatio: number): void {\n        this._cssWidth = Math.max(1, Math.floor(cssWidth));\n        this._cssHeight = Math.max(1, Math.floor(cssHeight));\n        this._devicePixelRatio = Number.isFinite(devicePixelRatio) && devicePixelRatio > 0 ? devicePixelRatio : 1;\n        this._pixelWidth = Math.max(1, Math.floor(this._cssWidth * this._devicePixelRatio));\n        this._pixelHeight = Math.max(1, Math.floor(this._cssHeight * this._devicePixelRatio));\n\n        this._canvas.width = this._pixelWidth;\n        this._canvas.height = this._pixelHeight;\n    }\n}\n","/**\n * @module Layer\n * Base abstractions for map-layer lifecycle and rendering.\n *\n * This module defines the abstract `Layer` class used by the map renderer to\n * manage heterogeneous layer implementations through a common interface. It\n * centralizes shared layer metadata, mutable render-state tracking, dirty-flag\n * handling, and the lifecycle hooks subclasses implement for pipeline creation,\n * rendering, picking, highlighting, and cleanup.\n */\n\nimport { Camera } from '@urban-toolkit/autk-core';\nimport { LayerInfo, LayerRenderInfo, DEFAULT_POINT_SIZE, DEFAULT_LINE_WIDTH } from './types-layers';\nimport { Renderer } from './renderer';\n\n/**\n * Base class for map layers.\n *\n * `Layer` provides the shared metadata and lifecycle surface used by the layer\n * manager and renderer to work with different layer implementations in a\n * uniform way.\n *\n * Subclasses are responsible for creating GPU resources, executing render\n * passes, and optionally supporting picking and highlighting. The base class\n * also tracks whether layer data or render-state changes require GPU-side\n * synchronization before the next draw.\n */\nexport abstract class Layer {\n    /** Static layer identity and ordering metadata. */\n    protected _layerInfo: LayerInfo;\n    /** Mutable rendering state used by pipeline uniforms and interaction flags. */\n    protected _layerRenderInfo: LayerRenderInfo;\n    /** Indicates that render-state uniforms must be refreshed on the GPU. */\n    protected _renderInfoIsDirty = false;\n    /** Indicates that geometry/data buffers must be refreshed on the GPU. */\n    protected _dataIsDirty = false;\n    /** Callback run whenever the layer marks its data or render state dirty. */\n    private _onChange: (() => void) | null = null;\n\n    /**\n     * Creates a base layer instance.\n     *\n     * @param layerInfo Layer identity and z-order metadata.\n     * @param layerRenderInfo Initial render configuration.\n     * @throws Never throws.\n     */\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo) {\n        this._layerInfo = layerInfo;\n        this._layerRenderInfo = { ...layerRenderInfo };\n        delete this._layerRenderInfo.pointSize;\n        delete this._layerRenderInfo.polylinesWidth;\n        if (layerInfo.typeLayer === 'points') { this._layerRenderInfo.pointSize = DEFAULT_POINT_SIZE; }\n        if (layerInfo.typeLayer === 'polylines') { this._layerRenderInfo.polylinesWidth = DEFAULT_LINE_WIDTH; }\n        this.updateLayerRenderInfo(layerRenderInfo);\n    }\n\n    /**\n     * Indicates whether this layer supports picking interactions.\n     *\n     * Subclasses override this when they implement a picking pass and expose\n     * stable component ids that can be resolved back to features.\n     *\n     * @returns `true` when picking is supported for this layer.\n     */\n    get supportsPicking(): boolean { return false; }\n\n    /**\n     * Indicates whether this layer supports feature highlighting.\n     *\n     * Highlight support is used together with picking and explicit highlight\n     * updates to control per-feature emphasis during rendering.\n     *\n     * @returns `true` when highlight state can be updated for this layer.\n     */\n    get supportsHighlight(): boolean { return false; }\n\n    /**\n     * Layer identity and ordering metadata.\n     *\n     * @returns The current layer metadata object.\n     */\n    get layerInfo(): LayerInfo { return this._layerInfo; }\n\n    /**\n     * Current render configuration and interaction flags.\n     *\n     * @returns The current mutable render-state object for this layer.\n     */\n    get layerRenderInfo(): LayerRenderInfo { return this._layerRenderInfo; }\n\n    /**\n     * Updates layer metadata and marks geometry-dependent resources dirty.\n     *\n     * @param info Partial metadata patch to merge into `layerInfo`.\n     * @returns Marks layer data as stale for the next render cycle.\n     * @throws Never throws.\n     */\n    updateLayerInfo(info: Partial<LayerInfo>): void {\n        this._layerInfo = { ...this._layerInfo, ...info };\n        this.makeLayerDataDirty();\n    }\n\n    /**\n     * Updates render metadata and marks render uniforms dirty.\n     *\n     * @param info Partial render-state patch to merge into `layerRenderInfo`.\n     * @returns Marks render-state uniforms as stale for the next render cycle.\n     * @throws Never throws.\n     */\n    updateLayerRenderInfo(info: Partial<LayerRenderInfo>): void {\n        const canPick = this.supportsPicking && this.supportsHighlight;\n        const nextInfo: Partial<LayerRenderInfo> = { ...info };\n\n        for (const key of ['pointSize', 'polylinesWidth'] as const) {\n            if (!(key in nextInfo)) { continue; }\n            const value = nextInfo[key];\n            if (typeof value !== 'number' || !Number.isFinite(Math.fround(value)) || Math.fround(value) <= 0) {\n                console.warn(`Layer '${this._layerInfo.id}': ${key} must be a finite positive float32 number.`);\n                delete nextInfo[key];\n            }\n        }\n\n        // Keep picking state coherent with layer capabilities.\n        if ('isPick' in nextInfo && nextInfo.isPick === true && !canPick) {\n            nextInfo.isPick = false;\n            nextInfo.pickedComps = undefined;\n        }\n\n        this._layerRenderInfo = { ...this._layerRenderInfo, ...nextInfo };\n        this.makeLayerRenderInfoDirty();\n    }\n\n    /**\n     * Registers the callback run whenever this layer marks itself dirty.\n     *\n     * `AutkMap` uses it to schedule a frame in on-demand mode. Pass `null` to\n     * remove the callback.\n     *\n     * @param listener Callback run after each dirty mark, or `null`.\n     * @returns Nothing.\n     * @throws Never throws.\n     */\n    setChangeListener(listener: (() => void) | null): void { this._onChange = listener; }\n\n    /**\n     * Marks layer data buffers as stale for the next render pass.\n     *\n     * @returns Causes subclasses to refresh geometry-dependent GPU resources.\n     * @throws Never throws.\n     */\n    makeLayerDataDirty(): void {\n        this._dataIsDirty = true;\n        this._onChange?.();\n    }\n\n    /**\n     * Marks render uniforms and render-state as stale for the next render pass.\n     *\n     * @returns Causes subclasses to refresh GPU-side render-state.\n     * @throws Never throws.\n     */\n    makeLayerRenderInfoDirty(): void {\n        this._renderInfoIsDirty = true;\n        this._onChange?.();\n    }\n\n    /**\n     * Initializes GPU resources and pipeline objects for this layer.\n     *\n     * This is called once the renderer is available and should allocate any\n     * pipeline state, buffers, bind groups, or other GPU resources required by\n     * the concrete layer implementation.\n     *\n     * @param renderer Active renderer instance.\n     * @returns Initializes the layer so it can participate in subsequent render\n     * passes.\n     */\n    abstract createPipeline(renderer: Renderer): void;\n\n    /**\n     * Executes the regular render pass for this layer.\n     *\n     * Implementations should encode draw commands for the main shared render\n     * pass using the current camera state and any synchronized layer resources.\n     *\n     * @param camera Active camera used to compute view/projection transforms.\n     * @param passEncoder Render-pass encoder for the active main pass.\n     * @returns Encodes this layer's draw commands into the provided render pass.\n     */\n    abstract renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void;\n\n    /**\n     * Runs any offscreen or prepass work required before the shared main pass.\n     *\n     * Subclasses can override this to perform preparation steps that must occur\n     * before `renderPass`, such as updating intermediate render targets or other\n     * camera-dependent precomputations.\n     *\n     * @param _camera Active camera used to compute view/projection transforms.\n     * @returns Performs any layer-specific pre-render work. The base\n     * implementation does nothing.\n     */\n    prepareRender(_camera: Camera): void {}\n\n    /**\n     * Executes the picking render pass.\n     *\n     * Layers that support picking can override this to render feature or\n     * component ids into an offscreen target for hit-testing. The base\n     * implementation is a no-op.\n     *\n     * @param _camera Active camera used to compute view/projection transforms.\n     * @returns Renders picking data when supported. Otherwise does nothing.\n     */\n    renderPickingPass(_camera: Camera, _passEncoder?: GPURenderPassEncoder): void {}\n\n    /**\n     * Clears all highlighted features.\n     *\n     * Layers that support highlighting should override this to remove any\n     * current highlight selection. The base implementation is a no-op.\n     *\n     * @returns Clears highlight state when supported. Otherwise does nothing.\n     */\n    clearHighlightedIds(): void {}\n\n    /**\n     * Replaces the highlighted feature selection.\n     *\n     * Layers that support highlighting should interpret the provided component\n     * ids according to their own feature-to-component mapping. The base\n     * implementation is a no-op.\n     *\n     * @param _ids Component ids to highlight.\n     * @returns Updates highlight state when supported. Otherwise does nothing.\n     */\n    setHighlightedIds(_ids: number[]): void {}\n\n    /**\n     * Applies a skip mask to the provided component ids.\n     *\n     * Layers can override this to suppress rendering for selected components.\n     * The base implementation is a no-op.\n     *\n     * @param _ids Component ids to skip during rendering.\n     * @returns Updates the layer's skip mask when supported. Otherwise does\n     * nothing.\n     */\n    setSkippedIds(_ids: number[]): void {}\n\n    /**\n     * Clears the skip mask.\n     *\n     * Layers that implement skipped-component handling should override this to\n     * restore normal rendering for all components. The base implementation is a\n     * no-op.\n     *\n     * @returns Clears skipped-component state when supported. Otherwise does\n     * nothing.\n     */\n    clearSkippedIds(): void {}\n\n    /**\n     * Releases resources owned by this layer.\n     *\n     * @returns Releases any layer-owned resources. The base implementation does nothing.\n     * @throws Never throws.\n     */\n    destroy(): void {}\n}\n","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4<f32>,\\n    @location(0) outTexCoord: vec2<f32>,\\n };\\n\\n@vertex\\nfn main(@location(0) inPosition: vec2f, @location(1) inTexCoord: vec2f) -> VSOut {\\n    var vsOut: VSOut;\\n\\n    vsOut.outPosition = projection * modelView * vec4f(inPosition.x, inPosition.y, zIndex, 1);\\n    vsOut.outTexCoord = inTexCoord;\\n\\n    return vsOut;\\n}\";","export default \"@group(0) @binding(6) var<uniform> opacity : f32;\\n\\n@group(2) @binding(0) var rasterData : texture_2d<f32>;\\n@group(2) @binding(1) var rasterSampler : sampler;\\n\\n@fragment \\nfn main(@location(0) inTexCoord: vec2f) -> @location(0) vec4f {\\n    var color = textureSample(rasterData, rasterSampler, inTexCoord);\\n\\n    let alpha = color.a * opacity;\\n    return vec4f(color.rgb * alpha, alpha);\\n}\";","/// <reference types=\"@webgpu/types\" />\n\n/**\n * @module Pipeline\n * Shared WebGPU pipeline base for layer rendering.\n *\n * This module defines the abstract `Pipeline` base class used by layer-specific\n * renderers. It owns the common camera and render-info GPU resources, creates\n * bind groups for shared shader inputs, and provides cache helpers that\n * subclasses reuse while building and updating their own draw pipelines.\n */\n\nimport { Layer } from './layer';\n\nimport { \n    Camera, \n    ColorMap, \n    DEFAULT_COLORMAP_RESOLUTION \n} from '@urban-toolkit/autk-core';\nimport type { ColorRGB } from '@urban-toolkit/autk-core';\n\nimport { Renderer } from './renderer';\n\nconst COLORMAP_HEIGHT = 1;\n\n/**\n * Base class for layer rendering pipelines.\n *\n * `Pipeline` coordinates the shared WebGPU resources used by map layers,\n * including camera uniforms, render-state uniforms, and their bind groups.\n * Subclasses use it to initialize common GPU state, update per-frame and\n * per-layer uniforms, and implement the layer-specific build, vertex upload,\n * and draw-pass hooks.\n */\nexport abstract class Pipeline {\n    /** WebGPU renderer used to allocate and update GPU resources. */\n    protected _renderer: Renderer;\n\n    /** Model-view matrix uniform buffer. */\n    protected _mviewBuffer!: GPUBuffer;\n\n    /** Projection matrix uniform buffer. */\n    protected _projectionBuffer!: GPUBuffer;\n    /** Layer z-index uniform buffer. */\n    protected _zIndexBuffer!: GPUBuffer;\n\n    /** Camera bind group shared by vertex shaders. */\n    protected _cameraBindGroup!: GPUBindGroup;\n\n    /** Camera bind group layout. */\n    protected _cameraBindGroupLayout!: GPUBindGroupLayout;\n\n    /** Fixed color uniform buffer. */\n    protected _colorBuffer!: GPUBuffer;\n\n    /** Highlight color uniform buffer. */\n    protected _highlightColorBuffer!: GPUBuffer;\n    /** Invalid thematic value color uniform buffer. */\n    protected _invalidValueColorBuffer!: GPUBuffer;\n\n    /** Colormap texture. */\n    protected _cMapTexture!: GPUTexture;\n\n    /** Flag uniform that enables thematic color mapping. */\n    protected _useColorMap!: GPUBuffer;\n\n    /** Flag uniform that enables highlight rendering. */\n    protected _useHighlight!: GPUBuffer;\n\n    /** Opacity uniform buffer. */\n    protected _opacity!: GPUBuffer;\n\n    /** Colormap domain parameters: [min, max, useNormalization, _pad]. */\n    protected _domainBuffer!: GPUBuffer;\n\n    /** Render-state bind group shared by fragment shaders. */\n    protected _renderInfoBindGroup!: GPUBindGroup;\n\n    /** Render-state bind group layout. */\n    protected _renderInfoBindGroupLayout!: GPUBindGroupLayout;\n\n    /** Cached matrix uniform data to avoid per-frame allocations. */\n    private _mviewData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(16 * Float32Array.BYTES_PER_ELEMENT));\n    /** Cached projection matrix data to avoid per-frame allocations. */\n    private _projectionData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(16 * Float32Array.BYTES_PER_ELEMENT));\n    /** Cached z-index uniform payload. */\n    private _zIndexData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT));\n    /** Cached fixed-color uniform payload (rgba). */\n    private _colorData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4 * Float32Array.BYTES_PER_ELEMENT));\n    /** Cached highlight-color uniform payload (rgba). */\n    private _highlightColorData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4 * Float32Array.BYTES_PER_ELEMENT));\n    /** Cached invalid-value-color uniform payload (rgba). */\n    private _invalidValueColorData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4 * Float32Array.BYTES_PER_ELEMENT));\n    /** Cached use-colormap flag uniform payload. */\n    private _useColorMapData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT));\n    /** Cached use-highlight flag uniform payload. */\n    private _useHighlightData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT));\n    /** Cached opacity uniform payload. */\n    private _opacityData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(Float32Array.BYTES_PER_ELEMENT));\n    /** Cached domain uniform payload. */\n    private _domainData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4 * Float32Array.BYTES_PER_ELEMENT));\n\n    /**\n     * Creates a pipeline bound to the shared renderer.\n     *\n     * @param renderer Renderer used to create and update GPU resources.\n     * @throws Never throws.\n     */\n    constructor(renderer: Renderer) {\n        this._renderer = renderer;\n    }\n\n    /**\n     * Creates the shared camera uniform resources and bind group.\n     *\n     * @throws If GPU buffer allocation fails.\n     */\n    createCameraUniformBindGroup(): void {\n        this._mviewBuffer = this._renderer.device.createBuffer({\n            label: 'ModelView matrix buffer',\n            size: 16 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._projectionBuffer = this._renderer.device.createBuffer({\n            label: 'Projection matrix buffer',\n            size: 16 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._zIndexBuffer = this._renderer.device.createBuffer({\n            label: 'Z index buffer',\n            size: 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._cameraBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            entries: [\n                {\n                    binding: 0, // modelview\n                    visibility: GPUShaderStage.VERTEX,\n                    buffer: {},\n                },\n                {\n                    binding: 1, // projection\n                    visibility: GPUShaderStage.VERTEX,\n                    buffer: {},\n                },\n                {\n                    binding: 2, // zIndex\n                    visibility: GPUShaderStage.VERTEX,\n                    buffer: {},\n                },\n            ],\n        });\n\n        this._cameraBindGroup = this._renderer.device.createBindGroup({\n            layout: this._cameraBindGroupLayout,\n            entries: [\n                {\n                    binding: 0,\n                    resource: { buffer: this._mviewBuffer },\n                },\n                {\n                    binding: 1,\n                    resource: { buffer: this._projectionBuffer },\n                },\n                {\n                    binding: 2,\n                    resource: { buffer: this._zIndexBuffer },\n                },\n            ],\n        });\n    }\n\n    /**\n     * Writes the current camera state into the shared camera uniforms.\n     *\n     * @param camera Camera instance whose matrices are uploaded to the GPU.\n     * @throws Never throws.\n     */\n    updateCameraUniforms(camera: Camera): void {\n        this._mviewData.set(camera.getModelViewMatrix());\n        this._projectionData.set(camera.getProjectionMatrix());\n\n        this._renderer.device.queue.writeBuffer(this._mviewBuffer, 0, this._mviewData);\n        this._renderer.device.queue.writeBuffer(this._projectionBuffer, 0, this._projectionData);\n    }\n\n    /**\n     * Writes the layer z-index to the shared vertex uniform buffer.\n     *\n     * @param value Layer z-index value.\n     * @throws Never throws.\n     */\n    updateZIndex(value: number): void {\n        this._zIndexData[0] = value;\n        this._renderer.device.queue.writeBuffer(this._zIndexBuffer, 0, this._zIndexData);\n    }\n\n    /**\n     * Creates the shared render-state uniform resources and bind group.\n     *\n     * @throws If GPU buffer or texture allocation fails.\n     */\n    createColorUniformBindGroup(): void {\n        this._colorBuffer = this._renderer.device.createBuffer({\n            label: 'Fixed color buffer',\n            size: 4 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._highlightColorBuffer = this._renderer.device.createBuffer({\n            label: 'Highlight color buffer',\n            size: 4 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._invalidValueColorBuffer = this._renderer.device.createBuffer({\n            label: 'Invalid thematic value color buffer',\n            size: 4 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._useColorMap = this._renderer.device.createBuffer({\n            label: 'Enable colormap on render',\n            size: 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._useHighlight = this._renderer.device.createBuffer({\n            label: 'Enable highlight on render',\n            size: 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._cMapTexture = this._renderer.device.createTexture({\n            label: 'Colormap texture',\n            size: { width: DEFAULT_COLORMAP_RESOLUTION, height: COLORMAP_HEIGHT },\n            usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n            format: 'rgba8unorm',\n        });\n\n        const cMapSampler = this._renderer.device.createSampler({\n            label: 'Fixed color buffer',\n            magFilter: 'linear',\n            minFilter: 'linear',\n            addressModeU: 'clamp-to-edge',\n            addressModeV: 'clamp-to-edge',\n        });\n\n        this._opacity = this._renderer.device.createBuffer({\n            label: 'Enable opacity on render',\n            size: 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._domainBuffer = this._renderer.device.createBuffer({\n            label: 'Colormap domain buffer',\n            size: 4 * 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._renderInfoBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            entries: [\n                {\n                    binding: 0, // fixed color\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 1, // highlight color\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 2, // show thematic data\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 3, // show highlight\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 4, // cMap texture\n                    visibility: GPUShaderStage.FRAGMENT,\n                    texture: {},\n                },\n                {\n                    binding: 5, // cMap sampler\n                    visibility: GPUShaderStage.FRAGMENT,\n                    sampler: {},\n                },\n                {\n                    binding: 6, // opacity\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 7, // colormap domain params\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n                {\n                    binding: 8, // invalid thematic value color\n                    visibility: GPUShaderStage.FRAGMENT,\n                    buffer: {},\n                },\n            ],\n        });\n\n        this._renderInfoBindGroup = this._renderer.device.createBindGroup({\n            layout: this._renderInfoBindGroupLayout,\n            entries: [\n                {\n                    binding: 0,\n                    resource: { buffer: this._colorBuffer },\n                },\n                {\n                    binding: 1,\n                    resource: { buffer: this._highlightColorBuffer },\n                },\n                {\n                    binding: 2,\n                    resource: { buffer: this._useColorMap },\n                },\n                {\n                    binding: 3,\n                    resource: { buffer: this._useHighlight },\n                },\n                {\n                    binding: 4,\n                    resource: this._cMapTexture.createView(),\n                },\n                {\n                    binding: 5,\n                    resource: cMapSampler,\n                },\n                {\n                    binding: 6,\n                    resource: { buffer: this._opacity },\n                },\n                {\n                    binding: 7,\n                    resource: { buffer: this._domainBuffer },\n                },\n                {\n                    binding: 8,\n                    resource: { buffer: this._invalidValueColorBuffer },\n                },\n            ],\n        });\n    }\n\n    /**\n     * Resolves the fixed base color used by this pipeline.\n     *\n     * Subclasses can override this for alternate passes such as polygon borders.\n     *\n     * @param layer Layer instance whose render configuration is uploaded.\n     * @returns RGB color consumed by the shader uniform.\n     */\n    protected resolveLayerColor(layer: Layer): ColorRGB {\n        return layer.layerRenderInfo.color ?? this._renderer.style.getColor(layer.layerInfo.typeLayer);\n    }\n\n    /**\n     * Writes the current layer styling state into the shared render uniforms.\n     *\n     * @param layer Layer instance whose render configuration is uploaded.\n     * @throws Never throws.\n     */\n    updateColorUniforms(layer: Layer): void {\n        const computedDomain = layer.layerRenderInfo.colormap.computedDomain;\n\n        const isNumericDomain = Array.isArray(computedDomain)\n            && computedDomain.length > 0\n            && computedDomain.every(v => typeof v === 'number');\n        const isCategoricalDomain = Array.isArray(computedDomain)\n            && computedDomain.length > 0\n            && computedDomain.every(v => typeof v === 'string');\n\n        const colors = {\n            color: this.resolveLayerColor(layer),\n            highlightColor: this._renderer.style.getHighlightColor(),\n            invalidValueColor: this._renderer.style.getInvalidValueColor(),\n            colorMap: ColorMap.getColorMap(\n                layer.layerRenderInfo.colormap.config.interpolator,\n                undefined,\n                isCategoricalDomain ? computedDomain : undefined,\n            ),\n            useColorMap: Boolean(layer.layerRenderInfo.isColorMap),\n            useHighlight: Boolean(layer.layerRenderInfo.isPick),\n            opacity: layer.layerRenderInfo.opacity,\n        };\n\n        const min = isNumericDomain ? Number(computedDomain[0]) : 0;\n        const max = isNumericDomain ? Number(computedDomain[computedDomain.length - 1]) : 1;\n        const categoryCount = isCategoricalDomain ? computedDomain.length : 0;\n\n        this._colorData[0] = colors.color.r;\n        this._colorData[1] = colors.color.g;\n        this._colorData[2] = colors.color.b;\n        this._colorData[3] = 1.0;\n\n        this._highlightColorData[0] = colors.highlightColor.r;\n        this._highlightColorData[1] = colors.highlightColor.g;\n        this._highlightColorData[2] = colors.highlightColor.b;\n        this._highlightColorData[3] = 1.0;\n\n        this._invalidValueColorData[0] = colors.invalidValueColor.r;\n        this._invalidValueColorData[1] = colors.invalidValueColor.g;\n        this._invalidValueColorData[2] = colors.invalidValueColor.b;\n        this._invalidValueColorData[3] = 1.0;\n\n        this._useColorMapData[0] = colors.useColorMap ? 1.0 : 0.0;\n        this._useHighlightData[0] = colors.useHighlight ? 1.0 : 0.0;\n        this._opacityData[0] = colors.opacity;\n        this._domainData[0] = min;\n        this._domainData[1] = max;\n        this._domainData[2] = isNumericDomain ? 1.0 : (isCategoricalDomain ? 2.0 : 0.0);\n        this._domainData[3] = categoryCount;\n\n        const colorMapTexture = new Uint8Array(colors.colorMap);\n\n        this._renderer.device.queue.writeBuffer(this._colorBuffer, 0, this._colorData);\n        this._renderer.device.queue.writeBuffer(this._highlightColorBuffer, 0, this._highlightColorData);\n        this._renderer.device.queue.writeBuffer(this._invalidValueColorBuffer, 0, this._invalidValueColorData);\n        this._renderer.device.queue.writeBuffer(this._useHighlight, 0, this._useHighlightData);\n        this._renderer.device.queue.writeBuffer(this._useColorMap, 0, this._useColorMapData);\n        this._renderer.device.queue.writeTexture(\n            { texture: this._cMapTexture },\n            colorMapTexture,\n            {},\n            { width: DEFAULT_COLORMAP_RESOLUTION, height: COLORMAP_HEIGHT },\n        );\n        this._renderer.device.queue.writeBuffer(this._opacity, 0, this._opacityData);\n        this._renderer.device.queue.writeBuffer(this._domainBuffer, 0, this._domainData);\n    }\n\n    /**\n     * Releases GPU resources owned by this base pipeline.\n     *\n     * @throws Never throws. Missing resources are silently ignored.\n     */\n    destroy(): void {\n        this._mviewBuffer?.destroy();\n        this._projectionBuffer?.destroy();\n        this._zIndexBuffer?.destroy();\n\n        this._colorBuffer?.destroy();\n        this._highlightColorBuffer?.destroy();\n        this._invalidValueColorBuffer?.destroy();\n        this._useColorMap?.destroy();\n        this._useHighlight?.destroy();\n        this._opacity?.destroy();\n        this._domainBuffer?.destroy();\n        this._cMapTexture?.destroy();\n    }\n\n    /** Returns a float32 cache sized to the source and copies the values into it. */\n    protected _syncFloatData(\n        cache: Float32Array<ArrayBuffer> | null,\n        source: ArrayLike<number>,\n    ): Float32Array<ArrayBuffer> {\n        if (!cache || cache.length !== source.length) {\n            cache = new Float32Array(new ArrayBuffer(source.length * Float32Array.BYTES_PER_ELEMENT));\n        }\n        cache.set(source);\n        return cache;\n    }\n\n    /** Returns a uint32 cache sized to the source and copies the values into it. */\n    protected _syncUintData(\n        cache: Uint32Array<ArrayBuffer> | null,\n        source: ArrayLike<number>,\n    ): Uint32Array<ArrayBuffer> {\n        if (!cache || cache.length !== source.length) {\n            cache = new Uint32Array(new ArrayBuffer(source.length * Uint32Array.BYTES_PER_ELEMENT));\n        }\n        cache.set(source);\n        return cache;\n    }\n\n    /** Returns a uint8 cache sized to the source and copies the values into it. */\n    protected _syncU8Data(\n        cache: Uint8Array<ArrayBuffer> | null,\n        source: ArrayLike<number>,\n    ): Uint8Array<ArrayBuffer> {\n        if (!cache || cache.length !== source.length) {\n            cache = new Uint8Array(new ArrayBuffer(source.length * Uint8Array.BYTES_PER_ELEMENT));\n        }\n        cache.set(source);\n        return cache;\n    }\n\n    /** Returns a float32 cache with the requested length. */\n    protected _syncFloatLength(\n        cache: Float32Array<ArrayBuffer> | null,\n        length: number,\n    ): Float32Array<ArrayBuffer> {\n        if (!cache || cache.length !== length) {\n            cache = new Float32Array(new ArrayBuffer(length * Float32Array.BYTES_PER_ELEMENT));\n        }\n        return cache;\n    }\n\n    /** Runs any offscreen or preparatory work required before the shared main pass. */\n    prepareRender(_camera: Camera): void {}\n\n    /**\n     * Builds the layer-specific pipeline state.\n     *\n     * Implementations are responsible for creating the GPU pipeline and any\n     * resources required by the layer, including the shared bind groups when\n     * they are part of the pipeline setup.\n     *\n     * @param data Layer instance used to derive pipeline configuration.\n     */\n    abstract build(data: Layer): void;\n\n    /**\n     * Creates the vertex buffers for the layer.\n     *\n     * @param data Layer instance used to build vertex buffer contents.\n     */\n    abstract createVertexBuffers(data: Layer): void;\n\n    /**\n     * Updates the layer's vertex buffers from the current layer data.\n     *\n     * @param data Layer instance whose buffered data should be refreshed.\n     */\n    abstract updateVertexBuffers(data: Layer): void;\n\n    /** Records draw commands; picking pipelines may create their own pass when no encoder is supplied. */\n    abstract renderPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void;\n}\n","/**\n * @module PipelineTriangleRaster\n * WebGPU raster-triangle rendering pipeline.\n *\n * This module defines the `PipelineTriangleRaster` class, a concrete pipeline\n * implementation used by raster-backed layers. It owns the GPU buffers,\n * texture resources, bind groups, shader modules, and render pipeline state\n * required to draw indexed 2D triangles textured with RGBA raster data.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport rasterVertexSource from './shaders/raster.vert.wgsl';\nimport rasterFragmentSource from './shaders/raster.frag.wgsl';\n\nimport { Pipeline } from './pipeline';\nimport { Renderer } from './renderer';\n\nimport { Camera } from '@urban-toolkit/autk-core';\n\nimport { RasterLayer } from './layer-raster';\n\n/**\n * Raster-triangle pipeline for rendering textured 2D raster surfaces.\n *\n * `PipelineTriangleRaster` uploads flattened triangle geometry, texture\n * coordinates, and raster texture data from a `RasterLayer`, then renders the\n * result using a dedicated vertex/fragment shader pair. It also coordinates the\n * shared camera and render-info uniform bindings inherited from `Pipeline`.\n *\n * @example\n * const pipeline = new PipelineTriangleRaster(renderer);\n * pipeline.build(rasterLayer);\n */\nexport class PipelineTriangleRaster extends Pipeline {\n    /** Vertex buffer storing 2D raster triangle positions. */\n    protected _positionBuffer!: GPUBuffer;\n\n    /** Vertex buffer storing texture coordinates aligned with raster vertices. */\n    protected _texCoordBuffer!: GPUBuffer;\n\n    /** Index buffer describing raster triangles. */\n    protected _indicesBuffer!: GPUBuffer;\n\n    /** Compiled vertex shader module for raster geometry. */\n    protected _vertModule!: GPUShaderModule;\n\n    /** Compiled fragment shader module for raster sampling. */\n    protected _fragModule!: GPUShaderModule;\n\n    /** Render pipeline used for raster triangle draw passes. */\n    protected _pipeline!: GPURenderPipeline;\n\n    /** Texture resource containing the layer's RGBA raster payload. */\n    protected _rasterBuffer!: GPUTexture;\n    /** Bind group that exposes the raster texture and sampler to the fragment shader. */\n    protected _rasterBindGroup!: GPUBindGroup;\n\n    /** Bind group layout for raster texture sampling resources. */\n    protected _rasterBindGroupLayout!: GPUBindGroupLayout;\n\n    /** Reused CPU-side upload buffer for vertex positions. */\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for texture coordinates. */\n    private _texCoordData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for triangle indices. */\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload payload for RGBA raster texture data. */\n    private _rasterTextureData: Uint8Array<ArrayBuffer> | null = null;\n\n    /**\n     * Creates a raster-triangle pipeline bound to a renderer.\n     *\n     * The renderer provides the WebGPU device, target format, and shared render\n     * settings used by all resources created by this pipeline.\n     *\n     * @param renderer Renderer that owns the WebGPU device and canvas state.\n     */\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    /**\n     * Releases GPU resources owned by this pipeline.\n     *\n     * This destroys the geometry buffers and raster texture created by this\n     * pipeline, then delegates to the base pipeline to release shared uniform\n     * resources.\n     *\n     * @returns Nothing. This pipeline's GPU allocations are destroyed in place.\n     */\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._texCoordBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._rasterBuffer?.destroy();\n        super.destroy();\n    }\n\n    /**\n     * Builds all GPU resources needed to render a raster layer.\n     *\n     * This initializes shader modules, geometry buffers, raster texture\n     * bindings, shared render-info bindings, camera bindings, and the final\n     * render pipeline. It also uploads the layer's current geometry, render\n     * state, and raster payload before the first draw.\n     *\n     * @param mesh Raster layer supplying triangle geometry, texture\n     * coordinates, render configuration, and raster texture data.\n     * @returns Nothing. The pipeline becomes ready for use in render passes.\n     */\n    build(mesh: RasterLayer): void {\n        this.createShaders();\n\n        this.createVertexBuffers(mesh);\n        this.createRasterUniformBindGroup(mesh);\n\n        this.createColorUniformBindGroup();\n        this.createCameraUniformBindGroup();\n\n        this.updateVertexBuffers(mesh);\n        this.updateColorUniforms(mesh);\n        this.updateRasterUniforms(mesh);\n\n        this.createPipeline();\n    }\n\n    /**\n     * Creates the shader modules used by the raster pipeline.\n     *\n     * The compiled modules are later referenced when the render pipeline is\n     * created.\n     *\n     * @returns Nothing. Shader modules are created and stored on the instance.\n     */\n    createShaders(): void {\n        // Vertex shader\n        const vsmDesc = {\n            code: rasterVertexSource,\n        };\n        this._vertModule = this._renderer.device.createShaderModule(vsmDesc);\n\n        // Fragment shader\n        const fsmDesc = {\n            code: rasterFragmentSource,\n        };\n        this._fragModule = this._renderer.device.createShaderModule(fsmDesc);\n    }\n\n    /**\n     * Creates GPU buffers for raster geometry uploads.\n     *\n     * Buffer sizes are derived directly from the current layer geometry. This\n     * method allocates buffers only; it does not upload any geometry data.\n     *\n     * @param raster Raster layer whose position, texture-coordinate, and index\n     * arrays determine the required buffer sizes.\n     * @returns Nothing. Empty GPU buffers are allocated for later uploads.\n     */\n    override createVertexBuffers(raster: RasterLayer): void {\n        // vertex data\n        this._positionBuffer = this._renderer.device.createBuffer({\n            label: 'Position buffer',\n            size: raster.position.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // texture coordinates data\n        this._texCoordBuffer = this._renderer.device.createBuffer({\n            label: 'Texture coordinates buffer',\n            size: raster.texCoord.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Primitive indices buffer',\n            size: raster.indices.length * 4,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    /**\n     * Uploads raster geometry data into the existing GPU buffers.\n     *\n     * The method reuses cached typed arrays when possible to avoid repeated CPU\n     * allocations during updates.\n     *\n     * @param mesh Raster layer supplying the latest position,\n     * texture-coordinate, and index data.\n     * @returns Nothing. The GPU geometry buffers are overwritten in place.\n     */\n    override updateVertexBuffers(mesh: RasterLayer): void {\n        this._positionData = this._syncFloatData(this._positionData, mesh.position);\n        this._texCoordData = this._syncFloatData(this._texCoordData, mesh.texCoord);\n        this._indicesData = this._syncUintData(this._indicesData, mesh.indices);\n\n        this._renderer.device.queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        this._renderer.device.queue.writeBuffer(this._texCoordBuffer, 0, this._texCoordData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n    }\n\n    /**\n     * Creates the raster texture, sampler, and bind group used for sampling.\n     *\n     * The texture dimensions are taken from the layer's raster resolution and\n     * the bind group is configured for fragment-stage access.\n     *\n     * @param raster Raster layer providing the raster texture resolution.\n     * @returns Nothing. Raster sampling resources are allocated and bound.\n     */\n    createRasterUniformBindGroup(raster: RasterLayer): void {\n        this._rasterBuffer = this._renderer.device.createTexture({\n            label: 'Raster texture',\n            size: { width: raster.rasterResX, height: raster.rasterResY },\n            usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n            format: 'rgba8unorm',\n        });\n\n        const rasterSampler = this._renderer.device.createSampler({\n            label: 'Raster sampler',\n            magFilter: 'linear',\n            minFilter: 'linear',\n            addressModeU: 'clamp-to-edge',\n            addressModeV: 'clamp-to-edge',\n        });\n\n        // Raster uniform bind group layout\n        this._rasterBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            label: 'Raster bind group layout',\n            entries: [\n                {\n                    binding: 0,\n                    visibility: GPUShaderStage.FRAGMENT,\n                    texture: {},\n                },\n                {\n                    binding: 1,\n                    visibility: GPUShaderStage.FRAGMENT,\n                    sampler: {},\n                },\n            ],\n        });\n\n        // Raster uniform bind group\n        this._rasterBindGroup = this._renderer.device.createBindGroup({\n            layout: this._rasterBindGroupLayout,\n            label: 'Raster bind group',\n            entries: [\n                {\n                    binding: 0,\n                    resource: this._rasterBuffer.createView(),\n                },\n                {\n                    binding: 1,\n                    resource: rasterSampler,\n                },\n            ],\n        });\n    }\n\n    /**\n     * Uploads RGBA raster data into the raster texture.\n     *\n     * Calls with a missing or empty raster payload are ignored. The upload uses\n     * the layer's current raster resolution to define texture copy dimensions.\n     *\n     * @param raster Raster layer containing the RGBA raster payload and texture\n     * dimensions.\n     * @returns Nothing. The raster texture is updated when data are available.\n     */\n    updateRasterUniforms(raster: RasterLayer): void {\n        if (!raster.rasterData || raster.rasterData.length === 0) { return; }\n\n        this._rasterTextureData = this._syncU8Data(this._rasterTextureData, raster.rasterData);\n\n        this._renderer.device.queue.writeTexture(\n            { texture: this._rasterBuffer },\n            this._rasterTextureData,\n            {\n                bytesPerRow: raster.rasterResX * 4,\n                rowsPerImage: raster.rasterResY,\n            },\n            { width: raster.rasterResX, height: raster.rasterResY },\n        );\n    }\n\n    /**\n     * Creates the WebGPU render pipeline for raster triangle drawing.\n     *\n     * The pipeline combines raster vertex inputs, alpha blending, depth\n     * testing, multisampling, and the shared render-info, camera, and raster\n     * sampling bind-group layouts.\n     *\n     * @returns Nothing. The render pipeline is created and stored on the instance.\n     */\n    createPipeline(): void {\n        // Vertex data\n        const positionAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 0, // [[location(0)]]\n            offset: 0,\n            format: 'float32x2',\n        };\n\n        // Vertex data\n        const texCoordAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 1, // [[location(1)]]\n            offset: 0,\n            format: 'float32x2',\n        };\n\n        const positionBufferDesc: GPUVertexBufferLayout = {\n            attributes: [positionAttribDesc],\n            arrayStride: 4 * 2, // sizeof(float) * 2\n            stepMode: 'vertex',\n        };\n\n        const texCoordBufferDesc: GPUVertexBufferLayout = {\n            attributes: [texCoordAttribDesc],\n            arrayStride: 4 * 2, // sizeof(float) * 2\n            stepMode: 'vertex',\n        };\n\n        // Vertex Shader\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [positionBufferDesc, texCoordBufferDesc],\n        };\n\n        // Fragment Shader\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [\n                {\n                    format: this._renderer.canvasFormat,\n                    blend: {\n                        color: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha',\n                        },\n                        alpha: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha'\n                        },\n                    },\n                },\n            ],\n        };\n\n        // Rasterization\n        const primitive: GPUPrimitiveState = {\n            frontFace: 'cw',\n            cullMode: 'none',\n            topology: 'triangle-list',\n        };\n\n        // Antialising\n        const multisample: GPUMultisampleState = {\n            count: this._renderer.sampleCount,\n        };\n\n        // Depth test\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: false,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n\n        // Uniform Data\n        const pipelineLayoutDesc = {\n            bindGroupLayouts: [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout, this._rasterBindGroupLayout],\n        };\n\n        // Pipeline\n        const layout = this._renderer.device.createPipelineLayout(pipelineLayoutDesc);\n        const pipelineDesc: GPURenderPipelineDescriptor = {\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            multisample,\n            label: 'Pipeline Raster',\n        };\n        this._pipeline = this._renderer.device.createRenderPipeline(pipelineDesc);\n    }\n\n    /**\n     * Encodes a raster draw pass into the provided render pass encoder.\n     *\n     * This updates camera uniforms for the current view, binds the geometry and\n     * raster resources created by `build`, and issues an indexed draw call only\n     * when the index buffer contains at least one triangle.\n     *\n     * @param camera Camera whose matrices are uploaded before drawing.\n     * @param passEncoder Active render pass encoder that receives the draw commands.\n     * @returns Nothing. Draw commands are appended to the render pass when indices are present.\n     */\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        // sets the current pipeline\n        passEncoder.setPipeline(this._pipeline);\n\n        // updates camera\n        this.updateCameraUniforms(camera);\n\n        // sets the vertex buffers\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._texCoordBuffer);\n\n        // sets primitive indices buffer\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n\n        // sets the uniform buffers\n        passEncoder.setBindGroup(0, this._renderInfoBindGroup);\n        passEncoder.setBindGroup(1, this._cameraBindGroup);\n        passEncoder.setBindGroup(2, this._rasterBindGroup);\n\n        // draw command\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0) { passEncoder.drawIndexed(indexCount); }\n    }\n\n}\n","/**\n * @module RasterLayer\n * Raster-backed map layer rendering.\n *\n * This module defines the `RasterLayer` class, which stores triangulated raster\n * surface geometry, raster texture payloads, and the WebGPU pipeline state used\n * to render them. It is responsible for loading raster geometry and component\n * metadata, converting scalar rasters into RGBA texture data using the active\n * color-map and transfer-function configuration, and synchronizing those data\n * updates with the raster rendering pipeline.\n */\n\nimport { \n    LayerInfo,\n    LayerRenderInfo,\n    LayerData,\n} from \"./types-layers\";\n\nimport {\n    Camera,\n    LayerGeometry,\n    LayerComponent,\n    ColorMap,\n    DEFAULT_TRANSFER_FUNCTION,\n    buildTransferContext,\n    computeAlphaByte,\n} from '@urban-toolkit/autk-core';\n\nimport type { \n    TransferFunction,\n    RequiredTransferFunction\n} from '@urban-toolkit/autk-core';\n\nimport { Layer } from \"./layer\";\n\nimport { Renderer } from \"./renderer\";\n\nimport { Pipeline } from \"./pipeline\";\n\nimport { PipelineTriangleRaster } from \"./pipeline-triangle-raster\";\n\n/**\n * Raster layer implementation backed by triangulated geometry and texture data.\n *\n * `RasterLayer` extends the generic layer lifecycle with raster-specific data\n * loading and rendering behavior. It stores flattened 2D triangle geometry,\n * cumulative component metadata, raster resolution, and both scalar and RGBA\n * raster payloads. Scalar rasters are colorized on load using the active\n * colormap configuration and transfer function before being uploaded through\n * the raster pipeline.\n */\nexport class RasterLayer extends Layer {\n    /** Triangle vertex positions. */\n    protected _position!: Float32Array;\n\n    /** Triangle index buffer. */\n    protected _indices!: Uint32Array;\n\n    /** Texture coordinates aligned with raster vertices. */\n    protected _texCoord!: Float32Array;\n\n    /** Cumulative per-feature component metadata. */\n    protected _components: LayerComponent[] = [];\n\n    /** Raster width in pixels. */\n    protected _rasterResX!: number;\n\n    /** Raster height in pixels. */\n    protected _rasterResY!: number;\n\n    /** RGBA raster payload consumed by the GPU pipeline. */\n    protected _rasterData!: Float32Array;\n\n    /** Canonical scalar raster payload used for domain recomputation. */\n    protected _rasterValues: Float32Array = new Float32Array(0);\n\n    /** Opacity transfer-function configuration used while rebuilding raster RGBA data. */\n    protected _transferFunction: RequiredTransferFunction = { ...DEFAULT_TRANSFER_FUNCTION };\n\n    /** WebGPU pipeline used to render the raster layer. */\n    protected _pipeline!: Pipeline;\n\n    /**\n     * Creates a raster layer from precomputed layer metadata and raster payloads.\n     *\n     * The constructor delegates all geometry, component, and raster loading to\n     * `loadLayerData`, which also initializes the raster resolution and derives\n     * RGBA texture data when scalar raster values are provided.\n     *\n     * @param layerInfo Static layer identity and ordering information.\n     * @param layerRenderInfo Render-state configuration, including colormap settings.\n     * @param layerData Geometry, component metadata, raster resolution, and raster values.\n     */\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData) {\n        super(layerInfo, layerRenderInfo);\n\n        this.loadLayerData(layerData);\n    }\n\n    /** Triangle vertex positions. */\n    get position(): Float32Array {\n        return this._position;\n    }\n\n    /** Triangle index buffer. */\n    get indices(): Uint32Array {\n        return this._indices;\n    }\n\n    /** Texture coordinates aligned with raster vertices. */\n    get texCoord(): Float32Array {\n        return this._texCoord;\n    }\n\n    /** Cumulative per-feature component metadata. */\n    get components(): LayerComponent[] {\n        return this._components;\n    }\n\n    /** Raster width in pixels. */\n    get rasterResX(): number {\n        return this._rasterResX;\n    }\n\n    /** Raster height in pixels. */\n    get rasterResY(): number {\n        return this._rasterResY;\n    }\n\n    /** RGBA raster payload consumed by the GPU pipeline. */\n    get rasterData(): Float32Array {\n        return this._rasterData;\n    }\n\n    /** Original scalar raster values (not normalized). */\n    get rasterValues(): Float32Array {\n        return this._rasterValues;\n    }\n\n    /**\n     * Updates the transfer-function configuration used to map scalar values to opacity.\n     *\n     * The provided values are merged into the existing transfer-function state.\n     * This only updates the stored configuration; callers must reload raster\n     * values separately if they need the RGBA raster payload to be rebuilt.\n     *\n     * @param config Partial transfer-function override to apply.\n     * @returns Nothing. The transfer-function configuration is updated in place.\n     */\n    setTransferFunction(config: TransferFunction): void {\n        this._transferFunction = {\n            ...this._transferFunction,\n            ...config,\n        };\n    }\n\n    /**\n     * Loads geometry, components, raster resolution, and raster payloads.\n     *\n     * Geometry and component metadata are always loaded. Raster resolution is\n     * updated only when both `rasterResX` and `rasterResY` are present. Raster\n     * values are loaded only when a non-empty raster payload is provided.\n     *\n     * @param layerData Layer data bundle for the raster layer.\n     * @returns Nothing. The layer's CPU-side geometry and raster state are replaced.\n     */\n    loadLayerData(layerData: LayerData): void {\n        this.loadGeometry(layerData.geometry);\n        this.loadComponent(layerData.components);\n\n        if (layerData.rasterResX !== undefined && layerData.rasterResY !== undefined) {\n            this._rasterResX = layerData.rasterResX;\n            this._rasterResY = layerData.rasterResY;\n        }\n\n        if (layerData.raster && layerData.raster.length) {\n            this.loadRaster(layerData.raster);\n        }\n    }\n\n    /**\n     * Flattens raster geometry chunks into contiguous position, index, and UV buffers.\n     *\n     * Indices from each geometry chunk are rebased to the cumulative vertex\n     * count so the merged buffers can be rendered as a single indexed mesh.\n     * Raster geometry is expected to remain 2D, with one texture-coordinate pair\n     * for each vertex.\n     *\n     * @param layerGeometry Geometry chunks to merge into layer-local buffers.\n     * @returns Nothing. The layer geometry buffers are rebuilt in memory.\n     */\n    loadGeometry(layerGeometry: LayerGeometry[]): void {\n        let totalVerts = 0;\n        let totalIndices = 0;\n        let totalTexCoords = 0;\n\n        for (const g of layerGeometry) {\n            totalVerts += g.position.length;\n            totalIndices += (g.indices?.length ?? 0);\n            totalTexCoords += (g.texCoord?.length ?? 0);\n        }\n\n        const position = new Float32Array(totalVerts);\n        const indices = new Uint32Array(totalIndices);\n        const texCoord = new Float32Array(totalTexCoords);\n\n        let vOffset = 0;\n        let iOffset = 0;\n        let tOffset = 0;\n        let vertexCount = 0;\n\n        for (let id = 0; id < layerGeometry.length; id++) {\n            const g = layerGeometry[id];\n            \n            position.set(g.position, vOffset);\n\n            if (g.indices) {\n                for (let i = 0; i < g.indices.length; i++) {\n                    indices[iOffset + i] = g.indices[i] + vertexCount;\n                }\n                iOffset += g.indices.length;\n            }\n\n            if (g.texCoord) {\n                texCoord.set(g.texCoord, tOffset);\n                tOffset += g.texCoord.length;\n            }\n\n            vOffset += g.position.length;\n            vertexCount += g.position.length / 2; // Raster is always 2D\n        }\n\n        // Raster triangles are expected to be 2D vertices and 2D UV pairs.\n        console.assert(position.length % 2 === 0, 'Raster geometry position length must be a multiple of 2.');\n        console.assert(texCoord.length % 2 === 0, 'Raster geometry texCoord length must be a multiple of 2.');\n        console.assert(position.length === texCoord.length, 'Raster geometry and texCoord arrays should have matching lengths.');\n        \n        this._position = position;\n        this._indices = indices;\n        this._texCoord = texCoord;\n    }\n\n    /**\n     * Builds cumulative component metadata for the merged raster geometry.\n     *\n     * Each stored component keeps running totals for points and triangles so\n     * downstream consumers can address the flattened geometry by feature.\n     * Feature index and feature id metadata are preserved from the source\n     * components.\n     *\n     * @param layerComponents Per-feature component metadata to accumulate.\n     * @returns Nothing. The component list is rebuilt from the provided data.\n     */\n    loadComponent(layerComponents: LayerComponent[]): void {\n        this._components = [];\n\n        const accum = { nPoints: 0, nTriangles: 0 };\n        for (let cId = 0; cId < layerComponents.length; cId++) {\n            const comp = layerComponents[cId];\n\n            accum.nPoints += comp.nPoints;\n            accum.nTriangles += comp.nTriangles;\n\n            this._components.push({\n                nPoints: accum.nPoints,\n                nTriangles: accum.nTriangles,\n                featureIndex: comp.featureIndex,\n                featureId: comp.featureId,\n            });\n        }\n    }\n\n    /**\n     * Loads raster values and rebuilds the RGBA texture payload.\n     *\n     * If the input length matches `rasterResX * rasterResY * 4`, the values are\n     * treated as a precomputed RGBA raster and copied directly. Otherwise the\n     * input is treated as a scalar raster, colorized using the active colormap,\n     * and assigned per-pixel opacity using the current transfer function.\n     * `NaN` samples produce fully transparent pixels.\n     *\n     * When a numeric computed colormap domain is available, transfer-function\n     * statistics are derived from values inside that domain. If no valid scalar\n     * values remain, the raster payload is cleared to transparent black.\n     *\n     * @param rasterValues Flattened scalar or RGBA raster values.\n     * @returns Nothing. The stored scalar values and RGBA raster payload are updated when input is non-empty.\n     */\n    loadRaster(rasterValues: Float32Array): void {\n        if (!rasterValues || rasterValues.length === 0) {\n            return;\n        }\n\n        this._rasterValues = rasterValues;\n\n        const isRGBA = rasterValues.length === this._rasterResX * this._rasterResY * 4;\n        const rasterData = new Float32Array(isRGBA ? rasterValues.length : this._rasterResX * this._rasterResY * 4);\n\n        if (!isRGBA) {\n            const validValues: number[] = [];\n            for (let i = 0; i < rasterValues.length; i++) {\n                if (!isNaN(rasterValues[i])) validValues.push(rasterValues[i]);\n            }\n\n            const colorDomain = this._layerRenderInfo.colormap.computedDomain;\n            const numericDomain = (\n                Array.isArray(colorDomain)\n                && colorDomain.length > 0\n                && colorDomain.every(v => typeof v === 'number')\n            )\n                ? colorDomain as [number, number] | [number, number, number]\n                : null;\n\n            const transferValues = numericDomain\n                ? validValues.filter(v => v >= numericDomain[0] && v <= numericDomain[numericDomain.length - 1])\n                : validValues;\n\n            const transferContext = buildTransferContext(\n                transferValues.length > 0 ? transferValues : validValues,\n                this._transferFunction,\n            );\n\n            if (transferContext.validCount === 0) {\n                rasterData.fill(0);\n                this._rasterData = rasterData;\n                return;\n            }\n\n            for (let i = 0; i < rasterValues.length; i++) {\n                const d = rasterValues[i];\n                const offset = i * 4;\n                if (isNaN(d)) {\n                    rasterData[offset] = 0;\n                    rasterData[offset + 1] = 0;\n                    rasterData[offset + 2] = 0;\n                    rasterData[offset + 3] = 0;\n                    continue;\n                }\n\n                const effectiveDomain = numericDomain ?? [transferContext.min, transferContext.max] as [number, number];\n\n                const color = ColorMap.getColor(\n                    d,\n                    this._layerRenderInfo.colormap.config.interpolator,\n                    effectiveDomain,\n                );\n                const alpha = computeAlphaByte(d, transferContext);\n\n                rasterData[offset] = color.r;\n                rasterData[offset + 1] = color.g;\n                rasterData[offset + 2] = color.b;\n                rasterData[offset + 3] = alpha;\n            }\n        }\n        else {\n            rasterData.set(rasterValues);\n        }\n\n        this._rasterData = rasterData;\n    }\n\n    /**\n     * Creates the raster rendering pipeline for this layer.\n     *\n     * The pipeline is instantiated as `PipelineTriangleRaster` and built against\n     * the layer's current geometry and raster state.\n     *\n     * @param renderer Renderer that owns the GPU device and shared resources.\n     * @returns Nothing. The layer becomes ready for raster draw calls.\n     */\n    createPipeline(renderer: Renderer): void {\n        this._pipeline = new PipelineTriangleRaster(renderer);\n        this._pipeline.build(this);\n    }\n\n    /**\n     * Renders the raster layer during the current render pass.\n     *\n     * Dirty geometry or raster data trigger raster vertex-buffer and uniform\n     * updates before drawing. Dirty render-info state triggers a color-uniform\n     * update. The layer z-index is refreshed on every call before delegating the\n     * draw to the underlying pipeline.\n     *\n     * @param camera Active camera used to populate view-dependent uniforms.\n     * @param passEncoder Render-pass encoder receiving the draw commands.\n     * @returns Nothing. The layer uploads pending state changes and issues its draw call.\n     */\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        if (this._dataIsDirty) {\n            const rasterPipeline = this._pipeline as PipelineTriangleRaster;\n            rasterPipeline.updateVertexBuffers(this);\n            rasterPipeline.updateRasterUniforms(this);\n            this._dataIsDirty = false;\n        }\n\n        if (this._renderInfoIsDirty) {\n            this._pipeline.updateColorUniforms(this);\n            this._renderInfoIsDirty = false;\n        }\n\n        this._pipeline.updateZIndex(this._layerInfo.zIndex);\n        this._pipeline.renderPass(camera, passEncoder);\n    }\n\n    /**\n     * Releases GPU resources owned by the raster pipeline.\n     *\n     * @returns Nothing. Any pipeline resources currently allocated for this layer are destroyed.\n     */\n    override destroy(): void {\n        this._pipeline?.destroy();\n    }\n}\n","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4<f32>,\\n    @location(0) outThematic: f32,\\n    @location(1) outHighlighted: f32,\\n    @location(2) outThematicValid: f32,\\n    @location(3) outSkipped: f32\\n };\\n\\n@vertex\\nfn main(@location(0) inPosition: vec2f, @location(1) inThematic: f32, @location(2) inHighlighted: f32, @location(3) inThematicValid: f32, @location(4) inSkipped: f32) -> VSOut {\\n    var vsOut: VSOut;\\n\\n    vsOut.outPosition = projection * modelView * vec4f(inPosition.x, inPosition.y, zIndex, 1);\\n    vsOut.outThematic = inThematic;\\n    vsOut.outHighlighted = inHighlighted;\\n    vsOut.outThematicValid = inThematicValid;\\n    vsOut.outSkipped = inSkipped;\\n\\n    return vsOut;\\n}\";","export default \"@group(0) @binding(0) var<uniform> color : vec4f;\\n@group(0) @binding(1) var<uniform> highlightColor : vec4f;\\n@group(0) @binding(2) var<uniform> showThematic : f32;\\n@group(0) @binding(3) var<uniform> showHighlight : f32;\\n@group(0) @binding(4) var cMapTex : texture_2d<f32>;\\n@group(0) @binding(5) var cMapSampler : sampler;\\n@group(0) @binding(6) var<uniform> opacity : f32;\\n@group(0) @binding(7) var<uniform> domainParams : vec4f;\\n@group(0) @binding(8) var<uniform> invalidValueColor : vec4f;\\n\\n@fragment \\nfn main(@location(0) inThematic: f32, @location(1) inHighlighted: f32, @location(2) inThematicValid: f32, @location(3) inSkipped: f32) -> @location(0) vec4f {\\n\\n    if (inSkipped > 0.0) {\\n        discard;\\n    }\\n\\n    var color = vec4f(color.r / 255, color.g / 255, color.b / 255, color.a);\\n\\n    var thematicValue = inThematic;\\n    if (domainParams.z > 1.5) {\\n        let nCategories = domainParams.w;\\n        let denom = max(1.0, nCategories - 1.0);\\n        thematicValue = clamp(inThematic / denom, 0.0, 1.0);\\n    } else if (domainParams.z > 0.5) {\\n        let minVal = domainParams.x;\\n        let maxVal = domainParams.y;\\n        let range = maxVal - minVal;\\n        thematicValue = select(0.0, clamp((inThematic - minVal) / range, 0.0, 1.0), range > 0.0);\\n    }\\n\\n    var sampledColor = textureSample(cMapTex, cMapSampler, vec2f(thematicValue, 0.0));\\n\\n    if(showHighlight > 0 && inHighlighted > 0) {\\n        color = vec4f(highlightColor.r / 255, highlightColor.g / 255, highlightColor.b / 255, highlightColor.a);\\n    }\\n    else if (showThematic > 0 && inThematicValid < 0.5) {\\n        color = vec4f(invalidValueColor.r / 255, invalidValueColor.g / 255, invalidValueColor.b / 255, invalidValueColor.a);\\n    }\\n    else if (showThematic > 0) {\\n        color = sampledColor;\\n    }\\n    return vec4f(color.rgb * opacity, opacity);\\n}\";","/**\n * @module PipelineTriangleFlat\n * WebGPU pipeline for rendering flat indexed triangle geometry.\n *\n * This module defines the `PipelineTriangleFlat` class, a vector-layer render\n * pipeline that uploads per-vertex position, thematic, validity, highlight,\n * and skip state into GPU buffers and draws them with a triangle-list render\n * pipeline. It works with `VectorLayer` mesh data and integrates shared camera\n * and render-info uniform bind groups provided by the base `Pipeline` class.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport trianglesVertexSource from './shaders/triangle-01.vert.wgsl';\nimport trianglesFragmentSource from './shaders/triangle-01.frag.wgsl';\n\nimport { Pipeline } from './pipeline';\nimport { Renderer } from './renderer';\n\nimport { Camera } from '@urban-toolkit/autk-core';\n\nimport { VectorLayer } from './layer-vector';\n\n/**\n * Renders flat indexed triangles for a vector layer.\n *\n * `PipelineTriangleFlat` owns the GPU resources needed to draw triangle meshes\n * whose vertex data is supplied by a `VectorLayer`. It creates shader modules,\n * allocates and updates vertex and index buffers, binds shared render-info and\n * camera uniforms from the base pipeline, and records indexed draw calls for\n * the current render pass.\n */\nexport class PipelineTriangleFlat extends Pipeline {\n    /** GPU vertex buffer containing 2D positions. */\n    protected _positionBuffer!: GPUBuffer;\n\n    /** GPU vertex buffer containing per-vertex thematic values. */\n    protected _thematicBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing per-vertex thematic validity flags. */\n    protected _thematicValidityBuffer!: GPUBuffer;\n\n    /** GPU vertex buffer containing per-vertex highlight flags. */\n    protected _highlightedBuffer!: GPUBuffer;\n\n    /** GPU vertex buffer containing per-vertex skip flags. */\n    protected _skippedBuffer!: GPUBuffer;\n\n    /** GPU index buffer defining triangle primitives. */\n    protected _indicesBuffer!: GPUBuffer;\n\n    /** Compiled vertex shader module for triangle rendering. */\n    protected _vertModule!: GPUShaderModule;\n\n    /** Compiled fragment shader module for triangle rendering. */\n    protected _fragModule!: GPUShaderModule;\n\n    /** WebGPU render pipeline used for indexed triangle draws. */\n    protected _pipeline!: GPURenderPipeline;\n\n    /** Reused CPU-side upload buffer for positions. */\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for thematic values. */\n    private _thematicData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for thematic validity flags. */\n    private _thematicValidityData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for highlighted flags. */\n    private _highlightedData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for skipped flags. */\n    private _skippedData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for triangle indices. */\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n\n    /**\n     * Creates a flat-triangle pipeline bound to a renderer.\n     *\n     * The renderer provides the WebGPU device, canvas format, multisampling\n     * configuration, and shared resources required to create pipeline state and\n     * upload buffers.\n     *\n     * @param renderer Renderer that owns the WebGPU device and render context.\n     */\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    /**\n     * Releases GPU resources owned by this pipeline.\n     *\n     * This destroys all vertex and index buffers created by the pipeline and\n     * then delegates to the base pipeline to release shared resources.\n     *\n     * @returns Releases this pipeline's GPU allocations in place.\n     */\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._thematicBuffer?.destroy();\n        this._thematicValidityBuffer?.destroy();\n        this._highlightedBuffer?.destroy();\n        this._skippedBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        super.destroy();\n    }\n\n    /**\n     * Builds all GPU resources needed to render a vector-layer triangle mesh.\n     *\n     * This method creates shader modules, allocates vertex and index buffers,\n     * initializes the shared color and camera uniform bind groups inherited from\n     * `Pipeline`, uploads the current mesh data, updates render-info uniforms,\n     * and finally creates the render pipeline state.\n     *\n     * @param mesh Vector layer whose typed arrays provide positions, thematic\n     * values, thematic validity flags, highlight flags, skip flags, and\n     * triangle indices.\n     * @returns Initializes this pipeline for subsequent render passes.\n     */\n    build(mesh: VectorLayer): void {\n        this.createShaders();\n\n        this.createVertexBuffers(mesh);\n        this.createColorUniformBindGroup();\n        this.createCameraUniformBindGroup();\n\n        this.updateVertexBuffers(mesh);\n        this.updateColorUniforms(mesh);\n\n        this.createPipeline();\n    }\n\n    /**\n     * Creates the shader modules used by this pipeline.\n     *\n     * The modules are compiled from the flat-triangle WGSL vertex and fragment\n     * shader sources imported by this module.\n     *\n     * @returns Creates and stores the compiled shader modules on the pipeline.\n     */\n    createShaders(): void {\n        // Vertex shader\n        const vsmDesc = {\n            code: trianglesVertexSource,\n        };\n        this._vertModule = this._renderer.device.createShaderModule(vsmDesc);\n\n        // Fragment shader\n        const fsmDesc = {\n            code: trianglesFragmentSource,\n        };\n        this._fragModule = this._renderer.device.createShaderModule(fsmDesc);\n    }\n\n    /**\n     * Allocates GPU vertex and index buffers sized for the current mesh.\n     *\n     * Buffer sizes are derived directly from the current lengths of the mesh's\n     * typed arrays. The buffers are created with copy destinations so their\n     * contents can be uploaded later by {@link updateVertexBuffers}.\n     *\n     * @param mesh Vector layer whose typed-array lengths determine buffer sizes.\n     * @returns Creates GPU buffers for all per-vertex attributes and indices.\n     */\n    createVertexBuffers(mesh: VectorLayer): void {\n        // vertex data\n        this._positionBuffer = this._renderer.device.createBuffer({\n            label: 'Position buffer',\n            size: mesh.position.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._thematicBuffer = this._renderer.device.createBuffer({\n            label: 'Thematic data buffer',\n            size: mesh.thematic.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        this._thematicValidityBuffer = this._renderer.device.createBuffer({\n            label: 'Thematic validity buffer',\n            size: mesh.thematicValidity.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._highlightedBuffer = this._renderer.device.createBuffer({\n            label: 'Highlighted data buffer',\n            size: mesh.highlightedVertices.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._skippedBuffer = this._renderer.device.createBuffer({\n            label: 'Skipped data buffer',\n            size: mesh.skippedVertices.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Primitive indices buffer',\n            size: mesh.indices.length * 4,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    /**\n     * Uploads the current mesh data into the pipeline's GPU buffers.\n     *\n     * This method reuses cached CPU-side typed arrays when possible via the\n     * base pipeline sync helpers, then writes the synchronized data into the\n     * corresponding GPU buffers. It assumes the buffers have already been\n     * created with sizes compatible with the current mesh data.\n     *\n     * @param mesh Vector layer providing the latest position, thematic,\n     * thematic-validity, highlight, skip, and index arrays.\n     * @returns Updates the GPU buffer contents in place.\n     */\n    updateVertexBuffers(mesh: VectorLayer): void {\n        this._positionData = this._syncFloatData(this._positionData, mesh.position);\n        this._thematicData = this._syncFloatData(this._thematicData, mesh.thematic);\n        this._thematicValidityData = this._syncFloatData(this._thematicValidityData, mesh.thematicValidity);\n        this._highlightedData = this._syncFloatData(this._highlightedData, mesh.highlightedVertices);\n        this._skippedData = this._syncFloatData(this._skippedData, mesh.skippedVertices);\n        this._indicesData = this._syncUintData(this._indicesData, mesh.indices);\n\n        this._renderer.device.queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        this._renderer.device.queue.writeBuffer(this._thematicBuffer, 0, this._thematicData);\n        this._renderer.device.queue.writeBuffer(this._thematicValidityBuffer, 0, this._thematicValidityData);\n        this._renderer.device.queue.writeBuffer(this._highlightedBuffer, 0, this._highlightedData);\n        this._renderer.device.queue.writeBuffer(this._skippedBuffer, 0, this._skippedData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n    }\n\n    /**\n     * Creates the WebGPU render pipeline used to draw the triangle mesh.\n     *\n     * The pipeline defines the vertex buffer layouts expected by the shaders,\n     * configures alpha blending, uses a triangle-list primitive topology, and\n     * binds the render-info and camera uniform group layouts inherited from the\n     * base pipeline.\n     *\n     * @returns Creates and stores the render pipeline state object.\n     */\n    createPipeline(): void {\n        // Vertex data\n        const positionAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 0, // [[location(0)]]\n            offset: 0,\n            format: 'float32x2',\n        };\n        const thematicAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 1, // [[location(1)]]\n            offset: 0,\n            format: 'float32',\n        };\n        const highlightedAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 2, // [[location(2)]]\n            offset: 0,\n            format: 'float32',\n        };\n        const thematicValidityAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 3,\n            offset: 0,\n            format: 'float32',\n        };\n        const skippedAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 4, // [[location(4)]]\n            offset: 0,\n            format: 'float32',\n        };\n\n\n        const positionBufferDesc: GPUVertexBufferLayout = {\n            attributes: [positionAttribDesc],\n            arrayStride: 4 * 2, // sizeof(float) * 2\n            stepMode: 'vertex',\n        };\n        const thematicBufferDesc: GPUVertexBufferLayout = {\n            attributes: [thematicAttribDesc],\n            arrayStride: 4 * 1, // sizeof(float) * 3\n            stepMode: 'vertex',\n        };\n        const highlightedBufferDesc: GPUVertexBufferLayout = {\n            attributes: [highlightedAttribDesc],\n            arrayStride: 4 * 1, // sizeof(float) * 3\n            stepMode: 'vertex',\n        };\n        const thematicValidityBufferDesc: GPUVertexBufferLayout = {\n            attributes: [thematicValidityAttribDesc],\n            arrayStride: 4 * 1,\n            stepMode: 'vertex',\n        };\n        const skippedBufferDesc: GPUVertexBufferLayout = {\n            attributes: [skippedAttribDesc],\n            arrayStride: 4 * 1, // sizeof(float) * 3\n            stepMode: 'vertex',\n        };\n\n        // Vertex Shader\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [positionBufferDesc, thematicBufferDesc, highlightedBufferDesc, thematicValidityBufferDesc, skippedBufferDesc],\n        };\n\n        // Fragment Shader\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [\n                {\n                    format: this._renderer.canvasFormat,\n                    blend: {\n                        color: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha',\n                        },\n                        alpha: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha'\n                        },\n                    },\n                },\n            ],\n        };\n\n        // Rasterization\n        const primitive: GPUPrimitiveState = {\n            frontFace: 'cw',\n            cullMode: 'none',\n            topology: 'triangle-list',\n        };\n\n        // Antialising\n        const multisample: GPUMultisampleState = {\n            count: this._renderer.sampleCount,\n        };\n\n        // Depth test\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: false,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n\n        // Uniform Data\n        const pipelineLayoutDesc = {\n            bindGroupLayouts: [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout],\n        };\n\n        // Pipeline\n        const layout = this._renderer.device.createPipelineLayout(pipelineLayoutDesc);\n        const pipelineDesc: GPURenderPipelineDescriptor = {\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            multisample,\n            label: 'Pipeline triangle flat',\n        };\n        this._pipeline = this._renderer.device.createRenderPipeline(pipelineDesc);\n    }\n\n    /**\n     * Records draw commands for this pipeline into a render pass.\n     *\n     * The method updates camera uniforms for the current frame, binds the\n     * pipeline, vertex buffers, index buffer, and uniform bind groups, and\n     * issues an indexed draw only when the index buffer contains at least one\n     * element.\n     *\n     * @param camera Camera whose current view and projection state is uploaded\n     * before drawing.\n     * @param passEncoder Active render pass encoder that receives the draw\n     * commands for this pipeline.\n     * @returns Records an indexed draw for the current mesh when indices are available.\n     */\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        // sets the current pipeline\n        passEncoder.setPipeline(this._pipeline);\n\n        // updates camera\n        this.updateCameraUniforms(camera);\n\n        // sets the vertex buffers\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._thematicBuffer);\n        passEncoder.setVertexBuffer(2, this._highlightedBuffer);\n        passEncoder.setVertexBuffer(3, this._thematicValidityBuffer);\n        passEncoder.setVertexBuffer(4, this._skippedBuffer);\n\n        // sets primitive indices buffer\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n\n        // sets the uniform buffers\n        passEncoder.setBindGroup(0, this._renderInfoBindGroup);\n        passEncoder.setBindGroup(1, this._cameraBindGroup);\n\n        // draw command\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0) { passEncoder.drawIndexed(indexCount); }\n    }\n\n}\n","export default \"@group(0) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(0) @binding(1) var<uniform> projection: mat4x4f;\\n@group(0) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct VSOut {\\n    @builtin(position) position: vec4<f32>,\\n    @location(0) color: vec3<f32>,\\n };\\n\\n@vertex\\nfn main(@builtin(vertex_index) i: u32, @location(0) inPosition: vec2f, @location(1) objectId: vec3<f32>) -> VSOut {\\n    var vsOut: VSOut;\\n    vsOut.position = projection * modelView * vec4f(inPosition.x, inPosition.y, zIndex, 1);\\n    vsOut.color = objectId;\\n\\n    return vsOut;\\n}\";","export default \"@fragment\\nfn main(@location(0) color: vec3<f32>) -> @location(0) vec4<f32> {\\n    return vec4<f32>(color, 1.0);\\n}\";","export default \"@group(0) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(0) @binding(1) var<uniform> projection: mat4x4f;\\n@group(0) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct TerrainUniform {\\n    heightOriginCell: vec4<f32>,\\n    heightDimsEnabled: vec4<f32>,\\n};\\n\\n@group(1) @binding(0) var<uniform> terrain: TerrainUniform;\\n@group(1) @binding(1) var terrainHeightTexture: texture_2d<f32>;\\n\\nstruct VSOut {\\n    @builtin(position) position: vec4<f32>,\\n    @location(0) color: vec3<f32>,\\n };\\n\\nfn terrainHeight(xy: vec2<f32>) -> f32 {\\n    if (terrain.heightDimsEnabled.z < 0.5) {\\n        return 0.0;\\n    }\\n\\n    let origin = terrain.heightOriginCell.xy;\\n    let cellSize = terrain.heightOriginCell.zw;\\n    let dims = vec2<i32>(i32(terrain.heightDimsEnabled.x), i32(terrain.heightDimsEnabled.y));\\n    let texel = clamp((xy - origin) / cellSize, vec2<f32>(0.0), vec2<f32>(f32(dims.x - 2), f32(dims.y - 2)));\\n    let base = vec2<i32>(floor(texel));\\n    let blend = fract(texel);\\n    let h00 = textureLoad(terrainHeightTexture, base, 0).r;\\n    let h10 = textureLoad(terrainHeightTexture, base + vec2<i32>(1, 0), 0).r;\\n    let h01 = textureLoad(terrainHeightTexture, base + vec2<i32>(0, 1), 0).r;\\n    let h11 = textureLoad(terrainHeightTexture, base + vec2<i32>(1, 1), 0).r;\\n\\n    return mix(mix(h00, h10, blend.x), mix(h01, h11, blend.x), blend.y);\\n}\\n\\n@vertex\\nfn main(@location(0) inPosition: vec3f, @location(1) objectId: vec3<f32>) -> VSOut {\\n    var vsOut: VSOut;\\n    let terrainZ = terrainHeight(inPosition.xy);\\n    vsOut.position = projection * modelView * vec4f(inPosition.x, inPosition.y, inPosition.z + terrainZ + zIndex, 1);\\n    vsOut.color = objectId;\\n\\n    return vsOut;\\n}\";","/**\n * @module PipelineTrianglePicking\n * Picking render pipeline for triangle-based vector layers.\n *\n * This module defines `PipelineTrianglePicking`, a WebGPU pipeline that renders\n * triangle geometry into the renderer's picking target instead of the visible\n * color buffer. Each component is encoded as a unique RGB value so the picking\n * system can recover the hit component from the rendered pixel color. The\n * pipeline supports both 2D triangle layers and 3D triangle geometry such as\n * buildings by switching between 2-component and 3-component vertex layouts.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport pickingVertexSource from './shaders/picking.vert.wgsl';\nimport pickingFragmentSource from './shaders/picking.frag.wgsl';\nimport picking3dTerrainVertexSource from './shaders/picking-3d-terrain.vert.wgsl';\n\nimport { Camera } from '@urban-toolkit/autk-core';\nimport { Renderer } from './renderer';\nimport { Pipeline } from './pipeline';\nimport { VectorLayer } from './layer-vector';\nimport type { Heightfield } from '@urban-toolkit/autk-core';\n\n/**\n * Picking pipeline for triangle-based vector geometry.\n *\n * `PipelineTrianglePicking` renders mesh components into the picking framebuffer\n * using per-vertex encoded identifiers instead of display colors. The rendered\n * output is used by higher-level picking logic to map a pixel hit back to a\n * layer component. The pipeline can be configured for either 2D triangle data\n * (`xy`) or 3D triangle data (`xyz`).\n */\nexport class PipelineTrianglePicking extends Pipeline {\n    /** Vertex position buffer for the current mesh. */\n    private _positionBuffer!: GPUBuffer;\n\n    /** Per-vertex encoded component-id colors used by the picking pass. */\n    private _objectIdsBuffer!: GPUBuffer;\n\n    /** Triangle index buffer for indexed drawing. */\n    private _indicesBuffer!: GPUBuffer;\n\n    /** Render pipeline used for the picking pass. */\n    private _pipeline!: GPURenderPipeline;\n\n    /** Vertex shader module for 2D or 3D picking geometry. */\n    protected _vertModule!: GPUShaderModule;\n\n    /** Fragment shader module that writes encoded picking colors. */\n    protected _fragModule!: GPUShaderModule;\n\n    /** Vertex component count: `2` for `xy` data, `3` for `xyz` data. */\n    private _dimension: number;\n    /** Uniform buffer describing the active terrain heightfield for 3D picking. */\n    private _terrainUniformBuffer?: GPUBuffer;\n    /** Bind group layout for terrain height uniforms and texture sampling. */\n    private _terrainBindGroupLayout?: GPUBindGroupLayout;\n    /** Bind group containing the active or dummy terrain height source. */\n    private _terrainBindGroup?: GPUBindGroup;\n    /** Fallback height texture used when terrain mode is disabled. */\n    private _dummyTerrainTexture?: GPUTexture;\n    /** Reused CPU-side terrain uniform upload buffer. */\n    private _terrainUniformData = new Float32Array(8);\n\n    /** Reused CPU-side upload buffer for positions. */\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for indices. */\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for encoded component-id colors. */\n    private _objectIdsData: Float32Array<ArrayBuffer> | null = null;\n\n    /**\n     * Creates a triangle picking pipeline.\n     *\n     * The `dimension` controls which vertex shader is used and how position\n     * data is interpreted when vertex buffers are created and uploaded.\n     *\n     * @param renderer Renderer that owns the WebGPU device and picking targets.\n     * @param dimension Vertex component count. Use `2` for planar triangle\n     * layers and `3` for 3D triangle geometry.\n     */\n    constructor(renderer: Renderer, dimension: number = 2) {\n        super(renderer);\n        this._dimension = dimension;\n    }\n\n    /**\n     * Releases GPU resources owned by this pipeline.\n     *\n     * @returns Destroys the pipeline's vertex and index buffers, then delegates\n     * to the base pipeline cleanup.\n     */\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._objectIdsBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._terrainUniformBuffer?.destroy();\n        this._dummyTerrainTexture?.destroy();\n        super.destroy();\n    }\n\n    /**\n     * Initializes GPU resources for a triangle layer.\n     *\n     * This creates shader modules, allocates GPU buffers sized for the provided\n     * layer, uploads the current mesh data, and creates the render pipeline used\n     * by subsequent picking passes.\n     *\n     * @param mesh Vector layer that provides triangle positions, indices, and\n     * component ranges.\n     * @returns Prepares the pipeline for rendering picking passes for `mesh`.\n     */\n    build(mesh: VectorLayer): void {\n        this.createShaders();\n\n        this.createVertexBuffers(mesh);\n        this.createCameraUniformBindGroup();\n        if (this._dimension === 3) {\n            this.createTerrainHeightBindGroup();\n        }\n        this.updateVertexBuffers(mesh);\n\n        this.createPipeline();\n    }\n\n    /**\n     * Creates the shader modules used by the picking pipeline.\n     *\n     * The vertex shader source depends on the configured vertex dimension. The\n     * fragment shader always writes encoded picking colors.\n     *\n     * @returns Creates and stores the WebGPU shader modules on this instance.\n     */\n    createShaders(): void {\n        // Vertex shader\n        const vsmDesc = {\n            code: this._dimension === 3 ? picking3dTerrainVertexSource : pickingVertexSource,\n        };\n        this._vertModule = this._renderer.device.createShaderModule(vsmDesc);\n\n        // Fragment shader\n        const fsmDesc = {\n            code: pickingFragmentSource,\n        };\n        this._fragModule = this._renderer.device.createShaderModule(fsmDesc);\n    }\n\n    /**\n     * Allocates GPU buffers for the provided layer geometry.\n     *\n     * Buffer sizes are derived from the current layer's position and index\n     * arrays, and from the configured vertex dimension used to derive the number\n     * of vertices.\n     *\n     * @param mesh Vector layer that provides the triangle positions and indices.\n     * @returns Creates empty GPU buffers ready to receive uploaded mesh data.\n     */\n    createVertexBuffers(mesh: VectorLayer): void {\n        this._positionBuffer = this._renderer.device.createBuffer({\n            label: 'Position buffer',\n            size: mesh.position.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        this._objectIdsBuffer = this._renderer.device.createBuffer({\n            label: 'Object id buffer',\n            size: (mesh.position.length / this._dimension) * 3 * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Primitive indices buffer',\n            size: mesh.indices.length * 4,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    /**\n     * Creates terrain height bindings for 3D picking.\n     *\n     * @returns Nothing. A dummy flat height source is bound initially.\n     * @throws If GPU buffer, texture, or bind group creation fails.\n     * @example\n     * pipeline.createTerrainHeightBindGroup();\n     */\n    createTerrainHeightBindGroup(): void {\n        this._terrainUniformBuffer = this._renderer.device.createBuffer({\n            label: 'Picking terrain height uniform',\n            size: 8 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n        this._dummyTerrainTexture = this._renderer.device.createTexture({\n            label: 'Picking dummy terrain height texture',\n            size: [2, 2],\n            format: 'r32float',\n            usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n        });\n        this._terrainBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            label: 'Picking terrain height bind group layout',\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },\n                { binding: 1, visibility: GPUShaderStage.VERTEX, texture: { sampleType: 'unfilterable-float' } },\n            ],\n        });\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Picking terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: this._dummyTerrainTexture.createView() },\n            ],\n        });\n        this.clearTerrainHeightSource();\n    }\n\n    /**\n     * Binds a heightfield texture used to offset 3D picking geometry.\n     *\n     * @param source Heightfield metadata used by the vertex shader.\n     * @param heightTextureView GPU texture view containing height samples.\n     * @returns Nothing. Calls are ignored before terrain bindings are created.\n     * @throws If bind group creation fails.\n     * @example\n     * pipeline.setTerrainHeightSource(heightfield, terrainHeightTextureView);\n     */\n    setTerrainHeightSource(source: Heightfield, heightTextureView: GPUTextureView): void {\n        if (!this._terrainUniformBuffer || !this._terrainBindGroupLayout) {\n            return;\n        }\n\n        this._terrainUniformData.set([\n            source.originX,\n            source.originY,\n            source.cellSizeX,\n            source.cellSizeY,\n            source.width,\n            source.height,\n            1,\n            0,\n        ]);\n        this._renderer.device.queue.writeBuffer(this._terrainUniformBuffer, 0, this._terrainUniformData);\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Picking terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: heightTextureView },\n            ],\n        });\n    }\n\n    /**\n     * Restores the dummy flat height source for 3D picking.\n     *\n     * @returns Nothing. Calls are ignored before terrain bindings are created.\n     * @throws If bind group creation fails.\n     * @example\n     * pipeline.clearTerrainHeightSource();\n     */\n    clearTerrainHeightSource(): void {\n        if (!this._terrainUniformBuffer || !this._terrainBindGroupLayout || !this._dummyTerrainTexture) {\n            return;\n        }\n\n        this._terrainUniformData.fill(0);\n        this._terrainUniformData[4] = 2;\n        this._terrainUniformData[5] = 2;\n        this._renderer.device.queue.writeBuffer(this._terrainUniformBuffer, 0, this._terrainUniformData);\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Picking terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: this._dummyTerrainTexture.createView() },\n            ],\n        });\n    }\n\n    /**\n     * Uploads mesh data and per-component picking colors to the GPU.\n     *\n     * Position and index buffers are synchronized directly from the layer. The\n     * object-id buffer is rebuilt by walking the layer's component triangle\n     * ranges and assigning the same encoded RGB identifier to every vertex index\n     * referenced by triangles in that component. Identifier `0` is reserved for\n     * \"no hit\", so encoded component ids start at `1`.\n     *\n     * @param layer Vector layer that provides positions, indices, and component\n     * triangle boundaries.\n     * @returns Updates the pipeline's GPU buffers in place for the current layer state.\n     */\n    updateVertexBuffers(layer: VectorLayer): void {\n        this._positionData = this._syncFloatData(this._positionData, layer.position);\n        this._indicesData = this._syncUintData(this._indicesData, layer.indices);\n\n        this._renderer.device.queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n\n        // Prepare per-vertex object IDs\n        const numVertices = layer.position.length / this._dimension;\n        this._objectIdsData = this._syncFloatLength(this._objectIdsData, numVertices * 3);\n        this._objectIdsData.fill(0);\n\n        for (let compId = 0; compId < layer.components.length; compId++) {\n            const color = this._encodeIdToRGB(compId);\n            const comp = layer.components[compId];\n\n            const sTri = compId > 0 ? layer.components[compId - 1].nTriangles : 0;\n            const eTri = comp.nTriangles;\n\n            for (let t = sTri * 3; t < eTri * 3; t++) {\n                const vertexIndex = layer.indices[t];\n                const base = vertexIndex * 3;\n                this._objectIdsData[base + 0] = color[0];\n                this._objectIdsData[base + 1] = color[1];\n                this._objectIdsData[base + 2] = color[2];\n            }\n        }\n\n        this._renderer.device.queue.writeBuffer(this._objectIdsBuffer, 0, this._objectIdsData);\n    }\n\n    /**\n     * Encodes a component id as a normalized RGB picking color.\n     *\n     * The encoded value is offset by one so the all-zero color remains reserved\n     * for pixels where no geometry was hit.\n     *\n     * @param id Zero-based component identifier.\n     * @returns Three normalized color channels representing the encoded id.\n     */\n    private _encodeIdToRGB(id: number): [number, number, number] {\n        const shifted = id + 1; // reserve 0 for \"no hit\"\n        const r = (shifted & 0xff) / 255;\n        const g = ((shifted >> 8) & 0xff) / 255;\n        const b = ((shifted >> 16) & 0xff) / 255;\n        return [r, g, b];\n    }\n\n    /**\n     * Creates the WebGPU render pipeline for triangle picking.\n     *\n     * The pipeline uses two vertex buffers: positions and encoded picking\n     * colors. It renders into the renderer's `rgba8unorm` picking target and\n     * shares the camera bind group layout defined by the base pipeline.\n     *\n     * @returns Creates and stores the render pipeline used by `renderPass`.\n     */\n    private createPipeline(): void {\n        const positionAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 0,\n            offset: 0,\n            format: this._dimension === 3 ? 'float32x3' : 'float32x2',\n        };\n        const idAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 1, // [[location(1)]]\n            offset: 0,\n            format: 'float32x3',\n        };\n\n        const positionBufferDesc: GPUVertexBufferLayout = {\n            attributes: [positionAttribDesc],\n            arrayStride: 4 * this._dimension,\n            stepMode: 'vertex',\n        };\n\n        const idBufferDesc: GPUVertexBufferLayout = {\n            attributes: [idAttribDesc],\n            arrayStride: 4 * 3,\n            stepMode: 'vertex',\n        };\n\n        // Vertex Shader\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [positionBufferDesc, idBufferDesc],\n        };\n\n        // Fragment Shader\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [\n                {\n                    format: 'rgba8unorm',\n                },\n            ],\n        };\n\n        // Rasterization\n        const primitive: GPUPrimitiveState = {\n            frontFace: 'cw',\n            cullMode: 'none',\n            topology: 'triangle-list',\n        };\n\n        // Depth test\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: true,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n\n        // Uniform Data\n        const pipelineLayoutDesc = {\n            bindGroupLayouts: this._dimension === 3\n                ? [this._cameraBindGroupLayout, this._terrainBindGroupLayout!]\n                : [this._cameraBindGroupLayout],\n        };\n\n        // Pipeline\n        const layout = this._renderer.device.createPipelineLayout(pipelineLayoutDesc);\n        const pipelineDesc: GPURenderPipelineDescriptor = {\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            label: 'Pipeline triangle picking',\n        };\n        this._pipeline = this._renderer.device.createRenderPipeline(pipelineDesc);\n    }\n\n    /**\n     * Renders this layer into the picking framebuffer.\n     *\n     * The pass uses the renderer's dedicated picking color and depth targets,\n     * updates camera uniforms for the supplied view, and issues an indexed draw\n     * only when the index buffer contains data. The optional pass encoder\n     * parameter is ignored because this method creates and completes its own\n     * render pass.\n     *\n     * @param camera Camera providing the current view and projection uniforms.\n     * @param _passEncoder Unused external pass encoder.\n     * @returns Records a picking render pass on the renderer's current command encoder.\n     */\n    renderPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        if (!this._renderer) {\n            return;\n        }\n\n        const ownsPass = !passEncoder;\n        passEncoder ??= this._renderer.commandEncoder.beginRenderPass({\n            colorAttachments: [this._renderer.pickingBuffer],\n            depthStencilAttachment: this._renderer.pickingDepthBuffer,\n        });\n\n        // sets the current pipeline\n        passEncoder.setPipeline(this._pipeline);\n\n        // updates camera\n        this.updateCameraUniforms(camera);\n\n        // sets the vertex buffers\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._objectIdsBuffer);\n\n        // sets primitive indices buffer\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n\n        // sets the uniform buffers\n        passEncoder.setBindGroup(0, this._cameraBindGroup);\n        if (this._dimension === 3 && this._terrainBindGroup) {\n            passEncoder.setBindGroup(1, this._terrainBindGroup);\n        }\n\n        // draw command\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0) { passEncoder.drawIndexed(indexCount); }\n        if (ownsPass) {\n            passEncoder.end();\n        }\n    }\n\n}\n","/**\n * @module VectorLayer\n * Base implementation for renderable vector layers.\n *\n * This module defines `VectorLayer`, an abstract `Layer` subclass that stores\n * flattened vector geometry, per-feature thematic values, and interaction state\n * used for highlighting, skipping, and picking. It also owns the shared GPU\n * pipeline setup used by triangle-based vector rendering passes.\n */\n\nimport { Camera, LayerComponent, LayerGeometry } from '@urban-toolkit/autk-core';\n\nimport {\n    LayerData, \n    LayerInfo, \n    LayerRenderInfo, \n    LayerThematic \n} from './types-layers';\n\nimport { Layer } from './layer';\n\nimport { Renderer } from './renderer';\n\nimport { Pipeline } from './pipeline';\nimport { PipelineTriangleFlat } from './pipeline-triangle-flat';\nimport { PipelineTrianglePicking } from './pipeline-triangle-picking';\n\n/**\n * Abstract base class for vector-backed map layers.\n *\n * `VectorLayer` stores merged geometry buffers, cumulative component metadata,\n * per-vertex thematic values, and interaction masks used by rendering and\n * picking pipelines. Concrete subclasses supply layer-specific semantics while\n * reusing the shared logic for loading flattened geometry, maintaining\n * highlight/skip state, and issuing draw passes.\n */\nexport abstract class VectorLayer extends Layer {\n    /** Vertex dimension used by the position buffer. */\n    protected _dimension: number;\n\n    /** Flattened vertex position buffer. */\n    protected _position!: Float32Array;\n\n    /** Per-vertex thematic values used for color mapping. */\n    protected _thematic!: Float32Array;\n\n    /** Per-vertex validity mask for thematic values. */\n    protected _thematicValidity!: Float32Array;\n\n    /** Triangle index buffer into {@link _position}. */\n    protected _indices!: Uint32Array;\n\n    /** Cumulative component ranges aligned with source features. */\n    protected _components: LayerComponent[] = [];\n\n    /** Component ids currently marked as highlighted. */\n    protected _highlightedIds!: Set<number>;\n\n    /** Per-vertex highlight mask. */\n    protected _highlightedVertices!: Float32Array;\n\n    /** Component ids currently marked as skipped. */\n    protected _skippedIds!: Set<number>;\n\n    /** Per-vertex skip mask. */\n    protected _skippedVertices!: Float32Array;\n\n    /** Primary triangle-rendering pipeline. */\n    protected _pipeline!: Pipeline;\n\n    /** Off-screen triangle-picking pipeline. */\n    protected _pipelinePicking!: Pipeline;\n\n    /** Number of vertices in the position buffer. */\n    protected get _vertexCount(): number {\n        return this._position.length / this._dimension;\n    }\n\n    /**\n     * Creates a vector layer and loads its initial buffers.\n     *\n     * Construction immediately flattens the provided geometry and component\n     * metadata into layer-local buffers and resets any interaction state. The\n     * optional thematic payload is loaded only when entries are present.\n     *\n     * @param layerInfo Static layer metadata such as id, type, and z-index.\n     * @param layerRenderInfo Render configuration used by shared layer pipelines.\n     * @param layerData Initial geometry, component, and optional thematic data.\n     * @param dimension Number of coordinates stored per vertex. Use `2` for planar layers and `3` for layers with explicit elevation.\n     */\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData, dimension: number = 2) {\n        super(layerInfo, layerRenderInfo);\n\n        this._dimension = dimension;\n        this.loadLayerData(layerData);\n    }\n\n    /** Indicates that vector layers participate in picking passes. */\n    get supportsPicking(): boolean { return true; }\n\n    /** Indicates that vector layers support per-feature highlighting. */\n    get supportsHighlight(): boolean { return true; }\n\n    /** Flattened vertex position buffer. */\n    get position(): Float32Array {\n        return this._position;\n    }\n\n    /** Per-vertex thematic values aligned with {@link position}. */\n    get thematic(): Float32Array {\n        return this._thematic;\n    }\n\n    /** Per-vertex thematic validity mask aligned with {@link thematic}. */\n    get thematicValidity(): Float32Array {\n        return this._thematicValidity;\n    }\n\n    /** Triangle index buffer referencing vertices in {@link position}. */\n    get indices(): Uint32Array {\n        return this._indices;\n    }\n\n    /** Cumulative component ranges aligned with the source feature order. */\n    get components(): LayerComponent[] {\n        return this._components;\n    }\n\n    /** Highlighted component ids as an array snapshot. */\n    get highlightedIds(): number[] {\n        return Array.from(this._highlightedIds);\n    }\n\n    /** Per-vertex highlight mask uploaded to rendering pipelines. */\n    get highlightedVertices(): Float32Array {\n        return this._highlightedVertices;\n    }\n\n    /** Skipped component ids as an array snapshot. */\n    get skippedIds(): number[] {\n        return Array.from(this._skippedIds);\n    }\n\n    /** Per-vertex skip mask uploaded to rendering pipelines. */\n    get skippedVertices(): Float32Array {\n        return this._skippedVertices;\n    }\n\n    /**\n     * Replaces the layer's geometry, component metadata, and optional thematic data.\n     *\n     * Geometry and components are always reloaded together and reset highlight\n     * and skip state, because component-to-vertex alignment may change. Thematic\n     * data is loaded only when a non-empty thematic array is provided.\n     *\n     * @param layerData Layer payload containing geometry, components, and optional thematic values.\n     * @returns Updates the layer's in-memory buffers and interaction masks.\n     */\n    loadLayerData(layerData: LayerData): void {\n        this.loadGeometry(layerData.geometry);\n        this.loadComponent(layerData.components);\n        this._resetInteractionState();\n\n        if (layerData.thematic && layerData.thematic.length) {\n            this.loadThematic(layerData.thematic);\n        }\n    }\n\n    /**\n     * Flattens component geometry into shared position and index buffers.\n     *\n     * Positions from all geometries are concatenated in input order. When an\n     * individual geometry provides indices, they are re-based to the current\n     * accumulated vertex offset before being appended to the shared index buffer.\n     *\n     * @param layerGeometry Geometry records to merge into contiguous buffers.\n     * @returns Updates {@link position} and {@link indices} in place for subsequent rendering.\n     */\n    loadGeometry(layerGeometry: LayerGeometry[]): void {\n        let totalVerts = 0;\n        let totalIndices = 0;\n        for (const g of layerGeometry) {\n            totalVerts += g.position.length;\n            totalIndices += (g.indices?.length ?? 0);\n        }\n\n        const position = new Float32Array(totalVerts);\n        const indices = new Uint32Array(totalIndices);\n\n        let vOffset = 0;\n        let iOffset = 0;\n        let vertexCount = 0;\n\n        for (let id = 0; id < layerGeometry.length; id++) {\n            const g = layerGeometry[id];\n            \n            position.set(g.position, vOffset);\n\n            if (g.indices) {\n                for (let i = 0; i < g.indices.length; i++) {\n                    indices[iOffset + i] = g.indices[i] + vertexCount;\n                }\n                iOffset += g.indices.length;\n            }\n\n            const vertsAdded = g.position.length / this._dimension;\n            vOffset += g.position.length;\n            vertexCount += vertsAdded;\n        }\n\n        this._position = position;\n        this._indices = indices;\n    }\n\n    /**\n     * Loads cumulative component ranges for feature-level addressing.\n     *\n     * Input components are converted into cumulative point and triangle counts.\n     * This lets the layer resolve feature-local ranges when applying thematic\n     * values or interaction masks by component id.\n     *\n     * @param layerComponents Per-feature component metadata in source order.\n     * @returns Replaces the component table used for thematic aggregation and interaction updates.\n     */\n    loadComponent(layerComponents: LayerComponent[]): void {\n        this._components = [];\n\n        const accum = { nPoints: 0, nTriangles: 0 };\n        for (let cId = 0; cId < layerComponents.length; cId++) {\n            const comp = layerComponents[cId];\n\n            accum.nPoints += comp.nPoints;\n            accum.nTriangles += comp.nTriangles;\n\n            this._components.push({\n                nPoints: accum.nPoints,\n                nTriangles: accum.nTriangles,\n                featureIndex: comp.featureIndex,\n                featureId: comp.featureId,\n            });\n        }\n    }\n\n    /**\n     * Expands per-component thematic values into per-vertex buffers.\n     *\n     * Thematic input must contain exactly one entry per loaded component. Each\n     * component value is repeated across all vertices belonging to that\n     * component, and a parallel validity mask is generated from\n     * `LayerThematic.valid`. On mismatch or incomplete filling, the method logs\n     * an error and leaves the existing thematic buffers unchanged.\n     *\n     * @param layerThematic Thematic entries aligned one-to-one with {@link components}.\n     * @returns `true` when both thematic buffers were rebuilt successfully; otherwise `false`.\n     */\n    loadThematic(layerThematic: LayerThematic[]): boolean {\n        if (layerThematic.length !== this._components.length) {\n            console.error(\n                `VectorLayer.loadThematic: expected ${this._components.length} thematic entries, got ${layerThematic.length}.`\n            );\n            return false;\n        }\n\n        const thematic = new Float32Array(this._vertexCount);\n        const thematicValidity = new Float32Array(this._vertexCount);\n\n        let offset = 0;\n        for (let compId = 0; compId < layerThematic.length; compId++) {\n            const aggr = this.aggregateThematicComponent(compId, layerThematic[compId]);\n            thematic.set(aggr.value, offset);\n            thematicValidity.set(aggr.valid, offset);\n            offset += aggr.value.length;\n        }\n\n        if (offset !== this._vertexCount) {\n            console.error(\n                `VectorLayer.loadThematic: filled ${offset} thematic values for ${this._vertexCount} vertices.`\n            );\n            return false;\n        }\n\n        this._thematic = thematic;\n        this._thematicValidity = thematicValidity;\n        return true;\n    }\n\n    /**\n     * Builds the render and picking pipelines for this layer.\n     *\n     * The primary pipeline renders the visible vector pass, and the picking\n     * pipeline renders the same geometry into the off-screen picking target.\n     * Both pipelines are built against the layer's current buffers.\n     *\n     * @param renderer Renderer used to create GPU resources and pipeline state.\n     * @returns Initializes GPU pipelines required for normal rendering and picking.\n     */\n    createPipeline(renderer: Renderer): void {\n        this._pipeline = new PipelineTriangleFlat(renderer);\n        this._pipeline.build(this);\n\n        this._pipelinePicking = new PipelineTrianglePicking(renderer, this._dimension);\n        this._pipelinePicking.build(this);\n    }\n\n    /**\n     * Renders the layer into the active color pass.\n     *\n     * Pending render-info updates refresh color uniforms before drawing. Pending\n     * data updates refresh vertex buffers for both the visible and picking\n     * pipelines so the two passes stay aligned.\n     *\n     * @param camera Camera providing the current view and projection state.\n     * @param passEncoder Active render-pass encoder for the current frame.\n     * @returns Issues draw commands for the layer's visible triangle pass.\n     */\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        if (this._renderInfoIsDirty) {\n            this._pipeline.updateColorUniforms(this);\n            this._renderInfoIsDirty = false;\n        }\n\n        if (this._dataIsDirty) {\n            this._pipeline.updateVertexBuffers(this);\n            this._pipelinePicking.updateVertexBuffers(this);\n            this._dataIsDirty = false;\n        }\n\n        this._pipeline.updateZIndex(this._layerInfo.zIndex);\n        this._pipeline.renderPass(camera, passEncoder);\n    }\n\n    /**\n     * Renders the layer into the picking target.\n     *\n     * This pass uses the dedicated picking pipeline and updates its z-index to\n     * match the visible pass before rendering.\n     *\n     * @param camera Camera providing the current view and projection state.\n     * @returns Issues draw commands for the off-screen picking pass.\n     */\n    renderPickingPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        this._pipelinePicking.updateZIndex(this._layerInfo.zIndex);\n        this._pipelinePicking.renderPass(camera, passEncoder);\n    }\n\n    /**\n     * Toggles highlight state for the specified component ids.\n     *\n     * Each id is toggled independently. The corresponding vertex mask is also\n     * toggled once per unique vertex referenced by the affected components. Ids\n     * outside the current component range are ignored by the vertex update step.\n     *\n     * @param ids Component ids to toggle.\n     * @returns Marks layer render state and GPU data as dirty for the next frame.\n     */\n    toggleHighlightedIds(ids: number[]): void {\n        ids.forEach(id => {\n            if (this._highlightedIds.has(id)) {\n                this._highlightedIds.delete(id);\n            }\n            else {\n                this._highlightedIds.add(id);\n            }\n        });\n\n        this._forEachUniqueVertexInComponents(ids, (vertexIndex) => {\n            this._highlightedVertices[vertexIndex] = 1 - this._highlightedVertices[vertexIndex];\n        });\n\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    /**\n     * Replaces the current highlight selection.\n     *\n     * Existing highlight state is cleared before the new ids are applied. The\n     * highlight mask is then set to `1` for each unique vertex referenced by the\n     * provided component ids.\n     *\n     * @param ids Component ids that should remain highlighted.\n     * @returns Marks layer render state and GPU data as dirty for the next frame.\n     */\n    setHighlightedIds(ids: number[]): void {\n        this.clearHighlightedIds();\n        \n        this._highlightedIds = new Set(ids);\n\n        this._forEachUniqueVertexInComponents(ids, (vertexIndex) => {\n            this._highlightedVertices[vertexIndex] = 1;\n        });\n\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }    \n\n    /**\n     * Toggles skip state for the specified component ids.\n     *\n     * Each id is toggled independently, and the per-vertex skip mask is updated\n     * once per unique vertex referenced by the affected components. This method\n     * does not clear previously skipped ids before applying the toggle.\n     *\n     * @param ids Component ids to toggle in the skip set.\n     * @returns Marks layer render state and GPU data as dirty for the next frame.\n     */\n    setSkippedIds(ids: number[]): void {\n        ids.forEach(id => {\n            if (this._skippedIds.has(id)) {\n                this._skippedIds.delete(id);\n            }\n            else {\n                this._skippedIds.add(id);\n            }\n        });\n\n        this._forEachUniqueVertexInComponents(ids, (vertexIndex) => {\n            this._skippedVertices[vertexIndex] = 1 - this._skippedVertices[vertexIndex];\n        });\n\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    /**\n     * Clears all highlighted component ids and vertex flags.\n     *\n     * @returns Marks layer render state and GPU data as dirty for the next frame.\n     */\n    clearHighlightedIds(): void {\n        this._highlightedVertices.fill(0);\n        this._highlightedIds.clear();\n\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    /**\n     * Clears all skipped component ids and vertex flags.\n     *\n     * @returns Marks layer render state and GPU data as dirty for the next frame.\n     */\n    clearSkippedIds(): void {\n        this._skippedVertices.fill(0);\n        this._skippedIds.clear();\n\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    /**\n     * Releases GPU resources owned by this layer's pipelines.\n     *\n     * @returns Destroys the visible and picking pipelines when they have been created.\n     */\n    override destroy(): void {\n        this._pipeline?.destroy();\n        this._pipelinePicking?.destroy();\n    }\n\n    /**\n     * Expands one component's thematic payload to the component's vertex range.\n     *\n     * Missing thematic values default to `0`, and missing validity flags also\n     * default to `0`.\n     *\n     * @param component Index of the component in the cumulative component table.\n     * @param layerThematic Thematic payload associated with that component.\n     * @returns Object containing per-vertex thematic values and validity flags for the component.\n     */\n    private aggregateThematicComponent(component: number, layerThematic: LayerThematic): { value: Float32Array; valid: Float32Array } {\n        const sPoint = component > 0 ? this._components[component - 1].nPoints : 0;\n        const ePoint = this._components[component].nPoints;\n        const nPoint = ePoint - sPoint;\n\n        const thematic = new Float32Array(nPoint);\n        const thematicValidity = new Float32Array(nPoint);\n        const value = layerThematic.value ?? 0;\n        thematic.fill(value);\n        thematicValidity.fill(layerThematic.valid ?? 0);\n\n        return { value: thematic, valid: thematicValidity };\n    }\n\n    /**\n     * Resets all interaction masks after geometry or component data changes.\n     *\n     * The interaction buffers are rebuilt to match the current vertex count, and\n     * both highlight and skip id sets are cleared.\n     */\n    private _resetInteractionState(): void {\n        this._highlightedVertices = new Float32Array(this._vertexCount).fill(0);\n        this._highlightedIds = new Set<number>();\n        this._skippedVertices = new Float32Array(this._vertexCount).fill(0);\n        this._skippedIds = new Set<number>();\n    }\n\n    /**\n     * Visits each unique indexed vertex referenced by the given components.\n     *\n     * Invalid component ids are ignored. Vertices shared by multiple triangles\n     * or component ids are visited only once.\n     *\n     * @param ids Component ids whose indexed vertices should be traversed.\n     * @param fn Callback invoked once for each unique vertex index.\n     */\n    private _forEachUniqueVertexInComponents(ids: number[], fn: (vertexIndex: number) => void): void {\n        const visited = new Set<number>();\n\n        for (const id of ids) {\n            if (id < 0 || id >= this._components.length) { continue; }\n\n            const sTriangle = id > 0 ? this._components[id - 1].nTriangles : 0;\n            const eTriangle = this._components[id].nTriangles;\n\n            for (let i = 3 * sTriangle; i < 3 * eTriangle; i++) {\n                const vertexIndex = this._indices[i];\n                if (visited.has(vertexIndex)) { continue; }\n                visited.add(vertexIndex);\n                fn(vertexIndex);\n            }\n        }\n    }\n}\n","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct TerrainUniform {\\n    heightOriginCell: vec4<f32>,\\n    heightDimsEnabled: vec4<f32>,\\n};\\n\\n@group(2) @binding(0) var<uniform> terrain: TerrainUniform;\\n@group(2) @binding(1) var terrainHeightTexture: texture_2d<f32>;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4<f32>,\\n    @location(0) outNormal: vec3<f32>,\\n    @location(1) outThematic: f32,\\n    @location(2) outHighlighted: f32,\\n    @location(3) outThematicValid: f32,\\n    @location(4) outSkipped: f32\\n };\\n\\nfn terrainHeight(xy: vec2<f32>) -> f32 {\\n    if (terrain.heightDimsEnabled.z < 0.5) {\\n        return 0.0;\\n    }\\n\\n    let origin = terrain.heightOriginCell.xy;\\n    let cellSize = terrain.heightOriginCell.zw;\\n    let dims = vec2<i32>(i32(terrain.heightDimsEnabled.x), i32(terrain.heightDimsEnabled.y));\\n    let texel = clamp((xy - origin) / cellSize, vec2<f32>(0.0), vec2<f32>(f32(dims.x - 2), f32(dims.y - 2)));\\n    let base = vec2<i32>(floor(texel));\\n    let blend = fract(texel);\\n    let h00 = textureLoad(terrainHeightTexture, base, 0).r;\\n    let h10 = textureLoad(terrainHeightTexture, base + vec2<i32>(1, 0), 0).r;\\n    let h01 = textureLoad(terrainHeightTexture, base + vec2<i32>(0, 1), 0).r;\\n    let h11 = textureLoad(terrainHeightTexture, base + vec2<i32>(1, 1), 0).r;\\n\\n    return mix(mix(h00, h10, blend.x), mix(h01, h11, blend.x), blend.y);\\n}\\n\\n@vertex\\nfn main(@location(0) inPosition: vec3f, @location(1) inNormal: vec3f, @location(2) inThematic: f32, @location(3) inHighlighted: f32, @location(4) inThematicValid: f32, @location(5) inSkipped: f32) -> VSOut {\\n    var vsOut: VSOut;\\n\\n    let terrainZ = terrainHeight(inPosition.xy);\\n    vsOut.outPosition = projection * modelView * vec4f(inPosition.x, inPosition.y, inPosition.z + terrainZ, 1);\\n    vsOut.outNormal = inNormal;\\n    vsOut.outThematic = inThematic;\\n    vsOut.outHighlighted = inHighlighted;\\n    vsOut.outThematicValid = inThematicValid;\\n    vsOut.outSkipped = inSkipped;\\n\\n    return vsOut;\\n}\";","export default \"@group(0) @binding(0) var<uniform> color : vec4f;\\n@group(0) @binding(1) var<uniform> highlightColor : vec4f;\\n@group(0) @binding(2) var<uniform> showThematic : f32;\\n@group(0) @binding(3) var<uniform> showHighlight : f32;\\n@group(0) @binding(4) var cMapTex : texture_2d<f32>;\\n@group(0) @binding(5) var cMapSampler : sampler;\\n@group(0) @binding(6) var<uniform> opacity : f32;\\n@group(0) @binding(7) var<uniform> domainParams : vec4f;\\n@group(0) @binding(8) var<uniform> invalidValueColor : vec4f;\\n\\nstruct BufferOut {\\n    @location(0) color  : vec4f,\\n    @location(1) normal : vec4f,\\n}\\n\\n@fragment\\nfn main(@builtin(position) fragPos: vec4f, @location(0) inNormal: vec3f, @location(1) inThematic: f32, @location(2) inHighlighted: f32, @location(3) inThematicValid: f32, @location(4) inSkipped: f32) -> BufferOut {\\n\\n    if (inSkipped > 0.0) {\\n        discard;\\n    }\\n\\n    \\n    \\n    \\n    var light: vec3f = normalize(vec3f(0.8, 0.5, 1.5));\\n\\n    var normal: vec3f = normalize(inNormal);\\n\\n    var diffuse: f32 = 0.28 * max(dot(normal, light), 0.0);\\n    var ambient: f32 = 0.62;\\n\\n    var color = vec4f(color.r / 255, color.g / 255, color.b / 255, color.a);\\n\\n    var thematicValue = inThematic;\\n    if (domainParams.z > 1.5) {\\n        let nCategories = domainParams.w;\\n        let denom = max(1.0, nCategories - 1.0);\\n        thematicValue = clamp(inThematic / denom, 0.0, 1.0);\\n    } else if (domainParams.z > 0.5) {\\n        let minVal = domainParams.x;\\n        let maxVal = domainParams.y;\\n        let range = maxVal - minVal;\\n        thematicValue = select(0.0, clamp((inThematic - minVal) / range, 0.0, 1.0), range > 0.0);\\n    }\\n\\n    var sampledColor = textureSample(cMapTex, cMapSampler, vec2f(thematicValue, 0.0));\\n\\n    if(showHighlight > 0 && inHighlighted > 0) {\\n        color = vec4f(highlightColor.r / 255, highlightColor.g / 255, highlightColor.b / 255, highlightColor.a);\\n    }\\n    else if (showThematic > 0 && inThematicValid < 0.5) {\\n        color = vec4f(invalidValueColor.r / 255, invalidValueColor.g / 255, invalidValueColor.b / 255, invalidValueColor.a);\\n    }\\n    else if (showThematic > 0) {\\n        color = sampledColor;\\n    }\\n\\n    var shade: vec4f = color * (diffuse + ambient);\\n\\n    var output : BufferOut;\\n    output.color  = vec4f(shade.rgb * opacity, opacity);\\n    \\n    \\n    output.normal = vec4f(normal * 0.5 + 0.5, fragPos.z * 0.998 + 0.001);\\n\\n    return output;\\n}\";","export default \"struct VSOut {\\n    @builtin(position) Position: vec4<f32>,\\n    @location(0) uvs : vec2<f32>,\\n};\\n\\n@vertex \\nfn main(@builtin(vertex_index) VertexIndex : u32) -> VSOut {\\n \\n    var pos = array( \\n        vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0),\\n        vec2(-1.0,  1.0), vec2(1.0, -1.0), vec2( 1.0, 1.0),\\n    );\\n\\n    var vsOut: VSOut;\\n    vsOut.Position = vec4<f32>(pos[VertexIndex], 0.0, 1.0);\\n    vsOut.uvs = (pos[VertexIndex] + 1.0) * 0.5;\\n\\n    return vsOut;\\n}\";","export default \"fn rand(n: f32) -> f32 { return fract(sin(n) * 43758.5453123); }\\n\\n@group(0) @binding(0) var texSampler: sampler;\\n@group(0) @binding(1) var colorTex: texture_2d<f32>;\\n@group(0) @binding(2) var normalTex: texture_2d<f32>;\\n\\n@fragment\\nfn main(@location(0) uvs : vec2<f32>) -> @location(0) vec4f {\\n    var fuvs = vec2f(uvs.x, 1.0 - uvs.y);\\n\\n    var n0tex = textureSample(normalTex, texSampler, fuvs);\\n    var n0    = normalize(n0tex.xyz * 2.0 - 1.0);\\n\\n    \\n    \\n    \\n    let num = 32;\\n    var sss = 0.0;\\n    for(var i: i32 = 0; i < num; i = i + 1)\\n    {\\n        var off = f32(i);\\n        var dd = 0.0003;\\n        if ( i % 5  == 0 ) { dd = 0.001; };\\n        if ( i % 10 == 0 ) { dd = 0.002; };\\n        let sx = (rand(off)        * 2.0 - 1.0) * dd;\\n        let sy = (rand(off*2000.0) * 2.0 - 1.0) * dd;\\n\\n        var n1tex = textureSample(normalTex, texSampler, fuvs + vec2<f32>(sx, sy));\\n\\n        if (n1tex.a > 0.0005) {\\n            var n1 = normalize(n1tex.xyz * 2.0 - 1.0);\\n            sss = sss + dot(n0, n1);\\n        } else {\\n            sss = sss + 1.0;\\n        }\\n    }\\n\\n    let fr = 1.0 / f32(num);\\n    let cc = clamp( (sss * fr), 0.40, 1.0);\\n\\n    let color = textureSample(colorTex, texSampler, fuvs);\\n    var result = cc * color.rgb;\\n\\nreturn vec4<f32>(result, color.a);\\n}\";","export default \"fn rand(n: f32) -> f32 { return fract(sin(n) * 43758.5453123); }\\n\\n@group(0) @binding(0) var texSampler: sampler;\\n@group(0) @binding(1) var colorTex: texture_2d<f32>;\\n@group(0) @binding(2) var normalTex: texture_2d<f32>;\\n@group(0) @binding(3) var terrainDepthTex: texture_depth_2d;\\n@group(0) @binding(4) var buildingDepthTex: texture_depth_2d;\\n\\nfn terrainDepthAt(uv: vec2<f32>) -> f32 {\\n    let dims = vec2<i32>(textureDimensions(terrainDepthTex));\\n    let coords = clamp(vec2<i32>(floor(uv * vec2<f32>(dims))), vec2<i32>(0), dims - vec2<i32>(1));\\n    return textureLoad(terrainDepthTex, coords, 0);\\n}\\n\\nfn buildingDepthAt(uv: vec2<f32>) -> f32 {\\n    let dims = vec2<i32>(textureDimensions(buildingDepthTex));\\n    let coords = clamp(vec2<i32>(floor(uv * vec2<f32>(dims))), vec2<i32>(0), dims - vec2<i32>(1));\\n    return textureLoad(buildingDepthTex, coords, 0);\\n}\\n\\n@fragment\\nfn main(@location(0) uvs : vec2<f32>) -> @location(0) vec4f {\\n    var fuvs = vec2f(uvs.x, 1.0 - uvs.y);\\n\\n    let n0tex = textureSample(normalTex, texSampler, fuvs);\\n    let color = textureSample(colorTex, texSampler, fuvs);\\n    let terrainDepth = terrainDepthAt(fuvs);\\n    let buildingDepth = buildingDepthAt(fuvs);\\n    let visible = color.a > 0.0005 && buildingDepth >= terrainDepth - 0.00001;\\n    let visibleFactor = select(0.0, 1.0, visible);\\n\\n    let n0 = normalize(n0tex.xyz * 2.0 - 1.0);\\n    let num = 32;\\n    var sss = 0.0;\\n    for(var i: i32 = 0; i < num; i = i + 1)\\n    {\\n        var off = f32(i);\\n        var dd = 0.0003;\\n        if ( i % 5  == 0 ) { dd = 0.001; };\\n        if ( i % 10 == 0 ) { dd = 0.002; };\\n        let sx = (rand(off)        * 2.0 - 1.0) * dd;\\n        let sy = (rand(off*2000.0) * 2.0 - 1.0) * dd;\\n\\n        var n1tex = textureSample(normalTex, texSampler, fuvs + vec2<f32>(sx, sy));\\n\\n        if (n1tex.a > 0.0005) {\\n            var n1 = normalize(n1tex.xyz * 2.0 - 1.0);\\n            sss = sss + dot(n0, n1);\\n        } else {\\n            sss = sss + 1.0;\\n        }\\n    }\\n\\n    let fr = 1.0 / f32(num);\\n    let cc = clamp( (sss * fr), 0.40, 1.0);\\n    var result = cc * color.rgb;\\n\\n    return vec4<f32>(result * color.a * visibleFactor, color.a * visibleFactor);\\n}\";","/**\n * @module PipelineBuildingSSAO\n * WebGPU pipeline for rendering building geometry with a shared SSAO pass.\n *\n * This module defines the `PipelineBuildingSSAO` class, which builds the\n * geometry pass for indexed 3D building meshes and the renderer-scoped shared\n * resources used by the SSAO composite pass. It owns the per-instance vertex\n * and index buffers, uploads mesh data into those buffers, and coordinates the\n * two-pass render flow through shared offscreen textures and a fullscreen\n * composite pipeline.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport buildingsVS01 from './shaders/buildings-01.vert.wgsl';\nimport buildingsFS01 from './shaders/buildings-01.frag.wgsl';\n\nimport buildingsVS02 from './shaders/buildings-02.vert.wgsl';\nimport buildingsFS02 from './shaders/buildings-02.frag.wgsl';\nimport buildingsTerrainFS02 from './shaders/buildings-02-terrain.frag.wgsl';\n\nimport { Camera } from '@urban-toolkit/autk-core';\nimport { Renderer } from './renderer';\n\nimport { Pipeline } from './pipeline';\nimport { Triangles3DLayer } from './layer-triangles3D';\nimport type { Heightfield } from '@urban-toolkit/autk-core';\n\ntype SharedSsaoState = {\n    colorsSharedBuffer: GPURenderPassColorAttachment;\n    normalsSharedBuffer: GPURenderPassColorAttachment;\n    depthBufferPass01: GPURenderPassDepthStencilAttachment;\n    colorsSharedTexture: GPUTexture;\n    normalsSharedTexture: GPUTexture;\n    depthTexturePass01: GPUTexture;\n    texSampler: GPUSampler;\n    texturesPass02BindGroup: GPUBindGroup;\n    texturesPass02BindGroupLayout: GPUBindGroupLayout;\n    pipeline02: GPURenderPipeline;\n    terrainCompositeBindGroupLayout: GPUBindGroupLayout;\n    terrainCompositePipeline: GPURenderPipeline;\n    width: number;\n    height: number;\n};\n\n/**\n * Geometry pipeline for 3D building layers and shared SSAO composite helpers.\n *\n * `PipelineBuildingSSAO` renders indexed building meshes in an offscreen\n * geometry pass, stores color and normal outputs in renderer-scoped shared\n * textures, and exposes helpers for the fullscreen SSAO composite pass. The\n * class manages mesh-specific GPU buffers and shader state, while shared\n * textures, sampler state, and the composite pipeline are cached per renderer.\n *\n * @example\n * const pipeline = new PipelineBuildingSSAO(renderer);\n * pipeline.build(buildingMesh);\n */\nexport class PipelineBuildingSSAO extends Pipeline {\n    /** Renderer-scoped shared SSAO state cache. */\n    private static _sharedState = new WeakMap<Renderer, SharedSsaoState>();\n\n    /** GPU vertex buffer containing building positions. */\n    protected _positionBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing building normals. */\n    protected _normalBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing thematic values. */\n    protected _thematicBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing thematic validity flags. */\n    protected _thematicValidityBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing highlighted-vertex flags. */\n    protected _highlightedBuffer!: GPUBuffer;\n    /** GPU vertex buffer containing skipped-vertex flags. */\n    protected _skippedBuffer!: GPUBuffer;\n    /** GPU index buffer defining building triangles. */\n    protected _indicesBuffer!: GPUBuffer;\n\n    /** Compiled vertex shader module for the geometry pass. */\n    protected _vertModule01!: GPUShaderModule;\n    /** Compiled fragment shader module for the geometry pass. */\n    protected _fragModule01!: GPUShaderModule;\n    /** Render pipeline used for the geometry pass. */\n    protected _pipeline01!: GPURenderPipeline;\n\n    /** Reused CPU-side upload buffer for positions. */\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for normals. */\n    private _normalData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for thematic values. */\n    private _thematicData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for thematic validity flags. */\n    private _thematicValidityData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for highlight flags. */\n    private _highlightedData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for skip flags. */\n    private _skippedData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for triangle indices. */\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    /** Uniform buffer describing the active terrain heightfield for buildings. */\n    private _terrainUniformBuffer!: GPUBuffer;\n    /** Bind group layout for building terrain height uniforms and texture sampling. */\n    private _terrainBindGroupLayout!: GPUBindGroupLayout;\n    /** Bind group containing the active or dummy terrain height source. */\n    private _terrainBindGroup!: GPUBindGroup;\n    /** Fallback height texture used when terrain mode is disabled. */\n    private _dummyTerrainTexture!: GPUTexture;\n    /** Reused CPU-side terrain uniform upload buffer. */\n    private _terrainUniformData = new Float32Array(8);\n\n    /**\n     * Creates a building SSAO pipeline bound to a renderer.\n     *\n     * The renderer provides the WebGPU device, canvas format, multisampling\n     * configuration, and shared state used to build the geometry and composite\n     * passes.\n     *\n     * @param renderer Renderer that owns the WebGPU device and canvas state.\n     */\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    /**\n     * Releases GPU resources owned by this pipeline.\n     *\n     * This destroys the geometry buffers created by the pipeline and then\n     * delegates to the base pipeline for shared cleanup.\n     *\n     * @returns Releases this pipeline's GPU allocations in place.\n     */\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._normalBuffer?.destroy();\n        this._thematicBuffer?.destroy();\n        this._thematicValidityBuffer?.destroy();\n        this._highlightedBuffer?.destroy();\n        this._skippedBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._terrainUniformBuffer?.destroy();\n        this._dummyTerrainTexture?.destroy();\n        super.destroy();\n    }\n\n    /**\n     * Begins the shared geometry pass for all SSAO-enabled building layers.\n     *\n     * The pass writes color, normals, and depth into renderer-scoped offscreen\n     * textures. Those attachments are cleared before each use so callers can\n     * record one or more geometry draw calls into the returned encoder.\n     *\n     * @param renderer Renderer that owns the shared SSAO targets.\n     * @returns Render pass encoder targeting the shared geometry buffers.\n     */\n    static beginSharedGeometryPass(renderer: Renderer): GPURenderPassEncoder {\n        const shared = this._ensureSharedState(renderer);\n        shared.colorsSharedBuffer.loadOp = 'clear';\n        shared.normalsSharedBuffer.loadOp = 'clear';\n        shared.depthBufferPass01.depthLoadOp = 'clear';\n\n        return renderer.commandEncoder.beginRenderPass({\n            colorAttachments: [shared.colorsSharedBuffer, shared.normalsSharedBuffer],\n            depthStencilAttachment: shared.depthBufferPass01,\n        });\n    }\n\n    /**\n     * Draws the shared fullscreen SSAO composite pass.\n     *\n     * The pass samples the shared color and normal textures generated by the\n     * geometry pass and renders the composited result into the caller-provided\n     * pass encoder.\n     *\n     * @param renderer Renderer that owns the shared SSAO textures and pipeline.\n     * @param passEncoder Active render pass encoder for the final composite.\n     * @returns Records a fullscreen draw into the provided render pass.\n     */\n    static compositeSharedPass(renderer: Renderer, passEncoder: GPURenderPassEncoder): void {\n        const shared = this._ensureSharedState(renderer);\n        passEncoder.setPipeline(shared.pipeline02);\n        passEncoder.setBindGroup(0, shared.texturesPass02BindGroup);\n        passEncoder.draw(6);\n    }\n\n    /**\n     * Draws the shared SSAO composite while testing against terrain depth.\n     *\n     * @param renderer Renderer that owns shared SSAO textures and pipelines.\n     * @param passEncoder Active render pass encoder for the final composite.\n     * @param terrainDepthTextureView Depth texture view generated by the terrain pass.\n     * @returns Records a fullscreen terrain-aware composite draw.\n     * @throws If the transient terrain composite bind group cannot be created.\n     * @example\n     * PipelineBuildingSSAO.compositeSharedPassWithTerrainDepth(renderer, pass, terrainDepthView);\n     */\n    static compositeSharedPassWithTerrainDepth(\n        renderer: Renderer,\n        passEncoder: GPURenderPassEncoder,\n        terrainDepthTextureView: GPUTextureView,\n    ): void {\n        const shared = this._ensureSharedState(renderer);\n        const bindGroup = renderer.device.createBindGroup({\n            layout: shared.terrainCompositeBindGroupLayout,\n            entries: [\n                { binding: 0, resource: shared.texSampler },\n                { binding: 1, resource: shared.colorsSharedBuffer.view },\n                { binding: 2, resource: shared.normalsSharedBuffer.view },\n                { binding: 3, resource: terrainDepthTextureView },\n                { binding: 4, resource: shared.depthBufferPass01.view },\n            ],\n        });\n        passEncoder.setPipeline(shared.terrainCompositePipeline);\n        passEncoder.setBindGroup(0, bindGroup);\n        passEncoder.draw(6);\n    }\n\n    /**\n     * Builds the SSAO geometry and shared composite resources for a mesh.\n     *\n     * This creates shader modules, allocates and uploads per-mesh buffers,\n     * prepares the base pipeline bind groups, initializes the geometry render\n     * pipeline, and ensures that the renderer-scoped shared SSAO state exists.\n     *\n     * @param mesh Building mesh whose typed arrays provide geometry and render\n     * state for the pass.\n     * @returns Initializes this pipeline for subsequent render passes.\n     */\n    build(mesh: Triangles3DLayer): void {\n        this.createShaders();\n        this.createVertexBuffers(mesh);\n        this.createColorUniformBindGroup();\n        this.createCameraUniformBindGroup();\n        this.createTerrainHeightBindGroup();\n        this.updateVertexBuffers(mesh);\n        this.updateColorUniforms(mesh);\n        this.createPipeline01();\n        PipelineBuildingSSAO._ensureSharedState(this._renderer);\n    }\n\n    /**\n     * Creates the shader modules used by the geometry pass.\n     *\n     * The modules are compiled from the WGSL sources imported for the building\n     * SSAO geometry stage.\n     *\n     * @returns Creates and stores the compiled shader modules on the pipeline.\n     */\n    createShaders(): void {\n        this._vertModule01 = this._renderer.device.createShaderModule({\n            label: 'Buildings ssao: vertex shader pass 01',\n            code: buildingsVS01,\n        });\n        this._fragModule01 = this._renderer.device.createShaderModule({\n            label: 'Buildings ssao: fragment shader pass 01',\n            code: buildingsFS01,\n        });\n    }\n\n    /**\n     * Allocates GPU buffers sized for the current building mesh.\n     *\n     * Buffer sizes are derived from the current typed-array lengths on the mesh.\n     * This method allocates buffers only; data upload happens in\n     * {@link updateVertexBuffers}.\n     *\n     * @param mesh Building mesh whose typed-array lengths determine buffer sizes.\n     * @returns Creates GPU buffers for all geometry attributes and indices.\n     */\n    createVertexBuffers(mesh: Triangles3DLayer): void {\n        this._positionBuffer = this._renderer.device.createBuffer({\n            label: 'Position buffer',\n            size: mesh.position.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._normalBuffer = this._renderer.device.createBuffer({\n            label: 'Normal buffer',\n            size: mesh.normal.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._thematicBuffer = this._renderer.device.createBuffer({\n            label: 'Thematic data buffer',\n            size: mesh.thematic.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._thematicValidityBuffer = this._renderer.device.createBuffer({\n            label: 'Thematic validity buffer',\n            size: mesh.thematicValidity.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._highlightedBuffer = this._renderer.device.createBuffer({\n            label: 'Highlighted data buffer',\n            size: mesh.highlightedVertices.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._skippedBuffer = this._renderer.device.createBuffer({\n            label: 'Skipped data buffer',\n            size: mesh.skippedVertices.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Primitive indices buffer',\n            size: mesh.indices.length * 4,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    /**\n     * Creates terrain height bindings for building vertex displacement.\n     *\n     * @returns Nothing. A dummy flat height source is bound initially.\n     * @throws If GPU buffer, texture, or bind group creation fails.\n     * @example\n     * pipeline.createTerrainHeightBindGroup();\n     */\n    createTerrainHeightBindGroup(): void {\n        this._terrainUniformBuffer = this._renderer.device.createBuffer({\n            label: 'Building terrain height uniform',\n            size: 8 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n        this._dummyTerrainTexture = this._renderer.device.createTexture({\n            label: 'Building dummy terrain height texture',\n            size: [2, 2],\n            format: 'r32float',\n            usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n        });\n        this._terrainBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            label: 'Building terrain height bind group layout',\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },\n                { binding: 1, visibility: GPUShaderStage.VERTEX, texture: { sampleType: 'unfilterable-float' } },\n            ],\n        });\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Building terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: this._dummyTerrainTexture.createView() },\n            ],\n        });\n        this.clearTerrainHeightSource();\n    }\n\n    /**\n     * Binds a heightfield texture used to lift buildings onto terrain.\n     *\n     * @param source Heightfield metadata used by the vertex shader.\n     * @param heightTextureView GPU texture view containing height samples.\n     * @returns Nothing. Subsequent geometry passes use the terrain height source.\n     * @throws If bind group creation fails.\n     * @example\n     * pipeline.setTerrainHeightSource(heightfield, terrainHeightTextureView);\n     */\n    setTerrainHeightSource(source: Heightfield, heightTextureView: GPUTextureView): void {\n        this._terrainUniformData.set([\n            source.originX,\n            source.originY,\n            source.cellSizeX,\n            source.cellSizeY,\n            source.width,\n            source.height,\n            1,\n            0,\n        ]);\n        this._renderer.device.queue.writeBuffer(this._terrainUniformBuffer, 0, this._terrainUniformData);\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Building terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: heightTextureView },\n            ],\n        });\n    }\n\n    /**\n     * Restores the dummy flat height source for building rendering.\n     *\n     * @returns Nothing. Subsequent geometry passes render without terrain lift.\n     * @throws If bind group creation fails.\n     * @example\n     * pipeline.clearTerrainHeightSource();\n     */\n    clearTerrainHeightSource(): void {\n        this._terrainUniformData.fill(0);\n        this._terrainUniformData[4] = 2;\n        this._terrainUniformData[5] = 2;\n        this._renderer.device.queue.writeBuffer(this._terrainUniformBuffer, 0, this._terrainUniformData);\n        this._terrainBindGroup = this._renderer.device.createBindGroup({\n            label: 'Building terrain height bind group',\n            layout: this._terrainBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._terrainUniformBuffer } },\n                { binding: 1, resource: this._dummyTerrainTexture.createView() },\n            ],\n        });\n    }\n\n    /**\n     * Uploads the current mesh data into the pipeline's GPU buffers.\n     *\n     * The method reuses cached CPU-side typed arrays when possible and writes\n     * the synchronized data into the corresponding GPU buffers.\n     *\n     * @param mesh Building mesh providing the latest position, normal,\n     * thematic, highlight, skip, and index arrays.\n     * @returns Updates the GPU buffer contents in place.\n     */\n    updateVertexBuffers(mesh: Triangles3DLayer): void {\n        this._normalData = this._syncFloatData(this._normalData, mesh.normal);\n        this._thematicData = this._syncFloatData(this._thematicData, mesh.thematic);\n        this._thematicValidityData = this._syncFloatData(this._thematicValidityData, mesh.thematicValidity);\n        this._highlightedData = this._syncFloatData(this._highlightedData, mesh.highlightedVertices);\n        this._skippedData = this._syncFloatData(this._skippedData, mesh.skippedVertices);\n        this._positionData = this._syncFloatData(this._positionData, mesh.position);\n        this._indicesData = this._syncUintData(this._indicesData, mesh.indices);\n\n        this._renderer.device.queue.writeBuffer(this._normalBuffer, 0, this._normalData);\n        this._renderer.device.queue.writeBuffer(this._thematicBuffer, 0, this._thematicData);\n        this._renderer.device.queue.writeBuffer(this._thematicValidityBuffer, 0, this._thematicValidityData);\n        this._renderer.device.queue.writeBuffer(this._highlightedBuffer, 0, this._highlightedData);\n        this._renderer.device.queue.writeBuffer(this._skippedBuffer, 0, this._skippedData);\n        this._renderer.device.queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n    }\n\n    /**\n     * Creates the geometry render pipeline for the building SSAO pass.\n     *\n     * The pipeline writes color and normal outputs to the shared offscreen\n     * textures used by the SSAO composite stage, and uses the base pipeline's\n     * render-info and camera bind group layouts.\n     *\n     * @returns Creates and stores the geometry render pipeline on the instance.\n     */\n    createPipeline01(): void {\n        const positionAttribDesc: GPUVertexAttribute = { shaderLocation: 0, offset: 0, format: 'float32x3' };\n        const normalAttribDesc: GPUVertexAttribute = { shaderLocation: 1, offset: 0, format: 'float32x3' };\n        const thematicAttribDesc: GPUVertexAttribute = { shaderLocation: 2, offset: 0, format: 'float32' };\n        const highlightedAttribDesc: GPUVertexAttribute = { shaderLocation: 3, offset: 0, format: 'float32' };\n        const thematicValidityAttribDesc: GPUVertexAttribute = { shaderLocation: 4, offset: 0, format: 'float32' };\n        const skippedAttribDesc: GPUVertexAttribute = { shaderLocation: 5, offset: 0, format: 'float32' };\n\n        const vertex: GPUVertexState = {\n            module: this._vertModule01,\n            entryPoint: 'main',\n            buffers: [\n                { attributes: [positionAttribDesc], arrayStride: 4 * 3, stepMode: 'vertex' },\n                { attributes: [normalAttribDesc], arrayStride: 4 * 3, stepMode: 'vertex' },\n                { attributes: [thematicAttribDesc], arrayStride: 4, stepMode: 'vertex' },\n                { attributes: [highlightedAttribDesc], arrayStride: 4, stepMode: 'vertex' },\n                { attributes: [thematicValidityAttribDesc], arrayStride: 4, stepMode: 'vertex' },\n                { attributes: [skippedAttribDesc], arrayStride: 4, stepMode: 'vertex' },\n            ],\n        };\n        const fragment: GPUFragmentState = {\n            module: this._fragModule01,\n            entryPoint: 'main',\n            targets: [{ format: 'rgba16float' }, { format: 'rgba16float' }],\n        };\n        const primitive: GPUPrimitiveState = {\n            frontFace: 'cw',\n            cullMode: 'none',\n            topology: 'triangle-list',\n        };\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: true,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n        const layout = this._renderer.device.createPipelineLayout({\n            bindGroupLayouts: [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout, this._terrainBindGroupLayout],\n        });\n\n        this._pipeline01 = this._renderer.device.createRenderPipeline({\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            label: 'Pipeline triangle ssao 01',\n        });\n    }\n\n    /**\n     * Records the indexed geometry draw calls for the building pass.\n     *\n     * This binds the geometry pipeline, uploads the latest camera uniforms,\n     * binds the vertex and index buffers, and skips the draw when the mesh has\n     * no indices.\n     *\n     * @param camera Camera used to update the shared camera uniforms.\n     * @param passEncoder Active render pass encoder for the geometry pass.\n     * @returns Records indexed geometry draws into the provided render pass.\n     */\n    renderGeometryPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        passEncoder.setPipeline(this._pipeline01);\n        this.updateCameraUniforms(camera);\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._normalBuffer);\n        passEncoder.setVertexBuffer(2, this._thematicBuffer);\n        passEncoder.setVertexBuffer(3, this._highlightedBuffer);\n        passEncoder.setVertexBuffer(4, this._thematicValidityBuffer);\n        passEncoder.setVertexBuffer(5, this._skippedBuffer);\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n        passEncoder.setBindGroup(0, this._renderInfoBindGroup);\n        passEncoder.setBindGroup(1, this._cameraBindGroup);\n        passEncoder.setBindGroup(2, this._terrainBindGroup);\n\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0) {\n            passEncoder.drawIndexed(indexCount);\n        }\n    }\n\n    /**\n     * No-op preparation hook for this pipeline's render flow.\n     *\n     * The SSAO pipeline is driven through the shared geometry and composite\n     * helpers instead of the base pipeline's per-layer render preparation.\n     *\n     * @returns Intentionally performs no per-frame preparation.\n     */\n    override prepareRender(_camera: Camera): void {}\n\n    /**\n     * No-op render hook for this pipeline's render flow.\n     *\n     * The SSAO pipeline records work through {@link renderGeometryPass} and the\n     * static shared pass helpers rather than this base render entry point.\n     *\n     * @returns Intentionally performs no draw work.\n     */\n    renderPass(_camera: Camera, _passEncoder: GPURenderPassEncoder): void {}\n\n    /**\n     * Returns the renderer-scoped shared SSAO resources, recreating them when\n     * the render target size changes.\n     *\n     * Shared textures are sized at twice the renderer's pixel dimensions and\n     * cached per renderer. When the size changes, the previous textures are\n     * destroyed and a new geometry/composite state bundle is created.\n     *\n     * @param renderer Renderer that owns the shared SSAO state.\n     * @returns Shared SSAO attachments, bind groups, and composite pipeline.\n     */\n    private static _ensureSharedState(renderer: Renderer): SharedSsaoState {\n        const width = 2 * renderer.pixelWidth;\n        const height = 2 * renderer.pixelHeight;\n        const existing = this._sharedState.get(renderer);\n        if (existing && existing.width === width && existing.height === height) {\n            return existing;\n        }\n\n        existing?.colorsSharedTexture.destroy();\n        existing?.normalsSharedTexture.destroy();\n        existing?.depthTexturePass01.destroy();\n\n        const colorsSharedTexture = renderer.device.createTexture({\n            label: 'Shared colors texture',\n            size: [width, height],\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n            format: 'rgba16float',\n        });\n        const normalsSharedTexture = renderer.device.createTexture({\n            label: 'Shared normals texture',\n            size: [width, height],\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n            format: 'rgba16float',\n        });\n        const depthTexturePass01 = renderer.device.createTexture({\n            label: 'Shared building depth texture',\n            size: [width, height],\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n        });\n\n        const colorsSharedBuffer: GPURenderPassColorAttachment = {\n            view: colorsSharedTexture.createView(),\n            clearValue: [0.0, 0.0, 0.0, 0.0],\n            loadOp: 'clear',\n            storeOp: 'store',\n        };\n        const normalsSharedBuffer: GPURenderPassColorAttachment = {\n            view: normalsSharedTexture.createView(),\n            clearValue: [0.0, 0.0, 0.0, 0.0],\n            loadOp: 'clear',\n            storeOp: 'store',\n        };\n        const depthBufferPass01: GPURenderPassDepthStencilAttachment = {\n            view: depthTexturePass01.createView(),\n            depthClearValue: 0.0,\n            depthLoadOp: 'clear',\n            depthStoreOp: 'store',\n        };\n\n        const texSampler = renderer.device.createSampler({\n            label: 'Shared building pass 02 sampler',\n            magFilter: 'linear',\n            minFilter: 'linear',\n            addressModeU: 'clamp-to-edge',\n            addressModeV: 'clamp-to-edge',\n        });\n        const texturesPass02BindGroupLayout = renderer.device.createBindGroupLayout({\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {} },\n                { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: {} },\n                { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: {} },\n            ],\n        });\n        const terrainCompositeBindGroupLayout = renderer.device.createBindGroupLayout({\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.FRAGMENT, sampler: {} },\n                { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: {} },\n                { binding: 2, visibility: GPUShaderStage.FRAGMENT, texture: {} },\n                { binding: 3, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'depth', viewDimension: '2d' } },\n                { binding: 4, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'depth', viewDimension: '2d' } },\n            ],\n        });\n        const texturesPass02BindGroup = renderer.device.createBindGroup({\n            layout: texturesPass02BindGroupLayout,\n            entries: [\n                { binding: 0, resource: texSampler },\n                { binding: 1, resource: colorsSharedBuffer.view },\n                { binding: 2, resource: normalsSharedBuffer.view },\n            ],\n        });\n\n        const vertModule02 = renderer.device.createShaderModule({\n            label: 'Buildings ssao: vertex shader pass 02',\n            code: buildingsVS02,\n        });\n        const fragModule02 = renderer.device.createShaderModule({\n            label: 'Buildings ssao: fragment shader pass 02',\n            code: buildingsFS02,\n        });\n        const terrainFragModule02 = renderer.device.createShaderModule({\n            label: 'Buildings ssao: terrain-aware fragment shader pass 02',\n            code: buildingsTerrainFS02,\n        });\n        const pipeline02 = renderer.device.createRenderPipeline({\n            layout: renderer.device.createPipelineLayout({\n                bindGroupLayouts: [texturesPass02BindGroupLayout],\n            }),\n            vertex: {\n                module: vertModule02,\n                entryPoint: 'main',\n            },\n            fragment: {\n                module: fragModule02,\n                entryPoint: 'main',\n                targets: [{\n                    format: renderer.canvasFormat,\n                    blend: {\n                        color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                        alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                    },\n                }],\n            },\n            primitive: {\n                topology: 'triangle-strip',\n                stripIndexFormat: 'uint32',\n            },\n            depthStencil: {\n                depthWriteEnabled: false,\n                depthCompare: 'greater-equal',\n                format: 'depth32float',\n            },\n            multisample: {\n                count: renderer.sampleCount,\n            },\n            label: 'Pipeline triangle ssao 02 shared',\n        });\n        const terrainCompositePipeline = renderer.device.createRenderPipeline({\n            layout: renderer.device.createPipelineLayout({\n                bindGroupLayouts: [terrainCompositeBindGroupLayout],\n            }),\n            vertex: {\n                module: vertModule02,\n                entryPoint: 'main',\n            },\n            fragment: {\n                module: terrainFragModule02,\n                entryPoint: 'main',\n                targets: [{\n                    format: renderer.canvasFormat,\n                    blend: {\n                        color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                        alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                    },\n                }],\n            },\n            primitive: {\n                topology: 'triangle-strip',\n                stripIndexFormat: 'uint32',\n            },\n            multisample: {\n                count: renderer.sampleCount,\n            },\n            label: 'Pipeline triangle ssao 02 terrain shared',\n        });\n\n        const state: SharedSsaoState = {\n            colorsSharedBuffer,\n            normalsSharedBuffer,\n            depthBufferPass01,\n            colorsSharedTexture,\n            normalsSharedTexture,\n            depthTexturePass01,\n            texSampler,\n            texturesPass02BindGroup,\n            texturesPass02BindGroupLayout,\n            pipeline02,\n            terrainCompositeBindGroupLayout,\n            terrainCompositePipeline,\n            width,\n            height,\n        };\n        this._sharedState.set(renderer, state);\n        return state;\n    }\n}\n","/**\n * @module Triangles3DLayer\n * A 3D triangle-mesh layer with per-vertex normal generation.\n *\n * This module defines `Triangles3DLayer`, a specialized vector layer for\n * rendering indexed triangle geometry in 3D. In addition to the standard\n * vector-layer data flow, it maintains derived vertex normals used by the\n * building SSAO pipeline and keeps those normals synchronized with geometry\n * updates before rendering.\n */\n\nimport { Camera, LayerGeometry } from '@urban-toolkit/autk-core';\n\nimport {\n    LayerInfo,\n    LayerRenderInfo,\n    LayerData\n} from './types-layers';\n\nimport { VectorLayer } from './layer-vector';\n\nimport { Renderer } from './renderer';\n\nimport { PipelineBuildingSSAO } from './pipeline-triangle-ssao';\nimport { PipelineTrianglePicking } from './pipeline-triangle-picking';\nimport type { Heightfield } from '@urban-toolkit/autk-core';\n\n/**\n * 3D indexed-triangle layer with derived lighting normals.\n *\n * `Triangles3DLayer` extends `VectorLayer` for triangle meshes rendered in\n * three dimensions. It computes one normal vector per vertex from the current\n * indexed geometry, keeps those normals invalidated when geometry changes, and\n * ensures the derived buffers are ready before render passes that depend on\n * lighting or geometry-only output.\n *\n * @example\n * const layer = new Triangles3DLayer(layerInfo, layerRenderInfo, layerData);\n * layer.loadGeometry(meshGeometry);\n * layer.createPipeline(renderer);\n */\nexport class Triangles3DLayer extends VectorLayer {\n    declare protected _pipelinePicking: PipelineTrianglePicking;\n    /**\n     * Vertex normals for lighting calculations.\n     * One normal (3 floats: x, y, z) per vertex.\n     * @type {Float32Array}\n     */\n    protected _normal: Float32Array = new Float32Array(0);\n\n    /**\n     * Tracks whether normals are out of sync with current geometry.\n     * @type {boolean}\n     */\n    protected _normalsAreDirty: boolean = false;\n\n    private readonly COORD_DIM = 3;\n\n    /**\n     * Creates a 3D triangle layer.\n     *\n     * The layer is initialized with a fixed coordinate dimension of `3` and\n     * immediately derives normals from the initial geometry payload, if any.\n     *\n     * @param {LayerInfo} layerInfo Layer metadata such as id, type, and z-index.\n     * @param {LayerRenderInfo} layerRenderInfo Initial render configuration for color, opacity, and picking.\n     * @param {LayerData} layerData Initial geometry, component metadata, and thematic data.\n     * @returns {Triangles3DLayer} A new 3D triangles layer instance.\n     */\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData) {\n        super(layerInfo, layerRenderInfo, layerData, 3);\n        this.computeNormals();\n    }\n\n    /**\n     * Gets the derived per-vertex normal buffer.\n     *\n     * The returned array stores three floats per vertex in xyz order and is\n     * kept aligned with the current position buffer.\n     *\n     * @returns {Float32Array} The vertex-normal buffer used for lighting.\n     */\n    get normal(): Float32Array {\n        return this._normal;\n    }\n\n    /**\n     * Loads geometry for the layer and invalidates derived normals.\n     *\n     * Normals are not recomputed eagerly here. Instead, the layer marks them as\n     * dirty so the next render preparation or render pass can rebuild them from\n     * the updated indexed geometry.\n     *\n     * @param {LayerGeometry[]} layerGeometry Geometry chunks to load into the layer.\n     * @returns {void} The layer geometry is replaced and normals are marked dirty.\n     */\n    override loadGeometry(layerGeometry: LayerGeometry[]): void {\n        super.loadGeometry(layerGeometry);\n        this._normalsAreDirty = true;\n    }\n\n    /**\n     * Creates the render and picking pipelines for the layer.\n     *\n     * The main rendering pipeline uses the SSAO-enabled building triangle\n     * implementation, while the picking pipeline uses triangle-based picking in\n     * the layer's fixed 3D dimension.\n     *\n     * @param {Renderer} renderer Renderer that owns the WebGPU device and shared resources.\n     * @returns {void} The layer pipelines are created and built against the current layer state.\n     */\n    override createPipeline(renderer: Renderer): void {\n        this._pipeline = new PipelineBuildingSSAO(renderer);\n        this._pipeline.build(this);\n\n        this._pipelinePicking = new PipelineTrianglePicking(renderer, this._dimension);\n        this._pipelinePicking.build(this);\n    }\n\n    /**\n     * Renders the layer during the standard render pass.\n     *\n     * If geometry changed since normals were last derived, normals are rebuilt\n     * immediately before delegating to the base vector-layer render flow.\n     *\n     * @param {Camera} camera Active camera for view and projection state.\n     * @param {GPURenderPassEncoder} passEncoder Render-pass encoder for the active pass.\n     * @returns {void} The layer is rendered into the current pass when not skipped by base-layer logic.\n     */\n    override renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        if (this._normalsAreDirty) {\n            this.computeNormals();\n        }\n\n        super.renderPass(camera, passEncoder);\n    }\n\n    /**\n     * Prepares derived geometry state required for rendering.\n     *\n     * This override ensures per-vertex normals are synchronized with the latest\n     * geometry before later render stages consume the layer. The camera argument\n     * is accepted to match the base-layer lifecycle but is not used here.\n     *\n     * @param {Camera} _camera Active camera passed by the renderer's prepare phase.\n     * @returns {void} Normals are recomputed if geometry invalidated the cached values.\n     */\n    override prepareRender(_camera: Camera): void {\n        if (this._normalsAreDirty) {\n            this.computeNormals();\n        }\n    }\n\n    /**\n     * Renders the layer's scene geometry into the geometry pass.\n     *\n     * This method keeps normal data current, pushes pending render-info and\n     * vertex-buffer updates to the active pipelines, refreshes the pipeline\n     * z-index from the current layer metadata, and then delegates the draw call\n     * to the SSAO geometry pass implementation.\n     *\n     * Render-info updates are applied only when flagged dirty. Vertex-buffer\n     * uploads are applied to both the main render pipeline and the picking\n     * pipeline when layer data changed.\n     *\n     * @param {Camera} camera Active camera for view and projection uniforms.\n     * @param {GPURenderPassEncoder} passEncoder Render-pass encoder for the scene geometry pass.\n     * @returns {void} Pending layer state is synchronized and the geometry pass is issued.\n     */\n    renderSceneGeometry(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        if (this._normalsAreDirty) {\n            this.computeNormals();\n        }\n\n        if (this._renderInfoIsDirty) {\n            this._pipeline.updateColorUniforms(this);\n            this._renderInfoIsDirty = false;\n        }\n\n        if (this._dataIsDirty) {\n            this._pipeline.updateVertexBuffers(this);\n            this._pipelinePicking.updateVertexBuffers(this);\n            this._dataIsDirty = false;\n        }\n\n        this._pipeline.updateZIndex(this._layerInfo.zIndex);\n        (this._pipeline as PipelineBuildingSSAO).renderGeometryPass(camera, passEncoder);\n    }\n\n    /**\n     * Binds a heightfield to the 3D render and picking pipelines.\n     *\n     * @param source Heightfield sampled to offset 3D geometry in terrain mode.\n     * @param heightTextureView GPU texture view containing heightfield samples.\n     * @returns Nothing. Subsequent render and picking passes use terrain heights.\n     * @throws Never throws.\n     * @example\n     * layer.setTerrainHeightSource(heightfield, terrainHeightTextureView);\n     */\n    setTerrainHeightSource(source: Heightfield, heightTextureView: GPUTextureView): void {\n        (this._pipeline as PipelineBuildingSSAO).setTerrainHeightSource(source, heightTextureView);\n        this._pipelinePicking.setTerrainHeightSource(source, heightTextureView);\n    }\n\n    /**\n     * Clears terrain height bindings from the 3D render and picking pipelines.\n     *\n     * @returns Nothing. Subsequent passes use the dummy flat height source.\n     * @throws Never throws.\n     * @example\n     * layer.clearTerrainHeightSource();\n     */\n    clearTerrainHeightSource(): void {\n        (this._pipeline as PipelineBuildingSSAO).clearTerrainHeightSource();\n        this._pipelinePicking.clearTerrainHeightSource();\n    }\n\n    /**\n     * Recomputes per-vertex normals from the current indexed triangle geometry.\n     *\n     * The normal buffer is recreated to match the current vertex count, face\n     * normals are accumulated for each referenced triangle, and the accumulated\n     * vectors are normalized per vertex. When the layer has no positions or no\n     * triangle indices, the normal buffer is cleared instead.\n     *\n     * @returns {void} The normal buffer is rebuilt and the dirty flag is cleared.\n     */\n    private computeNormals(): void {\n        if (this._position.length === 0 || this._indices.length === 0) {\n            this._normal = new Float32Array(0);\n            this._normalsAreDirty = false;\n            return;\n        }\n\n        const vertexCount = this._position.length / this.COORD_DIM;\n        this._normal = new Float32Array(vertexCount * this.COORD_DIM);\n\n        this._accumulateFaceNormals();\n        this._normalizeVertexNormals();\n\n        this._normalsAreDirty = false;\n    }\n\n    /**\n     * Accumulates unnormalized face normals into each referenced vertex normal.\n     *\n     * For every indexed triangle, this method computes the cross product of two\n     * triangle edges and adds the resulting face normal to the three vertices\n     * that form the triangle. The accumulation operates in place on\n     * `this._normal`, which is expected to be zero-initialized before this\n     * method runs.\n     *\n     * @returns {void} Face-normal contributions are summed into the vertex-normal buffer.\n     */\n    private _accumulateFaceNormals(): void {\n        for (let triIdx = 0; triIdx < this._indices.length; triIdx += 3) {\n            const i0 = this._indices[triIdx];\n            const i1 = this._indices[triIdx + 1];\n            const i2 = this._indices[triIdx + 2];\n\n            const p0 = i0 * this.COORD_DIM;\n            const p1 = i1 * this.COORD_DIM;\n            const p2 = i2 * this.COORD_DIM;\n\n            const e1x = this._position[p1]     - this._position[p0];\n            const e1y = this._position[p1 + 1] - this._position[p0 + 1];\n            const e1z = this._position[p1 + 2] - this._position[p0 + 2];\n\n            const e2x = this._position[p2]     - this._position[p0];\n            const e2y = this._position[p2 + 1] - this._position[p0 + 1];\n            const e2z = this._position[p2 + 2] - this._position[p0 + 2];\n\n            const nx = e1y * e2z - e1z * e2y;\n            const ny = e1z * e2x - e1x * e2z;\n            const nz = e1x * e2y - e1y * e2x;\n\n            for (const vi of [i0, i1, i2]) {\n                const n = vi * this.COORD_DIM;\n                this._normal[n]     += nx;\n                this._normal[n + 1] += ny;\n                this._normal[n + 2] += nz;\n            }\n        }\n    }\n\n    /**\n     * Normalizes the accumulated normal vector for each vertex.\n     *\n     * Vertices with a near-zero accumulated magnitude receive a fallback normal\n     * of `(0, 1, 0)` instead of attempting to divide by a very small value.\n     * This keeps the normal buffer well-formed even when geometry is degenerate\n     * or does not contribute a stable face normal for a vertex.\n     *\n     * @returns {void} The vertex-normal buffer is normalized in place.\n     */\n    private _normalizeVertexNormals(): void {\n        const vertexCount = this._normal.length / this.COORD_DIM;\n        for (let i = 0; i < vertexCount; i++) {\n            const n = i * this.COORD_DIM;\n            const nx = this._normal[n];\n            const ny = this._normal[n + 1];\n            const nz = this._normal[n + 2];\n            const mag = Math.sqrt(nx * nx + ny * ny + nz * nz);\n            if (mag > 1e-6) {\n                this._normal[n]     = nx / mag;\n                this._normal[n + 1] = ny / mag;\n                this._normal[n + 2] = nz / mag;\n            } else {\n                this._normal[n]     = 0;\n                this._normal[n + 1] = 1;\n                this._normal[n + 2] = 0;\n            }\n        }\n    }\n}\n","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4<f32>,\\n    @location(0) outSkipped: f32\\n };\\n\\n@vertex\\nfn main(@location(0) inPosition: vec2f, @location(3) inSkipped: f32) -> VSOut {\\n    var vsOut: VSOut;\\n\\n    vsOut.outPosition = projection * modelView * vec4f(inPosition.x, inPosition.y, zIndex, 1);\\n    vsOut.outSkipped = inSkipped;\\n\\n    return vsOut;\\n}\";","export default \"@group(0) @binding(0) var<uniform> color : vec4f;\\n@group(0) @binding(6) var<uniform> opacity : f32;\\n\\n@fragment\\nfn main(@location(0) inSkipped: f32) -> @location(0) vec4f {\\n    if (inSkipped > 0.0) {\\n        discard;\\n    }\\n\\n    let outColor = vec4f(color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a);\\n    return vec4f(outColor.rgb * opacity, opacity);\\n}\";","/**\n * @module PipelineTriangleBorder\n * WebGPU line pipeline for rendering 2D triangle borders.\n *\n * This module defines {@link PipelineTriangleBorder}, a specialized rendering\n * pipeline used by triangle-based 2D layers to draw border edges. The pipeline\n * manages shader creation, GPU buffer allocation and uploads, uniform bind\n * groups inherited from the base pipeline, and indexed line-list draw calls.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\nimport linesVertexSource from './shaders/triangle-02.vert.wgsl';\nimport linesFragmentSource from './shaders/triangle-02.frag.wgsl';\n\nimport { Pipeline } from './pipeline';\nimport { Renderer } from './renderer';\n\nimport { Camera } from '@urban-toolkit/autk-core';\nimport type { ColorRGB } from '@urban-toolkit/autk-core';\n\nimport { Triangles2DLayer } from './layer-triangles2D';\n\nconst DEFAULT_BORDER_COLOR: ColorRGB = { r: 0, g: 0, b: 0, alpha: 1 };\n\n/**\n * Rendering pipeline for drawing 2D triangle borders as indexed lines.\n *\n * `PipelineTriangleBorder` uploads border vertex positions, edge indices, and\n * per-vertex skipped flags from a {@link Triangles2DLayer}, then renders them\n * with a dedicated WebGPU line-list pipeline. It relies on the base\n * {@link Pipeline} implementation for shared camera and render-info uniform\n * management.\n */\nexport class PipelineTriangleBorder extends Pipeline {\n    /** GPU vertex buffer containing border positions. */\n    protected _positionBuffer!: GPUBuffer;\n\n    /** GPU index buffer describing border line segments. */\n    protected _borderIndicesBuffer!: GPUBuffer;\n\n    /** GPU vertex buffer containing per-vertex skipped flags. */\n    protected _skippedBuffer!: GPUBuffer;\n\n    /** Compiled vertex shader module for border rendering. */\n    protected _vertModule!: GPUShaderModule;\n\n    /** Compiled fragment shader module for border rendering. */\n    protected _fragModule!: GPUShaderModule;\n\n    /** WebGPU render pipeline used for indexed border draw calls. */\n    protected _pipeline!: GPURenderPipeline;\n\n    /** Reused CPU-side upload buffer for border positions. */\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for border indices. */\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    /** Reused CPU-side upload buffer for skipped flags. */\n    private _skippedData: Float32Array<ArrayBuffer> | null = null;\n\n    /**\n     * Creates a triangle-border pipeline bound to a renderer.\n     *\n     * The renderer provides the GPU device, canvas format, sample count, and\n     * shared rendering state required to allocate buffers and create the render\n     * pipeline.\n     *\n     * @param renderer Renderer that owns the WebGPU device and render targets.\n     */\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    /**\n     * Border passes use the stroke color when one is configured.\n     *\n     * @param layer Layer instance whose render configuration is uploaded.\n     * @returns RGB color consumed by the border shader uniform.\n     */\n    protected override resolveLayerColor(layer: Triangles2DLayer): ColorRGB {\n        return layer.layerRenderInfo.strokeColor ?? DEFAULT_BORDER_COLOR;\n    }\n\n    /**\n     * Releases GPU resources owned by this pipeline.\n     *\n     * @returns Destroys this pipeline's buffers, then delegates to the base\n     * pipeline to release shared resources such as uniform buffers and bind\n     * groups.\n     */\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._borderIndicesBuffer?.destroy();\n        this._skippedBuffer?.destroy();\n        super.destroy();\n    }\n\n    /**\n     * Builds GPU resources and uploads layer data for border rendering.\n     *\n     * This method creates shader modules, allocates vertex and index buffers,\n     * initializes shared uniform bind groups, uploads the current layer data,\n     * and creates the WebGPU render pipeline. It is expected to be called\n     * before the first render pass for the layer.\n     *\n     * @param borders Triangle layer supplying border positions, edge indices,\n     * and skipped-vertex flags.\n     * @returns Initializes this pipeline instance for subsequent draw calls.\n     */\n    build(borders: Triangles2DLayer): void {\n        this.createShaders();\n\n        this.createVertexBuffers(borders);\n        this.createColorUniformBindGroup();\n        this.createCameraUniformBindGroup();\n\n        this.updateVertexBuffers(borders);\n        this.updateColorUniforms(borders);\n\n        this.createPipeline();\n    }\n\n    /**\n     * Creates the shader modules used by the border pipeline.\n     *\n     * @returns Compiles the WGSL vertex and fragment shader sources into GPU\n     * shader modules stored on this instance.\n     */\n    createShaders(): void {\n        // Vertex shader\n        const vsmDesc = {\n            code: linesVertexSource,\n        };\n        this._vertModule = this._renderer.device.createShaderModule(vsmDesc);\n\n        // Fragment shader\n        const fsmDesc = {\n            code: linesFragmentSource,\n        };\n        this._fragModule = this._renderer.device.createShaderModule(fsmDesc);\n    }\n\n    /**\n     * Allocates GPU buffers sized for the current border data.\n     *\n     * Buffer sizes are derived directly from the current layer arrays. If the\n     * layer data changes size later, callers must ensure buffers are recreated\n     * before uploading larger payloads.\n     *\n     * @param borders Triangle layer supplying the border arrays used to size\n     * the position, index, and skipped buffers.\n     * @returns Creates GPU buffers for subsequent uploads and draw calls.\n     */\n    createVertexBuffers(borders: Triangles2DLayer): void {\n        // vertex data\n        this._positionBuffer = this._renderer.device.createBuffer({\n            label: 'Position buffer',\n            size: borders.borderPosition.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._borderIndicesBuffer = this._renderer.device.createBuffer({\n            label: 'Primitive indices buffer',\n            size: borders.borderIndices.length * 4,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n\n        // vertex data\n        this._skippedBuffer = this._renderer.device.createBuffer({\n            label: 'Skipped data buffer',\n            size: borders.skippedVertices.length * 4,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    /**\n     * Uploads the current border arrays into the pipeline's GPU buffers.\n     *\n     * The method reuses cached typed arrays when possible via base-pipeline\n     * synchronization helpers, then writes the synchronized data to the GPU\n     * queue for the position, index, and skipped buffers.\n     *\n     * @param borders Triangle layer supplying border positions, edge indices,\n     * and skipped-vertex flags.\n     * @returns Updates the GPU-side buffer contents used by rendering.\n     */\n    updateVertexBuffers(borders: Triangles2DLayer): void {\n        this._positionData = this._syncFloatData(this._positionData, borders.borderPosition);\n        this._indicesData = this._syncUintData(this._indicesData, borders.borderIndices);\n        this._skippedData = this._syncFloatData(this._skippedData, borders.skippedVertices);\n\n        this._renderer.device.queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        this._renderer.device.queue.writeBuffer(this._borderIndicesBuffer, 0, this._indicesData);\n        this._renderer.device.queue.writeBuffer(this._skippedBuffer, 0, this._skippedData);\n    }\n\n    /**\n     * Creates the WebGPU render pipeline used to draw borders.\n     *\n     * The pipeline renders indexed `line-list` primitives, uses the renderer's\n     * multisample configuration, disables depth writes while still participating\n     * in depth testing, and binds the shared render-info and camera uniform\n     * layouts inherited from the base pipeline.\n     *\n     * @returns Stores the created render pipeline on this instance.\n     */\n    createPipeline(): void {\n        // Vertex data\n        const positionAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 0, // [[location(0)]]\n            offset: 0,\n            format: 'float32x2',\n        };\n\n        const positionBufferDesc: GPUVertexBufferLayout = {\n            attributes: [positionAttribDesc],\n            arrayStride: 4 * 2, // sizeof(float) * 2\n            stepMode: 'vertex',\n        };\n\n        const skippedAttribDesc: GPUVertexAttribute = {\n            shaderLocation: 3, // [[location(3)]]\n            offset: 0,\n            format: 'float32',\n        };\n\n        const skippedBufferDesc: GPUVertexBufferLayout = {\n            attributes: [skippedAttribDesc],\n            arrayStride: 4 * 1, // sizeof(float) * 3\n            stepMode: 'vertex',\n        };\n\n        // Vertex Shader\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [positionBufferDesc, skippedBufferDesc],\n        };\n\n        // Fragment Shader\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [\n                {\n                    format: this._renderer.canvasFormat,\n                    blend: {\n                        color: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha',\n                        },\n                        alpha: {\n                            srcFactor: 'one',\n                            dstFactor: 'one-minus-src-alpha'\n                        },\n                    },\n                },\n            ],\n        };\n\n        // Rasterization\n        const primitive: GPUPrimitiveState = {\n            topology: 'line-list'\n        };\n\n        // Antialising\n        const multisample: GPUMultisampleState = {\n            count: this._renderer.sampleCount,\n        };\n\n        // Depth test\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: false,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n\n        // Uniform Data\n        const pipelineLayoutDesc = {\n            bindGroupLayouts: [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout],\n        };\n\n        // Pipeline\n        const layout = this._renderer.device.createPipelineLayout(pipelineLayoutDesc);\n        const pipelineDesc: GPURenderPipelineDescriptor = {\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            multisample,\n            label: 'Pipeline border flat',\n        };\n        this._pipeline = this._renderer.device.createRenderPipeline(pipelineDesc);\n    }\n\n    /**\n     * Encodes a render pass for the current triangle borders.\n     *\n     * The method updates camera uniforms for the current frame, binds the\n     * pipeline, vertex buffers, index buffer, and uniform bind groups, then\n     * issues an indexed draw only when the border index buffer contains at\n     * least one index.\n     *\n     * @param camera Camera whose current view and projection state should be\n     * uploaded before drawing.\n     * @param passEncoder Active render-pass encoder that receives the draw\n     * commands.\n     * @returns Encodes draw commands into the provided render pass when border\n     * indices are available; otherwise, no draw call is issued.\n     */\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        // sets the current pipeline\n        passEncoder.setPipeline(this._pipeline);\n\n        // updates camera\n        this.updateCameraUniforms(camera);\n\n        // sets the vertex buffers\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._skippedBuffer);\n\n        // sets primitive indices buffer\n        passEncoder.setIndexBuffer(this._borderIndicesBuffer, 'uint32');\n\n        // sets the uniform buffers\n        passEncoder.setBindGroup(0, this._renderInfoBindGroup);\n        passEncoder.setBindGroup(1, this._cameraBindGroup);\n\n        const indexCount = this._borderIndicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0) { passEncoder.drawIndexed(indexCount); }\n    }\n\n}\n","/**\n * @module LayerTriangles2D\n * 2D triangle layer with optional border rendering.\n *\n * This module defines `Triangles2DLayer`, a vector layer specialization for\n * triangulated 2D polygonal geometry. In addition to the standard filled\n * triangle rendering provided by `VectorLayer`, it manages derived border\n * geometry and an auxiliary border pipeline so outlines stay synchronized with\n * the main layer data.\n */\n\nimport { Camera, LayerBorder, LayerBorderComponent } from '@urban-toolkit/autk-core';\n\nimport {\n    LayerInfo,\n    LayerRenderInfo,\n    LayerData\n} from './types-layers';\n\nimport { VectorLayer } from './layer-vector';\n\nimport { Renderer } from './renderer';\n\nimport { PipelineTriangleBorder } from './pipeline-triangle-border';\n\n/**\n * Vector layer for triangulated 2D geometry with optional borders.\n *\n * `Triangles2DLayer` extends `VectorLayer` with additional geometry and GPU\n * pipeline management for line-based borders associated with filled triangle\n * meshes. Border data is loaded alongside the main layer geometry and, when\n * present, is rendered as a separate pass using a dedicated pipeline.\n */\nexport class Triangles2DLayer extends VectorLayer {\n    /** Packed 2D border vertex positions. */\n    protected _borderPosition: Float32Array = new Float32Array(0);\n\n    /** Packed border index buffer. */\n    protected _borderIndices: Uint32Array = new Uint32Array(0);\n\n    /** Cumulative border component ranges aligned with rendered features. */\n    protected _borderComponents: LayerBorderComponent[] = [];\n\n    /** Border rendering pipeline, created only when border geometry exists. */\n    protected _pipelineBorder!: PipelineTriangleBorder;\n\n    /**\n     * Creates a 2D triangles layer.\n     *\n     * Border geometry is reloaded after the base `VectorLayer` constructor runs\n     * because field initializers reset the border arrays after the polymorphic\n     * `loadLayerData` call made by the parent class.\n     *\n     * @param layerInfo Static layer metadata such as id, type, and z-index.\n     * @param layerRenderInfo Mutable rendering configuration for visibility,\n     * color mapping, opacity, and picking.\n     * @param layerData Geometry, thematic values, and optional border data used\n     * to populate the layer.\n     */\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData) {\n        super(layerInfo, layerRenderInfo, layerData, 2);\n        // Field initializers run after super() and overwrite data set during the\n        // polymorphic loadLayerData call inside VectorLayer.constructor.\n        // Re-load border data explicitly so it is available for createPipeline.\n        this.loadBorderGeometry(layerData.border ?? []);\n        this.loadBorderComponent(layerData.borderComponents ?? []);\n    }\n\n    /** Packed 2D border vertex positions. */\n    get borderPosition(): Float32Array {\n        return this._borderPosition;\n    }\n\n    /** Packed border index buffer. */\n    get borderIndices(): Uint32Array {\n        return this._borderIndices;\n    }\n\n    /** Cumulative border component ranges aligned with rendered features. */\n    get borderComponents(): LayerBorderComponent[] {\n        return this._borderComponents;\n    }\n\n    /**\n     * Loads layer geometry, thematic data, and border metadata.\n     *\n     * This extends the base `VectorLayer` loading path by rebuilding the packed\n     * border buffers and cumulative border-component ranges from the optional\n     * border data stored in `layerData`.\n     *\n     * @param layerData Layer payload containing triangle geometry and optional\n     * border geometry/components.\n     * @returns Nothing. The layer's CPU-side geometry caches are replaced in\n     * place.\n     */\n    override loadLayerData(layerData: LayerData): void {\n        super.loadLayerData(layerData);\n\n        this.loadBorderGeometry(layerData.border ?? []);\n        this.loadBorderComponent(layerData.borderComponents ?? []);\n    }\n\n    /**\n     * Packs per-feature border geometry into contiguous buffers.\n     *\n     * Input border segments are concatenated into single position and index\n     * arrays. Indices are rebased as each segment is appended so the resulting\n     * buffers can be uploaded directly to the border pipeline.\n     *\n     * @param border Border geometry chunks to merge.\n     * @returns Nothing. Existing packed border position and index buffers are\n     * replaced.\n     */\n    loadBorderGeometry(border: LayerBorder[]): void {\n        let totalVerts = 0;\n        let totalIndices = 0;\n        for (const b of border) {\n            totalVerts += b.position.length;\n            totalIndices += b.indices.length;\n        }\n\n        const position = new Float32Array(totalVerts);\n        const indices = new Uint32Array(totalIndices);\n\n        let vOffset = 0;\n        let iOffset = 0;\n        let vertexCount = 0;\n\n        for (let id = 0; id < border.length; id++) {\n            const b = border[id];\n            \n            position.set(b.position, vOffset);\n\n            for (let i = 0; i < b.indices.length; i++) {\n                indices[iOffset + i] = b.indices[i] + vertexCount;\n            }\n\n            const vertsAdded = b.position.length / 2; // Always 2D for 2D borders\n            vOffset += b.position.length;\n            iOffset += b.indices.length;\n            vertexCount += vertsAdded;\n        }\n\n        this._borderPosition = position;\n        this._borderIndices = indices;\n    }\n\n    /**\n     * Builds cumulative border component ranges for feature-level lookup.\n     *\n     * Each stored component accumulates point and line counts from the start of\n     * the border buffers through the corresponding feature, matching the range\n     * convention used by the main vector components.\n     *\n     * @param borderComponents Per-feature border component metadata.\n     * @returns Nothing. Existing border component ranges are replaced.\n     */\n    loadBorderComponent(borderComponents: LayerBorderComponent[]): void {\n        this._borderComponents = [];\n\n        const accum = { nPoints: 0, nLines: 0 };\n        for (let cId = 0; cId < borderComponents.length; cId++) {\n            const comp = borderComponents[cId];\n\n            accum.nPoints += comp.nPoints;\n            accum.nLines += comp.nLines;\n\n            this._borderComponents.push({\n                nPoints: accum.nPoints,\n                nLines: accum.nLines\n            });\n        }\n    }\n\n    /**\n     * Creates GPU pipelines for the filled triangles and optional border pass.\n     *\n     * The border pipeline is created only when packed border geometry is\n     * available.\n     *\n     * @param renderer Renderer that owns the WebGPU device and shared render\n     * state.\n     * @returns Nothing. Required GPU pipeline resources are created for the\n     * layer.\n     */\n    override createPipeline(renderer: Renderer): void {\n        super.createPipeline(renderer);\n\n        if (this._borderPosition.length > 0) {\n            this._pipelineBorder = new PipelineTriangleBorder(renderer);\n            this._pipelineBorder.build(this);\n        }\n    }\n\n    /**\n     * Renders the filled geometry and, when present, the border pass.\n     *\n     * The border pipeline reuses the layer's current z-index and updates its\n     * vertex buffers whenever the layer data was dirty at the start of the pass.\n     * This preserves synchronization between filled geometry updates and border\n     * rendering.\n     *\n     * @param camera Active view and projection camera.\n     * @param passEncoder Render pass encoder for the current frame.\n     * @returns Nothing. Draw commands are recorded into the provided render\n     * pass.\n     */\n    override renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        // VectorLayer.renderPass() clears dirty flags after updating the main\n        // fill/picking pipelines, so preserve the data-dirty state needed to\n        // keep the border buffers in sync for skip/geometry changes.\n        const dataDirty = this._dataIsDirty;\n        const renderInfoDirty = this._renderInfoIsDirty;\n\n        super.renderPass(camera, passEncoder);\n\n        if (!this._pipelineBorder) { return; }\n\n        if (dataDirty) {\n            this._pipelineBorder.updateVertexBuffers(this);\n        }\n\n        if (renderInfoDirty) {\n            this._pipelineBorder.updateColorUniforms(this);\n        }\n\n        // Keep hidden border buffers/uniforms synchronized so toggling them back on needs no reload.\n        if (this._layerRenderInfo.showBorders !== false) {\n            this._pipelineBorder.updateZIndex(this._layerInfo.zIndex);\n            this._pipelineBorder.renderPass(camera, passEncoder);\n        }\n    }\n\n    /**\n     * Releases GPU resources owned by the layer and its border pipeline.\n     *\n     * @returns Nothing. After destruction, GPU resources owned by this layer\n     * are no longer usable.\n     */\n    override destroy(): void {\n        super.destroy();\n        this._pipelineBorder?.destroy();\n    }\n}\n","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n@group(2) @binding(0) var<uniform> pointSize: f32;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4<f32>,\\n    @location(0) outLocal: vec2<f32>,\\n    @location(1) outThematic: f32,\\n    @location(2) outHighlighted: f32,\\n    @location(3) outThematicValid: f32,\\n    @location(4) outSkipped: f32,\\n };\\n\\n@vertex\\nfn main(\\n    @location(0) inLocal: vec2f,\\n    @location(1) inCenter: vec2f,\\n    @location(2) inThematic: f32,\\n    @location(3) inHighlighted: f32,\\n    @location(4) inThematicValid: f32,\\n    @location(5) inSkipped: f32,\\n) -> VSOut {\\n    var vsOut: VSOut;\\n    let worldPosition = inCenter + inLocal * pointSize;\\n\\n    vsOut.outPosition = projection * modelView * vec4f(worldPosition.x, worldPosition.y, zIndex, 1.0);\\n    vsOut.outLocal = inLocal;\\n    vsOut.outThematic = inThematic;\\n    vsOut.outHighlighted = inHighlighted;\\n    vsOut.outThematicValid = inThematicValid;\\n    vsOut.outSkipped = inSkipped;\\n\\n    return vsOut;\\n}\";","export default \"@group(0) @binding(0) var<uniform> color : vec4f;\\n@group(0) @binding(1) var<uniform> highlightColor : vec4f;\\n@group(0) @binding(2) var<uniform> showThematic : f32;\\n@group(0) @binding(3) var<uniform> showHighlight : f32;\\n@group(0) @binding(4) var cMapTex : texture_2d<f32>;\\n@group(0) @binding(5) var cMapSampler : sampler;\\n@group(0) @binding(6) var<uniform> opacity : f32;\\n@group(0) @binding(7) var<uniform> domainParams : vec4f;\\n@group(0) @binding(8) var<uniform> invalidValueColor : vec4f;\\n\\n@fragment\\nfn main(\\n    @location(0) inLocal: vec2<f32>,\\n    @location(1) inThematic: f32,\\n    @location(2) inHighlighted: f32,\\n    @location(3) inThematicValid: f32,\\n    @location(4) inSkipped: f32,\\n) -> @location(0) vec4f {\\n    if (dot(inLocal, inLocal) > 1.0) {\\n        discard;\\n    }\\n\\n    if (inSkipped > 0.0) {\\n        discard;\\n    }\\n\\n    var outColor = vec4f(color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a);\\n\\n    var thematicValue = inThematic;\\n    if (domainParams.z > 1.5) {\\n        let nCategories = domainParams.w;\\n        let denom = max(1.0, nCategories - 1.0);\\n        thematicValue = clamp(inThematic / denom, 0.0, 1.0);\\n    } else if (domainParams.z > 0.5) {\\n        let minVal = domainParams.x;\\n        let maxVal = domainParams.y;\\n        let range = maxVal - minVal;\\n        thematicValue = select(0.0, clamp((inThematic - minVal) / range, 0.0, 1.0), range > 0.0);\\n    }\\n\\n    let sampledColor = textureSample(cMapTex, cMapSampler, vec2f(thematicValue, 0.0));\\n\\n    if (showHighlight > 0.0 && inHighlighted > 0.0) {\\n        outColor = vec4f(highlightColor.r / 255.0, highlightColor.g / 255.0, highlightColor.b / 255.0, highlightColor.a);\\n    } else if (showThematic > 0.0 && inThematicValid < 0.5) {\\n        outColor = vec4f(invalidValueColor.r / 255.0, invalidValueColor.g / 255.0, invalidValueColor.b / 255.0, invalidValueColor.a);\\n    } else if (showThematic > 0.0) {\\n        outColor = sampledColor;\\n    }\\n\\n    return vec4f(outColor.rgb * opacity, opacity);\\n}\";","/// <reference types=\"@webgpu/types\" />\n\nimport spriteVertexSource from './shaders/sprite.vert.wgsl';\nimport spriteFragmentSource from './shaders/sprite.frag.wgsl';\n\nimport { Pipeline } from './pipeline';\nimport { Renderer } from './renderer';\nimport { Camera } from '@urban-toolkit/autk-core';\nimport { SpriteLayer } from './layer-sprite';\n\nexport class PipelineSprite extends Pipeline {\n    protected _quadBuffer!: GPUBuffer;\n    protected _instanceBuffer!: GPUBuffer;\n    protected _thematicBuffer!: GPUBuffer;\n    protected _highlightedBuffer!: GPUBuffer;\n    protected _thematicValidityBuffer!: GPUBuffer;\n    protected _skippedBuffer!: GPUBuffer;\n    protected _indicesBuffer!: GPUBuffer;\n    protected _pointSizeBuffer!: GPUBuffer;\n    protected _pointBindGroup!: GPUBindGroup;\n    protected _pointBindGroupLayout!: GPUBindGroupLayout;\n    protected _vertModule!: GPUShaderModule;\n    protected _fragModule!: GPUShaderModule;\n    protected _pipeline!: GPURenderPipeline;\n\n    private _quadData: Float32Array<ArrayBuffer> | null = null;\n    private _instanceData: Float32Array<ArrayBuffer> | null = null;\n    private _thematicData: Float32Array<ArrayBuffer> | null = null;\n    private _highlightedData: Float32Array<ArrayBuffer> | null = null;\n    private _thematicValidityData: Float32Array<ArrayBuffer> | null = null;\n    private _skippedData: Float32Array<ArrayBuffer> | null = null;\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    private _pointSizeData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4));\n\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    override destroy(): void {\n        this._quadBuffer?.destroy();\n        this._instanceBuffer?.destroy();\n        this._thematicBuffer?.destroy();\n        this._highlightedBuffer?.destroy();\n        this._thematicValidityBuffer?.destroy();\n        this._skippedBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._pointSizeBuffer?.destroy();\n        super.destroy();\n    }\n\n    build(layer: SpriteLayer): void {\n        this.createShaders();\n        this.createVertexBuffers(layer);\n        this.createColorUniformBindGroup();\n        this.createCameraUniformBindGroup();\n        this.createPointUniformBindGroup();\n        this.updateVertexBuffers(layer);\n        this.updateColorUniforms(layer);\n        this.updatePointSize(layer.pointSize);\n        this.createPipeline();\n    }\n\n    createShaders(): void {\n        this._vertModule = this._renderer.device.createShaderModule({ code: spriteVertexSource });\n        this._fragModule = this._renderer.device.createShaderModule({ code: spriteFragmentSource });\n    }\n\n    createVertexBuffers(layer: SpriteLayer): void {\n        this._quadBuffer = this._renderer.device.createBuffer({\n            label: 'Point quad buffer',\n            size: 4 * 2 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._instanceBuffer = this._renderer.device.createBuffer({\n            label: 'Point instance center buffer',\n            size: layer.pointInstances.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._thematicBuffer = this._renderer.device.createBuffer({\n            label: 'Point thematic buffer',\n            size: layer.thematic.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._highlightedBuffer = this._renderer.device.createBuffer({\n            label: 'Point highlighted buffer',\n            size: layer.highlightedVertices.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._thematicValidityBuffer = this._renderer.device.createBuffer({\n            label: 'Point thematic validity buffer',\n            size: layer.thematicValidity.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._skippedBuffer = this._renderer.device.createBuffer({\n            label: 'Point skipped buffer',\n            size: layer.skippedVertices.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Point quad indices buffer',\n            size: 6 * Uint32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    updateVertexBuffers(layer: SpriteLayer): void {\n        this._quadData = this._syncFloatData(this._quadData, [-1, -1, 1, -1, 1, 1, -1, 1]);\n        this._instanceData = this._syncFloatData(this._instanceData, layer.pointInstances);\n        this._thematicData = this._syncFloatData(this._thematicData, layer.thematic);\n        this._highlightedData = this._syncFloatData(this._highlightedData, layer.highlightedVertices);\n        this._thematicValidityData = this._syncFloatData(this._thematicValidityData, layer.thematicValidity);\n        this._skippedData = this._syncFloatData(this._skippedData, layer.skippedVertices);\n        this._indicesData = this._syncUintData(this._indicesData, [0, 1, 2, 0, 2, 3]);\n\n        this._renderer.device.queue.writeBuffer(this._quadBuffer, 0, this._quadData);\n        this._renderer.device.queue.writeBuffer(this._instanceBuffer, 0, this._instanceData);\n        this._renderer.device.queue.writeBuffer(this._thematicBuffer, 0, this._thematicData);\n        this._renderer.device.queue.writeBuffer(this._highlightedBuffer, 0, this._highlightedData);\n        this._renderer.device.queue.writeBuffer(this._thematicValidityBuffer, 0, this._thematicValidityData);\n        this._renderer.device.queue.writeBuffer(this._skippedBuffer, 0, this._skippedData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n    }\n\n    createPointUniformBindGroup(): void {\n        this._pointSizeBuffer = this._renderer.device.createBuffer({\n            label: 'Point size buffer',\n            size: Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n\n        this._pointBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            entries: [{\n                binding: 0,\n                visibility: GPUShaderStage.VERTEX,\n                buffer: {},\n            }],\n        });\n\n        this._pointBindGroup = this._renderer.device.createBindGroup({\n            layout: this._pointBindGroupLayout,\n            entries: [{ binding: 0, resource: { buffer: this._pointSizeBuffer } }],\n        });\n    }\n\n    updatePointSize(size: number): void {\n        this._pointSizeData[0] = size;\n        this._renderer.device.queue.writeBuffer(this._pointSizeBuffer, 0, this._pointSizeData);\n    }\n\n    createPipeline(): void {\n        const quadBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x2' }],\n            arrayStride: 2 * Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'vertex',\n        };\n        const instanceBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 1, offset: 0, format: 'float32x2' }],\n            arrayStride: 2 * Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n        const thematicBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 2, offset: 0, format: 'float32' }],\n            arrayStride: Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n        const highlightedBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 3, offset: 0, format: 'float32' }],\n            arrayStride: Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n        const thematicValidityBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 4, offset: 0, format: 'float32' }],\n            arrayStride: Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n        const skippedBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 5, offset: 0, format: 'float32' }],\n            arrayStride: Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [\n                quadBufferDesc,\n                instanceBufferDesc,\n                thematicBufferDesc,\n                highlightedBufferDesc,\n                thematicValidityBufferDesc,\n                skippedBufferDesc,\n            ],\n        };\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [{\n                format: this._renderer.canvasFormat,\n                blend: {\n                    color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                    alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                },\n            }],\n        };\n        const primitive: GPUPrimitiveState = { frontFace: 'cw', cullMode: 'none', topology: 'triangle-list' };\n        const multisample: GPUMultisampleState = { count: this._renderer.sampleCount };\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: false,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n\n        const layout = this._renderer.device.createPipelineLayout({\n            bindGroupLayouts: [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout, this._pointBindGroupLayout],\n        });\n        this._pipeline = this._renderer.device.createRenderPipeline({\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            multisample,\n            label: 'Pipeline sprite',\n        });\n    }\n\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        passEncoder.setPipeline(this._pipeline);\n        this.updateCameraUniforms(camera);\n        passEncoder.setVertexBuffer(0, this._quadBuffer);\n        passEncoder.setVertexBuffer(1, this._instanceBuffer);\n        passEncoder.setVertexBuffer(2, this._thematicBuffer);\n        passEncoder.setVertexBuffer(3, this._highlightedBuffer);\n        passEncoder.setVertexBuffer(4, this._thematicValidityBuffer);\n        passEncoder.setVertexBuffer(5, this._skippedBuffer);\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n        passEncoder.setBindGroup(0, this._renderInfoBindGroup);\n        passEncoder.setBindGroup(1, this._cameraBindGroup);\n        passEncoder.setBindGroup(2, this._pointBindGroup);\n\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0 && this._instanceBuffer.size > 0) {\n            passEncoder.drawIndexed(indexCount, this._instanceBuffer.size / (2 * Float32Array.BYTES_PER_ELEMENT));\n        }\n    }\n}\n","export default \"@group(0) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(0) @binding(1) var<uniform> projection: mat4x4f;\\n@group(0) @binding(2) var<uniform> zIndex: f32;\\n@group(1) @binding(0) var<uniform> pointSize: f32;\\n\\nstruct VSOut {\\n    @builtin(position) position: vec4<f32>,\\n    @location(0) color: vec3<f32>,\\n    @location(1) local: vec2<f32>,\\n };\\n\\n@vertex\\nfn main(\\n    @location(0) inLocal: vec2f,\\n    @location(1) inCenter: vec2f,\\n    @location(2) objectId: vec3<f32>,\\n) -> VSOut {\\n    var vsOut: VSOut;\\n    let worldPosition = inCenter + inLocal * pointSize;\\n    vsOut.position = projection * modelView * vec4f(worldPosition.x, worldPosition.y, zIndex, 1.0);\\n    vsOut.color = objectId;\\n    vsOut.local = inLocal;\\n    return vsOut;\\n}\";","export default \"@fragment\\nfn main(@location(0) color: vec3<f32>, @location(1) local: vec2<f32>) -> @location(0) vec4<f32> {\\n    if (dot(local, local) > 1.0) {\\n        discard;\\n    }\\n    return vec4<f32>(color, 1.0);\\n}\";","/// <reference types=\"@webgpu/types\" />\n\nimport pickingVertexSource from './shaders/sprite-picking.vert.wgsl';\nimport pickingFragmentSource from './shaders/sprite-picking.frag.wgsl';\n\nimport { Pipeline } from './pipeline';\nimport { Renderer } from './renderer';\nimport { Camera } from '@urban-toolkit/autk-core';\nimport { SpriteLayer } from './layer-sprite';\n\nexport class PipelineSpritePicking extends Pipeline {\n    private _quadBuffer!: GPUBuffer;\n    private _instanceBuffer!: GPUBuffer;\n    private _objectIdsBuffer!: GPUBuffer;\n    private _indicesBuffer!: GPUBuffer;\n    private _pointSizeBuffer!: GPUBuffer;\n    private _pointBindGroup!: GPUBindGroup;\n    private _pointBindGroupLayout!: GPUBindGroupLayout;\n    private _vertModule!: GPUShaderModule;\n    private _fragModule!: GPUShaderModule;\n    private _pipeline!: GPURenderPipeline;\n\n    private _quadData: Float32Array<ArrayBuffer> | null = null;\n    private _instanceData: Float32Array<ArrayBuffer> | null = null;\n    private _objectIdsData: Float32Array<ArrayBuffer> | null = null;\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    private _pointSizeData: Float32Array<ArrayBuffer> = new Float32Array(new ArrayBuffer(4));\n\n    constructor(renderer: Renderer) {\n        super(renderer);\n    }\n\n    override destroy(): void {\n        this._quadBuffer?.destroy();\n        this._instanceBuffer?.destroy();\n        this._objectIdsBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._pointSizeBuffer?.destroy();\n        super.destroy();\n    }\n\n    build(layer: SpriteLayer): void {\n        this.createShaders();\n        this.createVertexBuffers(layer);\n        this.createCameraUniformBindGroup();\n        this.createPointUniformBindGroup();\n        this.updateVertexBuffers(layer);\n        this.updatePointSize(layer.pointSize);\n        this.createPipeline();\n    }\n\n    createShaders(): void {\n        this._vertModule = this._renderer.device.createShaderModule({ code: pickingVertexSource });\n        this._fragModule = this._renderer.device.createShaderModule({ code: pickingFragmentSource });\n    }\n\n    createVertexBuffers(layer: SpriteLayer): void {\n        this._quadBuffer = this._renderer.device.createBuffer({\n            label: 'Point picking quad buffer',\n            size: 4 * 2 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._instanceBuffer = this._renderer.device.createBuffer({\n            label: 'Point picking center buffer',\n            size: layer.pointInstances.length * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._objectIdsBuffer = this._renderer.device.createBuffer({\n            label: 'Point picking ids buffer',\n            size: layer.instanceCount * 3 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this._indicesBuffer = this._renderer.device.createBuffer({\n            label: 'Point picking quad indices buffer',\n            size: 6 * Uint32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,\n        });\n    }\n\n    updateVertexBuffers(layer: SpriteLayer): void {\n        this._quadData = this._syncFloatData(this._quadData, [-1, -1, 1, -1, 1, 1, -1, 1]);\n        this._instanceData = this._syncFloatData(this._instanceData, layer.pointInstances);\n        this._indicesData = this._syncUintData(this._indicesData, [0, 1, 2, 0, 2, 3]);\n        this._objectIdsData = this._syncFloatLength(this._objectIdsData, layer.instanceCount * 3);\n        this._objectIdsData.fill(0);\n\n        for (let compId = 0; compId < layer.components.length; compId++) {\n            const color = this._encodeIdToRGB(compId);\n            const start = compId > 0 ? layer.components[compId - 1].nPoints : 0;\n            const end = layer.components[compId].nPoints;\n            for (let instanceId = start; instanceId < end; instanceId++) {\n                const base = instanceId * 3;\n                this._objectIdsData[base + 0] = color[0];\n                this._objectIdsData[base + 1] = color[1];\n                this._objectIdsData[base + 2] = color[2];\n            }\n        }\n\n        this._renderer.device.queue.writeBuffer(this._quadBuffer, 0, this._quadData);\n        this._renderer.device.queue.writeBuffer(this._instanceBuffer, 0, this._instanceData);\n        this._renderer.device.queue.writeBuffer(this._objectIdsBuffer, 0, this._objectIdsData);\n        this._renderer.device.queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n    }\n\n    private _encodeIdToRGB(id: number): [number, number, number] {\n        const shifted = id + 1;\n        return [\n            (shifted & 0xff) / 255,\n            ((shifted >> 8) & 0xff) / 255,\n            ((shifted >> 16) & 0xff) / 255,\n        ];\n    }\n\n    createPointUniformBindGroup(): void {\n        this._pointSizeBuffer = this._renderer.device.createBuffer({\n            label: 'Point picking size buffer',\n            size: Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n        this._pointBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: {} }],\n        });\n        this._pointBindGroup = this._renderer.device.createBindGroup({\n            layout: this._pointBindGroupLayout,\n            entries: [{ binding: 0, resource: { buffer: this._pointSizeBuffer } }],\n        });\n    }\n\n    updatePointSize(size: number): void {\n        this._pointSizeData[0] = size;\n        this._renderer.device.queue.writeBuffer(this._pointSizeBuffer, 0, this._pointSizeData);\n    }\n\n    private createPipeline(): void {\n        const quadBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x2' }],\n            arrayStride: 2 * Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'vertex',\n        };\n        const instanceBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 1, offset: 0, format: 'float32x2' }],\n            arrayStride: 2 * Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n        const idsBufferDesc: GPUVertexBufferLayout = {\n            attributes: [{ shaderLocation: 2, offset: 0, format: 'float32x3' }],\n            arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,\n            stepMode: 'instance',\n        };\n\n        const vertex: GPUVertexState = {\n            module: this._vertModule,\n            entryPoint: 'main',\n            buffers: [quadBufferDesc, instanceBufferDesc, idsBufferDesc],\n        };\n        const fragment: GPUFragmentState = {\n            module: this._fragModule,\n            entryPoint: 'main',\n            targets: [{ format: 'rgba8unorm' }],\n        };\n        const primitive: GPUPrimitiveState = { frontFace: 'cw', cullMode: 'none', topology: 'triangle-list' };\n        const depthStencil: GPUDepthStencilState = {\n            depthWriteEnabled: false,\n            depthCompare: 'greater-equal',\n            format: 'depth32float',\n        };\n        const layout = this._renderer.device.createPipelineLayout({\n            bindGroupLayouts: [this._cameraBindGroupLayout, this._pointBindGroupLayout],\n        });\n        this._pipeline = this._renderer.device.createRenderPipeline({\n            layout,\n            vertex,\n            fragment,\n            primitive,\n            depthStencil,\n            label: 'Pipeline sprite picking',\n        });\n    }\n\n    renderPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        const ownsPass = !passEncoder;\n        passEncoder ??= this._renderer.commandEncoder.beginRenderPass({\n            colorAttachments: [this._renderer.pickingBuffer],\n            depthStencilAttachment: this._renderer.pickingDepthBuffer,\n        });\n        passEncoder.setPipeline(this._pipeline);\n        this.updateCameraUniforms(camera);\n        passEncoder.setVertexBuffer(0, this._quadBuffer);\n        passEncoder.setVertexBuffer(1, this._instanceBuffer);\n        passEncoder.setVertexBuffer(2, this._objectIdsBuffer);\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n        passEncoder.setBindGroup(0, this._cameraBindGroup);\n        passEncoder.setBindGroup(1, this._pointBindGroup);\n        const indexCount = this._indicesBuffer.size / Uint32Array.BYTES_PER_ELEMENT;\n        if (indexCount > 0 && this._instanceBuffer.size > 0) {\n            passEncoder.drawIndexed(indexCount, this._instanceBuffer.size / (2 * Float32Array.BYTES_PER_ELEMENT));\n        }\n        if (ownsPass) {\n            passEncoder.end();\n        }\n    }\n}\n","import { Camera, LayerComponent } from '@urban-toolkit/autk-core';\nimport { LayerData, LayerInfo, LayerRenderInfo, LayerThematic, DEFAULT_POINT_SIZE } from './types-layers';\nimport { Layer } from './layer';\nimport { Renderer } from './renderer';\nimport { PipelineSprite } from './pipeline-sprite';\nimport { PipelineSpritePicking } from './pipeline-sprite-picking';\n\nexport class SpriteLayer extends Layer {\n    protected _pointInstances: Float32Array = new Float32Array(0);\n    protected _components: LayerComponent[] = [];\n    protected _thematic: Float32Array = new Float32Array(0);\n    protected _thematicValidity: Float32Array = new Float32Array(0);\n    protected _highlightedVertices: Float32Array = new Float32Array(0);\n    protected _skippedVertices: Float32Array = new Float32Array(0);\n    protected _pipeline!: PipelineSprite;\n    protected _pipelinePicking!: PipelineSpritePicking;\n    protected _highlightedIds: Set<number> = new Set();\n    protected _skippedIds: Set<number> = new Set();\n\n    constructor(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData) {\n        super(layerInfo, layerRenderInfo);\n        this.loadLayerData(layerData);\n    }\n\n    override get supportsPicking(): boolean { return true; }\n    override get supportsHighlight(): boolean { return true; }\n\n    get components(): LayerComponent[] {\n        return this._components;\n    }\n\n    get highlightedIds(): number[] {\n        return Array.from(this._highlightedIds);\n    }\n\n    get pointInstances(): Float32Array {\n        return this._pointInstances;\n    }\n\n    get pointSize(): number {\n        return this._layerRenderInfo.pointSize ?? DEFAULT_POINT_SIZE;\n    }\n\n    get thematic(): Float32Array {\n        return this._thematic;\n    }\n\n    get thematicValidity(): Float32Array {\n        return this._thematicValidity;\n    }\n\n    get highlightedVertices(): Float32Array {\n        return this._highlightedVertices;\n    }\n\n    get skippedVertices(): Float32Array {\n        return this._skippedVertices;\n    }\n\n    get instanceCount(): number {\n        return this._pointInstances.length / 2;\n    }\n\n    loadLayerData(layerData: LayerData): void {\n        this._pointInstances = layerData.pointInstances ?? new Float32Array(0);\n        this.loadComponent(layerData.components);\n        this._resetInteractionState();\n\n        if (layerData.thematic && layerData.thematic.length) {\n            this.loadThematic(layerData.thematic);\n        } else {\n            this._thematic = new Float32Array(this.instanceCount);\n            this._thematicValidity = new Float32Array(this.instanceCount);\n            this._thematicValidity.fill(1);\n        }\n    }\n\n    loadComponent(layerComponents: LayerComponent[]): void {\n        const accum = { nPoints: 0, nTriangles: 0 };\n        this._components = layerComponents.map((comp) => {\n            accum.nPoints += comp.nPoints;\n            accum.nTriangles += comp.nTriangles;\n            return {\n                ...comp,\n                nPoints: accum.nPoints,\n                nTriangles: accum.nTriangles,\n            };\n        });\n    }\n\n    loadThematic(layerThematic: LayerThematic[]): boolean {\n        if (layerThematic.length !== this._components.length) {\n            console.error(\n                `SpriteLayer.loadThematic: expected ${this._components.length} thematic entries, got ${layerThematic.length}.`\n            );\n            return false;\n        }\n\n        const thematic = new Float32Array(this.instanceCount);\n        const thematicValidity = new Float32Array(this.instanceCount);\n\n        let offset = 0;\n        for (let compId = 0; compId < layerThematic.length; compId++) {\n            const start = compId > 0 ? this._components[compId - 1].nPoints : 0;\n            const end = this._components[compId].nPoints;\n            const count = end - start;\n            thematic.fill(layerThematic[compId].value, offset, offset + count);\n            thematicValidity.fill(layerThematic[compId].valid, offset, offset + count);\n            offset += count;\n        }\n\n        if (offset !== this.instanceCount) {\n            console.error(\n                `SpriteLayer.loadThematic: filled ${offset} thematic values for ${this.instanceCount} instances.`\n            );\n            return false;\n        }\n\n        this._thematic = thematic;\n        this._thematicValidity = thematicValidity;\n        return true;\n    }\n\n    createPipeline(renderer: Renderer): void {\n        this._pipeline = new PipelineSprite(renderer);\n        this._pipeline.build(this);\n\n        this._pipelinePicking = new PipelineSpritePicking(renderer);\n        this._pipelinePicking.build(this);\n    }\n\n    renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        if (this._renderInfoIsDirty) {\n            this._pipeline.updateColorUniforms(this);\n            this._renderInfoIsDirty = false;\n        }\n\n        if (this._dataIsDirty) {\n            this._pipeline.updateVertexBuffers(this);\n            this._pipelinePicking.updateVertexBuffers(this);\n            this._dataIsDirty = false;\n        }\n\n        this._pipeline.updateZIndex(this._layerInfo.zIndex);\n        this._pipeline.updatePointSize(this.pointSize);\n        this._pipeline.renderPass(camera, passEncoder);\n    }\n\n    override renderPickingPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        this._pipelinePicking.updateZIndex(this._layerInfo.zIndex);\n        this._pipelinePicking.updatePointSize(this.pointSize);\n        this._pipelinePicking.renderPass(camera, passEncoder);\n    }\n\n    toggleHighlightedIds(ids: number[]): void {\n        for (const id of ids) {\n            if (id < 0 || id >= this._components.length) { continue; }\n            if (this._highlightedIds.has(id)) {\n                this._highlightedIds.delete(id);\n            } else {\n                this._highlightedIds.add(id);\n            }\n\n            const start = id > 0 ? this._components[id - 1].nPoints : 0;\n            const end = this._components[id].nPoints;\n            for (let index = start; index < end; index++) {\n                this._highlightedVertices[index] = 1 - this._highlightedVertices[index];\n            }\n        }\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    override clearHighlightedIds(): void {\n        this._highlightedIds.clear();\n        this._highlightedVertices.fill(0);\n        this.makeLayerRenderInfoDirty();\n        this.makeLayerDataDirty();\n    }\n\n    override setHighlightedIds(ids: number[]): void {\n        this.clearHighlightedIds();\n        for (const id of ids) {\n            if (id < 0 || id >= this._components.length) { continue; }\n            this._highlightedIds.add(id);\n            const start = id > 0 ? this._components[id - 1].nPoints : 0;\n            const end = this._components[id].nPoints;\n            this._highlightedVertices.fill(1, start, end);\n        }\n        this.makeLayerDataDirty();\n    }\n\n    override setSkippedIds(ids: number[]): void {\n        this.clearSkippedIds();\n        for (const id of ids) {\n            if (id < 0 || id >= this._components.length) { continue; }\n            this._skippedIds.add(id);\n            const start = id > 0 ? this._components[id - 1].nPoints : 0;\n            const end = this._components[id].nPoints;\n            this._skippedVertices.fill(1, start, end);\n        }\n        this.makeLayerDataDirty();\n    }\n\n    override clearSkippedIds(): void {\n        this._skippedIds.clear();\n        this._skippedVertices.fill(0);\n        this.makeLayerDataDirty();\n    }\n\n    override destroy(): void {\n        this._pipeline?.destroy();\n        this._pipelinePicking?.destroy();\n    }\n\n    private _resetInteractionState(): void {\n        this._highlightedIds = new Set();\n        this._skippedIds = new Set();\n        this._highlightedVertices = new Float32Array(this.instanceCount);\n        this._skippedVertices = new Float32Array(this.instanceCount);\n    }\n}\n","export default \"struct PolylineAdjacency {\\n    previous: vec2f,\\n    next: vec2f,\\n};\\n\\nfn polylineSideRole(vertexIndex: u32) -> vec2f {\\n    let vertex = vertexIndex % 5u;\\n    if (vertex == 4u) { return vec2f(0.0); }\\n    let side = select(-1.0, 1.0, vertex % 2u == 0u);\\n    let role = select(-1.0, 1.0, vertex >= 2u);\\n    return vec2f(side, role);\\n}\\n\\nfn expandPolyline(center: vec2f, previous: vec2f, next: vec2f, sideRole: vec2f, width: f32) -> vec2f {\\n    let side = sideRole.x;\\n    let role = sideRole.y;\\n    if (side == 0.0) { return center; }\\n\\n    let before = center - previous;\\n    let after = next - center;\\n    let beforeLength = length(before);\\n    let afterLength = length(after);\\n    var incoming = before / select(1.0, beforeLength, beforeLength > 0.0);\\n    var outgoing = after / select(1.0, afterLength, afterLength > 0.0);\\n    if (beforeLength == 0.0) { incoming = outgoing; }\\n    if (afterLength == 0.0) { outgoing = incoming; }\\n    let incomingNormal = vec2f(-incoming.y, incoming.x);\\n    let outgoingNormal = vec2f(-outgoing.y, outgoing.x);\\n    let sum = incomingNormal + outgoingNormal;\\n    let sumLength = length(sum);\\n\\n    \\n    if (sumLength > 0.000001) {\\n        let miter = sum / sumLength;\\n        let denominator = dot(miter, outgoingNormal);\\n        if (denominator >= 0.25) {\\n            return center + miter * (side * width * 0.5 / denominator);\\n        }\\n    }\\n    let normal = select(incomingNormal, outgoingNormal, role > 0.0);\\n    return center + normal * (side * width * 0.5);\\n}\";","export default \"@group(1) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(1) @binding(1) var<uniform> projection: mat4x4f;\\n@group(1) @binding(2) var<uniform> zIndex: f32;\\n@group(2) @binding(0) var<uniform> widthOverride: f32;\\n@group(2) @binding(1) var<storage, read> adjacency: array<PolylineAdjacency>;\\n\\nstruct VSOut {\\n    @builtin(position) outPosition: vec4f,\\n    @location(0) outThematic: f32,\\n    @location(1) outHighlighted: f32,\\n    @location(2) outThematicValid: f32,\\n    @location(3) outSkipped: f32,\\n};\\n\\n@vertex\\nfn main(\\n    @builtin(vertex_index) vertexIndex: u32,\\n    @location(0) center: vec2f,\\n    @location(4) defaultWidth: f32,\\n    @location(5) thematic: f32,\\n    @location(6) highlighted: f32,\\n    @location(7) thematicValid: f32,\\n    @location(8) skipped: f32,\\n) -> VSOut {\\n    let width = select(defaultWidth, widthOverride, widthOverride > 0.0);\\n    let node = adjacency[vertexIndex / 5u];\\n    let position = expandPolyline(center, node.previous, node.next, polylineSideRole(vertexIndex), width);\\n    var out: VSOut;\\n    out.outPosition = projection * modelView * vec4f(position, zIndex, 1.0);\\n    out.outThematic = thematic;\\n    out.outHighlighted = highlighted;\\n    out.outThematicValid = thematicValid;\\n    out.outSkipped = skipped;\\n    return out;\\n}\";","export default \"@group(0) @binding(0) var<uniform> modelView: mat4x4f;\\n@group(0) @binding(1) var<uniform> projection: mat4x4f;\\n@group(0) @binding(2) var<uniform> zIndex: f32;\\n@group(1) @binding(0) var<uniform> widthOverride: f32;\\n@group(1) @binding(1) var<storage, read> adjacency: array<PolylineAdjacency>;\\n\\nstruct VSOut {\\n    @builtin(position) position: vec4f,\\n    @location(0) color: vec3f,\\n    @location(1) skipped: f32,\\n};\\n\\n@vertex\\nfn main(\\n    @builtin(vertex_index) vertexIndex: u32,\\n    @location(0) center: vec2f,\\n    @location(4) defaultWidth: f32,\\n    @location(5) objectId: vec3f,\\n    @location(8) skipped: f32,\\n) -> VSOut {\\n    let width = select(defaultWidth, widthOverride, widthOverride > 0.0);\\n    let node = adjacency[vertexIndex / 5u];\\n    let position = expandPolyline(center, node.previous, node.next, polylineSideRole(vertexIndex), width);\\n    var out: VSOut;\\n    out.position = projection * modelView * vec4f(position, zIndex, 1.0);\\n    out.color = objectId;\\n    out.skipped = skipped;\\n    return out;\\n}\";","export default \"struct FSIn {\\n    @location(0) color: vec3f,\\n    @location(1) skipped: f32,\\n};\\n\\n@fragment\\nfn main(in: FSIn) -> @location(0) vec4f {\\n    if (in.skipped > 0.5) { discard; }\\n    return vec4f(in.color, 1.0);\\n}\";","/// <reference types=\"@webgpu/types\" />\n\nimport type { Camera } from '@urban-toolkit/autk-core';\nimport { TriangulatorPolylines } from '@urban-toolkit/autk-core';\nimport { DEFAULT_LINE_WIDTH } from './types-layers';\nimport { Pipeline } from './pipeline';\nimport type { PolylineLayer } from './layer-polyline';\nimport type { Renderer } from './renderer';\nimport expansionSource from './shaders/polyline-expansion.wgsl';\nimport vertexSource from './shaders/polyline.vert.wgsl';\nimport pickingVertexSource from './shaders/polyline-picking.vert.wgsl';\nimport fragmentSource from './shaders/triangle-01.frag.wgsl';\nimport pickingFragmentSource from './shaders/polyline-picking.frag.wgsl';\n\n/** Shader-expanded centerline pipeline, with identical topology for display and picking. */\nexport class PipelinePolyline extends Pipeline {\n    private _positionBuffer!: GPUBuffer;\n    private _attributesBuffer!: GPUBuffer;\n    private _widthsBuffer!: GPUBuffer;\n    private _stateBuffer!: GPUBuffer;\n    private _indicesBuffer!: GPUBuffer;\n    private _widthBuffer!: GPUBuffer;\n    private _widthBindGroup!: GPUBindGroup;\n    private _widthBindGroupLayout!: GPUBindGroupLayout;\n    private _pipeline!: GPURenderPipeline;\n    private _indexCount = 0;\n    private _widthData = new Float32Array(1);\n    private _stateData: Float32Array<ArrayBuffer> | null = null;\n    private _positionData: Float32Array<ArrayBuffer> | null = null;\n    private _attributesData: Float32Array<ArrayBuffer> | null = null;\n    private _indicesData: Uint32Array<ArrayBuffer> | null = null;\n    private _widthsData: Float32Array<ArrayBuffer> | null = null;\n    private _defaultWidths?: Float32Array;\n\n    constructor(renderer: Renderer, private readonly picking = false) {\n        super(renderer);\n    }\n\n    build(layer: PolylineLayer): void {\n        this.createVertexBuffers(layer);\n        this.createCameraUniformBindGroup();\n        if (!this.picking) { this.createColorUniformBindGroup(); }\n        this._widthBuffer = this._renderer.device.createBuffer({\n            label: 'Polyline width override', size: 4,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n        this._widthBindGroupLayout = this._renderer.device.createBindGroupLayout({\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: {} },\n                { binding: 1, visibility: GPUShaderStage.VERTEX, buffer: { type: 'read-only-storage' } },\n            ],\n        });\n        this._widthBindGroup = this._renderer.device.createBindGroup({\n            layout: this._widthBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this._widthBuffer } },\n                { binding: 1, resource: { buffer: this._attributesBuffer } },\n            ],\n        });\n        this.updateVertexBuffers(layer);\n        this.updateColorUniforms(layer);\n\n        const device = this._renderer.device;\n        const stateAttributes: GPUVertexAttribute[] = this.picking\n            ? [{ shaderLocation: 5, offset: 0, format: 'float32x3' }, { shaderLocation: 8, offset: 12, format: 'float32' }]\n            : [5, 6, 7, 8].map((shaderLocation, i) => ({ shaderLocation, offset: i * 4, format: 'float32' }));\n        this._pipeline = device.createRenderPipeline({\n            label: this.picking ? 'Pipeline polyline picking' : 'Pipeline polyline',\n            layout: device.createPipelineLayout({\n                bindGroupLayouts: this.picking\n                    ? [this._cameraBindGroupLayout, this._widthBindGroupLayout]\n                    : [this._renderInfoBindGroupLayout, this._cameraBindGroupLayout, this._widthBindGroupLayout],\n            }),\n            vertex: {\n                module: device.createShaderModule({ code: `${expansionSource}\\n${this.picking ? pickingVertexSource : vertexSource}` }),\n                entryPoint: 'main',\n                buffers: [\n                    { arrayStride: 8, attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x2' }] },\n                    { arrayStride: 4, attributes: [{ shaderLocation: 4, offset: 0, format: 'float32' }] },\n                    { arrayStride: 16, attributes: stateAttributes },\n                ],\n            },\n            fragment: {\n                module: device.createShaderModule({ code: this.picking ? pickingFragmentSource : fragmentSource }),\n                entryPoint: 'main',\n                targets: [{\n                    format: this.picking ? 'rgba8unorm' : this._renderer.canvasFormat,\n                    ...(this.picking ? {} : { blend: {\n                        color: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                        alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },\n                    } as GPUBlendState }),\n                }],\n            },\n            primitive: { topology: 'triangle-list', frontFace: 'cw', cullMode: 'none' },\n            depthStencil: { format: 'depth32float', depthWriteEnabled: this.picking, depthCompare: 'greater-equal' },\n            multisample: { count: this.picking ? 1 : this._renderer.sampleCount },\n        });\n    }\n\n    createVertexBuffers(layer: PolylineLayer): void {\n        const device = this._renderer.device;\n        const vertexCount = layer.position.length / 2;\n        this._positionBuffer = device.createBuffer({ label: 'Polyline centers', size: layer.position.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n        this._attributesBuffer = device.createBuffer({ label: 'Polyline adjacency', size: layer.polylineAttributes.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });\n        this._widthsBuffer = device.createBuffer({ label: 'Polyline default widths', size: vertexCount * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n        this._stateBuffer = device.createBuffer({ label: 'Polyline feature state', size: vertexCount * 16, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n        this._indicesBuffer = device.createBuffer({ label: 'Polyline topology', size: layer.indices.byteLength, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST });\n    }\n\n    updateVertexBuffers(layer: PolylineLayer): void {\n        this._positionData = this._syncFloatData(this._positionData, layer.position);\n        this._attributesData = this._syncFloatData(this._attributesData, layer.polylineAttributes);\n        this._indicesData = this._syncUintData(this._indicesData, layer.indices);\n        this._indexCount = layer.indices.length;\n        const count = layer.position.length / 2;\n        this._stateData = this._syncFloatLength(this._stateData, count * 4);\n        for (let component = 0; component < layer.components.length; component++) {\n            const start = component === 0 ? 0 : layer.components[component - 1].nPoints;\n            const end = layer.components[component].nPoints;\n            const id = component + 1;\n            for (let i = start; i < end; i++) {\n                this._stateData[i * 4] = this.picking ? (id & 0xff) / 255 : layer.thematic[i];\n                this._stateData[i * 4 + 1] = this.picking ? ((id >> 8) & 0xff) / 255 : layer.highlightedVertices[i];\n                this._stateData[i * 4 + 2] = this.picking ? ((id >> 16) & 0xff) / 255 : layer.thematicValidity[i];\n                this._stateData[i * 4 + 3] = layer.skippedVertices[i];\n            }\n        }\n        const queue = this._renderer.device.queue;\n        queue.writeBuffer(this._positionBuffer, 0, this._positionData);\n        queue.writeBuffer(this._attributesBuffer, 0, this._attributesData);\n        queue.writeBuffer(this._indicesBuffer, 0, this._indicesData);\n        queue.writeBuffer(this._stateBuffer, 0, this._stateData);\n        // Geometry replacement can change component ranges even when styles stay the same.\n        this._widthsData = null;\n        this.updateWidth(layer);\n    }\n\n    /** Updates only render-state resources; a uniform override never reuploads geometry. */\n    updateWidth(layer: PolylineLayer): void {\n        this._widthData[0] = layer.layerRenderInfo.polylinesWidth ?? 0;\n        this._renderer.device.queue.writeBuffer(this._widthBuffer, 0, this._widthData);\n        const widths = layer.layerRenderInfo.polylinesWidthByComponent;\n        if (this._widthsData && widths === this._defaultWidths) { return; }\n        this._defaultWidths = widths;\n        this._widthsData = this._syncFloatLength(this._widthsData, layer.position.length / 2);\n        for (let component = 0; component < layer.components.length; component++) {\n            const start = component === 0 ? 0 : layer.components[component - 1].nPoints;\n            const end = layer.components[component].nPoints;\n            const width = widths?.[component];\n            const fallback = layer.layerInfo.typeLayer === 'roads'\n                ? TriangulatorPolylines.DEFAULT_ROAD_HALF_WIDTH * 2\n                : DEFAULT_LINE_WIDTH;\n            this._widthsData.fill(typeof width === 'number' && Number.isFinite(width) && width > 0 ? width : fallback, start, end);\n        }\n        this._renderer.device.queue.writeBuffer(this._widthsBuffer, 0, this._widthsData);\n    }\n\n    override updateColorUniforms(layer: PolylineLayer): void {\n        if (!this.picking) { super.updateColorUniforms(layer); }\n        this.updateWidth(layer);\n    }\n\n    renderPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        const ownsPass = !passEncoder;\n        if (!passEncoder && !this.picking) { return; }\n        passEncoder ??= this._renderer.commandEncoder.beginRenderPass({\n            colorAttachments: [this._renderer.pickingBuffer],\n            depthStencilAttachment: this._renderer.pickingDepthBuffer,\n        });\n        this.updateCameraUniforms(camera);\n        passEncoder.setPipeline(this._pipeline);\n        passEncoder.setVertexBuffer(0, this._positionBuffer);\n        passEncoder.setVertexBuffer(1, this._widthsBuffer);\n        passEncoder.setVertexBuffer(2, this._stateBuffer);\n        passEncoder.setIndexBuffer(this._indicesBuffer, 'uint32');\n        if (!this.picking) { passEncoder.setBindGroup(0, this._renderInfoBindGroup); }\n        passEncoder.setBindGroup(this.picking ? 0 : 1, this._cameraBindGroup);\n        passEncoder.setBindGroup(this.picking ? 1 : 2, this._widthBindGroup);\n        if (this._indexCount > 0) { passEncoder.drawIndexed(this._indexCount); }\n        if (ownsPass) { passEncoder.end(); }\n    }\n\n    override destroy(): void {\n        this._positionBuffer?.destroy();\n        this._attributesBuffer?.destroy();\n        this._widthsBuffer?.destroy();\n        this._stateBuffer?.destroy();\n        this._indicesBuffer?.destroy();\n        this._widthBuffer?.destroy();\n        super.destroy();\n    }\n}\n","import type { Camera } from '@urban-toolkit/autk-core';\nimport { VectorLayer } from './layer-vector';\nimport { PipelinePolyline } from './pipeline-polyline';\nimport type { LayerData } from './types-layers';\nimport type { Renderer } from './renderer';\n\n/** Centerline layer whose visual width is resolved only by the render/picking shaders. */\nexport class PolylineLayer extends VectorLayer {\n    declare protected _pipeline: PipelinePolyline;\n    declare protected _pipelinePicking: PipelinePolyline;\n    // Initialized by the parent's polymorphic loadLayerData call; do not emit a field initializer.\n    declare private _polylineAttributes: Float32Array;\n\n    get polylineAttributes(): Float32Array { return this._polylineAttributes; }\n\n    override loadLayerData(data: LayerData): void {\n        const vertexCount = data.geometry.reduce((count, geometry) => count + geometry.position.length / 2, 0);\n        if (!data.polylineAttributes || vertexCount % 5 !== 0 || data.polylineAttributes.length !== vertexCount / 5 * 4) {\n            throw new Error('PolylineLayer requires width-independent adjacency attributes for every centerline node.');\n        }\n        this._polylineAttributes = data.polylineAttributes;\n        super.loadLayerData(data);\n    }\n\n    override createPipeline(renderer: Renderer): void {\n        this._pipeline = new PipelinePolyline(renderer);\n        this._pipeline.build(this);\n        this._pipelinePicking = new PipelinePolyline(renderer, true);\n        this._pipelinePicking.build(this);\n    }\n\n    override renderPass(camera: Camera, passEncoder: GPURenderPassEncoder): void {\n        // Picking must use the new width even if it executes before the visible pass.\n        this._pipelinePicking.updateWidth(this);\n        super.renderPass(camera, passEncoder);\n    }\n\n    override renderPickingPass(camera: Camera, passEncoder?: GPURenderPassEncoder): void {\n        if (this._dataIsDirty) {\n            this._pipeline.updateVertexBuffers(this);\n            this._pipelinePicking.updateVertexBuffers(this);\n            this._dataIsDirty = false;\n        }\n        this._pipelinePicking.updateWidth(this);\n        super.renderPickingPass(camera, passEncoder);\n    }\n}\n","/**\n * @module LayerManager\n * Layer ordering and shared-origin management for map layers.\n *\n * This module defines the `LayerManager` class, which owns the registered layer\n * list, computes the shared scene origin used by geometry loaders, and enforces\n * the render-stack ordering rules for base OSM layers, dynamic layers, and\n * buildings. It also creates the concrete layer implementation that matches each\n * layer type and handles layer insertion and removal lifecycle.\n */\n\nimport { FeatureCollection, Geometry } from 'geojson';\n\nimport { computeOrigin, OSM_BASE_LAYER_ORDER } from '@urban-toolkit/autk-core';\nimport type { LayerType } from '@urban-toolkit/autk-core';\n\nimport { \n    LayerData, \n    LayerInfo, \n    LayerRenderInfo\n} from './types-layers';\n\nimport { Layer } from './layer';\nimport { RasterLayer } from './layer-raster';\nimport { Triangles3DLayer } from './layer-triangles3D';\nimport { Triangles2DLayer } from './layer-triangles2D';\nimport { SpriteLayer } from './layer-sprite';\nimport { PolylineLayer } from './layer-polyline';\n\n/**\n * Manages all map layers as a single ordered list.\n *\n * `LayerManager` stores every registered layer in render order, computes the\n * shared local origin from the first loaded collection, and assigns z-indices\n * according to the map's layering rules. Base OSM layers occupy fixed slots,\n * dynamic layers are ordered by insertion, and buildings are always rendered\n * last.\n */\nexport class LayerManager {\n    /** Registered layers sorted by render order. */\n    protected _layers: Layer[] = [];\n    /** World-space origin derived from the bounding box center. */\n    protected _origin?: number[];\n\n    /** Layer ids of non-OSM, non-buildings layers in insertion order. */\n    private _dynamicOrder: string[] = [];\n\n    /** Registered layers sorted by render z-index. */\n    get layers(): Layer[] { return this._layers; }\n\n    /** World-space origin derived from the current bounding box center. */\n    get origin(): number[] {\n        if (!this._origin) {\n            throw new Error('Layer origin has not been initialized');\n        }\n        return this._origin;\n    }\n\n    /** Indicates whether the shared scene origin has been initialized. */\n    get hasOrigin(): boolean { return this._origin !== undefined; }\n\n    /**\n     * Computes the shared scene origin from the provided collection.\n     *\n     * @param collection Source feature collection.\n     * @returns Nothing. Updates the manager's shared origin in place.\n     * @throws Never throws.\n     */\n    initializeOrigin(collection: FeatureCollection<Geometry | null>): void {\n        this._origin = computeOrigin(collection as FeatureCollection);\n    }\n\n    /**\n     * Creates, registers, and reorders a layer based on `layerInfo.typeLayer`.\n     *\n     * @param layerInfo Layer identity and type metadata.\n     * @param layerRender Initial render configuration.\n     * @param layerData Geometry and auxiliary layer payload.\n     * @returns The created layer, or `null` if a layer with the same id is already registered.\n     * @throws Never throws. Duplicate ids log an error and return `null`.\n     */\n    addLayer(layerInfo: LayerInfo, layerRender: LayerRenderInfo, layerData: LayerData): Layer | null {\n        if (this._layers.some((layer) => layer.layerInfo.id === layerInfo.id)) {\n            console.error(`LayerManager: layer id '${layerInfo.id}' already exists.`);\n            return null;\n        }\n\n        const layer: Layer = layerInfo.typeLayer === 'buildings'\n            ? new Triangles3DLayer(layerInfo, layerRender, layerData)\n            : layerInfo.typeLayer === 'raster'\n                ? new RasterLayer(layerInfo, layerRender, layerData)\n                : layerInfo.typeLayer === 'points'\n                    ? new SpriteLayer(layerInfo, layerRender, layerData)\n                    : layerData.polylineAttributes\n                        ? new PolylineLayer(layerInfo, layerRender, layerData)\n                        : new Triangles2DLayer(layerInfo, layerRender, layerData);\n\n        if (!OSM_BASE_LAYER_ORDER.includes(layerInfo.typeLayer) && layerInfo.typeLayer !== 'buildings') {\n            this._dynamicOrder.push(layerInfo.id);\n        }\n        this._layers.push(layer);\n        this._recomputeZIndices();\n        this._layers.sort((a, b) => a.layerInfo.zIndex - b.layerInfo.zIndex);\n\n        return layer;\n    }\n\n    /**\n     * Removes the layer matching `layerId` and recomputes dynamic z-order.\n     *\n     * @param layerId Layer identifier to remove.\n     * @returns Nothing. Unknown ids are silently ignored.\n     * @throws Never throws.\n     */\n    removeLayerById(layerId: string): void {\n        const layer = this.searchByLayerId(layerId);\n        if (!layer) {\n            return;\n        }\n\n        layer.setChangeListener(null);\n        layer.destroy();\n        this._layers = this._layers.filter((candidate) => candidate.layerInfo.id !== layerId);\n        this._dynamicOrder = this._dynamicOrder.filter((id) => id !== layerId);\n        this._recomputeZIndices();\n    }\n\n    /**\n     * Returns the layer with the given `layerId`, or `null` if not found.\n     *\n     * @param layerId Layer identifier to search for.\n     * @returns The matching layer instance, or `null`.\n     * @throws Never throws.\n     */\n    searchByLayerId(layerId: string): Layer | null {\n        return this._layers.find(l => l.layerInfo.id === layerId) ?? null;\n    }\n\n    /**\n     * Returns a preliminary z-index placeholder for a layer type.\n     *\n     * @param layerType Layer type to place in the render stack.\n     * @returns The fixed OSM base-slot index, or `0` as a placeholder.\n     * @throws Never throws.\n     */\n    computeZindex(layerType: LayerType): number {\n        const osmIdx = OSM_BASE_LAYER_ORDER.indexOf(layerType);\n        return osmIdx !== -1 ? osmIdx : 0;\n    }\n\n    /**\n     * Reassigns z-indices across all registered layers:\n     *\n     * - OSM base types: fixed slots 0…N-1 (by `OSM_BASE` order)\n     * - Dynamic layers: slots N, N+1, … in load-insertion order\n     * - Buildings: always last (N + dynamic count)\n     *\n     * @returns Nothing. Updates each registered layer's `layerInfo.zIndex` in\n     * place.\n     */\n    private _recomputeZIndices(): void {\n        const buildingsZ = 0; // OSM_BASE_LAYER_ORDER.length + this._dynamicOrder.length;\n\n        for (const layer of this._layers) {\n            const { typeLayer, id } = layer.layerInfo;\n            const osmIdx = OSM_BASE_LAYER_ORDER.indexOf(typeLayer);\n\n            if (osmIdx !== -1) {\n                layer.layerInfo.zIndex = osmIdx;\n            } else if (typeLayer === 'buildings') {\n                layer.layerInfo.zIndex = buildingsZ;\n            } else {\n                layer.layerInfo.zIndex = OSM_BASE_LAYER_ORDER.length + this._dynamicOrder.indexOf(id);\n            }\n        }\n    }\n}\n","var noop = {value: () => {}};\n\nfunction dispatch() {\n  for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {\n    if (!(t = arguments[i] + \"\") || (t in _) || /[\\s.]/.test(t)) throw new Error(\"illegal type: \" + t);\n    _[t] = [];\n  }\n  return new Dispatch(_);\n}\n\nfunction Dispatch(_) {\n  this._ = _;\n}\n\nfunction parseTypenames(typenames, types) {\n  return typenames.trim().split(/^|\\s+/).map(function(t) {\n    var name = \"\", i = t.indexOf(\".\");\n    if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n    if (t && !types.hasOwnProperty(t)) throw new Error(\"unknown type: \" + t);\n    return {type: t, name: name};\n  });\n}\n\nDispatch.prototype = dispatch.prototype = {\n  constructor: Dispatch,\n  on: function(typename, callback) {\n    var _ = this._,\n        T = parseTypenames(typename + \"\", _),\n        t,\n        i = -1,\n        n = T.length;\n\n    // If no callback was specified, return the callback of the given type and name.\n    if (arguments.length < 2) {\n      while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;\n      return;\n    }\n\n    // If a type was specified, set the callback for the given type and name.\n    // Otherwise, if a null callback was specified, remove callbacks of the given name.\n    if (callback != null && typeof callback !== \"function\") throw new Error(\"invalid callback: \" + callback);\n    while (++i < n) {\n      if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);\n      else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);\n    }\n\n    return this;\n  },\n  copy: function() {\n    var copy = {}, _ = this._;\n    for (var t in _) copy[t] = _[t].slice();\n    return new Dispatch(copy);\n  },\n  call: function(type, that) {\n    if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];\n    if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n    for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n  },\n  apply: function(type, that, args) {\n    if (!this._.hasOwnProperty(type)) throw new Error(\"unknown type: \" + type);\n    for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);\n  }\n};\n\nfunction get(type, name) {\n  for (var i = 0, n = type.length, c; i < n; ++i) {\n    if ((c = type[i]).name === name) {\n      return c.value;\n    }\n  }\n}\n\nfunction set(type, name, callback) {\n  for (var i = 0, n = type.length; i < n; ++i) {\n    if (type[i].name === name) {\n      type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));\n      break;\n    }\n  }\n  if (callback != null) type.push({name: name, value: callback});\n  return type;\n}\n\nexport default dispatch;\n","export var xhtml = \"http://www.w3.org/1999/xhtml\";\n\nexport default {\n  svg: \"http://www.w3.org/2000/svg\",\n  xhtml: xhtml,\n  xlink: \"http://www.w3.org/1999/xlink\",\n  xml: \"http://www.w3.org/XML/1998/namespace\",\n  xmlns: \"http://www.w3.org/2000/xmlns/\"\n};\n","import namespaces from \"./namespaces.js\";\n\nexport default function(name) {\n  var prefix = name += \"\", i = prefix.indexOf(\":\");\n  if (i >= 0 && (prefix = name.slice(0, i)) !== \"xmlns\") name = name.slice(i + 1);\n  return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins\n}\n","import namespace from \"./namespace.js\";\nimport {xhtml} from \"./namespaces.js\";\n\nfunction creatorInherit(name) {\n  return function() {\n    var document = this.ownerDocument,\n        uri = this.namespaceURI;\n    return uri === xhtml && document.documentElement.namespaceURI === xhtml\n        ? document.createElement(name)\n        : document.createElementNS(uri, name);\n  };\n}\n\nfunction creatorFixed(fullname) {\n  return function() {\n    return this.ownerDocument.createElementNS(fullname.space, fullname.local);\n  };\n}\n\nexport default function(name) {\n  var fullname = namespace(name);\n  return (fullname.local\n      ? creatorFixed\n      : creatorInherit)(fullname);\n}\n","function none() {}\n\nexport default function(selector) {\n  return selector == null ? none : function() {\n    return this.querySelector(selector);\n  };\n}\n","import {Selection} from \"./index.js\";\nimport selector from \"../selector.js\";\n\nexport default function(select) {\n  if (typeof select !== \"function\") select = selector(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n      if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n        if (\"__data__\" in node) subnode.__data__ = node.__data__;\n        subgroup[i] = subnode;\n      }\n    }\n  }\n\n  return new Selection(subgroups, this._parents);\n}\n","// Given something array like (or null), returns something that is strictly an\n// array. This is used to ensure that array-like objects passed to d3.selectAll\n// or selection.selectAll are converted into proper arrays when creating a\n// selection; we don’t ever want to create a selection backed by a live\n// HTMLCollection or NodeList. However, note that selection.selectAll will use a\n// static NodeList as a group, since it safely derived from querySelectorAll.\nexport default function array(x) {\n  return x == null ? [] : Array.isArray(x) ? x : Array.from(x);\n}\n","function empty() {\n  return [];\n}\n\nexport default function(selector) {\n  return selector == null ? empty : function() {\n    return this.querySelectorAll(selector);\n  };\n}\n","import {Selection} from \"./index.js\";\nimport array from \"../array.js\";\nimport selectorAll from \"../selectorAll.js\";\n\nfunction arrayAll(select) {\n  return function() {\n    return array(select.apply(this, arguments));\n  };\n}\n\nexport default function(select) {\n  if (typeof select === \"function\") select = arrayAll(select);\n  else select = selectorAll(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        subgroups.push(select.call(node, node.__data__, i, group));\n        parents.push(node);\n      }\n    }\n  }\n\n  return new Selection(subgroups, parents);\n}\n","export default function(selector) {\n  return function() {\n    return this.matches(selector);\n  };\n}\n\nexport function childMatcher(selector) {\n  return function(node) {\n    return node.matches(selector);\n  };\n}\n\n","import {childMatcher} from \"../matcher.js\";\n\nvar find = Array.prototype.find;\n\nfunction childFind(match) {\n  return function() {\n    return find.call(this.children, match);\n  };\n}\n\nfunction childFirst() {\n  return this.firstElementChild;\n}\n\nexport default function(match) {\n  return this.select(match == null ? childFirst\n      : childFind(typeof match === \"function\" ? match : childMatcher(match)));\n}\n","import {childMatcher} from \"../matcher.js\";\n\nvar filter = Array.prototype.filter;\n\nfunction children() {\n  return Array.from(this.children);\n}\n\nfunction childrenFilter(match) {\n  return function() {\n    return filter.call(this.children, match);\n  };\n}\n\nexport default function(match) {\n  return this.selectAll(match == null ? children\n      : childrenFilter(typeof match === \"function\" ? match : childMatcher(match)));\n}\n","import {Selection} from \"./index.js\";\nimport matcher from \"../matcher.js\";\n\nexport default function(match) {\n  if (typeof match !== \"function\") match = matcher(match);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n      if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n        subgroup.push(node);\n      }\n    }\n  }\n\n  return new Selection(subgroups, this._parents);\n}\n","export default function(update) {\n  return new Array(update.length);\n}\n","import sparse from \"./sparse.js\";\nimport {Selection} from \"./index.js\";\n\nexport default function() {\n  return new Selection(this._enter || this._groups.map(sparse), this._parents);\n}\n\nexport function EnterNode(parent, datum) {\n  this.ownerDocument = parent.ownerDocument;\n  this.namespaceURI = parent.namespaceURI;\n  this._next = null;\n  this._parent = parent;\n  this.__data__ = datum;\n}\n\nEnterNode.prototype = {\n  constructor: EnterNode,\n  appendChild: function(child) { return this._parent.insertBefore(child, this._next); },\n  insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },\n  querySelector: function(selector) { return this._parent.querySelector(selector); },\n  querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }\n};\n","export default function(x) {\n  return function() {\n    return x;\n  };\n}\n","import {Selection} from \"./index.js\";\nimport {EnterNode} from \"./enter.js\";\nimport constant from \"../constant.js\";\n\nfunction bindIndex(parent, group, enter, update, exit, data) {\n  var i = 0,\n      node,\n      groupLength = group.length,\n      dataLength = data.length;\n\n  // Put any non-null nodes that fit into update.\n  // Put any null nodes into enter.\n  // Put any remaining data into enter.\n  for (; i < dataLength; ++i) {\n    if (node = group[i]) {\n      node.__data__ = data[i];\n      update[i] = node;\n    } else {\n      enter[i] = new EnterNode(parent, data[i]);\n    }\n  }\n\n  // Put any non-null nodes that don’t fit into exit.\n  for (; i < groupLength; ++i) {\n    if (node = group[i]) {\n      exit[i] = node;\n    }\n  }\n}\n\nfunction bindKey(parent, group, enter, update, exit, data, key) {\n  var i,\n      node,\n      nodeByKeyValue = new Map,\n      groupLength = group.length,\n      dataLength = data.length,\n      keyValues = new Array(groupLength),\n      keyValue;\n\n  // Compute the key for each node.\n  // If multiple nodes have the same key, the duplicates are added to exit.\n  for (i = 0; i < groupLength; ++i) {\n    if (node = group[i]) {\n      keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + \"\";\n      if (nodeByKeyValue.has(keyValue)) {\n        exit[i] = node;\n      } else {\n        nodeByKeyValue.set(keyValue, node);\n      }\n    }\n  }\n\n  // Compute the key for each datum.\n  // If there a node associated with this key, join and add it to update.\n  // If there is not (or the key is a duplicate), add it to enter.\n  for (i = 0; i < dataLength; ++i) {\n    keyValue = key.call(parent, data[i], i, data) + \"\";\n    if (node = nodeByKeyValue.get(keyValue)) {\n      update[i] = node;\n      node.__data__ = data[i];\n      nodeByKeyValue.delete(keyValue);\n    } else {\n      enter[i] = new EnterNode(parent, data[i]);\n    }\n  }\n\n  // Add any remaining nodes that were not bound to data to exit.\n  for (i = 0; i < groupLength; ++i) {\n    if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) {\n      exit[i] = node;\n    }\n  }\n}\n\nfunction datum(node) {\n  return node.__data__;\n}\n\nexport default function(value, key) {\n  if (!arguments.length) return Array.from(this, datum);\n\n  var bind = key ? bindKey : bindIndex,\n      parents = this._parents,\n      groups = this._groups;\n\n  if (typeof value !== \"function\") value = constant(value);\n\n  for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {\n    var parent = parents[j],\n        group = groups[j],\n        groupLength = group.length,\n        data = arraylike(value.call(parent, parent && parent.__data__, j, parents)),\n        dataLength = data.length,\n        enterGroup = enter[j] = new Array(dataLength),\n        updateGroup = update[j] = new Array(dataLength),\n        exitGroup = exit[j] = new Array(groupLength);\n\n    bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);\n\n    // Now connect the enter nodes to their following update node, such that\n    // appendChild can insert the materialized enter node before this node,\n    // rather than at the end of the parent node.\n    for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {\n      if (previous = enterGroup[i0]) {\n        if (i0 >= i1) i1 = i0 + 1;\n        while (!(next = updateGroup[i1]) && ++i1 < dataLength);\n        previous._next = next || null;\n      }\n    }\n  }\n\n  update = new Selection(update, parents);\n  update._enter = enter;\n  update._exit = exit;\n  return update;\n}\n\n// Given some data, this returns an array-like view of it: an object that\n// exposes a length property and allows numeric indexing. Note that unlike\n// selectAll, this isn’t worried about “live” collections because the resulting\n// array will only be used briefly while data is being bound. (It is possible to\n// cause the data to change while iterating by using a key function, but please\n// don’t; we’d rather avoid a gratuitous copy.)\nfunction arraylike(data) {\n  return typeof data === \"object\" && \"length\" in data\n    ? data // Array, TypedArray, NodeList, array-like\n    : Array.from(data); // Map, Set, iterable, string, or anything else\n}\n","import sparse from \"./sparse.js\";\nimport {Selection} from \"./index.js\";\n\nexport default function() {\n  return new Selection(this._exit || this._groups.map(sparse), this._parents);\n}\n","export default function(onenter, onupdate, onexit) {\n  var enter = this.enter(), update = this, exit = this.exit();\n  if (typeof onenter === \"function\") {\n    enter = onenter(enter);\n    if (enter) enter = enter.selection();\n  } else {\n    enter = enter.append(onenter + \"\");\n  }\n  if (onupdate != null) {\n    update = onupdate(update);\n    if (update) update = update.selection();\n  }\n  if (onexit == null) exit.remove(); else onexit(exit);\n  return enter && update ? enter.merge(update).order() : update;\n}\n","import {Selection} from \"./index.js\";\n\nexport default function(context) {\n  var selection = context.selection ? context.selection() : context;\n\n  for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n    for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group0[i] || group1[i]) {\n        merge[i] = node;\n      }\n    }\n  }\n\n  for (; j < m0; ++j) {\n    merges[j] = groups0[j];\n  }\n\n  return new Selection(merges, this._parents);\n}\n","export default function() {\n\n  for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {\n    for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {\n      if (node = group[i]) {\n        if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);\n        next = node;\n      }\n    }\n  }\n\n  return this;\n}\n","import {Selection} from \"./index.js\";\n\nexport default function(compare) {\n  if (!compare) compare = ascending;\n\n  function compareNode(a, b) {\n    return a && b ? compare(a.__data__, b.__data__) : !a - !b;\n  }\n\n  for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        sortgroup[i] = node;\n      }\n    }\n    sortgroup.sort(compareNode);\n  }\n\n  return new Selection(sortgroups, this._parents).order();\n}\n\nfunction ascending(a, b) {\n  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n}\n","export default function() {\n  var callback = arguments[0];\n  arguments[0] = this;\n  callback.apply(null, arguments);\n  return this;\n}\n","export default function() {\n  return Array.from(this);\n}\n","export default function() {\n\n  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n    for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {\n      var node = group[i];\n      if (node) return node;\n    }\n  }\n\n  return null;\n}\n","export default function() {\n  let size = 0;\n  for (const node of this) ++size; // eslint-disable-line no-unused-vars\n  return size;\n}\n","export default function() {\n  return !this.node();\n}\n","export default function(callback) {\n\n  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n    for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n      if (node = group[i]) callback.call(node, node.__data__, i, group);\n    }\n  }\n\n  return this;\n}\n","import namespace from \"../namespace.js\";\n\nfunction attrRemove(name) {\n  return function() {\n    this.removeAttribute(name);\n  };\n}\n\nfunction attrRemoveNS(fullname) {\n  return function() {\n    this.removeAttributeNS(fullname.space, fullname.local);\n  };\n}\n\nfunction attrConstant(name, value) {\n  return function() {\n    this.setAttribute(name, value);\n  };\n}\n\nfunction attrConstantNS(fullname, value) {\n  return function() {\n    this.setAttributeNS(fullname.space, fullname.local, value);\n  };\n}\n\nfunction attrFunction(name, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.removeAttribute(name);\n    else this.setAttribute(name, v);\n  };\n}\n\nfunction attrFunctionNS(fullname, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.removeAttributeNS(fullname.space, fullname.local);\n    else this.setAttributeNS(fullname.space, fullname.local, v);\n  };\n}\n\nexport default function(name, value) {\n  var fullname = namespace(name);\n\n  if (arguments.length < 2) {\n    var node = this.node();\n    return fullname.local\n        ? node.getAttributeNS(fullname.space, fullname.local)\n        : node.getAttribute(fullname);\n  }\n\n  return this.each((value == null\n      ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === \"function\"\n      ? (fullname.local ? attrFunctionNS : attrFunction)\n      : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));\n}\n","export default function(node) {\n  return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node\n      || (node.document && node) // node is a Window\n      || node.defaultView; // node is a Document\n}\n","import defaultView from \"../window.js\";\n\nfunction styleRemove(name) {\n  return function() {\n    this.style.removeProperty(name);\n  };\n}\n\nfunction styleConstant(name, value, priority) {\n  return function() {\n    this.style.setProperty(name, value, priority);\n  };\n}\n\nfunction styleFunction(name, value, priority) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) this.style.removeProperty(name);\n    else this.style.setProperty(name, v, priority);\n  };\n}\n\nexport default function(name, value, priority) {\n  return arguments.length > 1\n      ? this.each((value == null\n            ? styleRemove : typeof value === \"function\"\n            ? styleFunction\n            : styleConstant)(name, value, priority == null ? \"\" : priority))\n      : styleValue(this.node(), name);\n}\n\nexport function styleValue(node, name) {\n  return node.style.getPropertyValue(name)\n      || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);\n}\n","function propertyRemove(name) {\n  return function() {\n    delete this[name];\n  };\n}\n\nfunction propertyConstant(name, value) {\n  return function() {\n    this[name] = value;\n  };\n}\n\nfunction propertyFunction(name, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (v == null) delete this[name];\n    else this[name] = v;\n  };\n}\n\nexport default function(name, value) {\n  return arguments.length > 1\n      ? this.each((value == null\n          ? propertyRemove : typeof value === \"function\"\n          ? propertyFunction\n          : propertyConstant)(name, value))\n      : this.node()[name];\n}\n","function classArray(string) {\n  return string.trim().split(/^|\\s+/);\n}\n\nfunction classList(node) {\n  return node.classList || new ClassList(node);\n}\n\nfunction ClassList(node) {\n  this._node = node;\n  this._names = classArray(node.getAttribute(\"class\") || \"\");\n}\n\nClassList.prototype = {\n  add: function(name) {\n    var i = this._names.indexOf(name);\n    if (i < 0) {\n      this._names.push(name);\n      this._node.setAttribute(\"class\", this._names.join(\" \"));\n    }\n  },\n  remove: function(name) {\n    var i = this._names.indexOf(name);\n    if (i >= 0) {\n      this._names.splice(i, 1);\n      this._node.setAttribute(\"class\", this._names.join(\" \"));\n    }\n  },\n  contains: function(name) {\n    return this._names.indexOf(name) >= 0;\n  }\n};\n\nfunction classedAdd(node, names) {\n  var list = classList(node), i = -1, n = names.length;\n  while (++i < n) list.add(names[i]);\n}\n\nfunction classedRemove(node, names) {\n  var list = classList(node), i = -1, n = names.length;\n  while (++i < n) list.remove(names[i]);\n}\n\nfunction classedTrue(names) {\n  return function() {\n    classedAdd(this, names);\n  };\n}\n\nfunction classedFalse(names) {\n  return function() {\n    classedRemove(this, names);\n  };\n}\n\nfunction classedFunction(names, value) {\n  return function() {\n    (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);\n  };\n}\n\nexport default function(name, value) {\n  var names = classArray(name + \"\");\n\n  if (arguments.length < 2) {\n    var list = classList(this.node()), i = -1, n = names.length;\n    while (++i < n) if (!list.contains(names[i])) return false;\n    return true;\n  }\n\n  return this.each((typeof value === \"function\"\n      ? classedFunction : value\n      ? classedTrue\n      : classedFalse)(names, value));\n}\n","function textRemove() {\n  this.textContent = \"\";\n}\n\nfunction textConstant(value) {\n  return function() {\n    this.textContent = value;\n  };\n}\n\nfunction textFunction(value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    this.textContent = v == null ? \"\" : v;\n  };\n}\n\nexport default function(value) {\n  return arguments.length\n      ? this.each(value == null\n          ? textRemove : (typeof value === \"function\"\n          ? textFunction\n          : textConstant)(value))\n      : this.node().textContent;\n}\n","function htmlRemove() {\n  this.innerHTML = \"\";\n}\n\nfunction htmlConstant(value) {\n  return function() {\n    this.innerHTML = value;\n  };\n}\n\nfunction htmlFunction(value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    this.innerHTML = v == null ? \"\" : v;\n  };\n}\n\nexport default function(value) {\n  return arguments.length\n      ? this.each(value == null\n          ? htmlRemove : (typeof value === \"function\"\n          ? htmlFunction\n          : htmlConstant)(value))\n      : this.node().innerHTML;\n}\n","function raise() {\n  if (this.nextSibling) this.parentNode.appendChild(this);\n}\n\nexport default function() {\n  return this.each(raise);\n}\n","function lower() {\n  if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);\n}\n\nexport default function() {\n  return this.each(lower);\n}\n","import creator from \"../creator.js\";\n\nexport default function(name) {\n  var create = typeof name === \"function\" ? name : creator(name);\n  return this.select(function() {\n    return this.appendChild(create.apply(this, arguments));\n  });\n}\n","import creator from \"../creator.js\";\nimport selector from \"../selector.js\";\n\nfunction constantNull() {\n  return null;\n}\n\nexport default function(name, before) {\n  var create = typeof name === \"function\" ? name : creator(name),\n      select = before == null ? constantNull : typeof before === \"function\" ? before : selector(before);\n  return this.select(function() {\n    return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);\n  });\n}\n","function remove() {\n  var parent = this.parentNode;\n  if (parent) parent.removeChild(this);\n}\n\nexport default function() {\n  return this.each(remove);\n}\n","function selection_cloneShallow() {\n  var clone = this.cloneNode(false), parent = this.parentNode;\n  return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\nfunction selection_cloneDeep() {\n  var clone = this.cloneNode(true), parent = this.parentNode;\n  return parent ? parent.insertBefore(clone, this.nextSibling) : clone;\n}\n\nexport default function(deep) {\n  return this.select(deep ? selection_cloneDeep : selection_cloneShallow);\n}\n","export default function(value) {\n  return arguments.length\n      ? this.property(\"__data__\", value)\n      : this.node().__data__;\n}\n","function contextListener(listener) {\n  return function(event) {\n    listener.call(this, event, this.__data__);\n  };\n}\n\nfunction parseTypenames(typenames) {\n  return typenames.trim().split(/^|\\s+/).map(function(t) {\n    var name = \"\", i = t.indexOf(\".\");\n    if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);\n    return {type: t, name: name};\n  });\n}\n\nfunction onRemove(typename) {\n  return function() {\n    var on = this.__on;\n    if (!on) return;\n    for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {\n      if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {\n        this.removeEventListener(o.type, o.listener, o.options);\n      } else {\n        on[++i] = o;\n      }\n    }\n    if (++i) on.length = i;\n    else delete this.__on;\n  };\n}\n\nfunction onAdd(typename, value, options) {\n  return function() {\n    var on = this.__on, o, listener = contextListener(value);\n    if (on) for (var j = 0, m = on.length; j < m; ++j) {\n      if ((o = on[j]).type === typename.type && o.name === typename.name) {\n        this.removeEventListener(o.type, o.listener, o.options);\n        this.addEventListener(o.type, o.listener = listener, o.options = options);\n        o.value = value;\n        return;\n      }\n    }\n    this.addEventListener(typename.type, listener, options);\n    o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options};\n    if (!on) this.__on = [o];\n    else on.push(o);\n  };\n}\n\nexport default function(typename, value, options) {\n  var typenames = parseTypenames(typename + \"\"), i, n = typenames.length, t;\n\n  if (arguments.length < 2) {\n    var on = this.node().__on;\n    if (on) for (var j = 0, m = on.length, o; j < m; ++j) {\n      for (i = 0, o = on[j]; i < n; ++i) {\n        if ((t = typenames[i]).type === o.type && t.name === o.name) {\n          return o.value;\n        }\n      }\n    }\n    return;\n  }\n\n  on = value ? onAdd : onRemove;\n  for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));\n  return this;\n}\n","import defaultView from \"../window.js\";\n\nfunction dispatchEvent(node, type, params) {\n  var window = defaultView(node),\n      event = window.CustomEvent;\n\n  if (typeof event === \"function\") {\n    event = new event(type, params);\n  } else {\n    event = window.document.createEvent(\"Event\");\n    if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;\n    else event.initEvent(type, false, false);\n  }\n\n  node.dispatchEvent(event);\n}\n\nfunction dispatchConstant(type, params) {\n  return function() {\n    return dispatchEvent(this, type, params);\n  };\n}\n\nfunction dispatchFunction(type, params) {\n  return function() {\n    return dispatchEvent(this, type, params.apply(this, arguments));\n  };\n}\n\nexport default function(type, params) {\n  return this.each((typeof params === \"function\"\n      ? dispatchFunction\n      : dispatchConstant)(type, params));\n}\n","export default function*() {\n  for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {\n    for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {\n      if (node = group[i]) yield node;\n    }\n  }\n}\n","import selection_select from \"./select.js\";\nimport selection_selectAll from \"./selectAll.js\";\nimport selection_selectChild from \"./selectChild.js\";\nimport selection_selectChildren from \"./selectChildren.js\";\nimport selection_filter from \"./filter.js\";\nimport selection_data from \"./data.js\";\nimport selection_enter from \"./enter.js\";\nimport selection_exit from \"./exit.js\";\nimport selection_join from \"./join.js\";\nimport selection_merge from \"./merge.js\";\nimport selection_order from \"./order.js\";\nimport selection_sort from \"./sort.js\";\nimport selection_call from \"./call.js\";\nimport selection_nodes from \"./nodes.js\";\nimport selection_node from \"./node.js\";\nimport selection_size from \"./size.js\";\nimport selection_empty from \"./empty.js\";\nimport selection_each from \"./each.js\";\nimport selection_attr from \"./attr.js\";\nimport selection_style from \"./style.js\";\nimport selection_property from \"./property.js\";\nimport selection_classed from \"./classed.js\";\nimport selection_text from \"./text.js\";\nimport selection_html from \"./html.js\";\nimport selection_raise from \"./raise.js\";\nimport selection_lower from \"./lower.js\";\nimport selection_append from \"./append.js\";\nimport selection_insert from \"./insert.js\";\nimport selection_remove from \"./remove.js\";\nimport selection_clone from \"./clone.js\";\nimport selection_datum from \"./datum.js\";\nimport selection_on from \"./on.js\";\nimport selection_dispatch from \"./dispatch.js\";\nimport selection_iterator from \"./iterator.js\";\n\nexport var root = [null];\n\nexport function Selection(groups, parents) {\n  this._groups = groups;\n  this._parents = parents;\n}\n\nfunction selection() {\n  return new Selection([[document.documentElement]], root);\n}\n\nfunction selection_selection() {\n  return this;\n}\n\nSelection.prototype = selection.prototype = {\n  constructor: Selection,\n  select: selection_select,\n  selectAll: selection_selectAll,\n  selectChild: selection_selectChild,\n  selectChildren: selection_selectChildren,\n  filter: selection_filter,\n  data: selection_data,\n  enter: selection_enter,\n  exit: selection_exit,\n  join: selection_join,\n  merge: selection_merge,\n  selection: selection_selection,\n  order: selection_order,\n  sort: selection_sort,\n  call: selection_call,\n  nodes: selection_nodes,\n  node: selection_node,\n  size: selection_size,\n  empty: selection_empty,\n  each: selection_each,\n  attr: selection_attr,\n  style: selection_style,\n  property: selection_property,\n  classed: selection_classed,\n  text: selection_text,\n  html: selection_html,\n  raise: selection_raise,\n  lower: selection_lower,\n  append: selection_append,\n  insert: selection_insert,\n  remove: selection_remove,\n  clone: selection_clone,\n  datum: selection_datum,\n  on: selection_on,\n  dispatch: selection_dispatch,\n  [Symbol.iterator]: selection_iterator\n};\n\nexport default selection;\n","import {Selection, root} from \"./selection/index.js\";\n\nexport default function(selector) {\n  return typeof selector === \"string\"\n      ? new Selection([[document.querySelector(selector)]], [document.documentElement])\n      : new Selection([[selector]], root);\n}\n","var frame = 0, // is an animation frame pending?\n    timeout = 0, // is a timeout pending?\n    interval = 0, // are any timers active?\n    pokeDelay = 1000, // how frequently we check for clock skew\n    taskHead,\n    taskTail,\n    clockLast = 0,\n    clockNow = 0,\n    clockSkew = 0,\n    clock = typeof performance === \"object\" && performance.now ? performance : Date,\n    setFrame = typeof window === \"object\" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };\n\nexport function now() {\n  return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);\n}\n\nfunction clearNow() {\n  clockNow = 0;\n}\n\nexport function Timer() {\n  this._call =\n  this._time =\n  this._next = null;\n}\n\nTimer.prototype = timer.prototype = {\n  constructor: Timer,\n  restart: function(callback, delay, time) {\n    if (typeof callback !== \"function\") throw new TypeError(\"callback is not a function\");\n    time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);\n    if (!this._next && taskTail !== this) {\n      if (taskTail) taskTail._next = this;\n      else taskHead = this;\n      taskTail = this;\n    }\n    this._call = callback;\n    this._time = time;\n    sleep();\n  },\n  stop: function() {\n    if (this._call) {\n      this._call = null;\n      this._time = Infinity;\n      sleep();\n    }\n  }\n};\n\nexport function timer(callback, delay, time) {\n  var t = new Timer;\n  t.restart(callback, delay, time);\n  return t;\n}\n\nexport function timerFlush() {\n  now(); // Get the current time, if not already set.\n  ++frame; // Pretend we’ve set an alarm, if we haven’t already.\n  var t = taskHead, e;\n  while (t) {\n    if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e);\n    t = t._next;\n  }\n  --frame;\n}\n\nfunction wake() {\n  clockNow = (clockLast = clock.now()) + clockSkew;\n  frame = timeout = 0;\n  try {\n    timerFlush();\n  } finally {\n    frame = 0;\n    nap();\n    clockNow = 0;\n  }\n}\n\nfunction poke() {\n  var now = clock.now(), delay = now - clockLast;\n  if (delay > pokeDelay) clockSkew -= delay, clockLast = now;\n}\n\nfunction nap() {\n  var t0, t1 = taskHead, t2, time = Infinity;\n  while (t1) {\n    if (t1._call) {\n      if (time > t1._time) time = t1._time;\n      t0 = t1, t1 = t1._next;\n    } else {\n      t2 = t1._next, t1._next = null;\n      t1 = t0 ? t0._next = t2 : taskHead = t2;\n    }\n  }\n  taskTail = t0;\n  sleep(time);\n}\n\nfunction sleep(time) {\n  if (frame) return; // Soonest alarm already set, or will be.\n  if (timeout) timeout = clearTimeout(timeout);\n  var delay = time - clockNow; // Strictly less than if we recomputed clockNow.\n  if (delay > 24) {\n    if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);\n    if (interval) interval = clearInterval(interval);\n  } else {\n    if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);\n    frame = 1, setFrame(wake);\n  }\n}\n","import {Timer} from \"./timer.js\";\n\nexport default function(callback, delay, time) {\n  var t = new Timer;\n  delay = delay == null ? 0 : +delay;\n  t.restart(elapsed => {\n    t.stop();\n    callback(elapsed + delay);\n  }, delay, time);\n  return t;\n}\n","import {dispatch} from \"d3-dispatch\";\nimport {timer, timeout} from \"d3-timer\";\n\nvar emptyOn = dispatch(\"start\", \"end\", \"cancel\", \"interrupt\");\nvar emptyTween = [];\n\nexport var CREATED = 0;\nexport var SCHEDULED = 1;\nexport var STARTING = 2;\nexport var STARTED = 3;\nexport var RUNNING = 4;\nexport var ENDING = 5;\nexport var ENDED = 6;\n\nexport default function(node, name, id, index, group, timing) {\n  var schedules = node.__transition;\n  if (!schedules) node.__transition = {};\n  else if (id in schedules) return;\n  create(node, id, {\n    name: name,\n    index: index, // For context during callback.\n    group: group, // For context during callback.\n    on: emptyOn,\n    tween: emptyTween,\n    time: timing.time,\n    delay: timing.delay,\n    duration: timing.duration,\n    ease: timing.ease,\n    timer: null,\n    state: CREATED\n  });\n}\n\nexport function init(node, id) {\n  var schedule = get(node, id);\n  if (schedule.state > CREATED) throw new Error(\"too late; already scheduled\");\n  return schedule;\n}\n\nexport function set(node, id) {\n  var schedule = get(node, id);\n  if (schedule.state > STARTED) throw new Error(\"too late; already running\");\n  return schedule;\n}\n\nexport function get(node, id) {\n  var schedule = node.__transition;\n  if (!schedule || !(schedule = schedule[id])) throw new Error(\"transition not found\");\n  return schedule;\n}\n\nfunction create(node, id, self) {\n  var schedules = node.__transition,\n      tween;\n\n  // Initialize the self timer when the transition is created.\n  // Note the actual delay is not known until the first callback!\n  schedules[id] = self;\n  self.timer = timer(schedule, 0, self.time);\n\n  function schedule(elapsed) {\n    self.state = SCHEDULED;\n    self.timer.restart(start, self.delay, self.time);\n\n    // If the elapsed delay is less than our first sleep, start immediately.\n    if (self.delay <= elapsed) start(elapsed - self.delay);\n  }\n\n  function start(elapsed) {\n    var i, j, n, o;\n\n    // If the state is not SCHEDULED, then we previously errored on start.\n    if (self.state !== SCHEDULED) return stop();\n\n    for (i in schedules) {\n      o = schedules[i];\n      if (o.name !== self.name) continue;\n\n      // While this element already has a starting transition during this frame,\n      // defer starting an interrupting transition until that transition has a\n      // chance to tick (and possibly end); see d3/d3-transition#54!\n      if (o.state === STARTED) return timeout(start);\n\n      // Interrupt the active transition, if any.\n      if (o.state === RUNNING) {\n        o.state = ENDED;\n        o.timer.stop();\n        o.on.call(\"interrupt\", node, node.__data__, o.index, o.group);\n        delete schedules[i];\n      }\n\n      // Cancel any pre-empted transitions.\n      else if (+i < id) {\n        o.state = ENDED;\n        o.timer.stop();\n        o.on.call(\"cancel\", node, node.__data__, o.index, o.group);\n        delete schedules[i];\n      }\n    }\n\n    // Defer the first tick to end of the current frame; see d3/d3#1576.\n    // Note the transition may be canceled after start and before the first tick!\n    // Note this must be scheduled before the start event; see d3/d3-transition#16!\n    // Assuming this is successful, subsequent callbacks go straight to tick.\n    timeout(function() {\n      if (self.state === STARTED) {\n        self.state = RUNNING;\n        self.timer.restart(tick, self.delay, self.time);\n        tick(elapsed);\n      }\n    });\n\n    // Dispatch the start event.\n    // Note this must be done before the tween are initialized.\n    self.state = STARTING;\n    self.on.call(\"start\", node, node.__data__, self.index, self.group);\n    if (self.state !== STARTING) return; // interrupted\n    self.state = STARTED;\n\n    // Initialize the tween, deleting null tween.\n    tween = new Array(n = self.tween.length);\n    for (i = 0, j = -1; i < n; ++i) {\n      if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {\n        tween[++j] = o;\n      }\n    }\n    tween.length = j + 1;\n  }\n\n  function tick(elapsed) {\n    var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),\n        i = -1,\n        n = tween.length;\n\n    while (++i < n) {\n      tween[i].call(node, t);\n    }\n\n    // Dispatch the end event.\n    if (self.state === ENDING) {\n      self.on.call(\"end\", node, node.__data__, self.index, self.group);\n      stop();\n    }\n  }\n\n  function stop() {\n    self.state = ENDED;\n    self.timer.stop();\n    delete schedules[id];\n    for (var i in schedules) return; // eslint-disable-line no-unused-vars\n    delete node.__transition;\n  }\n}\n","import {STARTING, ENDING, ENDED} from \"./transition/schedule.js\";\n\nexport default function(node, name) {\n  var schedules = node.__transition,\n      schedule,\n      active,\n      empty = true,\n      i;\n\n  if (!schedules) return;\n\n  name = name == null ? null : name + \"\";\n\n  for (i in schedules) {\n    if ((schedule = schedules[i]).name !== name) { empty = false; continue; }\n    active = schedule.state > STARTING && schedule.state < ENDING;\n    schedule.state = ENDED;\n    schedule.timer.stop();\n    schedule.on.call(active ? \"interrupt\" : \"cancel\", node, node.__data__, schedule.index, schedule.group);\n    delete schedules[i];\n  }\n\n  if (empty) delete node.__transition;\n}\n","import interrupt from \"../interrupt.js\";\n\nexport default function(name) {\n  return this.each(function() {\n    interrupt(this, name);\n  });\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction tweenRemove(id, name) {\n  var tween0, tween1;\n  return function() {\n    var schedule = set(this, id),\n        tween = schedule.tween;\n\n    // If this node shared tween with the previous node,\n    // just assign the updated shared tween and we’re done!\n    // Otherwise, copy-on-write.\n    if (tween !== tween0) {\n      tween1 = tween0 = tween;\n      for (var i = 0, n = tween1.length; i < n; ++i) {\n        if (tween1[i].name === name) {\n          tween1 = tween1.slice();\n          tween1.splice(i, 1);\n          break;\n        }\n      }\n    }\n\n    schedule.tween = tween1;\n  };\n}\n\nfunction tweenFunction(id, name, value) {\n  var tween0, tween1;\n  if (typeof value !== \"function\") throw new Error;\n  return function() {\n    var schedule = set(this, id),\n        tween = schedule.tween;\n\n    // If this node shared tween with the previous node,\n    // just assign the updated shared tween and we’re done!\n    // Otherwise, copy-on-write.\n    if (tween !== tween0) {\n      tween1 = (tween0 = tween).slice();\n      for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {\n        if (tween1[i].name === name) {\n          tween1[i] = t;\n          break;\n        }\n      }\n      if (i === n) tween1.push(t);\n    }\n\n    schedule.tween = tween1;\n  };\n}\n\nexport default function(name, value) {\n  var id = this._id;\n\n  name += \"\";\n\n  if (arguments.length < 2) {\n    var tween = get(this.node(), id).tween;\n    for (var i = 0, n = tween.length, t; i < n; ++i) {\n      if ((t = tween[i]).name === name) {\n        return t.value;\n      }\n    }\n    return null;\n  }\n\n  return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));\n}\n\nexport function tweenValue(transition, name, value) {\n  var id = transition._id;\n\n  transition.each(function() {\n    var schedule = set(this, id);\n    (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);\n  });\n\n  return function(node) {\n    return get(node, id).value[name];\n  };\n}\n","import {color} from \"d3-color\";\nimport {interpolateNumber, interpolateRgb, interpolateString} from \"d3-interpolate\";\n\nexport default function(a, b) {\n  var c;\n  return (typeof b === \"number\" ? interpolateNumber\n      : b instanceof color ? interpolateRgb\n      : (c = color(b)) ? (b = c, interpolateRgb)\n      : interpolateString)(a, b);\n}\n","import {interpolateTransformSvg as interpolateTransform} from \"d3-interpolate\";\nimport {namespace} from \"d3-selection\";\nimport {tweenValue} from \"./tween.js\";\nimport interpolate from \"./interpolate.js\";\n\nfunction attrRemove(name) {\n  return function() {\n    this.removeAttribute(name);\n  };\n}\n\nfunction attrRemoveNS(fullname) {\n  return function() {\n    this.removeAttributeNS(fullname.space, fullname.local);\n  };\n}\n\nfunction attrConstant(name, interpolate, value1) {\n  var string00,\n      string1 = value1 + \"\",\n      interpolate0;\n  return function() {\n    var string0 = this.getAttribute(name);\n    return string0 === string1 ? null\n        : string0 === string00 ? interpolate0\n        : interpolate0 = interpolate(string00 = string0, value1);\n  };\n}\n\nfunction attrConstantNS(fullname, interpolate, value1) {\n  var string00,\n      string1 = value1 + \"\",\n      interpolate0;\n  return function() {\n    var string0 = this.getAttributeNS(fullname.space, fullname.local);\n    return string0 === string1 ? null\n        : string0 === string00 ? interpolate0\n        : interpolate0 = interpolate(string00 = string0, value1);\n  };\n}\n\nfunction attrFunction(name, interpolate, value) {\n  var string00,\n      string10,\n      interpolate0;\n  return function() {\n    var string0, value1 = value(this), string1;\n    if (value1 == null) return void this.removeAttribute(name);\n    string0 = this.getAttribute(name);\n    string1 = value1 + \"\";\n    return string0 === string1 ? null\n        : string0 === string00 && string1 === string10 ? interpolate0\n        : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n  };\n}\n\nfunction attrFunctionNS(fullname, interpolate, value) {\n  var string00,\n      string10,\n      interpolate0;\n  return function() {\n    var string0, value1 = value(this), string1;\n    if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);\n    string0 = this.getAttributeNS(fullname.space, fullname.local);\n    string1 = value1 + \"\";\n    return string0 === string1 ? null\n        : string0 === string00 && string1 === string10 ? interpolate0\n        : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n  };\n}\n\nexport default function(name, value) {\n  var fullname = namespace(name), i = fullname === \"transform\" ? interpolateTransform : interpolate;\n  return this.attrTween(name, typeof value === \"function\"\n      ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, \"attr.\" + name, value))\n      : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)\n      : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));\n}\n","import {namespace} from \"d3-selection\";\n\nfunction attrInterpolate(name, i) {\n  return function(t) {\n    this.setAttribute(name, i.call(this, t));\n  };\n}\n\nfunction attrInterpolateNS(fullname, i) {\n  return function(t) {\n    this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));\n  };\n}\n\nfunction attrTweenNS(fullname, value) {\n  var t0, i0;\n  function tween() {\n    var i = value.apply(this, arguments);\n    if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);\n    return t0;\n  }\n  tween._value = value;\n  return tween;\n}\n\nfunction attrTween(name, value) {\n  var t0, i0;\n  function tween() {\n    var i = value.apply(this, arguments);\n    if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);\n    return t0;\n  }\n  tween._value = value;\n  return tween;\n}\n\nexport default function(name, value) {\n  var key = \"attr.\" + name;\n  if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n  if (value == null) return this.tween(key, null);\n  if (typeof value !== \"function\") throw new Error;\n  var fullname = namespace(name);\n  return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));\n}\n","import {get, init} from \"./schedule.js\";\n\nfunction delayFunction(id, value) {\n  return function() {\n    init(this, id).delay = +value.apply(this, arguments);\n  };\n}\n\nfunction delayConstant(id, value) {\n  return value = +value, function() {\n    init(this, id).delay = value;\n  };\n}\n\nexport default function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each((typeof value === \"function\"\n          ? delayFunction\n          : delayConstant)(id, value))\n      : get(this.node(), id).delay;\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction durationFunction(id, value) {\n  return function() {\n    set(this, id).duration = +value.apply(this, arguments);\n  };\n}\n\nfunction durationConstant(id, value) {\n  return value = +value, function() {\n    set(this, id).duration = value;\n  };\n}\n\nexport default function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each((typeof value === \"function\"\n          ? durationFunction\n          : durationConstant)(id, value))\n      : get(this.node(), id).duration;\n}\n","import {get, set} from \"./schedule.js\";\n\nfunction easeConstant(id, value) {\n  if (typeof value !== \"function\") throw new Error;\n  return function() {\n    set(this, id).ease = value;\n  };\n}\n\nexport default function(value) {\n  var id = this._id;\n\n  return arguments.length\n      ? this.each(easeConstant(id, value))\n      : get(this.node(), id).ease;\n}\n","import {set} from \"./schedule.js\";\n\nfunction easeVarying(id, value) {\n  return function() {\n    var v = value.apply(this, arguments);\n    if (typeof v !== \"function\") throw new Error;\n    set(this, id).ease = v;\n  };\n}\n\nexport default function(value) {\n  if (typeof value !== \"function\") throw new Error;\n  return this.each(easeVarying(this._id, value));\n}\n","import {matcher} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\n\nexport default function(match) {\n  if (typeof match !== \"function\") match = matcher(match);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {\n      if ((node = group[i]) && match.call(node, node.__data__, i, group)) {\n        subgroup.push(node);\n      }\n    }\n  }\n\n  return new Transition(subgroups, this._parents, this._name, this._id);\n}\n","import {Transition} from \"./index.js\";\n\nexport default function(transition) {\n  if (transition._id !== this._id) throw new Error;\n\n  for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {\n    for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {\n      if (node = group0[i] || group1[i]) {\n        merge[i] = node;\n      }\n    }\n  }\n\n  for (; j < m0; ++j) {\n    merges[j] = groups0[j];\n  }\n\n  return new Transition(merges, this._parents, this._name, this._id);\n}\n","import {get, set, init} from \"./schedule.js\";\n\nfunction start(name) {\n  return (name + \"\").trim().split(/^|\\s+/).every(function(t) {\n    var i = t.indexOf(\".\");\n    if (i >= 0) t = t.slice(0, i);\n    return !t || t === \"start\";\n  });\n}\n\nfunction onFunction(id, name, listener) {\n  var on0, on1, sit = start(name) ? init : set;\n  return function() {\n    var schedule = sit(this, id),\n        on = schedule.on;\n\n    // If this node shared a dispatch with the previous node,\n    // just assign the updated shared dispatch and we’re done!\n    // Otherwise, copy-on-write.\n    if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);\n\n    schedule.on = on1;\n  };\n}\n\nexport default function(name, listener) {\n  var id = this._id;\n\n  return arguments.length < 2\n      ? get(this.node(), id).on.on(name)\n      : this.each(onFunction(id, name, listener));\n}\n","function removeFunction(id) {\n  return function() {\n    var parent = this.parentNode;\n    for (var i in this.__transition) if (+i !== id) return;\n    if (parent) parent.removeChild(this);\n  };\n}\n\nexport default function() {\n  return this.on(\"end.remove\", removeFunction(this._id));\n}\n","import {selector} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function(select) {\n  var name = this._name,\n      id = this._id;\n\n  if (typeof select !== \"function\") select = selector(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {\n      if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {\n        if (\"__data__\" in node) subnode.__data__ = node.__data__;\n        subgroup[i] = subnode;\n        schedule(subgroup[i], name, id, i, subgroup, get(node, id));\n      }\n    }\n  }\n\n  return new Transition(subgroups, this._parents, name, id);\n}\n","import {selectorAll} from \"d3-selection\";\nimport {Transition} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function(select) {\n  var name = this._name,\n      id = this._id;\n\n  if (typeof select !== \"function\") select = selectorAll(select);\n\n  for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {\n          if (child = children[k]) {\n            schedule(child, name, id, k, children, inherit);\n          }\n        }\n        subgroups.push(children);\n        parents.push(node);\n      }\n    }\n  }\n\n  return new Transition(subgroups, parents, name, id);\n}\n","import {selection} from \"d3-selection\";\n\nvar Selection = selection.prototype.constructor;\n\nexport default function() {\n  return new Selection(this._groups, this._parents);\n}\n","import {interpolateTransformCss as interpolateTransform} from \"d3-interpolate\";\nimport {style} from \"d3-selection\";\nimport {set} from \"./schedule.js\";\nimport {tweenValue} from \"./tween.js\";\nimport interpolate from \"./interpolate.js\";\n\nfunction styleNull(name, interpolate) {\n  var string00,\n      string10,\n      interpolate0;\n  return function() {\n    var string0 = style(this, name),\n        string1 = (this.style.removeProperty(name), style(this, name));\n    return string0 === string1 ? null\n        : string0 === string00 && string1 === string10 ? interpolate0\n        : interpolate0 = interpolate(string00 = string0, string10 = string1);\n  };\n}\n\nfunction styleRemove(name) {\n  return function() {\n    this.style.removeProperty(name);\n  };\n}\n\nfunction styleConstant(name, interpolate, value1) {\n  var string00,\n      string1 = value1 + \"\",\n      interpolate0;\n  return function() {\n    var string0 = style(this, name);\n    return string0 === string1 ? null\n        : string0 === string00 ? interpolate0\n        : interpolate0 = interpolate(string00 = string0, value1);\n  };\n}\n\nfunction styleFunction(name, interpolate, value) {\n  var string00,\n      string10,\n      interpolate0;\n  return function() {\n    var string0 = style(this, name),\n        value1 = value(this),\n        string1 = value1 + \"\";\n    if (value1 == null) string1 = value1 = (this.style.removeProperty(name), style(this, name));\n    return string0 === string1 ? null\n        : string0 === string00 && string1 === string10 ? interpolate0\n        : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));\n  };\n}\n\nfunction styleMaybeRemove(id, name) {\n  var on0, on1, listener0, key = \"style.\" + name, event = \"end.\" + key, remove;\n  return function() {\n    var schedule = set(this, id),\n        on = schedule.on,\n        listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined;\n\n    // If this node shared a dispatch with the previous node,\n    // just assign the updated shared dispatch and we’re done!\n    // Otherwise, copy-on-write.\n    if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);\n\n    schedule.on = on1;\n  };\n}\n\nexport default function(name, value, priority) {\n  var i = (name += \"\") === \"transform\" ? interpolateTransform : interpolate;\n  return value == null ? this\n      .styleTween(name, styleNull(name, i))\n      .on(\"end.style.\" + name, styleRemove(name))\n    : typeof value === \"function\" ? this\n      .styleTween(name, styleFunction(name, i, tweenValue(this, \"style.\" + name, value)))\n      .each(styleMaybeRemove(this._id, name))\n    : this\n      .styleTween(name, styleConstant(name, i, value), priority)\n      .on(\"end.style.\" + name, null);\n}\n","function styleInterpolate(name, i, priority) {\n  return function(t) {\n    this.style.setProperty(name, i.call(this, t), priority);\n  };\n}\n\nfunction styleTween(name, value, priority) {\n  var t, i0;\n  function tween() {\n    var i = value.apply(this, arguments);\n    if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);\n    return t;\n  }\n  tween._value = value;\n  return tween;\n}\n\nexport default function(name, value, priority) {\n  var key = \"style.\" + (name += \"\");\n  if (arguments.length < 2) return (key = this.tween(key)) && key._value;\n  if (value == null) return this.tween(key, null);\n  if (typeof value !== \"function\") throw new Error;\n  return this.tween(key, styleTween(name, value, priority == null ? \"\" : priority));\n}\n","import {tweenValue} from \"./tween.js\";\n\nfunction textConstant(value) {\n  return function() {\n    this.textContent = value;\n  };\n}\n\nfunction textFunction(value) {\n  return function() {\n    var value1 = value(this);\n    this.textContent = value1 == null ? \"\" : value1;\n  };\n}\n\nexport default function(value) {\n  return this.tween(\"text\", typeof value === \"function\"\n      ? textFunction(tweenValue(this, \"text\", value))\n      : textConstant(value == null ? \"\" : value + \"\"));\n}\n","function textInterpolate(i) {\n  return function(t) {\n    this.textContent = i.call(this, t);\n  };\n}\n\nfunction textTween(value) {\n  var t0, i0;\n  function tween() {\n    var i = value.apply(this, arguments);\n    if (i !== i0) t0 = (i0 = i) && textInterpolate(i);\n    return t0;\n  }\n  tween._value = value;\n  return tween;\n}\n\nexport default function(value) {\n  var key = \"text\";\n  if (arguments.length < 1) return (key = this.tween(key)) && key._value;\n  if (value == null) return this.tween(key, null);\n  if (typeof value !== \"function\") throw new Error;\n  return this.tween(key, textTween(value));\n}\n","import {Transition, newId} from \"./index.js\";\nimport schedule, {get} from \"./schedule.js\";\n\nexport default function() {\n  var name = this._name,\n      id0 = this._id,\n      id1 = newId();\n\n  for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        var inherit = get(node, id0);\n        schedule(node, name, id1, i, group, {\n          time: inherit.time + inherit.delay + inherit.duration,\n          delay: 0,\n          duration: inherit.duration,\n          ease: inherit.ease\n        });\n      }\n    }\n  }\n\n  return new Transition(groups, this._parents, name, id1);\n}\n","import {set} from \"./schedule.js\";\n\nexport default function() {\n  var on0, on1, that = this, id = that._id, size = that.size();\n  return new Promise(function(resolve, reject) {\n    var cancel = {value: reject},\n        end = {value: function() { if (--size === 0) resolve(); }};\n\n    that.each(function() {\n      var schedule = set(this, id),\n          on = schedule.on;\n\n      // If this node shared a dispatch with the previous node,\n      // just assign the updated shared dispatch and we’re done!\n      // Otherwise, copy-on-write.\n      if (on !== on0) {\n        on1 = (on0 = on).copy();\n        on1._.cancel.push(cancel);\n        on1._.interrupt.push(cancel);\n        on1._.end.push(end);\n      }\n\n      schedule.on = on1;\n    });\n\n    // The selection was empty, resolve end immediately\n    if (size === 0) resolve();\n  });\n}\n","import {selection} from \"d3-selection\";\nimport transition_attr from \"./attr.js\";\nimport transition_attrTween from \"./attrTween.js\";\nimport transition_delay from \"./delay.js\";\nimport transition_duration from \"./duration.js\";\nimport transition_ease from \"./ease.js\";\nimport transition_easeVarying from \"./easeVarying.js\";\nimport transition_filter from \"./filter.js\";\nimport transition_merge from \"./merge.js\";\nimport transition_on from \"./on.js\";\nimport transition_remove from \"./remove.js\";\nimport transition_select from \"./select.js\";\nimport transition_selectAll from \"./selectAll.js\";\nimport transition_selection from \"./selection.js\";\nimport transition_style from \"./style.js\";\nimport transition_styleTween from \"./styleTween.js\";\nimport transition_text from \"./text.js\";\nimport transition_textTween from \"./textTween.js\";\nimport transition_transition from \"./transition.js\";\nimport transition_tween from \"./tween.js\";\nimport transition_end from \"./end.js\";\n\nvar id = 0;\n\nexport function Transition(groups, parents, name, id) {\n  this._groups = groups;\n  this._parents = parents;\n  this._name = name;\n  this._id = id;\n}\n\nexport default function transition(name) {\n  return selection().transition(name);\n}\n\nexport function newId() {\n  return ++id;\n}\n\nvar selection_prototype = selection.prototype;\n\nTransition.prototype = transition.prototype = {\n  constructor: Transition,\n  select: transition_select,\n  selectAll: transition_selectAll,\n  selectChild: selection_prototype.selectChild,\n  selectChildren: selection_prototype.selectChildren,\n  filter: transition_filter,\n  merge: transition_merge,\n  selection: transition_selection,\n  transition: transition_transition,\n  call: selection_prototype.call,\n  nodes: selection_prototype.nodes,\n  node: selection_prototype.node,\n  size: selection_prototype.size,\n  empty: selection_prototype.empty,\n  each: selection_prototype.each,\n  on: transition_on,\n  attr: transition_attr,\n  attrTween: transition_attrTween,\n  style: transition_style,\n  styleTween: transition_styleTween,\n  text: transition_text,\n  textTween: transition_textTween,\n  remove: transition_remove,\n  tween: transition_tween,\n  delay: transition_delay,\n  duration: transition_duration,\n  ease: transition_ease,\n  easeVarying: transition_easeVarying,\n  end: transition_end,\n  [Symbol.iterator]: selection_prototype[Symbol.iterator]\n};\n","export function cubicIn(t) {\n  return t * t * t;\n}\n\nexport function cubicOut(t) {\n  return --t * t * t + 1;\n}\n\nexport function cubicInOut(t) {\n  return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;\n}\n","import {Transition, newId} from \"../transition/index.js\";\nimport schedule from \"../transition/schedule.js\";\nimport {easeCubicInOut} from \"d3-ease\";\nimport {now} from \"d3-timer\";\n\nvar defaultTiming = {\n  time: null, // Set on use.\n  delay: 0,\n  duration: 250,\n  ease: easeCubicInOut\n};\n\nfunction inherit(node, id) {\n  var timing;\n  while (!(timing = node.__transition) || !(timing = timing[id])) {\n    if (!(node = node.parentNode)) {\n      throw new Error(`transition ${id} not found`);\n    }\n  }\n  return timing;\n}\n\nexport default function(name) {\n  var id,\n      timing;\n\n  if (name instanceof Transition) {\n    id = name._id, name = name._name;\n  } else {\n    id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + \"\";\n  }\n\n  for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {\n    for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {\n      if (node = group[i]) {\n        schedule(node, name, id, i, group, timing || inherit(node, id));\n      }\n    }\n  }\n\n  return new Transition(groups, this._parents, name, id);\n}\n","import {selection} from \"d3-selection\";\nimport selection_interrupt from \"./interrupt.js\";\nimport selection_transition from \"./transition.js\";\n\nselection.prototype.interrupt = selection_interrupt;\nselection.prototype.transition = selection_transition;\n","import {dispatch} from \"d3-dispatch\";\nimport {dragDisable, dragEnable} from \"d3-drag\";\nimport {interpolate} from \"d3-interpolate\";\nimport {pointer, select} from \"d3-selection\";\nimport {interrupt} from \"d3-transition\";\nimport constant from \"./constant.js\";\nimport BrushEvent from \"./event.js\";\nimport noevent, {nopropagation} from \"./noevent.js\";\n\nvar MODE_DRAG = {name: \"drag\"},\n    MODE_SPACE = {name: \"space\"},\n    MODE_HANDLE = {name: \"handle\"},\n    MODE_CENTER = {name: \"center\"};\n\nconst {abs, max, min} = Math;\n\nfunction number1(e) {\n  return [+e[0], +e[1]];\n}\n\nfunction number2(e) {\n  return [number1(e[0]), number1(e[1])];\n}\n\nvar X = {\n  name: \"x\",\n  handles: [\"w\", \"e\"].map(type),\n  input: function(x, e) { return x == null ? null : [[+x[0], e[0][1]], [+x[1], e[1][1]]]; },\n  output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }\n};\n\nvar Y = {\n  name: \"y\",\n  handles: [\"n\", \"s\"].map(type),\n  input: function(y, e) { return y == null ? null : [[e[0][0], +y[0]], [e[1][0], +y[1]]]; },\n  output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }\n};\n\nvar XY = {\n  name: \"xy\",\n  handles: [\"n\", \"w\", \"e\", \"s\", \"nw\", \"ne\", \"sw\", \"se\"].map(type),\n  input: function(xy) { return xy == null ? null : number2(xy); },\n  output: function(xy) { return xy; }\n};\n\nvar cursors = {\n  overlay: \"crosshair\",\n  selection: \"move\",\n  n: \"ns-resize\",\n  e: \"ew-resize\",\n  s: \"ns-resize\",\n  w: \"ew-resize\",\n  nw: \"nwse-resize\",\n  ne: \"nesw-resize\",\n  se: \"nwse-resize\",\n  sw: \"nesw-resize\"\n};\n\nvar flipX = {\n  e: \"w\",\n  w: \"e\",\n  nw: \"ne\",\n  ne: \"nw\",\n  se: \"sw\",\n  sw: \"se\"\n};\n\nvar flipY = {\n  n: \"s\",\n  s: \"n\",\n  nw: \"sw\",\n  ne: \"se\",\n  se: \"ne\",\n  sw: \"nw\"\n};\n\nvar signsX = {\n  overlay: +1,\n  selection: +1,\n  n: null,\n  e: +1,\n  s: null,\n  w: -1,\n  nw: -1,\n  ne: +1,\n  se: +1,\n  sw: -1\n};\n\nvar signsY = {\n  overlay: +1,\n  selection: +1,\n  n: -1,\n  e: null,\n  s: +1,\n  w: null,\n  nw: -1,\n  ne: -1,\n  se: +1,\n  sw: +1\n};\n\nfunction type(t) {\n  return {type: t};\n}\n\n// Ignore right-click, since that should open the context menu.\nfunction defaultFilter(event) {\n  return !event.ctrlKey && !event.button;\n}\n\nfunction defaultExtent() {\n  var svg = this.ownerSVGElement || this;\n  if (svg.hasAttribute(\"viewBox\")) {\n    svg = svg.viewBox.baseVal;\n    return [[svg.x, svg.y], [svg.x + svg.width, svg.y + svg.height]];\n  }\n  return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];\n}\n\nfunction defaultTouchable() {\n  return navigator.maxTouchPoints || (\"ontouchstart\" in this);\n}\n\n// Like d3.local, but with the name “__brush” rather than auto-generated.\nfunction local(node) {\n  while (!node.__brush) if (!(node = node.parentNode)) return;\n  return node.__brush;\n}\n\nfunction empty(extent) {\n  return extent[0][0] === extent[1][0]\n      || extent[0][1] === extent[1][1];\n}\n\nexport function brushSelection(node) {\n  var state = node.__brush;\n  return state ? state.dim.output(state.selection) : null;\n}\n\nexport function brushX() {\n  return brush(X);\n}\n\nexport function brushY() {\n  return brush(Y);\n}\n\nexport default function() {\n  return brush(XY);\n}\n\nfunction brush(dim) {\n  var extent = defaultExtent,\n      filter = defaultFilter,\n      touchable = defaultTouchable,\n      keys = true,\n      listeners = dispatch(\"start\", \"brush\", \"end\"),\n      handleSize = 6,\n      touchending;\n\n  function brush(group) {\n    var overlay = group\n        .property(\"__brush\", initialize)\n      .selectAll(\".overlay\")\n      .data([type(\"overlay\")]);\n\n    overlay.enter().append(\"rect\")\n        .attr(\"class\", \"overlay\")\n        .attr(\"pointer-events\", \"all\")\n        .attr(\"cursor\", cursors.overlay)\n      .merge(overlay)\n        .each(function() {\n          var extent = local(this).extent;\n          select(this)\n              .attr(\"x\", extent[0][0])\n              .attr(\"y\", extent[0][1])\n              .attr(\"width\", extent[1][0] - extent[0][0])\n              .attr(\"height\", extent[1][1] - extent[0][1]);\n        });\n\n    group.selectAll(\".selection\")\n      .data([type(\"selection\")])\n      .enter().append(\"rect\")\n        .attr(\"class\", \"selection\")\n        .attr(\"cursor\", cursors.selection)\n        .attr(\"fill\", \"#777\")\n        .attr(\"fill-opacity\", 0.3)\n        .attr(\"stroke\", \"#fff\")\n        .attr(\"shape-rendering\", \"crispEdges\");\n\n    var handle = group.selectAll(\".handle\")\n      .data(dim.handles, function(d) { return d.type; });\n\n    handle.exit().remove();\n\n    handle.enter().append(\"rect\")\n        .attr(\"class\", function(d) { return \"handle handle--\" + d.type; })\n        .attr(\"cursor\", function(d) { return cursors[d.type]; });\n\n    group\n        .each(redraw)\n        .attr(\"fill\", \"none\")\n        .attr(\"pointer-events\", \"all\")\n        .on(\"mousedown.brush\", started)\n      .filter(touchable)\n        .on(\"touchstart.brush\", started)\n        .on(\"touchmove.brush\", touchmoved)\n        .on(\"touchend.brush touchcancel.brush\", touchended)\n        .style(\"touch-action\", \"none\")\n        .style(\"-webkit-tap-highlight-color\", \"rgba(0,0,0,0)\");\n  }\n\n  brush.move = function(group, selection, event) {\n    if (group.tween) {\n      group\n          .on(\"start.brush\", function(event) { emitter(this, arguments).beforestart().start(event); })\n          .on(\"interrupt.brush end.brush\", function(event) { emitter(this, arguments).end(event); })\n          .tween(\"brush\", function() {\n            var that = this,\n                state = that.__brush,\n                emit = emitter(that, arguments),\n                selection0 = state.selection,\n                selection1 = dim.input(typeof selection === \"function\" ? selection.apply(this, arguments) : selection, state.extent),\n                i = interpolate(selection0, selection1);\n\n            function tween(t) {\n              state.selection = t === 1 && selection1 === null ? null : i(t);\n              redraw.call(that);\n              emit.brush();\n            }\n\n            return selection0 !== null && selection1 !== null ? tween : tween(1);\n          });\n    } else {\n      group\n          .each(function() {\n            var that = this,\n                args = arguments,\n                state = that.__brush,\n                selection1 = dim.input(typeof selection === \"function\" ? selection.apply(that, args) : selection, state.extent),\n                emit = emitter(that, args).beforestart();\n\n            interrupt(that);\n            state.selection = selection1 === null ? null : selection1;\n            redraw.call(that);\n            emit.start(event).brush(event).end(event);\n          });\n    }\n  };\n\n  brush.clear = function(group, event) {\n    brush.move(group, null, event);\n  };\n\n  function redraw() {\n    var group = select(this),\n        selection = local(this).selection;\n\n    if (selection) {\n      group.selectAll(\".selection\")\n          .style(\"display\", null)\n          .attr(\"x\", selection[0][0])\n          .attr(\"y\", selection[0][1])\n          .attr(\"width\", selection[1][0] - selection[0][0])\n          .attr(\"height\", selection[1][1] - selection[0][1]);\n\n      group.selectAll(\".handle\")\n          .style(\"display\", null)\n          .attr(\"x\", function(d) { return d.type[d.type.length - 1] === \"e\" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })\n          .attr(\"y\", function(d) { return d.type[0] === \"s\" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })\n          .attr(\"width\", function(d) { return d.type === \"n\" || d.type === \"s\" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })\n          .attr(\"height\", function(d) { return d.type === \"e\" || d.type === \"w\" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });\n    }\n\n    else {\n      group.selectAll(\".selection,.handle\")\n          .style(\"display\", \"none\")\n          .attr(\"x\", null)\n          .attr(\"y\", null)\n          .attr(\"width\", null)\n          .attr(\"height\", null);\n    }\n  }\n\n  function emitter(that, args, clean) {\n    var emit = that.__brush.emitter;\n    return emit && (!clean || !emit.clean) ? emit : new Emitter(that, args, clean);\n  }\n\n  function Emitter(that, args, clean) {\n    this.that = that;\n    this.args = args;\n    this.state = that.__brush;\n    this.active = 0;\n    this.clean = clean;\n  }\n\n  Emitter.prototype = {\n    beforestart: function() {\n      if (++this.active === 1) this.state.emitter = this, this.starting = true;\n      return this;\n    },\n    start: function(event, mode) {\n      if (this.starting) this.starting = false, this.emit(\"start\", event, mode);\n      else this.emit(\"brush\", event);\n      return this;\n    },\n    brush: function(event, mode) {\n      this.emit(\"brush\", event, mode);\n      return this;\n    },\n    end: function(event, mode) {\n      if (--this.active === 0) delete this.state.emitter, this.emit(\"end\", event, mode);\n      return this;\n    },\n    emit: function(type, event, mode) {\n      var d = select(this.that).datum();\n      listeners.call(\n        type,\n        this.that,\n        new BrushEvent(type, {\n          sourceEvent: event,\n          target: brush,\n          selection: dim.output(this.state.selection),\n          mode,\n          dispatch: listeners\n        }),\n        d\n      );\n    }\n  };\n\n  function started(event) {\n    if (touchending && !event.touches) return;\n    if (!filter.apply(this, arguments)) return;\n\n    var that = this,\n        type = event.target.__data__.type,\n        mode = (keys && event.metaKey ? type = \"overlay\" : type) === \"selection\" ? MODE_DRAG : (keys && event.altKey ? MODE_CENTER : MODE_HANDLE),\n        signX = dim === Y ? null : signsX[type],\n        signY = dim === X ? null : signsY[type],\n        state = local(that),\n        extent = state.extent,\n        selection = state.selection,\n        W = extent[0][0], w0, w1,\n        N = extent[0][1], n0, n1,\n        E = extent[1][0], e0, e1,\n        S = extent[1][1], s0, s1,\n        dx = 0,\n        dy = 0,\n        moving,\n        shifting = signX && signY && keys && event.shiftKey,\n        lockX,\n        lockY,\n        points = Array.from(event.touches || [event], t => {\n          const i = t.identifier;\n          t = pointer(t, that);\n          t.point0 = t.slice();\n          t.identifier = i;\n          return t;\n        });\n\n    interrupt(that);\n    var emit = emitter(that, arguments, true).beforestart();\n\n    if (type === \"overlay\") {\n      if (selection) moving = true;\n      const pts = [points[0], points[1] || points[0]];\n      state.selection = selection = [[\n          w0 = dim === Y ? W : min(pts[0][0], pts[1][0]),\n          n0 = dim === X ? N : min(pts[0][1], pts[1][1])\n        ], [\n          e0 = dim === Y ? E : max(pts[0][0], pts[1][0]),\n          s0 = dim === X ? S : max(pts[0][1], pts[1][1])\n        ]];\n      if (points.length > 1) move(event);\n    } else {\n      w0 = selection[0][0];\n      n0 = selection[0][1];\n      e0 = selection[1][0];\n      s0 = selection[1][1];\n    }\n\n    w1 = w0;\n    n1 = n0;\n    e1 = e0;\n    s1 = s0;\n\n    var group = select(that)\n        .attr(\"pointer-events\", \"none\");\n\n    var overlay = group.selectAll(\".overlay\")\n        .attr(\"cursor\", cursors[type]);\n\n    if (event.touches) {\n      emit.moved = moved;\n      emit.ended = ended;\n    } else {\n      var view = select(event.view)\n          .on(\"mousemove.brush\", moved, true)\n          .on(\"mouseup.brush\", ended, true);\n      if (keys) view\n          .on(\"keydown.brush\", keydowned, true)\n          .on(\"keyup.brush\", keyupped, true)\n\n      dragDisable(event.view);\n    }\n\n    redraw.call(that);\n    emit.start(event, mode.name);\n\n    function moved(event) {\n      for (const p of event.changedTouches || [event]) {\n        for (const d of points)\n          if (d.identifier === p.identifier) d.cur = pointer(p, that);\n      }\n      if (shifting && !lockX && !lockY && points.length === 1) {\n        const point = points[0];\n        if (abs(point.cur[0] - point[0]) > abs(point.cur[1] - point[1]))\n          lockY = true;\n        else\n          lockX = true;\n      }\n      for (const point of points)\n        if (point.cur) point[0] = point.cur[0], point[1] = point.cur[1];\n      moving = true;\n      noevent(event);\n      move(event);\n    }\n\n    function move(event) {\n      const point = points[0], point0 = point.point0;\n      var t;\n\n      dx = point[0] - point0[0];\n      dy = point[1] - point0[1];\n\n      switch (mode) {\n        case MODE_SPACE:\n        case MODE_DRAG: {\n          if (signX) dx = max(W - w0, min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;\n          if (signY) dy = max(N - n0, min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;\n          break;\n        }\n        case MODE_HANDLE: {\n          if (points[1]) {\n            if (signX) w1 = max(W, min(E, points[0][0])), e1 = max(W, min(E, points[1][0])), signX = 1;\n            if (signY) n1 = max(N, min(S, points[0][1])), s1 = max(N, min(S, points[1][1])), signY = 1;\n          } else {\n            if (signX < 0) dx = max(W - w0, min(E - w0, dx)), w1 = w0 + dx, e1 = e0;\n            else if (signX > 0) dx = max(W - e0, min(E - e0, dx)), w1 = w0, e1 = e0 + dx;\n            if (signY < 0) dy = max(N - n0, min(S - n0, dy)), n1 = n0 + dy, s1 = s0;\n            else if (signY > 0) dy = max(N - s0, min(S - s0, dy)), n1 = n0, s1 = s0 + dy;\n          }\n          break;\n        }\n        case MODE_CENTER: {\n          if (signX) w1 = max(W, min(E, w0 - dx * signX)), e1 = max(W, min(E, e0 + dx * signX));\n          if (signY) n1 = max(N, min(S, n0 - dy * signY)), s1 = max(N, min(S, s0 + dy * signY));\n          break;\n        }\n      }\n\n      if (e1 < w1) {\n        signX *= -1;\n        t = w0, w0 = e0, e0 = t;\n        t = w1, w1 = e1, e1 = t;\n        if (type in flipX) overlay.attr(\"cursor\", cursors[type = flipX[type]]);\n      }\n\n      if (s1 < n1) {\n        signY *= -1;\n        t = n0, n0 = s0, s0 = t;\n        t = n1, n1 = s1, s1 = t;\n        if (type in flipY) overlay.attr(\"cursor\", cursors[type = flipY[type]]);\n      }\n\n      if (state.selection) selection = state.selection; // May be set by brush.move!\n      if (lockX) w1 = selection[0][0], e1 = selection[1][0];\n      if (lockY) n1 = selection[0][1], s1 = selection[1][1];\n\n      if (selection[0][0] !== w1\n          || selection[0][1] !== n1\n          || selection[1][0] !== e1\n          || selection[1][1] !== s1) {\n        state.selection = [[w1, n1], [e1, s1]];\n        redraw.call(that);\n        emit.brush(event, mode.name);\n      }\n    }\n\n    function ended(event) {\n      nopropagation(event);\n      if (event.touches) {\n        if (event.touches.length) return;\n        if (touchending) clearTimeout(touchending);\n        touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!\n      } else {\n        dragEnable(event.view, moving);\n        view.on(\"keydown.brush keyup.brush mousemove.brush mouseup.brush\", null);\n      }\n      group.attr(\"pointer-events\", \"all\");\n      overlay.attr(\"cursor\", cursors.overlay);\n      if (state.selection) selection = state.selection; // May be set by brush.move (on start)!\n      if (empty(selection)) state.selection = null, redraw.call(that);\n      emit.end(event, mode.name);\n    }\n\n    function keydowned(event) {\n      switch (event.keyCode) {\n        case 16: { // SHIFT\n          shifting = signX && signY;\n          break;\n        }\n        case 18: { // ALT\n          if (mode === MODE_HANDLE) {\n            if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n            if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n            mode = MODE_CENTER;\n            move(event);\n          }\n          break;\n        }\n        case 32: { // SPACE; takes priority over ALT\n          if (mode === MODE_HANDLE || mode === MODE_CENTER) {\n            if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;\n            if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;\n            mode = MODE_SPACE;\n            overlay.attr(\"cursor\", cursors.selection);\n            move(event);\n          }\n          break;\n        }\n        default: return;\n      }\n      noevent(event);\n    }\n\n    function keyupped(event) {\n      switch (event.keyCode) {\n        case 16: { // SHIFT\n          if (shifting) {\n            lockX = lockY = shifting = false;\n            move(event);\n          }\n          break;\n        }\n        case 18: { // ALT\n          if (mode === MODE_CENTER) {\n            if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n            if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n            mode = MODE_HANDLE;\n            move(event);\n          }\n          break;\n        }\n        case 32: { // SPACE\n          if (mode === MODE_SPACE) {\n            if (event.altKey) {\n              if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;\n              if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;\n              mode = MODE_CENTER;\n            } else {\n              if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;\n              if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;\n              mode = MODE_HANDLE;\n            }\n            overlay.attr(\"cursor\", cursors[type]);\n            move(event);\n          }\n          break;\n        }\n        default: return;\n      }\n      noevent(event);\n    }\n  }\n\n  function touchmoved(event) {\n    emitter(this, arguments).moved(event);\n  }\n\n  function touchended(event) {\n    emitter(this, arguments).ended(event);\n  }\n\n  function initialize() {\n    var state = this.__brush || {selection: null};\n    state.extent = number2(extent.apply(this, arguments));\n    state.dim = dim;\n    return state;\n  }\n\n  brush.extent = function(_) {\n    return arguments.length ? (extent = typeof _ === \"function\" ? _ : constant(number2(_)), brush) : extent;\n  };\n\n  brush.filter = function(_) {\n    return arguments.length ? (filter = typeof _ === \"function\" ? _ : constant(!!_), brush) : filter;\n  };\n\n  brush.touchable = function(_) {\n    return arguments.length ? (touchable = typeof _ === \"function\" ? _ : constant(!!_), brush) : touchable;\n  };\n\n  brush.handleSize = function(_) {\n    return arguments.length ? (handleSize = +_, brush) : handleSize;\n  };\n\n  brush.keyModifiers = function(_) {\n    return arguments.length ? (keys = !!_, brush) : keys;\n  };\n\n  brush.on = function() {\n    var value = listeners.on.apply(listeners, arguments);\n    return value === listeners ? brush : value;\n  };\n\n  return brush;\n}\n","export function Transform(k, x, y) {\n  this.k = k;\n  this.x = x;\n  this.y = y;\n}\n\nTransform.prototype = {\n  constructor: Transform,\n  scale: function(k) {\n    return k === 1 ? this : new Transform(this.k * k, this.x, this.y);\n  },\n  translate: function(x, y) {\n    return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);\n  },\n  apply: function(point) {\n    return [point[0] * this.k + this.x, point[1] * this.k + this.y];\n  },\n  applyX: function(x) {\n    return x * this.k + this.x;\n  },\n  applyY: function(y) {\n    return y * this.k + this.y;\n  },\n  invert: function(location) {\n    return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];\n  },\n  invertX: function(x) {\n    return (x - this.x) / this.k;\n  },\n  invertY: function(y) {\n    return (y - this.y) / this.k;\n  },\n  rescaleX: function(x) {\n    return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));\n  },\n  rescaleY: function(y) {\n    return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));\n  },\n  toString: function() {\n    return \"translate(\" + this.x + \",\" + this.y + \") scale(\" + this.k + \")\";\n  }\n};\n\nexport var identity = new Transform(1, 0, 0);\n\ntransform.prototype = Transform.prototype;\n\nexport default function transform(node) {\n  while (!node.__zoom) if (!(node = node.parentNode)) return identity;\n  return node.__zoom;\n}\n","/**\n * @module AutkMapUi\n * DOM-based user interface controller for `AutkMap`.\n *\n * This module defines the `AutkMapUi` class, which creates and maintains the\n * map's floating UI elements, including the layer menu, thematic legend, and\n * optional performance overlay. It coordinates UI state with map layer render\n * state so that visibility, color-map display, picking, and active-layer\n * selection stay aligned with the current map contents.\n */\n\nimport { ColorMap } from '@urban-toolkit/autk-core';\nimport type { ColorRGB } from '@urban-toolkit/autk-core';\nimport { Layer } from './layer';\nimport { AutkMap } from './map';\n\nimport * as d3 from 'd3';\n\nconst EYE_SVG = `<svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"#555\"><path d=\"M8 3C4.134 3 1 8 1 8s3.134 5 7 5 7-5 7-5-3.134-5-7-5zm0 8.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7zm0-5.5a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\"/></svg>`;\nconst RAMP_SVG  = `<svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\"><rect x=\"1\"   y=\"6\" width=\"3.5\" height=\"5\" rx=\"1\" fill=\"#4169e1\"/><rect x=\"4.5\" y=\"6\" width=\"3\"   height=\"5\"        fill=\"#44cccc\"/><rect x=\"7.5\" y=\"6\" width=\"3\"   height=\"5\"        fill=\"#fdd34d\"/><rect x=\"10.5\" y=\"6\" width=\"3.5\" height=\"5\" rx=\"1\" fill=\"#e04444\"/></svg>`;\nconst CURSOR_SVG = `<svg viewBox=\"0 0 16 16\" width=\"20\" height=\"20\" fill=\"#555\"><path d=\"M2 1l4.5 13 2.1-5.1L14 6.8z\"/></svg>`;\n\nconst DEBUG_FPS = false;\n\n/**\n * Floating DOM UI controller for an `AutkMap` instance.\n *\n * `AutkMapUi` builds lightweight overlay controls in the map canvas container\n * and keeps them synchronized with the current layer stack and render state.\n * It exposes methods for building and tearing down the UI, responding to map\n * resize and layer lifecycle events, and updating legend and performance\n * displays.\n *\n * @example\n * const map = new AutkMap(canvas);\n * await map.init();\n *\n * map.ui.changeActiveLayer(map.layerManager.layers[0] ?? null);\n */\nexport class AutkMapUi {\n    /** Parent map instance used for UI interactions and layer updates. */\n    protected _map: AutkMap;\n    /** Margin in CSS pixels used to place floating UI panels. */\n    protected _uiMargin: number = 10;\n    /** Currently active layer shown in the legend panel. */\n    protected _activeLayer: Layer | null = null;\n    /** Root menu icon element toggling submenu visibility. */\n    protected _menuIcon: HTMLDivElement | null = null;\n    /** Submenu container listing layers and controls. */\n    protected _subMenu: HTMLDivElement | null = null;\n    /** Legend panel for thematic colormap display. */\n    protected _legend: HTMLDivElement | null = null;\n    /** Performance overlay showing smoothed FPS and render time. */\n    protected _performanceOverlay: HTMLDivElement | null = null;\n    /** Persistent menu toggle handler removed during teardown. */\n    protected _onMenuIconClick: ((event: MouseEvent) => void) | null = null;\n    /** Branding shown independently of the optional map controls. */\n    private _branding: HTMLDivElement | null = null;\n    private _brandingResizeObserver: ResizeObserver | null = null;\n\n    /**\n     * Creates a UI controller bound to a map instance.\n     *\n     * The UI is not inserted into the DOM until {@link buildUi} is called.\n     *\n     * @param map Parent map whose canvas, layers, and update APIs are used by the UI.\n     */\n    constructor(map: AutkMap) {\n        this._map = map;\n    }\n\n    /** Parent map reference. */\n    get map(): AutkMap { return this._map; }\n    /** Updates the parent map reference used by subsequent UI operations. */\n    set map(map: AutkMap) { this._map = map; }\n    /** Layer currently used for legend display and pick activation. */\n    get activeLayer(): Layer | null { return this._activeLayer; }\n    /** Sets the cached active layer reference used by legend synchronization. */\n    set activeLayer(layer: Layer | null) { this._activeLayer = layer; }\n\n    // ── Resize ────────────────────────────────────────────────────────────────\n\n    /**\n     * Repositions floating UI elements to match the canvas location.\n     *\n     * This should be called after canvas size or page layout changes so the\n     * menu, submenu, legend, and performance overlay remain anchored to the\n     * correct corners of the map container.\n     *\n     * @returns Updates the inline position styles of any UI elements that have been built.\n     */\n    handleResize(): void {\n        if (this._branding) {\n            const canvas = this.map.canvas;\n            Object.assign(this._branding.style, {\n                left: `${canvas.offsetLeft}px`, top: `${canvas.offsetTop}px`,\n                width: `${canvas.offsetWidth}px`, height: `${canvas.offsetHeight}px`,\n                display: canvas.offsetWidth > 0 && canvas.offsetHeight > 0 ? 'block' : 'none',\n            });\n        }\n        if (this._menuIcon) {\n            this._menuIcon.style.top  = (this.map.canvas.offsetTop  + this._uiMargin) + 'px';\n            this._menuIcon.style.left = (this.map.canvas.offsetLeft + this._uiMargin) + 'px';\n        }\n        if (this._subMenu) {\n            this._subMenu.style.top  = (this.map.canvas.offsetTop  + 35 + 2 * this._uiMargin) + 'px';\n            this._subMenu.style.left = (this.map.canvas.offsetLeft + this._uiMargin) + 'px';\n        }\n        if (this._legend) {\n            const width  = parseInt(this._legend.style.width  || '0', 10) || 0;\n            const height = parseInt(this._legend.style.height || '0', 10) || 0;\n            this._legend.style.left = (this.map.canvas.offsetLeft + this.map.canvas.clientWidth  - 2 - width  - this._uiMargin) + 'px';\n            this._legend.style.top  = (this.map.canvas.offsetTop  + this.map.canvas.clientHeight - 2 - height - this._uiMargin) + 'px';\n        }\n        if (this._performanceOverlay) {\n            this._performanceOverlay.style.left = (this.map.canvas.offsetLeft + this.map.canvas.clientWidth - 92 - this._uiMargin) + 'px';\n            this._performanceOverlay.style.top = (this.map.canvas.offsetTop + this._uiMargin) + 'px';\n        }\n    }\n\n    /**\n     * Adds a faint “made with autark” watermark at the bottom right. Branding is independent of `showUi` and never\n     * intercepts canvas interaction. No animation loop is needed for positioning.\n     */\n    buildBranding(): void {\n        if (this._branding || !this.map.canvas.parentElement) return;\n\n        this._branding = document.createElement('div');\n        this._branding.className = 'autk-map-branding';\n        Object.assign(this._branding.style, {\n            position: 'absolute', pointerEvents: 'none', zIndex: '10', overflow: 'hidden',\n        });\n        this._branding.innerHTML = `<span class=\"autk-map-credit\" style=\"position:absolute;right:10px;bottom:10px;font:11px system-ui,sans-serif;color:#555;opacity:0.6;white-space:nowrap\">made with autark</span>`;\n        this.map.canvas.parentElement.appendChild(this._branding);\n        if (typeof ResizeObserver !== 'undefined') {\n            this._brandingResizeObserver = new ResizeObserver(() => this.handleResize());\n            this._brandingResizeObserver.observe(this.map.canvas);\n        }\n        this.handleResize();\n    }\n\n    // ── Active layer ──────────────────────────────────────────────────────────\n\n    /**\n     * Activates a layer for picking and legend display.\n     *\n     * The provided layer is first validated against the current layer manager.\n     * When a valid layer is found, this method makes picking exclusive by\n     * disabling `isPick` on every other registered layer before enabling it on\n     * the selected one. The legend is then refreshed to reflect the new active\n     * layer.\n     *\n     * Calls with `null` or with a layer object that is no longer the currently\n     * registered instance are ignored.\n     *\n     * @param layer Layer to activate.\n     * @returns Updates layer render state and refreshes the legend when activation succeeds.\n     */\n    changeActiveLayer(layer: Layer | null): void {\n        layer = this._resolveActiveLayer(layer);\n        if (!layer) return;\n        this._activeLayer = layer;\n\n        // Exclusive isPick: disable on all other vector layers\n        this._map.layerManager.layers.forEach((l: Layer) => {\n            if (l.layerInfo.id !== layer.layerInfo.id) {\n                this.map.updateRenderInfo(l.layerInfo.id, { renderInfo: { isPick: false } });\n            }\n        });\n\n        this.map.updateRenderInfo(layer.layerInfo.id, { renderInfo: { isPick: true } });\n        this.updateLegendContent();\n    }\n\n    // ── Public API ────────────────────────────────────────────────────────────\n\n    /**\n     * Builds the map UI overlays.\n     *\n     * This method creates the menu icon, submenu structure, layer list section,\n     * legend container, and optional performance overlay. Repeated calls are\n     * safe and reuse already-created elements.\n     *\n     * @returns Ensures the UI DOM structure exists for the current map.\n     */\n    buildUi(): void {\n        this.buildMenuIcon();\n        this.buildSubMenu();\n        this.buildLayerList();\n        this.buildLegend();\n\n        if(DEBUG_FPS) {\n            this.buildPerformanceOverlay(); \n        }\n    }\n\n    /**\n     * Removes all UI DOM nodes, listeners, and cached UI state.\n     *\n     * After teardown, the instance retains only its map reference. Calling\n     * {@link buildUi} again recreates the UI from scratch.\n     *\n     * @returns Detaches injected elements and clears cached element references.\n     */\n    destroy(): void {\n        if (this._menuIcon && this._onMenuIconClick) {\n            this._menuIcon.removeEventListener('click', this._onMenuIconClick);\n        }\n\n        this._brandingResizeObserver?.disconnect();\n        this._branding?.remove();\n        this._branding = null;\n        this._brandingResizeObserver = null;\n\n        this._menuIcon?.remove();\n        this._subMenu?.remove();\n        this._legend?.remove();\n        this._performanceOverlay?.remove();\n\n        this._onMenuIconClick = null;\n        this._menuIcon = null;\n        this._subMenu = null;\n        this._legend = null;\n        this._performanceOverlay = null;\n        this._activeLayer = null;\n    }\n\n    /**\n     * Updates the on-screen performance overlay.\n     *\n     * If the performance overlay has not been created, the call is ignored.\n     *\n     * @param fps Smoothed frames-per-second value to display.\n     * @param frameTimeMs Frame time in milliseconds to display.\n     * @returns Updates the overlay contents when the performance UI is enabled.\n     */\n    updatePerformance(fps: number, frameTimeMs: number): void {\n        if (!this._performanceOverlay) {\n            return;\n        }\n\n        this._performanceOverlay.innerHTML = `<div style=\"font-weight:600;\">${fps.toFixed(1)} fps</div><div>${frameTimeMs.toFixed(1)} ms</div>`;\n    }\n\n    /**\n     * Clears active-layer UI state after a layer is removed from the map.\n     *\n     * If the removed layer was the current active layer, the cached reference is\n     * cleared before the legend visibility is recomputed.\n     *\n     * @param layerId Identifier of the removed layer.\n     * @returns Synchronizes legend visibility with the remaining layer state.\n     */\n    handleLayerRemoved(layerId: string): void {\n        if (this._activeLayer?.layerInfo.id === layerId) {\n            this._activeLayer = null;\n        }\n        this.syncLegendVisibility();\n    }\n\n    /**\n     * Refreshes legend state after layer render settings change.\n     *\n     * If the provided layer is still registered and has color-map rendering\n     * enabled, it becomes the active legend layer. The legend container is then\n     * shown or hidden according to the resolved active layer state.\n     *\n     * @param layer Layer whose legend-related state may have changed.\n     * @returns Recomputes legend visibility and content for the current active layer.\n     */\n    refreshLegend(layer: Layer | null): void {\n        const resolvedLayer = this._resolveActiveLayer(layer);\n        if (resolvedLayer && resolvedLayer.layerRenderInfo.isColorMap) {\n            this._activeLayer = resolvedLayer;\n        }\n        this.syncLegendVisibility();\n    }\n\n    /**\n     * Rebuilds the layer list when visible layer state changes.\n     *\n     * This method is intended to be called after updates to render flags such as\n     * `isSkip`, `isPick`, or `isColorMap`. To avoid unnecessary DOM work, the\n     * list is repopulated only while the submenu is currently visible.\n     *\n     * @returns Re-renders the visible layer rows when the submenu is open.\n     */\n    refreshLayerList(): void {\n        if (this._subMenu?.style.visibility !== 'visible') return;\n        this.populateLayerList();\n    }\n\n    // ── State sync ────────────────────────────────────────────────────────────\n\n    /**\n     * Synchronizes legend visibility with the current active layer.\n     *\n     * The cached active layer is first validated against the current layer\n     * manager. The legend is visible only when that resolved layer exists and\n     * has color-map rendering enabled.\n     *\n     * @returns Updates legend visibility and redraws legend contents.\n     */\n    protected syncLegendVisibility(): void {\n        if (!this._legend) return;\n        this._activeLayer = this._resolveActiveLayer(this._activeLayer);\n        const isColorMap = this._activeLayer?.layerRenderInfo.isColorMap ?? false;\n        this._legend.style.visibility = isColorMap ? 'visible' : 'hidden';\n        this.updateLegendContent();\n    }\n\n    // ── Build structure (idempotent) ───────────────────────────────────────────\n\n    /**\n     * Creates the floating menu toggle button.\n     *\n     * The button is positioned relative to the map canvas and toggles submenu\n     * visibility on click. When opening the submenu, the layer list is\n     * repopulated so the displayed rows reflect current map state.\n     *\n     * Repeated calls are ignored after the element has been created.\n     *\n     * @returns Inserts the menu button into the canvas parent element.\n     */\n    protected buildMenuIcon(): void {\n        if (this._menuIcon) return;\n\n        this._menuIcon = document.createElement('div');\n        this._menuIcon.id = 'autkMapUi';\n        Object.assign(this._menuIcon.style, {\n            width: '40px', height: '40px', position: 'absolute', display: 'flex',\n            alignItems: 'center', justifyContent: 'center', zIndex: '11',\n            backgroundColor: '#fff', border: 'none', borderRadius: '10px',\n            cursor: 'pointer', boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\n            fontFamily: 'system-ui, sans-serif',\n            top:  (this.map.canvas.offsetTop  + this._uiMargin) + 'px',\n            left: (this.map.canvas.offsetLeft + this._uiMargin) + 'px',\n        });\n\n        this._menuIcon.innerHTML = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 40 40\">\n            <rect x=\"8\"  y=\"10\"   rx=\"1.5\" ry=\"1.5\" width=\"24\" height=\"3.5\" fill=\"#666\" stroke=\"none\"></rect>\n            <rect x=\"8\"  y=\"18.5\" rx=\"1.5\" ry=\"1.5\" width=\"24\" height=\"3.5\" fill=\"#666\" stroke=\"none\"></rect>\n            <rect x=\"8\"  y=\"27\"   rx=\"1.5\" ry=\"1.5\" width=\"24\" height=\"3.5\" fill=\"#666\" stroke=\"none\"></rect>\n        </svg>`;\n\n        this.map.canvas.parentElement?.appendChild(this._menuIcon);\n\n        this._onMenuIconClick = (e) => {\n            e.stopPropagation();\n            if (!this._subMenu) return;\n            const opening = this._subMenu.style.visibility !== 'visible';\n            if (opening) this.populateLayerList();\n            this._subMenu.style.visibility = opening ? 'visible' : 'hidden';\n        };\n        this._menuIcon.addEventListener('click', this._onMenuIconClick);\n    }\n\n    /**\n     * Creates the submenu container used for layer controls.\n     *\n     * The container is initially hidden and positioned below the main menu\n     * button. It serves as the parent for layer-related headings and rows.\n     *\n     * Repeated calls are ignored after the element has been created.\n     *\n     * @returns Inserts the submenu container into the canvas parent element.\n     */\n    protected buildSubMenu(): void {\n        if (this._subMenu) return;\n\n        this._subMenu = document.createElement('div');\n        this._subMenu.id = 'autkMapSubMenu';\n        Object.assign(this._subMenu.style, {\n            position: 'absolute', width: '260px', display: 'block', zIndex: '11',\n            backgroundColor: '#fff', border: 'none', borderRadius: '10px',\n            padding: '0', visibility: 'hidden',\n            boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\n            fontFamily: 'system-ui, sans-serif', fontSize: '14px',\n            overflow: 'hidden',\n            top:  (this.map.canvas.offsetTop  + 35 + 2 * this._uiMargin) + 'px',\n            left: (this.map.canvas.offsetLeft + this._uiMargin) + 'px',\n        });\n\n        this.map.canvas.parentElement?.appendChild(this._subMenu);\n    }\n\n    /**\n     * Creates the layer list section inside the submenu.\n     *\n     * This method adds the static heading and the container later populated by\n     * {@link populateLayerList}. If the section already exists, the call is\n     * ignored.\n     *\n     * @returns Ensures the submenu contains the layer-list structure.\n     */\n    protected buildLayerList(): void {\n        if (!this._subMenu || this._subMenu.querySelector('#layersTitle')) return;\n\n        this._subMenu.appendChild(this.makeHeading('layersTitle', 'Layers'));\n\n        const section = document.createElement('div');\n        section.id = 'layerListSection';\n        Object.assign(section.style, { padding: '4px 0 6px' });\n        this._subMenu.appendChild(section);\n    }\n\n    /**\n     * Creates the floating legend container.\n     *\n     * The legend is positioned in the lower-right corner of the map canvas and\n     * remains hidden until an active layer with color-map rendering is available.\n     *\n     * Repeated calls are ignored after the element has been created.\n     *\n     * @param width Legend width in CSS pixels.\n     * @param height Legend height in CSS pixels.\n     * @returns Inserts the legend container into the canvas parent element.\n     */\n    protected buildLegend(width = 250, height = 80): void {\n        if (this._legend) return;\n\n        this._legend = document.createElement('div');\n        this._legend.id = 'autkMapLegend';\n        Object.assign(this._legend.style, {\n            position: 'absolute', display: 'block', zIndex: '11', visibility: 'hidden',\n            backgroundColor: '#fff', border: 'none', borderRadius: '10px',\n            boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\n            fontFamily: 'system-ui, sans-serif', fontSize: '14px',\n            width: width + 'px', height: height + 'px',\n            left: (this.map.canvas.offsetLeft + this.map.canvas.clientWidth  - 2 - width  - this._uiMargin) + 'px',\n            top:  (this.map.canvas.offsetTop  + this.map.canvas.clientHeight - 2 - height - this._uiMargin) + 'px',\n        });\n\n        this.map.canvas.parentElement?.appendChild(this._legend);\n    }\n\n    /**\n     * Creates the optional performance overlay.\n     *\n     * The overlay is positioned near the upper-right corner of the map canvas\n     * and displays FPS and frame time values supplied through\n     * {@link updatePerformance}. Repeated calls are ignored after the element\n     * has been created.\n     *\n     * @returns Inserts the performance overlay into the canvas parent element.\n     */\n    protected buildPerformanceOverlay(): void {\n        if (this._performanceOverlay) return;\n\n        this._performanceOverlay = document.createElement('div');\n        this._performanceOverlay.id = 'autkMapPerformanceOverlay';\n        Object.assign(this._performanceOverlay.style, {\n            position: 'absolute', display: 'block', zIndex: '11',\n            minWidth: '82px', padding: '8px 10px',\n            backgroundColor: 'rgba(255,255,255,0.92)', borderRadius: '10px',\n            boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\n            fontFamily: 'system-ui, sans-serif', fontSize: '12px', color: '#222',\n            textAlign: 'right',\n            left: (this.map.canvas.offsetLeft + this.map.canvas.clientWidth - 92 - this._uiMargin - 10) + 'px',\n            top: (this.map.canvas.offsetTop + this._uiMargin) + 'px',\n        });\n        this._performanceOverlay.innerHTML = '<div style=\"font-weight:600;\">0.0 fps</div><div>0.0 ms</div>';\n\n        this.map.canvas.parentElement?.appendChild(this._performanceOverlay);\n    }\n\n    // ── Layer list population ─────────────────────────────────────────────────\n\n    /**\n     * Repopulates the submenu with one row per current layer.\n     *\n     * Existing row content is cleared before rows are rebuilt in the current\n     * layer-manager order.\n     *\n     * @returns Recreates the layer list DOM when the section is available.\n     */\n    protected populateLayerList(): void {\n        const section = this._subMenu?.querySelector('#layerListSection') as HTMLDivElement | null;\n        if (!section) return;\n        section.innerHTML = '';\n\n        const all = this.map.layerManager.layers;\n        for (const layer of all) {\n            section.appendChild(this.makeLayerRow(layer));\n        }\n    }\n\n    // ── Legend content ────────────────────────────────────────────────────────\n\n    /**\n     * Renders the legend contents for the active layer.\n     *\n     * The active layer is first validated against the current map state. When no\n     * valid active layer remains, the legend contents are cleared. Otherwise,\n     * this method renders the layer title and a color ramp derived from the\n     * layer's colormap interpolator and computed labels.\n     *\n     * Categorical color schemes are truncated to the supported scheme size,\n     * while continuous schemes render a 100-step ramp.\n     *\n     * @param width Legend width in CSS pixels.\n     * @param height Legend height in CSS pixels.\n     * @returns Rebuilds the legend DOM for the resolved active layer.\n     */\n    protected updateLegendContent(width = 250, height = 80): void {\n        if (!this._legend) return;\n\n        this._activeLayer = this._resolveActiveLayer(this._activeLayer);\n        if (!this._activeLayer) {\n            this._legend.innerHTML = '';\n            return;\n        }\n\n        this._legend.innerHTML = '';\n\n        const title = document.createElement('div');\n        title.textContent = this._activeLayer.layerInfo.id;\n        Object.assign(title.style, {\n            padding: '10px 14px 6px', fontWeight: '600', fontSize: '14px',\n            color: '#222', borderBottom: '1px solid #e8e8e8', textAlign: 'center',\n        });\n        this._legend.appendChild(title);\n\n        const padding     = this._uiMargin;\n        const titleHeight = 40;\n        const innerWidth  = width - 4 * padding;\n        const innerHeight = height - titleHeight;\n\n        const interpolator = this._activeLayer.layerRenderInfo.colormap.config.interpolator;\n        const labels       = this._activeLayer.layerRenderInfo.colormap.computedLabels ?? [];\n        const categoricalSize = ColorMap.getCategoricalSchemeSize(interpolator);\n        const isCategorical   = categoricalSize !== null;\n        const res             = isCategorical ? categoricalSize : 100;\n        const slc             = isCategorical ? Math.min(labels.length, categoricalSize) : 100;\n        const colorMap     = ColorMap.getColorArray(interpolator, res).slice(0, slc);\n\n        const svg       = d3.select(this._legend).append('svg').attr('width', width).attr('height', innerHeight);\n        const rectWidth = innerWidth / colorMap.length;\n        const rectH     = innerHeight * 0.3;\n        const g         = svg.append('g').attr('transform', `translate(${2 * padding}, 0)`);\n\n        g.selectAll<SVGRectElement, ColorRGB>('rect').data(colorMap).join('rect')\n            .attr('x', (_d, i) => i * rectWidth).attr('y', 0)\n            .attr('width', rectWidth).attr('height', rectH)\n            .style('fill',   (d) => `rgb(${d.r},${d.g},${d.b})`)\n            .style('stroke', (d) => `rgb(${d.r},${d.g},${d.b})`)\n            .style('stroke-width', '1px');\n\n        const textData = labels.map((d, i) => ({\n            label: d,\n            pos: isCategorical\n                ? i * rectWidth + rectWidth / 2\n                : i * (innerWidth / (labels.length - 1)),\n        }));\n\n        g.selectAll('text').data(textData).join('text')\n            .text((d) => d.label)\n            .attr('x', (d) => d.pos).attr('y', rectH + 12)\n            .style('font-size', '12px').style('fill', '#333').style('text-anchor', 'middle');\n    }\n\n    // ── Helpers ───────────────────────────────────────────────────────────────\n\n    /**\n     * Creates a layer-list row with visibility, color-map, and pick controls.\n     *\n     * Raster layers do not receive a picking button because they cannot be made\n     * the active picking layer by this UI.\n     *\n     * @param layer Layer represented by the row.\n     * @returns Newly created DOM row for the layer list.\n     */\n    private makeLayerRow(layer: Layer): HTMLDivElement {\n        const row = document.createElement('div');\n        Object.assign(row.style, {\n            display: 'flex', alignItems: 'center', gap: '2px',\n            padding: '4px 10px 4px 14px',\n        });\n\n        const eyeBtn = this.makeIconButton(EYE_SVG, !layer.layerRenderInfo.isSkip, () => {\n            this.map.updateRenderInfo(layer.layerInfo.id, { renderInfo: { isSkip: !layer.layerRenderInfo.isSkip } });\n        });\n\n        const paletteBtn = this.makeIconButton(RAMP_SVG, layer.layerRenderInfo.isColorMap ?? false, () => {\n            this.map.updateRenderInfo(layer.layerInfo.id, { renderInfo: { isColorMap: !layer.layerRenderInfo.isColorMap } });\n        });\n\n        const isRaster = layer.layerInfo.typeLayer === 'raster';\n        const cursorBtn = isRaster\n            ? (() => { const s = document.createElement('span'); s.style.width = '28px'; s.style.flexShrink = '0'; return s; })()\n            : this.makeIconButton(CURSOR_SVG, layer.layerRenderInfo.isPick ?? false, () => {\n                this.changeActiveLayer(this.map.layerManager.searchByLayerId(layer.layerInfo.id));\n            });\n\n        const nameEl = document.createElement('span');\n        nameEl.textContent = layer.layerInfo.id;\n        Object.assign(nameEl.style, {\n            flex: '1', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',\n            fontSize: '13px', color: '#333', marginLeft: '4px',\n        });\n\n        row.appendChild(eyeBtn);\n        row.appendChild(paletteBtn);\n        row.appendChild(cursorBtn);\n        row.appendChild(nameEl);\n        return row;\n    }\n\n    /**\n     * Creates a compact icon button for a layer-row action.\n     *\n     * The button's opacity reflects whether the corresponding action is\n     * currently active.\n     *\n     * @param svg Inline SVG markup displayed inside the button.\n     * @param active Whether the action is currently enabled.\n     * @param onClick Click handler invoked when the button is pressed.\n     * @returns Configured button element.\n     */\n    private makeIconButton(svg: string, active: boolean, onClick: () => void): HTMLButtonElement {\n        const btn = document.createElement('button');\n        btn.innerHTML = svg;\n        Object.assign(btn.style, {\n            width: '28px', height: '28px', flexShrink: '0',\n            border: 'none', borderRadius: '4px', cursor: 'pointer',\n            background: 'none', padding: '2px', display: 'flex',\n            alignItems: 'center', justifyContent: 'center',\n            opacity: active ? '1' : '0.25',\n        });\n        btn.addEventListener('click', onClick);\n        return btn;\n    }\n\n    /**\n     * Creates a styled submenu or legend heading element.\n     *\n     * @param id Element id assigned to the heading.\n     * @param text Visible heading text.\n     * @returns Styled heading element.\n     */\n    private makeHeading(id: string, text: string): HTMLDivElement {\n        const d = document.createElement('div');\n        d.id = id;\n        d.textContent = text;\n        Object.assign(d.style, {\n            padding: '10px 14px 6px', fontWeight: '600', fontSize: '14px',\n            color: '#222', borderBottom: '1px solid #e8e8e8',\n        });\n        return d;\n    }\n\n    /**\n     * Resolves a cached layer reference against the current layer manager.\n     *\n     * This guards against stale references after layers are removed or replaced.\n     * The layer is returned only when the current manager resolves the same\n     * object instance for the layer id.\n     *\n     * @param layer Candidate layer reference.\n     * @returns The current registered layer instance, or `null` when the reference is stale.\n     */\n    private _resolveActiveLayer(layer: Layer | null): Layer | null {\n        if (!layer) {\n            return null;\n        }\n\n        const currentLayer = this.map.layerManager.searchByLayerId(layer.layerInfo.id);\n        return currentLayer === layer ? currentLayer : null;\n    }\n}\n","{\n    \"background\": \"#b2c7cd\",\n    \"surface\": \"#e2eaed\",\n    \"parks\": \"#b8ccb0\",\n    \"water\": \"#9ec0cb\",\n    \"roads\": \"#b98c0f\",\n    \"buildings\": \"#c7d3d8\",\n    \"points\": \"#9ea4a6\",\n    \"polylines\": \"#b5bbbe\",\n    \"polygons\": \"#cbd3d5\"\n}\n","{\n    \"background\": \"#f2f3f2\",\n    \"surface\": \"#e6e8e7\",\n    \"parks\": \"#dde5d8\",\n    \"water\": \"#dce8f0\",\n    \"roads\": \"#b7bdc4\",\n    \"buildings\": \"#d4d8d6\",\n    \"points\": \"#a1a2a2\",\n    \"polylines\": \"#b8bab9\",\n    \"polygons\": \"#cfd1d0\"\n}\n","{\n    \"background\": \"#eeeae4\",\n    \"surface\": \"#e2ddd5\",\n    \"parks\": \"#a9e3ad\",\n    \"water\": \"#86c9e8\",\n    \"roads\": \"#a3b2c2\",\n    \"buildings\": \"#cfc7bc\",\n    \"points\": \"#9e9b95\",\n    \"polylines\": \"#b5b1aa\",\n    \"polygons\": \"#cbc7c0\"\n}\n","{\n    \"background\": \"#e8eff2\",\n    \"surface\": \"#f4f4f2\",\n    \"parks\": \"#d5eacb\",\n    \"water\": \"#b8def5\",\n    \"roads\": \"#c3cdd4\",\n    \"buildings\": \"#d8dde0\",\n    \"points\": \"#ababa9\",\n    \"polylines\": \"#c3c3c2\",\n    \"polygons\": \"#dcdcda\"\n}","{\n    \"background\": \"#eee9e1\",\n    \"surface\": \"#f7f3eb\",\n    \"parks\": \"#cdebb0\",\n    \"water\": \"#a9d3f5\",\n    \"roads\": \"#d2c0a5\",\n    \"buildings\": \"#decfb6\",\n    \"points\": \"#adaaa5\",\n    \"polylines\": \"#c6c2bc\",\n    \"polygons\": \"#dedbd4\"\n}\n","{\n    \"background\": \"#e6eef4\",\n    \"surface\": \"#ffffff\",\n    \"parks\": \"#ffffff\",\n    \"water\": \"#e6eef4\",\n    \"roads\": \"#353535\",\n    \"buildings\": \"#e2e2e2\",\n    \"points\": \"#666666\",\n    \"polylines\": \"#444444\",\n    \"polygons\": \"#eeeeee\"\n}\n","/**\n * @module MapStyle\n * Per-map color-style state and utilities for semantic map layers.\n *\n * This module defines the `MapStyle` class and related types used to manage\n * built-in and runtime-provided map styles. Each `AutkMap` owns its own\n * `MapStyle` instance so multiple maps can use different visual treatments.\n */\n\nimport { ColorHEX, ColorRGB, ColorMap, LAYER_TYPE_VALUES } from '@urban-toolkit/autk-core';\nimport type { LayerType } from '@urban-toolkit/autk-core';\n\nimport defaultStyle from './styles/default.json';\nimport light from './styles/light.json';\nimport google from './styles/google.json';\nimport apple from './styles/apple.json';\nimport osm from './styles/osm.json';\nimport poster from './styles/poster.json';\n\n/** Supported built-in style preset identifiers. */\nexport type MapStylePresetId = 'default' | 'light' | 'google' | 'apple' | 'osm' | 'poster';\n\n/** Ordered preset ids used for keyboard style cycling. */\nconst PRESET_IDS: readonly MapStylePresetId[] = ['apple', 'default', 'light', 'google', 'osm', 'poster'];\n/** Required keys for a valid map style object — derived from `LayerType` minus `raster`. */\nconst MAP_STYLE_KEYS: Array<keyof MapStyleShape> = LAYER_TYPE_VALUES.filter(\n  (l): l is Exclude<LayerType, 'raster'> => l !== 'raster',\n) as Array<keyof MapStyleShape>;\n/** Accepts #RGB, #RRGGBB and #RRGGBBAA color literals. */\nconst HEX_COLOR_RE = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;\n\n/**\n * Semantic color slots required by a map style.\n *\n * Each key maps a renderer-facing semantic layer or feature family to a hex\n * color literal. Runtime custom styles must provide every field defined by this\n * interface.\n */\nexport interface MapStyleShape {\n    background: ColorHEX;\n    surface: ColorHEX;\n    parks: ColorHEX;\n    water: ColorHEX;\n    roads: ColorHEX;\n    buildings: ColorHEX;\n    points: ColorHEX;\n    polylines: ColorHEX;\n    polygons: ColorHEX;\n}\n\n/**\n * Instance-owned map style state and semantic color resolver.\n *\n * `MapStyle` stores the active semantic style for one map, along with related\n * colors such as highlight and invalid-value fallbacks. Built-in and custom\n * styles are validated before they become active.\n *\n * @example\n * const style = new MapStyle('apple');\n * style.setPredefinedStyle('light');\n * const roads = style.getColor('roads');\n */\nexport class MapStyle {\n    /** Built-in style presets available by id. */\n    protected static _presets: Record<MapStylePresetId, MapStyleShape> = {\n        default: MapStyle._normalizeStyle(defaultStyle as MapStyleShape, 'default'),\n        light: MapStyle._normalizeStyle(light as MapStyleShape, 'light'),\n        google: MapStyle._normalizeStyle(google as MapStyleShape, 'google'),\n        apple: MapStyle._normalizeStyle(apple as MapStyleShape, 'apple'),\n        osm: MapStyle._normalizeStyle(osm as MapStyleShape, 'osm'),\n        poster: MapStyle._normalizeStyle(poster as MapStyleShape, 'poster'),\n    };\n\n    /** Default style assigned to new maps. */\n    protected static _defaultStyleId: MapStylePresetId = 'apple';\n\n    /** Color used for invalid thematic values. */\n    protected _invalidValue: ColorHEX = '#FFFFFF';\n    /** Highlight color used for interactive selections. */\n    protected _highlight: ColorHEX = '#5dade2';\n    /** Currently active semantic map style. */\n    protected _current: MapStyleShape;\n    /** Identifier of the currently active style or `custom`. */\n    protected _currentStyle: string;\n    /** Callback run after the active style or one of its colors changes. */\n    private _onChange: (() => void) | null = null;\n\n    /**\n     * Creates a style state initialized from a built-in preset.\n     *\n     * @param style Initial built-in style id. Unknown ids fall back to `apple`.\n     * @throws Never throws.\n     * @example\n     * const style = new MapStyle('apple');\n     */\n    constructor(style: string = MapStyle._defaultStyleId) {\n        const presetId: MapStylePresetId = MapStyle._isPresetId(style) ? style : MapStyle._defaultStyleId;\n        this._current = MapStyle._presets[presetId];\n        this._currentStyle = presetId;\n    }\n\n    /**\n     * Returns the identifier of the currently active style.\n     *\n     * Built-in presets return their preset id. Styles applied through\n     * `setCustomStyle()` report `custom`.\n     *\n     * @returns Active style identifier.\n     */\n    get currentStyle(): string {\n        return this._currentStyle;\n    }\n\n    /** Returns the list of built-in preset ids. */\n    get availableStyles(): MapStylePresetId[] {\n        return MapStyle.availableStyles;\n    }\n\n    /** Returns the list of built-in preset ids. */\n    static get availableStyles(): MapStylePresetId[] {\n        return [...PRESET_IDS];\n    }\n\n    /**\n     * Returns the feature color for a style key, falling back to polygons color.\n     *\n     * @param type Semantic style key to resolve.\n     * @returns RGB color for the requested key.\n     * @throws Never throws.\n     * @example\n     * const roadsColor = style.getColor('roads');\n     */\n    getColor(type: string): ColorRGB {\n        const hex = (Object.prototype.hasOwnProperty.call(this._current, type)\n            ? this._current[type as keyof MapStyleShape]\n            : undefined) ?? this._current.polygons;\n\n        return ColorMap.hexToRgb(hex);\n    }\n\n    /**\n     * Returns the color used for invalid thematic values.\n     *\n     * @returns RGB fallback color.\n     * @throws Never throws.\n     */\n    getInvalidValueColor(): ColorRGB {\n        return ColorMap.hexToRgb(this._invalidValue);\n    }\n\n    /**\n     * Registers the callback run after the style changes.\n     *\n     * `AutkMap` uses it to schedule a frame in on-demand mode. Pass `null` to\n     * remove the callback.\n     *\n     * @param listener Callback run after each style change, or `null`.\n     * @returns Nothing.\n     * @throws Never throws.\n     */\n    setChangeListener(listener: (() => void) | null): void {\n        this._onChange = listener;\n    }\n\n    /**\n     * Applies one of the built-in map style presets.\n     *\n     * @param style Preset identifier. Unknown ids fall back to `apple`.\n     * @returns Nothing.\n     * @throws Never throws.\n     * @example\n     * style.setPredefinedStyle('light');\n     */\n    setPredefinedStyle(style: string): void {\n        const presetId: MapStylePresetId = MapStyle._isPresetId(style) ? style : MapStyle._defaultStyleId;\n        this._current = MapStyle._presets[presetId];\n        this._currentStyle = presetId;\n        this._onChange?.();\n    }\n\n    /**\n     * Applies a runtime custom style after validation.\n     *\n     * @param style Style object with all required semantic color keys.\n     * @returns Nothing. The style id becomes `custom`.\n     * @throws If the style is missing required keys or has invalid hex color values.\n     * @example\n     * style.setCustomStyle({ background: '#fff', surface: '#eee', parks: '#cfc', water: '#bdf', roads: '#ddd', buildings: '#ccc', points: '#555', polylines: '#777', polygons: '#999' });\n     */\n    setCustomStyle(style: MapStyleShape): void {\n        this._current = MapStyle._normalizeStyle(style, 'custom');\n        this._currentStyle = 'custom';\n        this._onChange?.();\n    }\n\n    /**\n     * Returns the current highlight color.\n     *\n     * @returns RGB highlight color.\n     * @throws Never throws.\n     */\n    getHighlightColor(): ColorRGB {\n        return ColorMap.hexToRgb(this._highlight);\n    }\n\n    /**\n     * Sets the highlight color.\n     *\n     * @param color New highlight color in hex format.\n     * @returns Nothing.\n     * @throws Never throws.\n     */\n    setHighlightColor(color: ColorHEX): void {\n        this._highlight = color;\n        this._onChange?.();\n    }\n\n    /**\n     * Sets the color used for invalid thematic values.\n     *\n     * @param color New fallback color for invalid thematic values.\n     * @returns Nothing.\n     * @throws Never throws.\n     */\n    setInvalidValueColor(color: ColorHEX): void {\n        this._invalidValue = color;\n        this._onChange?.();\n    }\n\n    /**\n     * Checks whether a string matches one of the built-in preset ids.\n     *\n     * @param style Candidate preset identifier.\n     * @returns `true` when the value names a built-in preset.\n     */\n    private static _isPresetId(style: string): style is MapStylePresetId {\n        return (PRESET_IDS as readonly string[]).includes(style);\n    }\n\n    /**\n     * Normalizes and validates a style definition.\n     *\n     * Every required semantic key must be present and contain a non-empty hex\n     * color string. Values are trimmed before validation and before being stored\n     * in the returned object.\n     *\n     * Throws on invalid input so callers fail fast with actionable errors.\n     *\n     * @param style Style object to validate.\n     * @param source Human-readable source label included in thrown error messages.\n     * @returns Normalized style object containing trimmed hex color values for every required key.\n     */\n    private static _normalizeStyle(style: MapStyleShape, source: string): MapStyleShape {\n        const normalized: Partial<MapStyleShape> = {};\n\n        for (const key of MAP_STYLE_KEYS) {\n            const value = style[key];\n\n            if (typeof value !== 'string' || value.trim().length === 0) {\n                throw new Error(`MapStyle(${source}): missing required key \"${key}\".`);\n            }\n\n            const trimmed = value.trim();\n            if (!HEX_COLOR_RE.test(trimmed)) {\n                throw new Error(`MapStyle(${source}): key \"${key}\" must be a hex color (#RGB, #RRGGBB or #RRGGBBAA).`);\n            }\n\n            normalized[key] = trimmed as ColorHEX;\n        }\n\n        return normalized as MapStyleShape;\n    }\n}\n","/**\n * @module MapCamera\n * Map camera that reports its own changes.\n *\n * This module defines `MapCamera`, the `Camera` an `AutkMap` navigates with.\n * Every call that moves, turns, resets or resizes it runs a change callback,\n * which on-demand rendering uses to schedule the next frame. Rebuilding the\n * matrices with `update()` changes nothing, so it does not report.\n */\n\nimport { Camera } from '@urban-toolkit/autk-core';\n\n/**\n * Camera that runs a callback after each change to its view or viewport.\n *\n * Mouse, touch, keyboard and resize handlers, `CameraMotion` animations and\n * application code all change the map camera through these methods, so one\n * callback observes every camera change.\n */\nexport class MapCamera extends Camera {\n    /** Callback run after each change. Unset while the base constructor resets the camera. */\n    private _onChange?: () => void;\n\n    /**\n     * Creates a camera at the default map view.\n     *\n     * @param onChange Callback run after each change to the camera's view or viewport.\n     * @throws Never throws.\n     */\n    constructor(onChange: () => void) {\n        super();\n        this._onChange = onChange;\n    }\n\n    /** Resets the camera, then reports the change. */\n    override resetCamera(wUp: number[], wLookAt: number[], wEye: number[]): void {\n        super.resetCamera(wUp, wLookAt, wEye);\n        this._onChange?.();\n    }\n\n    /** Resizes the viewport, then reports the change. */\n    override resize(width: number, height: number): void {\n        super.resize(width, height);\n        this._onChange?.();\n    }\n\n    /** Zooms at the cursor, then reports the change. */\n    override zoom(delta: number, x: number, y: number): void {\n        super.zoom(delta, x, y);\n        this._onChange?.();\n    }\n\n    /** Pans, then reports the change. */\n    override translate(dx: number, dy: number): void {\n        super.translate(dx, dy);\n        this._onChange?.();\n    }\n\n    /** Rotates around the world Z axis, then reports the change. */\n    override yaw(delta: number): void {\n        super.yaw(delta);\n        this._onChange?.();\n    }\n\n    /** Tilts, then reports the change. */\n    override pitch(delta: number): void {\n        super.pitch(delta);\n        this._onChange?.();\n    }\n\n    /** Switches to an orthographic view, then reports the change. */\n    override setOrthographicBounds(left: number, right: number, bottom: number, top: number): void {\n        super.setOrthographicBounds(left, right, bottom, top);\n        this._onChange?.();\n    }\n}\n","/**\n * @module map-flat\n * Flat map render-path orchestration.\n *\n * This module contains the frame logic used when terrain mode is disabled. It\n * keeps the normal layer render path separate from `AutkMap` while reusing the\n * shared renderer, camera, layer manager, and picking controller.\n */\n\nimport { Camera } from '@urban-toolkit/autk-core';\n\nimport { LayerManager } from './layer-manager';\nimport { Triangles3DLayer } from './layer-triangles3D';\nimport { MapPickingController } from './map-picking';\nimport { PipelineBuildingSSAO } from './pipeline-triangle-ssao';\nimport { Renderer } from './renderer';\n\n/**\n * Coordinates one non-terrain map frame.\n *\n * The path renders visible layers, composites shared building SSAO output, and\n * resolves one pending picking request when present.\n */\nexport class FlatMapRenderPath {\n    /**\n     * Creates a flat render path using shared map services.\n     *\n     * @param renderer WebGPU renderer that owns frame targets and command encoders.\n     * @param camera Active map camera used by all layer render passes.\n     * @param layerManager Ordered source of map layers to draw.\n     * @param picking Shared controller for picking readback and event emission.\n     * @throws Never throws.\n     * @example\n     * const path = new FlatMapRenderPath(renderer, camera, layerManager, picking);\n     * path.renderFrame();\n     */\n    constructor(\n        /** WebGPU renderer used to open and submit frame passes. */\n        private readonly renderer: Renderer,\n        /** Active camera used for flat layer preparation and rendering. */\n        private readonly camera: Camera,\n        /** Ordered collection of layers participating in the frame. */\n        private readonly layerManager: LayerManager,\n        /** Shared picking helper used before and after render submission. */\n        private readonly picking: MapPickingController,\n    ) {}\n\n    /**\n     * Resets the main camera to the default flat map view.\n     *\n     * @returns Nothing. The camera state and viewport matrices are updated.\n     * @throws Never throws.\n     * @example\n     * flatPath.resetCamera();\n     */\n    resetCamera(): void {\n        this.camera.resetCamera([0, 1, 0], [0, 0, 0], [0, 0, 10000]);\n        this.camera.resize(this.renderer.pixelWidth, this.renderer.pixelHeight);\n    }\n\n    /**\n     * Renders one flat map frame.\n     *\n     * The method prepares visible layers, renders 3D building geometry into the\n     * shared SSAO buffers, renders non-3D layers to the main target, and then\n     * optionally performs one picking pass.\n     *\n     * @returns Nothing. GPU commands are submitted through the renderer.\n     * @throws Propagates renderer or layer errors to the caller's frame guard.\n     * @example\n     * flatPath.renderFrame();\n     */\n    renderFrame(): void {\n        const pendingPick = this.picking.consumePendingPick();\n\n        this.renderer.start();\n        const visible3DLayers = this.layerManager.layers.filter(\n            (layer): layer is Triangles3DLayer => !layer.layerRenderInfo.isSkip && layer instanceof Triangles3DLayer\n        );\n        this.layerManager.layers.forEach((layer) => {\n            if (!layer.layerRenderInfo.isSkip) {\n                layer.prepareRender(this.camera);\n            }\n        });\n        if (visible3DLayers.length > 0) {\n            const geometryPassEncoder = PipelineBuildingSSAO.beginSharedGeometryPass(this.renderer);\n            visible3DLayers.forEach((layer) => {\n                layer.renderSceneGeometry(this.camera, geometryPassEncoder);\n            });\n            geometryPassEncoder.end();\n        }\n        const mainPassEncoder = this.renderer.beginMainRenderPass();\n        this.layerManager.layers.forEach((layer) => {\n            if (!layer.layerRenderInfo.isSkip && !(layer instanceof Triangles3DLayer)) {\n                layer.renderPass(this.camera, mainPassEncoder);\n            }\n        });\n        if (visible3DLayers.length > 0) {\n            PipelineBuildingSSAO.compositeSharedPass(this.renderer, mainPassEncoder);\n        }\n        mainPassEncoder.end();\n\n        let pickReadbackSlot: number | null = null;\n        if (pendingPick) {\n            this.renderer.startPickingRenderPass();\n            pendingPick.layer.renderPickingPass(this.camera);\n            pickReadbackSlot = this.picking.enqueuePickingReadback(pendingPick);\n        }\n\n        this.renderer.finish();\n        this.picking.resolvePickingReadback(pendingPick, pickReadbackSlot);\n    }\n}\n","/**\n * @module map-picking\n * Shared picking coordination for map render paths.\n *\n * This module centralizes picking state consumption, GPU readback scheduling,\n * and map-event emission so flat and terrain render paths resolve selections in\n * the same way.\n */\n\nimport { EventEmitter } from '@urban-toolkit/autk-core';\n\nimport { Layer } from './layer';\nimport { LayerManager } from './layer-manager';\nimport { SpriteLayer } from './layer-sprite';\nimport { VectorLayer } from './layer-vector';\nimport { Renderer } from './renderer';\nimport { MapEvent } from './types-events';\nimport type { MapEventRecord } from './types-events';\n\n/** Layer families that can toggle highlighted feature ids after picking. */\ntype PickableLayer = VectorLayer | SpriteLayer;\n\n/**\n * Pending picking request captured from the active layer.\n *\n * Coordinates are stored in canvas pixel space and are consumed once per frame.\n */\nexport type PendingPick = {\n    /** Original active layer that requested picking. */\n    layer: Layer;\n    /** Layer instance that supports highlight toggling. */\n    pickableLayer: PickableLayer;\n    /** X coordinate to read from the picking texture. */\n    x: number;\n    /** Y coordinate to read from the picking texture. */\n    y: number;\n};\n\n/**\n * Coordinates picking readback and selection event emission.\n *\n * Render paths own the actual picking draw pass, while this controller owns the\n * common state transition from requested pick to emitted selection.\n */\nexport class MapPickingController {\n    /**\n     * Creates a picking controller bound to a renderer and event bus.\n     *\n     * @param renderer Renderer that owns picking textures and readback buffers.\n     * @param layerManager Ordered layer source used to find the active picking layer.\n     * @param mapEvents Event bus used to emit selection updates.\n     * @throws Never throws.\n     * @example\n     * const picking = new MapPickingController(renderer, layerManager, events);\n     */\n    constructor(\n        /** Renderer used to reserve and read picking buffers. */\n        private readonly renderer: Renderer,\n        /** Layer manager used to locate the currently pick-enabled layer. */\n        private readonly layerManager: LayerManager,\n        /** Event emitter notified when picking resolves a selection. */\n        private readonly mapEvents: EventEmitter<MapEventRecord>,\n    ) {}\n\n    /**\n     * Consumes one pending picking request from the active pick-enabled layer.\n     *\n     * Unsupported layer types have their highlight state cleared and do not\n     * produce a pending pick.\n     *\n     * @returns Pending pick data, or `null` when there is no valid request.\n     * @throws Never throws.\n     * @example\n     * const pending = picking.consumePendingPick();\n     * if (pending) renderPickingPass(pending);\n     */\n    consumePendingPick(): PendingPick | null {\n        const activePickingLayer = this.layerManager.layers.find((layer) => layer.layerRenderInfo.isPick) ?? null;\n        if (!activePickingLayer || activePickingLayer.layerRenderInfo.isSkip || !activePickingLayer.layerRenderInfo.pickedComps) {\n            return null;\n        }\n\n        const [x, y] = activePickingLayer.layerRenderInfo.pickedComps;\n        activePickingLayer.layerRenderInfo.pickedComps = undefined;\n\n        if (!(activePickingLayer instanceof VectorLayer) && !(activePickingLayer instanceof SpriteLayer)) {\n            activePickingLayer.clearHighlightedIds();\n            return null;\n        }\n\n        return { layer: activePickingLayer, pickableLayer: activePickingLayer, x, y };\n    }\n\n    /**\n     * Schedules readback of the selected pixel for a rendered picking pass.\n     *\n     * @param pendingPick Pending pick whose coordinates should be read.\n     * @returns Reserved readback slot, or `null` when all slots are busy.\n     * @throws Never throws.\n     * @example\n     * const slot = picking.enqueuePickingReadback(pendingPick);\n     */\n    enqueuePickingReadback(pendingPick: PendingPick): number | null {\n        const pickReadbackSlot = this.renderer.reservePickingReadbackSlot(1);\n        if (pickReadbackSlot === null) {\n            console.warn('Picking readback buffers are still busy; skipping this picking frame.');\n            return null;\n        }\n\n        this.renderer.enqueuePickingReadback(pickReadbackSlot, 0, pendingPick.x, pendingPick.y);\n        return pickReadbackSlot;\n    }\n\n    /**\n     * Resolves a completed picking readback and emits the selection event.\n     *\n     * The selected object id toggles highlight state on pickable layers. A\n     * negative or missing id clears the active layer selection.\n     *\n     * @param pendingPick Pending pick that produced the readback request.\n     * @param pickReadbackSlot Slot returned by `enqueuePickingReadback`.\n     * @returns Nothing. Selection updates are emitted asynchronously.\n     * @throws Never throws synchronously. Readback promise failures are owned by the renderer.\n     * @example\n     * picking.resolvePickingReadback(pendingPick, slot);\n     */\n    resolvePickingReadback(pendingPick: PendingPick | null, pickReadbackSlot: number | null): void {\n        if (pickReadbackSlot === null || !pendingPick) {\n            return;\n        }\n\n        this.renderer.readPickingResults(pickReadbackSlot, 1).then((ids) => {\n            const id = ids[0] ?? -1;\n            const { layer, pickableLayer } = pendingPick;\n\n            if (id >= 0) {\n                pickableLayer.toggleHighlightedIds([id]);\n                this.mapEvents.emit(MapEvent.PICKING, { selection: pickableLayer.highlightedIds, layerId: layer.layerInfo.id });\n            } else {\n                layer.clearHighlightedIds();\n                this.mapEvents.emit(MapEvent.PICKING, { selection: [], layerId: layer.layerInfo.id });\n            }\n        });\n    }\n}\n","export default \"struct CameraUniform {\\n  viewProjection: mat4x4<f32>,\\n  cameraPosition: vec4<f32>,\\n  lightDirection: vec4<f32>,\\n  settings: vec4<f32>,\\n  heightOriginCell: vec4<f32>,\\n  heightDims: vec4<f32>,\\n  overlayBounds: vec4<f32>,\\n  overlayUvRect: vec4<f32>,\\n  waterColor: vec4<f32>,\\n};\\n\\nstruct VertexOutput {\\n  @builtin(position) clipPosition: vec4<f32>,\\n  @location(0) worldPosition: vec3<f32>,\\n  @location(1) normal: vec3<f32>,\\n  @location(2) level: f32,\\n};\\n\\n@group(0) @binding(0) var<uniform> camera: CameraUniform;\\n@group(0) @binding(2) var overlaySampler: sampler;\\n@group(0) @binding(3) var overlayTexture: texture_2d<f32>;\\n\\nfn insideUnit(uv: vec2<f32>) -> bool {\\n  return uv.x >= 0.0 && uv.y >= 0.0 && uv.x <= 1.0 && uv.y <= 1.0;\\n}\\n\\nfn overlayUv(xy: vec2<f32>) -> vec2<f32> {\\n  let uv = (xy - camera.overlayBounds.xy) / camera.overlayBounds.zw;\\n  return camera.overlayUvRect.xy + vec2<f32>(uv.x, 1.0 - uv.y) * camera.overlayUvRect.zw;\\n}\\n\\nfn inOverlayBounds(xy: vec2<f32>) -> bool {\\n  let uv = (xy - camera.overlayBounds.xy) / camera.overlayBounds.zw;\\n  return insideUnit(uv);\\n}\\n\\nfn lodDebugColor(level: f32) -> vec3<f32> {\\n  let lod = i32(round(level));\\n  if (lod == 0) { return vec3<f32>(1.00, 0.10, 0.10); }\\n  if (lod == 1) { return vec3<f32>(1.00, 0.55, 0.00); }\\n  if (lod == 2) { return vec3<f32>(1.00, 0.95, 0.00); }\\n  if (lod == 3) { return vec3<f32>(0.20, 0.90, 0.20); }\\n  if (lod == 4) { return vec3<f32>(0.00, 0.85, 1.00); }\\n  if (lod == 5) { return vec3<f32>(0.15, 0.35, 1.00); }\\n  if (lod == 6) { return vec3<f32>(0.65, 0.25, 1.00); }\\n  return vec3<f32>(1.00, 0.20, 0.85);\\n}\\n\\n@fragment\\nfn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\\n  let overlay = textureSample(overlayTexture, overlaySampler, overlayUv(input.worldPosition.xy));\\n  if (!inOverlayBounds(input.worldPosition.xy) || overlay.a <= 0.001) {\\n    discard;\\n  }\\n\\n  let n = normalize(input.normal);\\n  let l = normalize(vec3<f32>(0.35, -0.45, 0.82));\\n  let diffuse = max(dot(n, l), 0.0);\\n  let shade = clamp(0.74 + 0.28 * diffuse, 0.70, 1.02);\\n  let unpremultipliedOverlay = overlay.rgb / max(overlay.a, 0.0001);\\n  let isWater = distance(unpremultipliedOverlay, camera.waterColor.rgb) <= camera.waterColor.a;\\n  let finalShade = select(shade, 1.0, isWater);\\n\\n  return vec4<f32>(overlay.rgb * finalShade, overlay.a);\\n}\\n\\n@fragment\\nfn meshFragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\\n  return vec4<f32>(lodDebugColor(input.level), 1.0);\\n}\\n\\n@fragment\\nfn boundsFragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\\n  _ = input;\\n  return vec4<f32>(1.0, 1.0, 0.0, 1.0);\\n}\\n\\n@fragment\\nfn visibleBoundsFragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\\n  return vec4<f32>(input.worldPosition.x, input.worldPosition.y, input.worldPosition.x, input.worldPosition.y);\\n}\";","export default \"struct CameraUniform {\\n  viewProjection: mat4x4<f32>,\\n  cameraPosition: vec4<f32>,\\n  lightDirection: vec4<f32>,\\n  settings: vec4<f32>,\\n  heightOriginCell: vec4<f32>,\\n  heightDims: vec4<f32>,\\n  overlayBounds: vec4<f32>,\\n  overlayUvRect: vec4<f32>,\\n  waterColor: vec4<f32>,\\n};\\n\\nstruct VertexOutput {\\n  @builtin(position) clipPosition: vec4<f32>,\\n  @location(0) worldPosition: vec3<f32>,\\n  @location(1) normal: vec3<f32>,\\n  @location(2) level: f32,\\n};\\n\\n@group(0) @binding(0) var<uniform> camera: CameraUniform;\\n@group(0) @binding(3) var overlayTexture: texture_2d<f32>;\\n\\nfn insideUnit(uv: vec2<f32>) -> bool {\\n  return uv.x >= 0.0 && uv.y >= 0.0 && uv.x <= 1.0 && uv.y <= 1.0;\\n}\\n\\nfn overlayUv(xy: vec2<f32>) -> vec2<f32> {\\n  let uv = (xy - camera.overlayBounds.xy) / camera.overlayBounds.zw;\\n  return camera.overlayUvRect.xy + vec2<f32>(uv.x, 1.0 - uv.y) * camera.overlayUvRect.zw;\\n}\\n\\nfn inOverlayBounds(xy: vec2<f32>) -> bool {\\n  let uv = (xy - camera.overlayBounds.xy) / camera.overlayBounds.zw;\\n  return insideUnit(uv);\\n}\\n\\n@fragment\\nfn pickingFragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {\\n  if (!inOverlayBounds(input.worldPosition.xy)) {\\n    return vec4<f32>(0.0, 0.0, 0.0, 1.0);\\n  }\\n\\n  let dims = vec2<i32>(textureDimensions(overlayTexture));\\n  let uv = overlayUv(input.worldPosition.xy);\\n  let coords = clamp(vec2<i32>(floor(uv * vec2<f32>(dims))), vec2<i32>(0), dims - vec2<i32>(1));\\n  let color = textureLoad(overlayTexture, coords, 0);\\n  return vec4<f32>(color.rgb, 1.0);\\n}\";","export default \"struct CameraUniform {\\n  viewProjection: mat4x4<f32>,\\n  cameraPosition: vec4<f32>,\\n  lightDirection: vec4<f32>,\\n  settings: vec4<f32>,\\n  heightOriginCell: vec4<f32>,\\n  heightDims: vec4<f32>,\\n  overlayBounds: vec4<f32>,\\n  overlayUvRect: vec4<f32>,\\n  waterColor: vec4<f32>,\\n};\\n\\nstruct VertexOutput {\\n  @builtin(position) clipPosition: vec4<f32>,\\n  @location(0) worldPosition: vec3<f32>,\\n  @location(1) normal: vec3<f32>,\\n  @location(2) level: f32,\\n};\\n\\n@group(0) @binding(0) var<uniform> camera: CameraUniform;\\n@group(0) @binding(1) var heightFieldTexture: texture_2d<f32>;\\n\\nfn terrainHeight(xy: vec2<f32>) -> f32 {\\n  let origin = camera.heightOriginCell.xy;\\n  let cellSize = camera.heightOriginCell.zw;\\n  let dims = vec2<i32>(i32(camera.heightDims.x), i32(camera.heightDims.y));\\n  let texel = clamp((xy - origin) / cellSize, vec2<f32>(0.0), vec2<f32>(f32(dims.x - 2), f32(dims.y - 2)));\\n  let base = vec2<i32>(floor(texel));\\n  let blend = fract(texel);\\n  let h00 = textureLoad(heightFieldTexture, base, 0).r;\\n  let h10 = textureLoad(heightFieldTexture, base + vec2<i32>(1, 0), 0).r;\\n  let h01 = textureLoad(heightFieldTexture, base + vec2<i32>(0, 1), 0).r;\\n  let h11 = textureLoad(heightFieldTexture, base + vec2<i32>(1, 1), 0).r;\\n\\n  return mix(mix(h00, h10, blend.x), mix(h01, h11, blend.x), blend.y);\\n}\\n\\nfn terrainNormal(xy: vec2<f32>, sampleDistance: f32) -> vec3<f32> {\\n  let d = max(sampleDistance, 1.0);\\n  let hL = terrainHeight(xy - vec2<f32>(d, 0.0));\\n  let hR = terrainHeight(xy + vec2<f32>(d, 0.0));\\n  let hD = terrainHeight(xy - vec2<f32>(0.0, d));\\n  let hU = terrainHeight(xy + vec2<f32>(0.0, d));\\n  return normalize(vec3<f32>(hL - hR, hD - hU, 2.0 * d));\\n}\\n\\n@vertex\\nfn vertexMain(\\n  @location(0) localPosition: vec2<f32>,\\n  @location(1) levelData: vec4<f32>,\\n  @location(2) unused: f32,\\n  @location(3) seamData: vec4<f32>,\\n) -> VertexOutput {\\n  _ = unused;\\n  _ = seamData;\\n  let blockOrigin = levelData.xy;\\n  let blockSize = levelData.z;\\n  let level = levelData.w;\\n  let scale = blockSize / camera.settings.w;\\n  let worldXY = blockOrigin + localPosition * blockSize;\\n  let height = terrainHeight(worldXY);\\n  let worldPosition = vec3<f32>(worldXY.x, worldXY.y, height);\\n\\n  var output: VertexOutput;\\n  output.clipPosition = camera.viewProjection * vec4<f32>(worldPosition, 1.0);\\n  output.worldPosition = worldPosition;\\n  output.normal = terrainNormal(worldXY, scale);\\n  output.level = level;\\n  return output;\\n}\\n\\n@vertex\\nfn meshVertexMain(\\n  @location(0) localPosition: vec2<f32>,\\n  @location(1) levelData: vec4<f32>,\\n  @location(2) unused: f32,\\n  @location(3) seamData: vec4<f32>,\\n) -> VertexOutput {\\n  _ = unused;\\n  _ = seamData;\\n  let blockOrigin = levelData.xy;\\n  let blockSize = levelData.z;\\n  let level = levelData.w;\\n  let scale = blockSize / camera.settings.w;\\n  let worldXY = blockOrigin + localPosition * blockSize;\\n  let height = terrainHeight(worldXY);\\n  let normal = terrainNormal(worldXY, scale);\\n  let worldPosition = vec3<f32>(worldXY.x, worldXY.y, height) + normal * max(0.6, scale * 0.08);\\n\\n  var output: VertexOutput;\\n  output.clipPosition = camera.viewProjection * vec4<f32>(worldPosition, 1.0);\\n  output.worldPosition = worldPosition;\\n  output.normal = normal;\\n  output.level = level;\\n  return output;\\n}\\n\\n@vertex\\nfn boundsVertexMain(@location(0) position: vec3<f32>) -> VertexOutput {\\n  var output: VertexOutput;\\n  output.clipPosition = camera.viewProjection * vec4<f32>(position, 1.0);\\n  output.worldPosition = position;\\n  output.normal = vec3<f32>(0.0, 0.0, 1.0);\\n  output.level = 0.0;\\n  return output;\\n}\\n\\n@vertex\\nfn visibleBoundsVertexMain(\\n  @location(0) localPosition: vec2<f32>,\\n  @location(1) levelData: vec4<f32>,\\n  @location(2) unused: f32,\\n  @location(3) seamData: vec4<f32>,\\n) -> VertexOutput {\\n  _ = unused;\\n  _ = seamData;\\n  let blockOrigin = levelData.xy;\\n  let blockSize = levelData.z;\\n  let level = levelData.w;\\n  let scale = blockSize / camera.settings.w;\\n  let worldXY = blockOrigin + localPosition * blockSize;\\n  let height = terrainHeight(worldXY);\\n  let worldPosition = vec3<f32>(worldXY.x, worldXY.y, height);\\n\\n  var output: VertexOutput;\\n  output.clipPosition = camera.viewProjection * vec4<f32>(worldPosition, 1.0);\\n  output.worldPosition = worldPosition;\\n  output.normal = terrainNormal(worldXY, scale);\\n  output.level = level;\\n  return output;\\n}\";","export default \"struct Params {\\n  total: u32,\\n  width: u32,\\n  height: u32,\\n  _pad: u32,\\n};\\n\\nstruct BoundsBuffer {\\n  values: array<vec4<f32>>,\\n};\\n\\n@group(0) @binding(0) var inputTexture: texture_2d<f32>;\\n@group(0) @binding(1) var<storage, read_write> outputBuffer: BoundsBuffer;\\n@group(0) @binding(2) var<uniform> params: Params;\\n\\n@group(1) @binding(0) var<storage, read> inputBuffer: BoundsBuffer;\\n@group(1) @binding(1) var<storage, read_write> nextOutputBuffer: BoundsBuffer;\\n@group(1) @binding(2) var<uniform> bufferParams: Params;\\n\\nvar<workgroup> partial: array<vec4<f32>, 256>;\\n\\nfn emptyBounds() -> vec4<f32> {\\n  return vec4<f32>(1.0e20, 1.0e20, -1.0e20, -1.0e20);\\n}\\n\\nfn mergeBounds(a: vec4<f32>, b: vec4<f32>) -> vec4<f32> {\\n  return vec4<f32>(min(a.x, b.x), min(a.y, b.y), max(a.z, b.z), max(a.w, b.w));\\n}\\n\\n@compute @workgroup_size(256)\\nfn reduceTexture(\\n  @builtin(local_invocation_id) localId: vec3<u32>,\\n  @builtin(workgroup_id) workgroupId: vec3<u32>,\\n) {\\n  let localIndex = localId.x;\\n  let globalIndex = workgroupId.x * 256u + localIndex;\\n  var value = emptyBounds();\\n\\n  if (globalIndex < params.total) {\\n    let x = i32(globalIndex % params.width);\\n    let y = i32(globalIndex / params.width);\\n    value = textureLoad(inputTexture, vec2<i32>(x, y), 0);\\n  }\\n\\n  partial[localIndex] = value;\\n  workgroupBarrier();\\n\\n  var stride = 128u;\\n  loop {\\n    if (stride == 0u) {\\n      break;\\n    }\\n    if (localIndex < stride) {\\n      partial[localIndex] = mergeBounds(partial[localIndex], partial[localIndex + stride]);\\n    }\\n    workgroupBarrier();\\n    stride = stride / 2u;\\n  }\\n\\n  if (localIndex == 0u) {\\n    outputBuffer.values[workgroupId.x] = partial[0];\\n  }\\n}\\n\\n@compute @workgroup_size(256)\\nfn reduceBuffer(\\n  @builtin(local_invocation_id) localId: vec3<u32>,\\n  @builtin(workgroup_id) workgroupId: vec3<u32>,\\n) {\\n  let localIndex = localId.x;\\n  let globalIndex = workgroupId.x * 256u + localIndex;\\n  var value = emptyBounds();\\n\\n  if (globalIndex < bufferParams.total) {\\n    value = inputBuffer.values[globalIndex];\\n  }\\n\\n  partial[localIndex] = value;\\n  workgroupBarrier();\\n\\n  var stride = 128u;\\n  loop {\\n    if (stride == 0u) {\\n      break;\\n    }\\n    if (localIndex < stride) {\\n      partial[localIndex] = mergeBounds(partial[localIndex], partial[localIndex + stride]);\\n    }\\n    workgroupBarrier();\\n    stride = stride / 2u;\\n  }\\n\\n  if (localIndex == 0u) {\\n    nextOutputBuffer.values[workgroupId.x] = partial[0];\\n  }\\n}\";","/**\n * @module renderer-terrain\n * Low-level WebGPU renderer for heightfield terrain.\n *\n * This module owns terrain-specific GPU resources: patch meshes, height\n * textures, terrain render pipelines, picking pipelines, LOD selection, and the\n * visible-bounds reduction pass used by terrain overlay rendering.\n */\n\nimport type { Camera } from '@urban-toolkit/autk-core';\nimport terrainFragmentSource from './shaders/terrain.frag.wgsl';\nimport terrainPickingFragmentSource from './shaders/terrain-picking.frag.wgsl';\nimport terrainVertexSource from './shaders/terrain.vert.wgsl';\nimport terrainBoundsReduceSource from './shaders/terrain-bounds-reduce.comp.wgsl';\nimport type { Heightfield } from '@urban-toolkit/autk-core';\n\n/** Number of grid cells per terrain patch side. */\nconst PATCH_CELLS = 32;\n/** Number of patch vertices per side. */\nconst PATCH_VERTICES = PATCH_CELLS + 1;\n/** Largest quadtree LOD level allowed for terrain blocks. */\nconst MAX_LOD_LEVEL = 7;\n/** Maximum terrain block instances uploaded in one frame. */\nconst MAX_INSTANCES = 4096;\n/** Target projected terrain cell size used by LOD splitting. */\nconst TARGET_CELL_PIXELS = 30;\n/** Reference height used when estimating terrain block distances. */\nconst TERRAIN_LOD_REFERENCE_HEIGHT = 0;\n/** Offscreen texture size used to estimate visible terrain bounds. */\nconst BOUNDS_PREPASS_SIZE = 512;\n/** Workgroup size used by the visible-bounds reduction compute shader. */\nconst REDUCE_WORKGROUP_SIZE = 256;\n/** Number of pixels reduced by the first visible-bounds pass. */\nconst BOUNDS_PIXEL_COUNT = BOUNDS_PREPASS_SIZE * BOUNDS_PREPASS_SIZE;\n/** Number of intermediate values emitted by reduction pass one. */\nconst BOUNDS_PASS_1_COUNT = Math.ceil(BOUNDS_PIXEL_COUNT / REDUCE_WORKGROUP_SIZE);\n/** Number of intermediate values emitted by reduction pass two. */\nconst BOUNDS_PASS_2_COUNT = Math.ceil(BOUNDS_PASS_1_COUNT / REDUCE_WORKGROUP_SIZE);\n/** Number of final vector groups emitted by reduction pass three. */\nconst BOUNDS_PASS_3_COUNT = Math.ceil(BOUNDS_PASS_2_COUNT / REDUCE_WORKGROUP_SIZE);\n\n/** Frustum plane stored as `[a, b, c, d]` for `ax + by + cz + d >= 0`. */\ntype Plane = [number, number, number, number];\n\n/** GPU buffers and counts for one reusable terrain patch mesh. */\ninterface TerrainMesh {\n    /** Vertex buffer containing patch-local grid coordinates. */\n    vertexBuffer: GPUBuffer;\n    /** Triangle index buffer used for filled terrain rendering. */\n    indexBuffer: GPUBuffer;\n    /** Line index buffer used by mesh debug rendering. */\n    lineIndexBuffer: GPUBuffer;\n    /** Number of triangle indices in `indexBuffer`. */\n    indexCount: number;\n    /** Number of line indices in `lineIndexBuffer`. */\n    lineIndexCount: number;\n}\n\n/** Candidate terrain quadtree block selected for rendering. */\ninterface BlockCandidate {\n    /** Local-space block minimum X coordinate. */\n    x: number;\n    /** Local-space block minimum Y coordinate. */\n    y: number;\n    /** Local-space block width and height. */\n    size: number;\n    /** Quadtree LOD level for the block. */\n    level: number;\n    /** Seam flag for the minimum-X edge. */\n    seamXMin: number;\n    /** Seam flag for the maximum-X edge. */\n    seamXMax: number;\n    /** Seam flag for the minimum-Y edge. */\n    seamYMin: number;\n    /** Seam flag for the maximum-Y edge. */\n    seamYMax: number;\n}\n\n/**\n * Runtime debug options for terrain rendering.\n */\nexport interface TerrainDebugOptions {\n    /** Draw patch wireframe lines on top of filled terrain. */\n    showMesh?: boolean;\n    /** Enable frustum culling when selecting terrain blocks. */\n    enableCulling?: boolean;\n    /** Reuse the previous LOD block selection instead of recomputing it. */\n    freezeLod?: boolean;\n}\n\n/**\n * Per-frame terrain selection statistics.\n */\nexport interface TerrainStats {\n    /** Number of terrain blocks selected for the current frame. */\n    selectedBlocks: number;\n    /** Number of triangles emitted by selected blocks. */\n    triangles: number;\n    /** Number of quadtree blocks rejected by culling. */\n    culledBlocks: number;\n}\n\n/**\n * Renders heightfield terrain and terrain-specific auxiliary passes.\n *\n * The renderer owns GPU resources derived from one heightfield and exposes pass\n * methods used by the terrain map render path.\n */\nexport class TerrainRenderer {\n    /** Selection statistics from the most recent `update` call. */\n    readonly stats: TerrainStats = { selectedBlocks: 0, triangles: 0, culledBlocks: 0 };\n    /** Local-space heightfield bounds as `[minX, minY, maxX, maxY]`. */\n    readonly bounds: [number, number, number, number];\n\n    /** Main terrain color pipeline. */\n    private readonly pipeline: GPURenderPipeline;\n    /** Depth-only pipeline used for terrain occlusion. */\n    private readonly depthPipeline: GPURenderPipeline;\n    /** Wireframe overlay pipeline used by mesh debug mode. */\n    private readonly meshPipeline: GPURenderPipeline;\n    /** Picking pipeline that maps terrain-projected overlay ids to screen pixels. */\n    private readonly pickingPipeline: GPURenderPipeline;\n    /** Debug bounds line pipeline. */\n    private readonly boundsPipeline: GPURenderPipeline;\n    /** Prepass pipeline that writes visible terrain positions for reduction. */\n    private readonly visibleBoundsPipeline: GPURenderPipeline;\n    /** Compute pipeline that reduces prepass texture pixels into partial bounds. */\n    private readonly reduceTexturePipeline: GPUComputePipeline;\n    /** Compute pipeline that reduces partial bounds buffers. */\n    private readonly reduceBufferPipeline: GPUComputePipeline;\n    /** Uniform buffer containing camera, bounds, and heightfield parameters. */\n    private readonly cameraBuffer: GPUBuffer;\n    /** Bind group used by main, depth, mesh, and bounds passes. */\n    private readonly bindGroup: GPUBindGroup;\n    /** Bind group used by terrain picking. */\n    private readonly pickingBindGroup: GPUBindGroup;\n    /** Instance buffer containing selected terrain blocks. */\n    private readonly instanceBuffer: GPUBuffer;\n    /** Dynamic vertex buffer used to draw frozen overlay bounds. */\n    private readonly boundsVertexBuffer: GPUBuffer;\n    /** GPU texture containing heightfield sample values. */\n    private readonly heightTexture: GPUTexture;\n    /** Texture view for `heightTexture`. */\n    private readonly heightTextureView: GPUTextureView;\n    /** Offscreen color texture used by visible-bounds prepass. */\n    private readonly visibleBoundsTexture: GPUTexture;\n    /** Depth texture paired with `visibleBoundsTexture`. */\n    private readonly visibleBoundsDepthTexture: GPUTexture;\n    /** Texture view for visible-bounds color output. */\n    private readonly visibleBoundsTextureView: GPUTextureView;\n    /** Texture view for visible-bounds depth output. */\n    private readonly visibleBoundsDepthTextureView: GPUTextureView;\n    /** Compute parameters for reducing visible-bounds texture pixels. */\n    private readonly reduceParamsTextureBuffer: GPUBuffer;\n    /** Compute parameters for reduction pass two. */\n    private readonly reduceParamsPass2Buffer: GPUBuffer;\n    /** Compute parameters for reduction pass three. */\n    private readonly reduceParamsPass3Buffer: GPUBuffer;\n    /** First partial reduction storage buffer. */\n    private readonly reducePartialA: GPUBuffer;\n    /** Second partial reduction storage buffer. */\n    private readonly reducePartialB: GPUBuffer;\n    /** Final reduced bounds storage buffer. */\n    private readonly reduceFinal: GPUBuffer;\n    /** CPU-readable buffer used to retrieve reduced bounds. */\n    private readonly reduceReadback: GPUBuffer;\n    /** Bind group for reducing the visible-bounds texture. */\n    private readonly reduceTextureBindGroup: GPUBindGroup;\n    /** Bind group for the second reduction pass. */\n    private readonly reducePass2BindGroup: GPUBindGroup;\n    /** Bind group for the third reduction pass. */\n    private readonly reducePass3BindGroup: GPUBindGroup;\n    /** Reusable terrain patch mesh drawn once per selected block. */\n    private readonly mesh: TerrainMesh;\n    /** CPU-side instance upload buffer for terrain block metadata. */\n    private readonly instanceData = new Float32Array(MAX_INSTANCES * 8);\n    /** Last selected terrain blocks, reused when LOD freezing is enabled. */\n    private readonly lastBlocks: BlockCandidate[] = [];\n    /** Most recent GPU-reduced visible bounds, if readback has completed. */\n    private latestReducedBounds: [number, number, number, number] | null = null;\n    /** Whether a visible-bounds readback has been requested but not consumed. */\n    private boundsReadbackPending = false;\n    /** Whether the readback buffer is currently mapped or awaiting mapping. */\n    private boundsReadbackInFlight = false;\n    /** Whether a frame drew while a readback was in flight, so the bounds of its own view were never read back. */\n    private boundsReadbackSkipped = false;\n    /** Number of block instances uploaded for the current frame. */\n    private instanceCount = 0;\n\n    /**\n     * Creates terrain GPU resources for one heightfield.\n     *\n     * @param device WebGPU device used to allocate buffers, textures, and pipelines.\n     * @param colorFormat Color format of the main canvas render target.\n     * @param depthFormat Depth format used by terrain render passes.\n     * @param sampleCount Multisample count used by color pipelines.\n     * @param _heightfield Local-space height samples used to build the terrain texture.\n     * @param overlayTextureView Texture view containing projected map overlay colors.\n     * @param overlayPickingTextureView Texture view containing projected map picking ids.\n     * @throws If WebGPU resource or pipeline creation fails.\n     * @example\n     * const terrain = new TerrainRenderer(device, format, 'depth32float', 4, heightfield, overlayView, pickingView);\n     */\n    constructor(\n        private readonly device: GPUDevice,\n        colorFormat: GPUTextureFormat,\n        depthFormat: GPUTextureFormat,\n        sampleCount: number,\n        private readonly _heightfield: Heightfield,\n        overlayTextureView: GPUTextureView,\n        overlayPickingTextureView: GPUTextureView,\n    ) {\n        this.bounds = this._heightfield.bounds;\n        this.mesh = createPatchMesh(device);\n        this.cameraBuffer = device.createBuffer({\n            label: 'Terrain camera uniform buffer',\n            size: 192,\n            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n        });\n        this.instanceBuffer = device.createBuffer({\n            label: 'Terrain block instance buffer',\n            size: this.instanceData.byteLength,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this.boundsVertexBuffer = device.createBuffer({\n            label: 'Terrain overlay bounds debug vertices',\n            size: 12 * 3 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n        });\n        this.heightTexture = device.createTexture({\n            label: 'Terrain height field texture',\n            size: [this._heightfield.width, this._heightfield.height],\n            format: 'r32float',\n            usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n        });\n        this.heightTextureView = this.heightTexture.createView();\n        device.queue.writeTexture(\n            { texture: this.heightTexture },\n            this._heightfield.data,\n            { bytesPerRow: this._heightfield.width * Float32Array.BYTES_PER_ELEMENT, rowsPerImage: this._heightfield.height },\n            { width: this._heightfield.width, height: this._heightfield.height },\n        );\n        this.visibleBoundsTexture = device.createTexture({\n            label: 'Terrain visible bounds prepass texture',\n            size: [BOUNDS_PREPASS_SIZE, BOUNDS_PREPASS_SIZE],\n            format: 'rgba16float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,\n        });\n        this.visibleBoundsDepthTexture = device.createTexture({\n            label: 'Terrain visible bounds prepass depth texture',\n            size: [BOUNDS_PREPASS_SIZE, BOUNDS_PREPASS_SIZE],\n            format: 'depth32float',\n            usage: GPUTextureUsage.RENDER_ATTACHMENT,\n        });\n        this.visibleBoundsTextureView = this.visibleBoundsTexture.createView();\n        this.visibleBoundsDepthTextureView = this.visibleBoundsDepthTexture.createView();\n        this.reduceParamsTextureBuffer = createReduceParamsBuffer(device, BOUNDS_PIXEL_COUNT, BOUNDS_PREPASS_SIZE, BOUNDS_PREPASS_SIZE);\n        this.reduceParamsPass2Buffer = createReduceParamsBuffer(device, BOUNDS_PASS_1_COUNT, 0, 0);\n        this.reduceParamsPass3Buffer = createReduceParamsBuffer(device, BOUNDS_PASS_2_COUNT, 0, 0);\n        this.reducePartialA = createStorageBuffer(device, BOUNDS_PASS_1_COUNT, 'Terrain bounds reduce partial A');\n        this.reducePartialB = createStorageBuffer(device, BOUNDS_PASS_2_COUNT, 'Terrain bounds reduce partial B');\n        this.reduceFinal = createStorageBuffer(device, BOUNDS_PASS_3_COUNT, 'Terrain bounds reduce final');\n        this.reduceReadback = device.createBuffer({\n            label: 'Terrain bounds readback buffer',\n            size: 4 * Float32Array.BYTES_PER_ELEMENT,\n            usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,\n        });\n\n        const overlaySampler = device.createSampler({\n            label: 'Terrain overlay sampler',\n            addressModeU: 'clamp-to-edge',\n            addressModeV: 'clamp-to-edge',\n            magFilter: 'linear',\n            minFilter: 'linear',\n        });\n        const bindGroupLayout = device.createBindGroupLayout({\n            label: 'Terrain bind group layout',\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },\n                { binding: 1, visibility: GPUShaderStage.VERTEX, texture: { sampleType: 'unfilterable-float' } },\n                { binding: 2, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },\n                { binding: 3, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },\n            ],\n        });\n        this.bindGroup = device.createBindGroup({\n            label: 'Terrain bind group',\n            layout: bindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this.cameraBuffer } },\n                { binding: 1, resource: this.heightTextureView },\n                { binding: 2, resource: overlaySampler },\n                { binding: 3, resource: overlayTextureView },\n            ],\n        });\n        this.pickingBindGroup = device.createBindGroup({\n            label: 'Terrain picking bind group',\n            layout: bindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this.cameraBuffer } },\n                { binding: 1, resource: this.heightTextureView },\n                { binding: 2, resource: overlaySampler },\n                { binding: 3, resource: overlayPickingTextureView },\n            ],\n        });\n\n        const vertexShaderModule = device.createShaderModule({ label: 'Terrain vertex shader', code: terrainVertexSource });\n        const fragmentShaderModule = device.createShaderModule({ label: 'Terrain fragment shader', code: terrainFragmentSource });\n        const pickingFragmentShaderModule = device.createShaderModule({ label: 'Terrain picking fragment shader', code: terrainPickingFragmentSource });\n        const reduceShaderModule = device.createShaderModule({ label: 'Terrain bounds reduce shader', code: terrainBoundsReduceSource });\n        const vertexBuffers: GPUVertexBufferLayout[] = [\n            {\n                arrayStride: 12,\n                attributes: [\n                    { shaderLocation: 0, offset: 0, format: 'float32x2' },\n                    { shaderLocation: 2, offset: 8, format: 'float32' },\n                ],\n            },\n            {\n                arrayStride: 32,\n                stepMode: 'instance',\n                attributes: [\n                    { shaderLocation: 1, offset: 0, format: 'float32x4' },\n                    { shaderLocation: 3, offset: 16, format: 'float32x4' },\n                ],\n            },\n        ];\n        const layout = device.createPipelineLayout({ label: 'Terrain pipeline layout', bindGroupLayouts: [bindGroupLayout] });\n        this.pipeline = device.createRenderPipeline({\n            label: 'LOD terrain pipeline',\n            layout,\n            vertex: { module: vertexShaderModule, entryPoint: 'vertexMain', buffers: vertexBuffers },\n            fragment: { module: fragmentShaderModule, entryPoint: 'fragmentMain', targets: [{ format: colorFormat }] },\n            primitive: { topology: 'triangle-list', cullMode: 'none' },\n            depthStencil: { depthWriteEnabled: true, depthCompare: 'greater-equal', format: depthFormat },\n            multisample: { count: sampleCount },\n        });\n        this.depthPipeline = device.createRenderPipeline({\n            label: 'LOD terrain composite depth pipeline',\n            layout,\n            vertex: { module: vertexShaderModule, entryPoint: 'vertexMain', buffers: vertexBuffers },\n            primitive: { topology: 'triangle-list', cullMode: 'none' },\n            depthStencil: { depthWriteEnabled: true, depthCompare: 'greater-equal', format: 'depth32float' },\n        });\n        this.meshPipeline = device.createRenderPipeline({\n            label: 'LOD terrain mesh overlay pipeline',\n            layout,\n            vertex: { module: vertexShaderModule, entryPoint: 'meshVertexMain', buffers: vertexBuffers },\n            fragment: { module: fragmentShaderModule, entryPoint: 'meshFragmentMain', targets: [{ format: colorFormat }] },\n            primitive: { topology: 'line-list' },\n            depthStencil: { depthWriteEnabled: false, depthCompare: 'greater-equal', format: depthFormat },\n            multisample: { count: sampleCount },\n        });\n        this.pickingPipeline = device.createRenderPipeline({\n            label: 'LOD terrain picking pipeline',\n            layout,\n            vertex: { module: vertexShaderModule, entryPoint: 'vertexMain', buffers: vertexBuffers },\n            fragment: { module: pickingFragmentShaderModule, entryPoint: 'pickingFragmentMain', targets: [{ format: 'rgba8unorm' }] },\n            primitive: { topology: 'triangle-list', cullMode: 'none' },\n            depthStencil: { depthWriteEnabled: true, depthCompare: 'greater-equal', format: 'depth32float' },\n        });\n        this.boundsPipeline = device.createRenderPipeline({\n            label: 'Terrain overlay bounds debug pipeline',\n            layout,\n            vertex: {\n                module: vertexShaderModule,\n                entryPoint: 'boundsVertexMain',\n                buffers: [\n                    {\n                        arrayStride: 3 * Float32Array.BYTES_PER_ELEMENT,\n                        attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' }],\n                    },\n                ],\n            },\n            fragment: { module: fragmentShaderModule, entryPoint: 'boundsFragmentMain', targets: [{ format: colorFormat }] },\n            primitive: { topology: 'line-list' },\n            depthStencil: { depthWriteEnabled: false, depthCompare: 'greater-equal', format: depthFormat },\n            multisample: { count: sampleCount },\n        });\n        this.visibleBoundsPipeline = device.createRenderPipeline({\n            label: 'Terrain visible bounds prepass pipeline',\n            layout,\n            vertex: { module: vertexShaderModule, entryPoint: 'visibleBoundsVertexMain', buffers: vertexBuffers },\n            fragment: { module: fragmentShaderModule, entryPoint: 'visibleBoundsFragmentMain', targets: [{ format: 'rgba16float' }] },\n            primitive: { topology: 'triangle-list', cullMode: 'none' },\n            depthStencil: { depthWriteEnabled: true, depthCompare: 'greater-equal', format: 'depth32float' },\n        });\n        const reduceTextureBindGroupLayout = device.createBindGroupLayout({\n            label: 'Terrain bounds texture reduce bind group layout',\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.COMPUTE, texture: { sampleType: 'unfilterable-float' } },\n                { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },\n                { binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },\n            ],\n        });\n        const reduceBufferBindGroupLayout = device.createBindGroupLayout({\n            label: 'Terrain bounds buffer reduce bind group layout',\n            entries: [\n                { binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'read-only-storage' } },\n                { binding: 1, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'storage' } },\n                { binding: 2, visibility: GPUShaderStage.COMPUTE, buffer: { type: 'uniform' } },\n            ],\n        });\n        const emptyBindGroupLayout = device.createBindGroupLayout({\n            label: 'Terrain bounds empty bind group layout',\n            entries: [],\n        });\n        this.reduceTexturePipeline = device.createComputePipeline({\n            label: 'Terrain bounds texture reduce pipeline',\n            layout: device.createPipelineLayout({ bindGroupLayouts: [reduceTextureBindGroupLayout] }),\n            compute: { module: reduceShaderModule, entryPoint: 'reduceTexture' },\n        });\n        this.reduceBufferPipeline = device.createComputePipeline({\n            label: 'Terrain bounds buffer reduce pipeline',\n            layout: device.createPipelineLayout({ bindGroupLayouts: [emptyBindGroupLayout, reduceBufferBindGroupLayout] }),\n            compute: { module: reduceShaderModule, entryPoint: 'reduceBuffer' },\n        });\n        this.reduceTextureBindGroup = device.createBindGroup({\n            label: 'Terrain bounds texture reduce bind group',\n            layout: reduceTextureBindGroupLayout,\n            entries: [\n                { binding: 0, resource: this.visibleBoundsTextureView },\n                { binding: 1, resource: { buffer: this.reducePartialA } },\n                { binding: 2, resource: { buffer: this.reduceParamsTextureBuffer } },\n            ],\n        });\n        this.reducePass2BindGroup = device.createBindGroup({\n            label: 'Terrain bounds reduce pass 2 bind group',\n            layout: reduceBufferBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this.reducePartialA } },\n                { binding: 1, resource: { buffer: this.reducePartialB } },\n                { binding: 2, resource: { buffer: this.reduceParamsPass2Buffer } },\n            ],\n        });\n        this.reducePass3BindGroup = device.createBindGroup({\n            label: 'Terrain bounds reduce pass 3 bind group',\n            layout: reduceBufferBindGroupLayout,\n            entries: [\n                { binding: 0, resource: { buffer: this.reducePartialB } },\n                { binding: 1, resource: { buffer: this.reduceFinal } },\n                { binding: 2, resource: { buffer: this.reduceParamsPass3Buffer } },\n            ],\n        });\n    }\n\n    /**\n     * Returns the heightfield used by this terrain renderer.\n     *\n     * @returns Source heightfield passed to the constructor.\n     * @throws Never throws.\n     * @example\n     * const heightfield = terrain.heightfield;\n     */\n    get heightfield(): Heightfield {\n        return this._heightfield;\n    }\n\n    /**\n     * Returns the GPU texture view containing height samples.\n     *\n     * @returns Texture view suitable for terrain-aware building pipelines.\n     * @throws Never throws.\n     * @example\n     * layer.setTerrainHeightSource(terrain.heightfield, terrain.terrainHeightTextureView);\n     */\n    get terrainHeightTextureView(): GPUTextureView {\n        return this.heightTextureView;\n    }\n\n    /**\n     * Returns the latest GPU-reduced visible bounds, if available.\n     *\n     * @returns Bounds as `[minX, minY, maxX, maxY]`, or `null` before readback completes.\n     * @throws Never throws.\n     * @example\n     * const bounds = terrain.visibleBounds;\n     */\n    get visibleBounds(): [number, number, number, number] | null {\n        return this.latestReducedBounds;\n    }\n\n    /**\n     * Updates camera uniforms and terrain block instances for the next passes.\n     *\n     * @param camera Current perspective camera.\n     * @param overlayBounds World bounds covered by the overlay texture.\n     * @param overlayUvRect UV rectangle inside the overlay texture.\n     * @param waterColor Normalized RGB water color used by terrain shading.\n     * @param debug Runtime debug flags controlling LOD, culling, and mesh display.\n     * @returns Nothing. GPU buffers are updated through the device queue.\n     * @throws Never throws.\n     * @example\n     * terrain.update(camera, bounds, [0, 0, 1, 1], [0.1, 0.2, 0.3], { enableCulling: true });\n     */\n    update(\n        camera: Camera,\n        overlayBounds: readonly [number, number, number, number],\n        overlayUvRect: readonly [number, number, number, number],\n        waterColor: readonly [number, number, number],\n        options: TerrainDebugOptions = {},\n    ): void {\n        const uniform = new Float32Array(48);\n        uniform.set(camera.getViewProjectionMatrix(), 0);\n        uniform.set([...camera.getEye(), 1], 16);\n        uniform.set([0.42, -0.46, -0.78, 0], 20);\n        uniform.set([performance.now() / 1000, MAX_LOD_LEVEL + 1, Math.min(this._heightfield.cellSizeX, this._heightfield.cellSizeY), PATCH_CELLS], 24);\n        uniform.set([this._heightfield.originX, this._heightfield.originY, this._heightfield.cellSizeX, this._heightfield.cellSizeY], 28);\n        uniform.set([this._heightfield.width, this._heightfield.height, this._heightfield.minHeight, this._heightfield.maxHeight], 32);\n        uniform.set([overlayBounds[0], overlayBounds[1], overlayBounds[2] - overlayBounds[0], overlayBounds[3] - overlayBounds[1]], 36);\n        uniform.set(overlayUvRect, 40);\n        uniform.set([waterColor[0], waterColor[1], waterColor[2], 0.08], 44);\n        this.device.queue.writeBuffer(this.cameraBuffer, 0, uniform);\n\n        if (!options.freezeLod || this.lastBlocks.length === 0) {\n            this.selectBlocks(camera, options.enableCulling !== false);\n        }\n\n        this.instanceCount = Math.min(this.lastBlocks.length, MAX_INSTANCES);\n        for (let i = 0; i < this.instanceCount; i += 1) {\n            const block = this.lastBlocks[i];\n            const offset = i * 8;\n            this.instanceData[offset] = block.x;\n            this.instanceData[offset + 1] = block.y;\n            this.instanceData[offset + 2] = block.size;\n            this.instanceData[offset + 3] = block.level;\n            this.instanceData[offset + 4] = block.seamXMin;\n            this.instanceData[offset + 5] = block.seamXMax;\n            this.instanceData[offset + 6] = block.seamYMin;\n            this.instanceData[offset + 7] = block.seamYMax;\n        }\n        this.device.queue.writeBuffer(this.instanceBuffer, 0, this.instanceData.subarray(0, this.instanceCount * 8));\n        this.stats.selectedBlocks = this.instanceCount;\n        this.stats.triangles = (this.mesh.indexCount / 3) * this.instanceCount;\n    }\n\n    /**\n     * Draws selected terrain blocks into a color render pass.\n     *\n     * @param pass Active render pass encoder targeting the main color attachment.\n     * @param showMesh Whether to draw terrain patch wireframe lines after fill.\n     * @returns Nothing. Draw commands are encoded into `pass`.\n     * @throws Never throws.\n     * @example\n     * terrain.render(mainPass, false);\n     */\n    render(pass: GPURenderPassEncoder, showMesh = false): void {\n        if (this.instanceCount === 0) {\n            return;\n        }\n\n        pass.setBindGroup(0, this.bindGroup);\n        pass.setVertexBuffer(0, this.mesh.vertexBuffer);\n        pass.setVertexBuffer(1, this.instanceBuffer);\n        pass.setPipeline(this.pipeline);\n        pass.setIndexBuffer(this.mesh.indexBuffer, 'uint32');\n        pass.drawIndexed(this.mesh.indexCount, this.instanceCount);\n\n        if (showMesh) {\n            pass.setPipeline(this.meshPipeline);\n            pass.setIndexBuffer(this.mesh.lineIndexBuffer, 'uint32');\n            pass.drawIndexed(this.mesh.lineIndexCount, this.instanceCount);\n        }\n    }\n\n    /**\n     * Draws terrain depth into an active depth-only pass.\n     *\n     * @param pass Active render pass encoder with a terrain depth attachment.\n     * @returns Nothing. Draw commands are encoded into `pass`.\n     * @throws Never throws.\n     * @example\n     * terrain.renderDepth(depthPass);\n     */\n    renderDepth(pass: GPURenderPassEncoder): void {\n        if (this.instanceCount === 0) {\n            return;\n        }\n\n        pass.setBindGroup(0, this.bindGroup);\n        pass.setVertexBuffer(0, this.mesh.vertexBuffer);\n        pass.setVertexBuffer(1, this.instanceBuffer);\n        pass.setPipeline(this.depthPipeline);\n        pass.setIndexBuffer(this.mesh.indexBuffer, 'uint32');\n        pass.drawIndexed(this.mesh.indexCount, this.instanceCount);\n    }\n\n    /**\n     * Draws terrain picking geometry into an active picking pass.\n     *\n     * @param pass Active render pass encoder targeting the picking attachment.\n     * @returns Nothing. Draw commands are encoded into `pass`.\n     * @throws Never throws.\n     * @example\n     * terrain.renderPicking(pickingPass);\n     */\n    renderPicking(pass: GPURenderPassEncoder): void {\n        if (this.instanceCount === 0) {\n            return;\n        }\n\n        pass.setBindGroup(0, this.pickingBindGroup);\n        pass.setVertexBuffer(0, this.mesh.vertexBuffer);\n        pass.setVertexBuffer(1, this.instanceBuffer);\n        pass.setPipeline(this.pickingPipeline);\n        pass.setIndexBuffer(this.mesh.indexBuffer, 'uint32');\n        pass.drawIndexed(this.mesh.indexCount, this.instanceCount);\n    }\n\n    /**\n     * Encodes the visible-bounds prepass and compute reductions.\n     *\n     * The result is copied into a readback buffer and becomes visible after\n     * `resolveVisibleBoundsReadback` completes.\n     *\n     * @param encoder Command encoder for the current terrain frame.\n     * @returns Nothing. Commands are appended to `encoder`.\n     * @throws If command encoding fails or required GPU resources are invalid.\n     * @example\n     * terrain.encodeVisibleBoundsReduction(commandEncoder);\n     */\n    encodeVisibleBoundsReduction(encoder: GPUCommandEncoder): void {\n        if (this.instanceCount === 0) {\n            return;\n        }\n\n        const renderPass = encoder.beginRenderPass({\n            label: 'Terrain visible bounds prepass',\n            colorAttachments: [\n                {\n                    view: this.visibleBoundsTextureView,\n                    clearValue: { r: 65504, g: 65504, b: -65504, a: -65504 },\n                    loadOp: 'clear',\n                    storeOp: 'store',\n                },\n            ],\n            depthStencilAttachment: {\n                view: this.visibleBoundsDepthTextureView,\n                depthClearValue: 0,\n                depthLoadOp: 'clear',\n                depthStoreOp: 'store',\n            },\n        });\n        renderPass.setBindGroup(0, this.bindGroup);\n        renderPass.setVertexBuffer(0, this.mesh.vertexBuffer);\n        renderPass.setVertexBuffer(1, this.instanceBuffer);\n        renderPass.setPipeline(this.visibleBoundsPipeline);\n        renderPass.setIndexBuffer(this.mesh.indexBuffer, 'uint32');\n        renderPass.drawIndexed(this.mesh.indexCount, this.instanceCount);\n        renderPass.end();\n\n        const computePass = encoder.beginComputePass({ label: 'Terrain visible bounds reduction' });\n        computePass.setPipeline(this.reduceTexturePipeline);\n        computePass.setBindGroup(0, this.reduceTextureBindGroup);\n        computePass.dispatchWorkgroups(BOUNDS_PASS_1_COUNT);\n        computePass.setPipeline(this.reduceBufferPipeline);\n        computePass.setBindGroup(1, this.reducePass2BindGroup);\n        computePass.dispatchWorkgroups(BOUNDS_PASS_2_COUNT);\n        computePass.setBindGroup(1, this.reducePass3BindGroup);\n        computePass.dispatchWorkgroups(BOUNDS_PASS_3_COUNT);\n        computePass.end();\n\n        if (!this.boundsReadbackPending && !this.boundsReadbackInFlight) {\n            encoder.copyBufferToBuffer(\n                this.reduceFinal,\n                0,\n                this.reduceReadback,\n                0,\n                4 * Float32Array.BYTES_PER_ELEMENT,\n            );\n            this.boundsReadbackPending = true;\n        }\n    }\n\n    /**\n     * Starts or completes asynchronous readback of reduced visible bounds.\n     *\n     * @param requestRender Optional callback run when the landed readback means the next frame draws\n     * differently: the bounds changed, or a frame drew while the readback was in flight, so the\n     * bounds of that frame's view were never read back.\n     * @returns Nothing. `visibleBounds` is updated asynchronously when mapping completes.\n     * @throws Never throws synchronously. Mapping failures are caught and logged.\n     * @example\n     * terrain.resolveVisibleBoundsReadback(() => map.requestRender());\n     */\n    resolveVisibleBoundsReadback(requestRender?: () => void): void {\n        if (this.boundsReadbackInFlight) {\n            // This frame could not queue its own copy, so the readback in flight describes an older view.\n            this.boundsReadbackSkipped = true;\n            return;\n        }\n        if (!this.boundsReadbackPending) {\n            return;\n        }\n\n        this.boundsReadbackPending = false;\n        this.boundsReadbackInFlight = true;\n        this.reduceReadback.mapAsync(GPUMapMode.READ).then(() => {\n            const values = new Float32Array(this.reduceReadback.getMappedRange().slice(0));\n            this.reduceReadback.unmap();\n            this.boundsReadbackInFlight = false;\n            const skipped = this.boundsReadbackSkipped;\n            this.boundsReadbackSkipped = false;\n\n            let changed = false;\n            const [minX, minY, maxX, maxY] = values;\n            if (\n                Number.isFinite(minX) &&\n                Number.isFinite(minY) &&\n                Number.isFinite(maxX) &&\n                Number.isFinite(maxY) &&\n                minX <= maxX &&\n                minY <= maxY\n            ) {\n                const previous = this.latestReducedBounds;\n                const bounds: [number, number, number, number] = [minX, minY, maxX, maxY];\n                this.latestReducedBounds = bounds;\n                changed = !previous || bounds.some((value, index) => value !== previous[index]);\n            }\n\n            // Every frame queues a readback, so requesting a frame after each one would redraw forever.\n            if (changed || skipped) {\n                requestRender?.();\n            }\n        }).catch((error: unknown) => {\n            this.boundsReadbackInFlight = false;\n            console.warn('Terrain visible bounds readback failed:', error);\n        });\n    }\n\n\n    /**\n     * Draws a debug rectangle for overlay bounds in the current terrain pass.\n     *\n     * @param pass Active render pass encoder targeting the main terrain pass.\n     * @param bounds Bounds to draw as a rectangle.\n     * @param cameraPosition Optional camera XY position marker to draw with the bounds.\n     * @returns Nothing. Debug line draw commands are encoded into `pass`.\n     * @throws Never throws.\n     * @example\n     * terrain.renderOverlayBounds(pass, bounds, [cameraX, cameraY]);\n     */\n    renderOverlayBounds(\n        pass: GPURenderPassEncoder,\n        bounds: readonly [number, number, number, number],\n        cameraPosition?: readonly [number, number],\n    ): void {\n        const z = this._heightfield.maxHeight + 20;\n        const [minX, minY, maxX, maxY] = bounds;\n        const values = [\n            minX, minY, z, maxX, minY, z,\n            maxX, minY, z, maxX, maxY, z,\n            maxX, maxY, z, minX, maxY, z,\n            minX, maxY, z, minX, minY, z,\n        ];\n        if (cameraPosition) {\n            const markerSize = Math.max(maxX - minX, maxY - minY) * 0.025;\n            const [x, y] = cameraPosition;\n            values.push(\n                x - markerSize, y, z, x + markerSize, y, z,\n                x, y - markerSize, z, x, y + markerSize, z,\n            );\n        }\n        const vertices = new Float32Array(values);\n\n        this.device.queue.writeBuffer(this.boundsVertexBuffer, 0, vertices);\n        pass.setBindGroup(0, this.bindGroup);\n        pass.setPipeline(this.boundsPipeline);\n        pass.setVertexBuffer(0, this.boundsVertexBuffer);\n        pass.draw(vertices.length / 3);\n    }\n\n    /**\n     * Destroys all terrain-owned GPU buffers and textures.\n     *\n     * @returns Nothing. The renderer must not be used after destruction.\n     * @throws Never throws.\n     * @example\n     * terrain.destroy();\n     */\n    destroy(): void {\n        this.heightTexture.destroy();\n        this.visibleBoundsTexture.destroy();\n        this.visibleBoundsDepthTexture.destroy();\n        this.mesh.vertexBuffer.destroy();\n        this.mesh.indexBuffer.destroy();\n        this.mesh.lineIndexBuffer.destroy();\n        this.cameraBuffer.destroy();\n        this.instanceBuffer.destroy();\n        this.boundsVertexBuffer.destroy();\n        this.reduceParamsTextureBuffer.destroy();\n        this.reduceParamsPass2Buffer.destroy();\n        this.reduceParamsPass3Buffer.destroy();\n        this.reducePartialA.destroy();\n        this.reducePartialB.destroy();\n        this.reduceFinal.destroy();\n        this.reduceReadback.destroy();\n    }\n\n    /**\n     * Selects terrain quadtree blocks for the current camera.\n     *\n     * @param camera Camera used for LOD distance and frustum tests.\n     * @param enableCulling Whether frustum culling should reject blocks.\n     * @returns Nothing. `instanceData`, `instanceCount`, and stats are updated.\n     * @throws Never throws.\n     * @example\n     * terrain['selectBlocks'](camera, true);\n     */\n    private selectBlocks(camera: Camera, enableCulling: boolean): void {\n        const viewProjection = camera.getViewProjectionMatrix();\n        const planes = extractFrustumPlanes(viewProjection);\n        const viewportHeight = Math.max(camera.getViewportHeight(), 1);\n        const projectionScale = viewportHeight / (2 * Math.tan(camera.getFovyRadians() / 2));\n        const [minX, minY, maxX, maxY] = this.bounds;\n        const terrainSize = Math.max(maxX - minX, maxY - minY);\n        const rootSize = nextPowerOfTwo(terrainSize);\n        const rootLevel = Math.min(MAX_LOD_LEVEL, Math.max(0, Math.ceil(Math.log2(rootSize / (PATCH_CELLS * Math.min(this._heightfield.cellSizeX, this._heightfield.cellSizeY))))));\n        const stack: BlockCandidate[] = [createBlock(minX, minY, rootSize, rootLevel)];\n        const blocks: BlockCandidate[] = [];\n\n        this.stats.culledBlocks = 0;\n        while (stack.length > 0 && blocks.length < MAX_INSTANCES) {\n            const block = stack.pop()!;\n            if (!rangesOverlap(block.x, block.x + block.size, minX, maxX) || !rangesOverlap(block.y, block.y + block.size, minY, maxY)) {\n                continue;\n            }\n            if (enableCulling && !blockIntersectsFrustum(block, planes, this._heightfield.minHeight, this._heightfield.maxHeight)) {\n                this.stats.culledBlocks += 1;\n                continue;\n            }\n            if (shouldSplitBlock(block, camera, projectionScale, Math.min(this._heightfield.cellSizeX, this._heightfield.cellSizeY))) {\n                const childSize = block.size * 0.5;\n                const childLevel = block.level - 1;\n                stack.push(\n                    createBlock(block.x, block.y, childSize, childLevel),\n                    createBlock(block.x + childSize, block.y, childSize, childLevel),\n                    createBlock(block.x, block.y + childSize, childSize, childLevel),\n                    createBlock(block.x + childSize, block.y + childSize, childSize, childLevel),\n                );\n            } else {\n                blocks.push(block);\n            }\n        }\n        this.lastBlocks.length = 0;\n        this.lastBlocks.push(...blocks.sort((a, b) => a.level - b.level));\n    }\n}\n\n/**\n * Creates the reusable unit patch mesh used by terrain instances.\n *\n * @param device WebGPU device used to allocate mesh buffers.\n * @returns Terrain mesh buffers and index counts.\n * @throws If GPU buffer creation fails.\n * @example\n * const mesh = createPatchMesh(device);\n */\nfunction createPatchMesh(device: GPUDevice): TerrainMesh {\n    const vertices: number[] = [];\n    for (let y = 0; y <= PATCH_CELLS; y += 1) {\n        for (let x = 0; x <= PATCH_CELLS; x += 1) {\n            vertices.push(x / PATCH_CELLS, y / PATCH_CELLS, 0);\n        }\n    }\n\n    const indices: number[] = [];\n    for (let y = 0; y < PATCH_CELLS; y += 1) {\n        for (let x = 0; x < PATCH_CELLS; x += 1) {\n            const i0 = gridIndex(x, y);\n            const i1 = gridIndex(x + 1, y);\n            const i2 = gridIndex(x, y + 1);\n            const i3 = gridIndex(x + 1, y + 1);\n            indices.push(i0, i2, i1, i1, i2, i3);\n        }\n    }\n\n    const lineIndices = createLineIndices();\n    const vertexData = new Float32Array(vertices);\n    const indexData = new Uint32Array(indices);\n    const lineIndexData = new Uint32Array(lineIndices);\n    const vertexBuffer = device.createBuffer({ label: 'Terrain patch vertices', size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n    const indexBuffer = device.createBuffer({ label: 'Terrain patch indices', size: indexData.byteLength, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST });\n    const lineIndexBuffer = device.createBuffer({ label: 'Terrain patch line indices', size: lineIndexData.byteLength, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST });\n    device.queue.writeBuffer(vertexBuffer, 0, vertexData);\n    device.queue.writeBuffer(indexBuffer, 0, indexData);\n    device.queue.writeBuffer(lineIndexBuffer, 0, lineIndexData);\n\n    return { vertexBuffer, indexBuffer, lineIndexBuffer, indexCount: indexData.length, lineIndexCount: lineIndexData.length };\n}\n\n/**\n * Builds line indices for terrain patch wireframe rendering.\n *\n * @returns Index list connecting adjacent patch grid vertices.\n * @throws Never throws.\n * @example\n * const indices = createLineIndices();\n */\nfunction createLineIndices(): number[] {\n    const indices: number[] = [];\n    for (let y = 0; y <= PATCH_CELLS; y += 1) {\n        for (let x = 0; x < PATCH_CELLS; x += 1) {\n            indices.push(gridIndex(x, y), gridIndex(x + 1, y));\n        }\n    }\n    for (let x = 0; x <= PATCH_CELLS; x += 1) {\n        for (let y = 0; y < PATCH_CELLS; y += 1) {\n            indices.push(gridIndex(x, y), gridIndex(x, y + 1));\n        }\n    }\n    return indices;\n}\n\n/**\n * Converts patch grid coordinates into a linear vertex index.\n *\n * @param x Patch-local X grid coordinate.\n * @param y Patch-local Y grid coordinate.\n * @returns Linear vertex index for the patch mesh.\n * @throws Never throws.\n * @example\n * const index = gridIndex(1, 2);\n */\nfunction gridIndex(x: number, y: number): number {\n    return y * PATCH_VERTICES + x;\n}\n\n/**\n * Creates a terrain quadtree block candidate.\n *\n * @param x Local-space minimum X coordinate.\n * @param y Local-space minimum Y coordinate.\n * @param size Local-space block size.\n * @param level Quadtree LOD level.\n * @returns Block candidate with seam flags initialized to zero.\n * @throws Never throws.\n * @example\n * const block = createBlock(0, 0, 1024, 2);\n */\nfunction createBlock(x: number, y: number, size: number, level: number): BlockCandidate {\n    return { x, y, size, level, seamXMin: 0, seamXMax: 0, seamYMin: 0, seamYMax: 0 };\n}\n\n/**\n * Decides whether a terrain block should split into children.\n *\n * @param block Candidate block being evaluated.\n * @param camera Camera used to estimate screen-space cell size.\n * @param projectionScale Scale factor from world units to projected pixels.\n * @param baseCellSize Heightfield cell size at the finest level.\n * @returns `true` when the block should use a finer LOD.\n * @throws Never throws.\n * @example\n * const split = shouldSplitBlock(block, camera, projectionScale, cellSize);\n */\nfunction shouldSplitBlock(block: BlockCandidate, camera: Camera, projectionScale: number, baseCellSize: number): boolean {\n    if (block.level === 0) {\n        return false;\n    }\n    const eye = camera.getEye();\n    const lookAt = camera.getLookAt();\n    const distance = Math.max(1, Math.min(distanceToBlock3d(eye[0], eye[1], eye[2], block), distanceToBlock3d(lookAt[0], lookAt[1], lookAt[2], block)));\n    const cellSize = baseCellSize * 2 ** block.level;\n    return (cellSize * projectionScale) / distance > TARGET_CELL_PIXELS;\n}\n\n/**\n * Computes the shortest 3D distance from a point to a block footprint.\n *\n * @param x Point X coordinate.\n * @param y Point Y coordinate.\n * @param z Point Z coordinate.\n * @param block Block footprint tested against the point.\n * @returns Euclidean distance to the block in local terrain space.\n * @throws Never throws.\n * @example\n * const distance = distanceToBlock3d(eyeX, eyeY, eyeZ, block);\n */\nfunction distanceToBlock3d(x: number, y: number, z: number, block: BlockCandidate): number {\n    const dx = Math.max(block.x - x, 0, x - (block.x + block.size));\n    const dy = Math.max(block.y - y, 0, y - (block.y + block.size));\n    return Math.hypot(dx, dy, Math.abs(z - TERRAIN_LOD_REFERENCE_HEIGHT));\n}\n\n/**\n * Tests whether a terrain block volume intersects the camera frustum.\n *\n * @param block Block footprint to test.\n * @param planes Normalized frustum planes.\n * @param minHeight Minimum terrain height used for the block volume.\n * @param maxHeight Maximum terrain height used for the block volume.\n * @returns `true` when any part of the block may be visible.\n * @throws Never throws.\n * @example\n * const visible = blockIntersectsFrustum(block, planes, minHeight, maxHeight);\n */\nfunction blockIntersectsFrustum(block: BlockCandidate, planes: Plane[], minHeight: number, maxHeight: number): boolean {\n    for (const plane of planes) {\n        const px = plane[0] >= 0 ? block.x + block.size : block.x;\n        const py = plane[1] >= 0 ? block.y + block.size : block.y;\n        const pz = plane[2] >= 0 ? maxHeight : minHeight;\n        if (plane[0] * px + plane[1] * py + plane[2] * pz + plane[3] < 0) {\n            return false;\n        }\n    }\n    return true;\n}\n\n/**\n * Extracts normalized frustum planes from a view-projection matrix.\n *\n * @param matrix Column-major view-projection matrix.\n * @returns Six normalized frustum planes.\n * @throws Never throws.\n * @example\n * const planes = extractFrustumPlanes(camera.getViewProjectionMatrix());\n */\nfunction extractFrustumPlanes(matrix: Float32Array): Plane[] {\n    return [\n        normalizePlane([matrix[3] + matrix[0], matrix[7] + matrix[4], matrix[11] + matrix[8], matrix[15] + matrix[12]]),\n        normalizePlane([matrix[3] - matrix[0], matrix[7] - matrix[4], matrix[11] - matrix[8], matrix[15] - matrix[12]]),\n        normalizePlane([matrix[3] + matrix[1], matrix[7] + matrix[5], matrix[11] + matrix[9], matrix[15] + matrix[13]]),\n        normalizePlane([matrix[3] - matrix[1], matrix[7] - matrix[5], matrix[11] - matrix[9], matrix[15] - matrix[13]]),\n        normalizePlane([matrix[2], matrix[6], matrix[10], matrix[14]]),\n        normalizePlane([matrix[3] - matrix[2], matrix[7] - matrix[6], matrix[11] - matrix[10], matrix[15] - matrix[14]]),\n    ];\n}\n\n/**\n * Normalizes a plane equation so its normal has unit length.\n *\n * @param plane Plane coefficients `[a, b, c, d]`.\n * @returns Normalized plane coefficients.\n * @throws Never throws.\n * @example\n * const plane = normalizePlane([1, 0, 0, -10]);\n */\nfunction normalizePlane(plane: Plane): Plane {\n    const length = Math.hypot(plane[0], plane[1], plane[2]) || 1;\n    return [plane[0] / length, plane[1] / length, plane[2] / length, plane[3] / length];\n}\n\n/**\n * Checks whether two inclusive numeric ranges overlap.\n *\n * @param minA Minimum value of the first range.\n * @param maxA Maximum value of the first range.\n * @param minB Minimum value of the second range.\n * @param maxB Maximum value of the second range.\n * @returns `true` when the ranges overlap.\n * @throws Never throws.\n * @example\n * rangesOverlap(0, 10, 5, 15); // true\n */\nfunction rangesOverlap(minA: number, maxA: number, minB: number, maxB: number): boolean {\n    return minA < maxB && minB < maxA;\n}\n\n/**\n * Computes the next power-of-two value greater than or equal to `value`.\n *\n * @param value Positive input value.\n * @returns Power-of-two integer greater than or equal to `value`.\n * @throws Never throws.\n * @example\n * nextPowerOfTwo(300); // 512\n */\nfunction nextPowerOfTwo(value: number): number {\n    return 2 ** Math.ceil(Math.log2(Math.max(1, value)));\n}\n\n/**\n * Creates a storage buffer sized for a number of `vec4<f32>` values.\n *\n * @param device WebGPU device used to allocate the buffer.\n * @param vec4Count Number of four-float values the buffer must hold.\n * @param label Debug label assigned to the GPU buffer.\n * @returns Storage buffer usable by compute reductions.\n * @throws If GPU buffer creation fails.\n * @example\n * const buffer = createStorageBuffer(device, 128, 'partial bounds');\n */\nfunction createStorageBuffer(device: GPUDevice, vec4Count: number, label: string): GPUBuffer {\n    return device.createBuffer({\n        label,\n        size: Math.max(1, vec4Count) * 4 * Float32Array.BYTES_PER_ELEMENT,\n        usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,\n    });\n}\n\n/**\n * Creates and initializes a uniform buffer for bounds reduction passes.\n *\n * @param device WebGPU device used to allocate and initialize the buffer.\n * @param total Number of input values consumed by the reduction pass.\n * @param width Width of the source texture for texture reduction, or `0` for buffer reduction.\n * @param height Height of the source texture for texture reduction, or `0` for buffer reduction.\n * @returns Uniform buffer containing reduction pass parameters.\n * @throws If GPU buffer creation fails.\n * @example\n * const params = createReduceParamsBuffer(device, 512 * 512, 512, 512);\n */\nfunction createReduceParamsBuffer(device: GPUDevice, total: number, width: number, height: number): GPUBuffer {\n    const data = new Uint32Array([total, width, height, 0]);\n    const buffer = device.createBuffer({\n        label: 'Terrain bounds reduce params',\n        size: data.byteLength,\n        usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n    });\n    device.queue.writeBuffer(buffer, 0, data);\n    return buffer;\n}\n","/**\n * @module map-terrain\n * Terrain-mode map render-path orchestration.\n *\n * This module coordinates the high-level terrain frame: overlay rendering,\n * terrain mesh rendering, terrain-aware building compositing, and terrain-mode\n * picking. Low-level terrain GPU resources are owned by `TerrainRenderer`.\n */\n\nimport { Camera } from '@urban-toolkit/autk-core';\n\nimport { LayerManager } from './layer-manager';\nimport { Triangles3DLayer } from './layer-triangles3D';\nimport { MapStyle } from './map-style';\nimport { MapPickingController } from './map-picking';\nimport type { PendingPick } from './map-picking';\nimport { PipelineBuildingSSAO } from './pipeline-triangle-ssao';\nimport { Renderer } from './renderer';\nimport { TerrainRenderer } from './renderer-terrain';\nimport type { TerrainDebugOptions } from './renderer-terrain';\nimport type { Heightfield } from '@urban-toolkit/autk-core';\n\n/** Maximum requested overlay texture dimension before clamping to device limits. */\nconst TERRAIN_OVERLAY_TEXTURE_SIZE = 4096;\n\n/** Pixel rectangle inside the overlay texture used for the current visible bounds. */\ntype OverlayPixelRect = { x: number; y: number; width: number; height: number };\n\n/**\n * Coordinates one terrain-mode map frame.\n *\n * The render path projects regular map layers into an offscreen overlay texture,\n * renders that overlay over terrain geometry, then composites terrain-aware 3D\n * layers and resolves picking.\n */\nexport class TerrainMapRenderPath {\n    /** Low-level terrain mesh renderer rebuilt when overlay views change. */\n    private terrainRenderer: TerrainRenderer | null = null;\n    /** Optional frozen world bounds used to draw overlay bounds debug geometry. */\n    private frozenTerrainOverlayBounds: [number, number, number, number] | null = null;\n    /** Camera XY position captured with frozen debug bounds. */\n    private frozenTerrainCameraPosition: [number, number] | null = null;\n    /** Orthographic camera used to render 2D layers into the terrain overlay. */\n    private readonly terrainOverlayCamera: Camera = new Camera();\n    /** Runtime terrain debug flags forwarded to the low-level terrain renderer. */\n    private terrainDebug: Required<TerrainDebugOptions> = {\n        showMesh: false,\n        enableCulling: true,\n        freezeLod: false,\n    };\n\n    /**\n     * Creates a terrain render path and initializes terrain GPU resources.\n     *\n     * @param renderer Shared renderer that owns frame and overlay targets.\n     * @param camera Main perspective camera used for terrain rendering.\n     * @param layerManager Ordered layer source used for overlays and buildings.\n     * @param picking Shared picking helper for readback and event emission.\n     * @param style Instance-specific style used for terrain water and overlay colors.\n     * @param heightfield Local-space heightfield sampled by terrain and buildings.\n     * @param requestRender Schedules another frame when GPU work that lands after a frame changes what the next one draws.\n     * @throws If renderer overlay texture views cannot be created by the renderer.\n     * @example\n     * const terrainPath = new TerrainMapRenderPath(renderer, camera, layers, picking, style, heightfield, () => map.requestRender());\n     */\n    constructor(\n        /** Shared renderer used to create render passes and submit commands. */\n        private readonly renderer: Renderer,\n        /** Main map camera used for terrain and 3D layer rendering. */\n        private readonly camera: Camera,\n        /** Ordered collection of layers drawn into the terrain frame. */\n        private readonly layerManager: LayerManager,\n        /** Shared picking helper used before and after terrain picking passes. */\n        private readonly picking: MapPickingController,\n        /** Instance-specific style used for terrain water and overlay colors. */\n        private readonly style: MapStyle,\n        /** Local-space height samples used to initialize the terrain renderer. */\n        private readonly heightfield: Heightfield,\n        /** Schedules another frame when a GPU readback changes what the next frame draws. */\n        private readonly requestRender: () => void,\n    ) {\n        this.fitCameraToTerrainBounds();\n        const overlaySize = this.getTerrainOverlayTextureSize();\n        this.renderer.configureOverlayTexture(overlaySize, overlaySize);\n        this.rebuildTerrainRenderer();\n    }\n\n    /**\n     * Renders one terrain-mode frame.\n     *\n     * The frame renders visible non-3D layers into an overlay texture, draws the\n     * terrain, records terrain depth, composites terrain-aware buildings, and\n     * resolves a pending picking request when present.\n     *\n     * @returns Nothing. GPU commands are submitted through the renderer.\n     * @throws Propagates renderer or layer errors to the caller's frame guard.\n     * @example\n     * terrainPath.renderFrame();\n     */\n    renderFrame(): void {\n        const terrain = this.terrainRenderer;\n        if (!terrain) {\n            return;\n        }\n\n        this.renderer.start();\n        const overlaySize = this.getTerrainOverlayTextureSize();\n        const overlayResized = this.renderer.configureOverlayTexture(overlaySize, overlaySize);\n        if (overlayResized) {\n            this.rebuildTerrainRenderer();\n        }\n        const activeTerrain = this.terrainRenderer;\n        if (!activeTerrain) {\n            return;\n        }\n        const pendingPick = this.picking.consumePendingPick();\n        const fallbackBounds = this.computeTerrainVisibleBounds(activeTerrain.bounds);\n        const waterColor = this.getTerrainWaterColor();\n        activeTerrain.update(this.camera, fallbackBounds, [0, 0, 1, 1], waterColor, this.terrainDebug);\n        const reducedBounds = activeTerrain.visibleBounds;\n        const overlayBounds = reducedBounds && this.isUsableTerrainOverlayBounds(reducedBounds, fallbackBounds, activeTerrain.bounds)\n            ? reducedBounds\n            : fallbackBounds;\n        const overlayPixelRect = this.computeTerrainOverlayPixelRect(overlayBounds);\n        const overlayUvRect: [number, number, number, number] = [\n            overlayPixelRect.x / this.renderer.overlayWidth,\n            overlayPixelRect.y / this.renderer.overlayHeight,\n            overlayPixelRect.width / this.renderer.overlayWidth,\n            overlayPixelRect.height / this.renderer.overlayHeight,\n        ];\n\n        try {\n            activeTerrain.encodeVisibleBoundsReduction(this.renderer.commandEncoder);\n        } catch (error) {\n            console.warn('Terrain visible bounds prepass failed; using fallback bounds:', error);\n        }\n        this.terrainOverlayCamera.setOrthographicBounds(\n            overlayBounds[0],\n            overlayBounds[2],\n            overlayBounds[1],\n            overlayBounds[3],\n        );\n\n        this.layerManager.layers.forEach((layer) => {\n            if (!layer.layerRenderInfo.isSkip && !(layer instanceof Triangles3DLayer)) {\n                layer.prepareRender(this.terrainOverlayCamera);\n            }\n        });\n        const overlayPass = this.renderer.beginOverlayRenderPass();\n        overlayPass.setViewport(overlayPixelRect.x, overlayPixelRect.y, overlayPixelRect.width, overlayPixelRect.height, 0, 1);\n        overlayPass.setScissorRect(overlayPixelRect.x, overlayPixelRect.y, overlayPixelRect.width, overlayPixelRect.height);\n        this.layerManager.layers.forEach((layer) => {\n            if (!layer.layerRenderInfo.isSkip && !(layer instanceof Triangles3DLayer)) {\n                layer.renderPass(this.terrainOverlayCamera, overlayPass);\n            }\n        });\n        overlayPass.end();\n\n        activeTerrain.update(this.camera, overlayBounds, overlayUvRect, waterColor, this.terrainDebug);\n        const terrainPass = this.renderer.beginMainRenderPass();\n        activeTerrain.render(terrainPass, this.terrainDebug.showMesh);\n        if (this.frozenTerrainOverlayBounds) {\n            activeTerrain.renderOverlayBounds(\n                terrainPass,\n                this.frozenTerrainOverlayBounds,\n                this.frozenTerrainCameraPosition ?? undefined,\n            );\n        }\n        terrainPass.end();\n        this.renderer.configureTerrainDepthTexture(\n            2 * this.renderer.pixelWidth,\n            2 * this.renderer.pixelHeight,\n        );\n        const terrainDepthPass = this.renderer.beginTerrainDepthRenderPass();\n        activeTerrain.renderDepth(terrainDepthPass);\n        terrainDepthPass.end();\n\n        const visible3DLayers = this.layerManager.layers.filter(\n            (layer): layer is Triangles3DLayer => !layer.layerRenderInfo.isSkip && layer instanceof Triangles3DLayer\n        );\n        if (visible3DLayers.length > 0) {\n            const heightfield = activeTerrain.heightfield;\n            const terrainHeightView = activeTerrain.terrainHeightTextureView;\n            const geometryPassEncoder = PipelineBuildingSSAO.beginSharedGeometryPass(this.renderer);\n            visible3DLayers.forEach((layer) => {\n                layer.setTerrainHeightSource(heightfield, terrainHeightView);\n                layer.renderSceneGeometry(this.camera, geometryPassEncoder);\n            });\n            geometryPassEncoder.end();\n\n            const buildingCompositePass = this.renderer.beginMainColorRenderPass('load');\n            PipelineBuildingSSAO.compositeSharedPassWithTerrainDepth(\n                this.renderer,\n                buildingCompositePass,\n                this.renderer.terrainDepthTextureView,\n            );\n            buildingCompositePass.end();\n        }\n        const pickReadbackSlot = this.renderTerrainPickingPass(pendingPick, activeTerrain, overlayPixelRect);\n        this.renderer.finish();\n        this.picking.resolvePickingReadback(pendingPick, pickReadbackSlot);\n        // The overlay of the next frame covers the bounds this readback finds, so new bounds need a frame.\n        activeTerrain.resolveVisibleBoundsReadback(this.requestRender);\n    }\n\n    /**\n     * Resets the main camera to frame the active heightfield bounds.\n     *\n     * @returns Nothing. The camera position and viewport matrices are updated.\n     * @throws Never throws.\n     * @example\n     * terrainPath.resetCamera();\n     */\n    resetCamera(): void {\n        this.fitCameraToTerrainBounds();\n    }\n\n    /**\n     * Updates terrain debug flags used on subsequent frames.\n     *\n     * @param options Partial debug settings to merge with the current state.\n     * @returns Nothing.\n     * @throws Never throws.\n     * @example\n     * terrainPath.updateDebug({ showMesh: true });\n     */\n    updateDebug(options: Partial<TerrainDebugOptions>): void {\n        this.terrainDebug = { ...this.terrainDebug, ...options };\n    }\n\n    /**\n     * Toggles frozen overlay bounds debug rendering.\n     *\n     * The first call captures the current computed visible bounds; the next call\n     * clears them.\n     *\n     * @returns Nothing.\n     * @throws Never throws.\n     * @example\n     * terrainPath.toggleOverlayBoundsDebug();\n     */\n    toggleOverlayBoundsDebug(): void {\n        if (this.frozenTerrainOverlayBounds) {\n            this.frozenTerrainOverlayBounds = null;\n            this.frozenTerrainCameraPosition = null;\n            console.log('Terrain overlay bounds debug: cleared');\n            return;\n        }\n\n        if (!this.terrainRenderer) {\n            console.warn('Terrain overlay bounds debug requires terrain mode.');\n            return;\n        }\n\n        this.frozenTerrainOverlayBounds = this.computeTerrainVisibleBounds(this.terrainRenderer.bounds);\n        const [x, y] = this.camera.getEye();\n        this.frozenTerrainCameraPosition = [x, y];\n        console.log('Terrain overlay bounds debug:', this.frozenTerrainOverlayBounds, 'camera:', this.frozenTerrainCameraPosition);\n    }\n\n    /**\n     * Releases terrain resources and clears terrain height bindings on 3D layers.\n     *\n     * @returns Nothing. Repeated calls are safe.\n     * @throws Never throws.\n     * @example\n     * terrainPath.destroy();\n     */\n    destroy(): void {\n        this.layerManager.layers.forEach((layer) => {\n            if (layer instanceof Triangles3DLayer) {\n                layer.clearTerrainHeightSource();\n            }\n        });\n        this.terrainRenderer?.destroy();\n        this.terrainRenderer = null;\n    }\n\n    /**\n     * Resolves the overlay texture size allowed by the current GPU device.\n     *\n     * @returns Clamped square texture dimension in pixels.\n     * @throws Never throws.\n     * @example\n     * const size = terrainPath['getTerrainOverlayTextureSize']();\n     */\n    private getTerrainOverlayTextureSize(): number {\n        return Math.min(TERRAIN_OVERLAY_TEXTURE_SIZE, this.renderer.device.limits.maxTextureDimension2D);\n    }\n\n    /**\n     * Recreates the low-level terrain renderer with current overlay texture views.\n     *\n     * @returns Nothing. Existing terrain GPU resources are destroyed first.\n     * @throws If terrain GPU resource creation fails.\n     * @example\n     * terrainPath['rebuildTerrainRenderer']();\n     */\n    private rebuildTerrainRenderer(): void {\n        this.terrainRenderer?.destroy();\n        this.terrainRenderer = new TerrainRenderer(\n            this.renderer.device,\n            this.renderer.canvasFormat,\n            'depth32float',\n            this.renderer.sampleCount,\n            this.heightfield,\n            this.renderer.overlayTextureView,\n            this.renderer.overlayPickingTextureView,\n        );\n    }\n\n    /**\n     * Positions the main camera so the heightfield bounds fit the viewport.\n     *\n     * @returns Nothing. The camera is reset and resized using renderer pixels.\n     * @throws Never throws.\n     * @example\n     * terrainPath['fitCameraToTerrainBounds']();\n     */\n    private fitCameraToTerrainBounds(): void {\n        const bounds = this.heightfield.bounds;\n        const width = Math.max(bounds[2] - bounds[0], 1);\n        const height = Math.max(bounds[3] - bounds[1], 1);\n        const centerX = (bounds[0] + bounds[2]) * 0.5;\n        const centerY = (bounds[1] + bounds[3]) * 0.5;\n        const aspect = Math.max(this.renderer.pixelWidth / Math.max(this.renderer.pixelHeight, 1), 1e-6);\n        const halfFovTangent = Math.tan(this.camera.getFovyRadians() * 0.5);\n        const distanceForHeight = height / (2 * halfFovTangent);\n        const distanceForWidth = width / (2 * halfFovTangent * aspect);\n        const distance = Math.max(distanceForHeight, distanceForWidth) * 1.08;\n\n        this.camera.resetCamera([0, 1, 0], [centerX, centerY, 0], [centerX, centerY, distance]);\n        this.camera.resize(this.renderer.pixelWidth, this.renderer.pixelHeight);\n    }\n\n    /**\n     * Renders the terrain-mode picking passes for one pending request.\n     *\n     * @param pendingPick Pending pick consumed at the start of the frame.\n     * @param activeTerrain Terrain renderer used for terrain depth and picking.\n     * @param overlayPixelRect Pixel rectangle occupied by the overlay in its texture.\n     * @returns Picking readback slot, or `null` when no pick is pending.\n     * @throws Propagates render-pass creation or layer rendering errors.\n     * @example\n     * const slot = terrainPath['renderTerrainPickingPass'](pendingPick, terrain, rect);\n     */\n    private renderTerrainPickingPass(\n        pendingPick: PendingPick | null,\n        activeTerrain: TerrainRenderer,\n        overlayPixelRect: OverlayPixelRect,\n    ): number | null {\n        if (!pendingPick) {\n            return null;\n        }\n\n        if (pendingPick.layer instanceof Triangles3DLayer) {\n            const terrainDepthPass = this.renderer.beginPickingDepthRenderPass();\n            activeTerrain.renderDepth(terrainDepthPass);\n            terrainDepthPass.end();\n\n            const buildingPickingPass = this.renderer.beginPickingRenderPass('load');\n            pendingPick.layer.setTerrainHeightSource(activeTerrain.heightfield, activeTerrain.terrainHeightTextureView);\n            pendingPick.layer.renderPickingPass(this.camera, buildingPickingPass);\n            buildingPickingPass.end();\n            return this.picking.enqueuePickingReadback(pendingPick);\n        }\n\n        const overlayPickingPass = this.renderer.beginOverlayPickingRenderPass();\n        overlayPickingPass.setViewport(overlayPixelRect.x, overlayPixelRect.y, overlayPixelRect.width, overlayPixelRect.height, 0, 1);\n        overlayPickingPass.setScissorRect(overlayPixelRect.x, overlayPixelRect.y, overlayPixelRect.width, overlayPixelRect.height);\n        pendingPick.layer.renderPickingPass(this.terrainOverlayCamera, overlayPickingPass);\n        overlayPickingPass.end();\n\n        const terrainPickingPass = this.renderer.beginPickingRenderPass();\n        activeTerrain.renderPicking(terrainPickingPass);\n        terrainPickingPass.end();\n        return this.picking.enqueuePickingReadback(pendingPick);\n    }\n\n    /**\n     * Reads the style water color as normalized RGB values for terrain shading.\n     *\n     * @returns Normalized water color as `[r, g, b]`.\n     * @throws Never throws.\n     * @example\n     * const color = terrainPath['getTerrainWaterColor']();\n     */\n    private getTerrainWaterColor(): [number, number, number] {\n        const color = this.style.getColor('water');\n        return [color.r / 255, color.g / 255, color.b / 255];\n    }\n\n    /**\n     * Estimates world-space XY bounds visible from the current camera.\n     *\n     * @param terrainBounds Full terrain bounds used to limit ray distance fallback.\n     * @returns Estimated visible bounds as `[minX, minY, maxX, maxY]`.\n     * @throws Never throws.\n     * @example\n     * const bounds = terrainPath['computeTerrainVisibleBounds'](terrain.bounds);\n     */\n    private computeTerrainVisibleBounds(terrainBounds: readonly [number, number, number, number]): [number, number, number, number] {\n        const points: Array<[number, number]> = [];\n        const eye = this.camera.getEye();\n        const terrainDiagonal = Math.hypot(terrainBounds[2] - terrainBounds[0], terrainBounds[3] - terrainBounds[1]);\n        const maxRayDistance = Math.min(\n            this.camera.getFar(),\n            Math.max(Math.abs(eye[2]) * 8, terrainDiagonal * 0.05, 1),\n        );\n        const corners: Array<[number, number]> = [\n            [0, 0],\n            [1, 0],\n            [1, 1],\n            [0, 1],\n        ];\n\n        for (const [x, y] of corners) {\n            const direction = this.camera.getWorldRayDirection(x, y);\n            const groundDistance = Math.abs(direction[2]) > 1e-6\n                ? -eye[2] / direction[2]\n                : Number.POSITIVE_INFINITY;\n            const distance = groundDistance > 0\n                ? Math.min(groundDistance, maxRayDistance)\n                : maxRayDistance;\n\n            points.push([eye[0] + direction[0] * distance, eye[1] + direction[1] * distance]);\n        }\n\n        if (points.length === 0) {\n            const lookAt = this.camera.getLookAt();\n            points.push([lookAt[0], lookAt[1]]);\n        }\n\n        const rawMinX = Math.min(...points.map((point) => point[0]));\n        const rawMaxX = Math.max(...points.map((point) => point[0]));\n        const rawMinY = Math.min(...points.map((point) => point[1]));\n        const rawMaxY = Math.max(...points.map((point) => point[1]));\n\n        return [\n            rawMinX,\n            rawMinY,\n            rawMaxX,\n            rawMaxY,\n        ];\n    }\n\n    /**\n     * Computes the centered overlay viewport for a world-space bounds aspect.\n     *\n     * @param bounds World-space overlay bounds that should fit inside the texture.\n     * @returns Pixel rectangle inside the overlay texture.\n     * @throws Never throws.\n     * @example\n     * const rect = terrainPath['computeTerrainOverlayPixelRect'](bounds);\n     */\n    private computeTerrainOverlayPixelRect(bounds: readonly [number, number, number, number]): OverlayPixelRect {\n        const textureWidth = Math.max(1, this.renderer.overlayWidth);\n        const textureHeight = Math.max(1, this.renderer.overlayHeight);\n        const boundsWidth = Math.max(bounds[2] - bounds[0], 1);\n        const boundsHeight = Math.max(bounds[3] - bounds[1], 1);\n        const boundsAspect = boundsWidth / boundsHeight;\n        const textureAspect = textureWidth / textureHeight;\n        let width: number;\n        let height: number;\n\n        if (boundsAspect >= textureAspect) {\n            width = textureWidth;\n            height = Math.max(1, Math.floor(textureWidth / boundsAspect));\n        } else {\n            height = textureHeight;\n            width = Math.max(1, Math.floor(textureHeight * boundsAspect));\n        }\n\n        return {\n            x: Math.floor((textureWidth - width) * 0.5),\n            y: Math.floor((textureHeight - height) * 0.5),\n            width,\n            height,\n        };\n    }\n\n    /**\n     * Checks whether GPU-reduced overlay bounds are safe to use this frame.\n     *\n     * Bounds must be finite, non-degenerate, and overlap both terrain and the\n     * camera-based fallback bounds.\n     *\n     * @param bounds Candidate reduced bounds.\n     * @param fallbackBounds Camera-derived fallback bounds.\n     * @param terrainBounds Full terrain bounds.\n     * @returns `true` when the candidate bounds can drive overlay rendering.\n     * @throws Never throws.\n     * @example\n     * const usable = terrainPath['isUsableTerrainOverlayBounds'](reduced, fallback, terrain.bounds);\n     */\n    private isUsableTerrainOverlayBounds(\n        bounds: readonly [number, number, number, number],\n        fallbackBounds: readonly [number, number, number, number],\n        terrainBounds: readonly [number, number, number, number],\n    ): boolean {\n        if (!bounds.every(Number.isFinite)) {\n            return false;\n        }\n\n        const width = bounds[2] - bounds[0];\n        const height = bounds[3] - bounds[1];\n        if (width <= 1 || height <= 1) {\n            return false;\n        }\n\n        const terrainOverlap = bounds[0] < terrainBounds[2]\n            && bounds[2] > terrainBounds[0]\n            && bounds[1] < terrainBounds[3]\n            && bounds[3] > terrainBounds[1];\n        const fallbackOverlap = bounds[0] < fallbackBounds[2]\n            && bounds[2] > fallbackBounds[0]\n            && bounds[1] < fallbackBounds[3]\n            && bounds[3] > fallbackBounds[1];\n\n        return terrainOverlap && fallbackOverlap;\n    }\n}\n","/**\n * @module AutkMap\n * A WebGPU-based map rendering engine for GeoJSON data.\n *\n * This module defines the `AutkMap` class, which serves as the main controller\n * for rendering, interaction, and layer lifecycle management. It provides\n * high-level APIs for loading GeoJSON feature collections and prebuilt meshes,\n * updating thematic mappings and color configurations, and handling user\n * interactions such as picking and highlighting.\n *\n * The `AutkMap` class integrates a WebGPU renderer, a camera system, a layer\n * manager, and event controllers for keyboard, mouse, and resize events. It\n * also exposes a public event bus for map events (e.g., picking) and a UI\n * controller for managing the map's user interface components.\n */\n\n/// <reference types=\"@webgpu/types\" />\n\n// Keep definitions independent of the map controller to avoid circular layer imports.\nimport { DEFAULT_LINE_WIDTH } from './types-layers';\n\nimport {\n    FeatureCollection,\n    Geometry,\n} from 'geojson';\n\nimport {\n    Camera,\n    ColorMapDomainStrategy,\n    ColorMapConfig,\n    ColorMap,\n    ColorMapInterpolator,\n    EventEmitter,\n    isNumericLike,\n    TriangulatorPoints,\n    PolylineBuilder,\n    TriangulatorPolygons,\n    TriangulatorPolylines,\n    TriangulatorBuildings,\n    TriangulatorRaster,\n    heightfieldFromRaster,\n    valueAtPath,\n    LayerType,\n    ResolvedDomain,\n    mapGeometryTypeToLayerType,\n} from '@urban-toolkit/autk-core';\n\nimport type { MapEventRecord } from './types-events';\n\nimport {\n    LayerData,\n    LayerInfo,\n    LayerRenderInfo,\n    LayerThematic,\n} from './types-layers';\n\nimport {\n    LoadCollectionParams,\n    LoadMeshParams,\n    MapDrawOptions,\n    UpdateColorMapParams,\n    UpdateRenderInfoParams,\n    UpdateRasterParams,\n    UpdateThematicParams,\n} from './api';\n\nimport { KeyEvents } from './events-key';\nimport { MouseEvents } from './events-mouse';\nimport { ResizeEvents } from './events-resize';\n\nimport { Renderer } from './renderer';\n\nimport { Layer } from './layer';\nimport { LayerManager } from './layer-manager';\nimport { VectorLayer } from './layer-vector';\nimport { RasterLayer } from './layer-raster';\nimport { SpriteLayer } from './layer-sprite';\nimport { AutkMapUi } from './map-ui';\nimport { MapStyle } from './map-style';\nimport { MapCamera } from './map-camera';\nimport { FlatMapRenderPath } from './map-flat';\nimport { MapPickingController } from './map-picking';\nimport { TerrainMapRenderPath } from './map-terrain';\nimport type { TerrainDebugOptions } from './renderer-terrain';\n\n/**\n * Main map controller for rendering, interaction, and layer lifecycle.\n *\n * `AutkMap` initializes the renderer, camera, layer manager, and interaction\n * controllers, and exposes high-level APIs for loading and updating layers.\n * \n * @example\n * const canvas = document.getElementById('map-canvas') as HTMLCanvasElement;\n *\n * const map = new AutkMap(canvas);\n * await map.init();\n * \n * const geojsonData = { \\/* GeoJSON data *\\/ };\n * map.loadCollection('my_data', { collection: geojsonData });\n */\nexport class AutkMap {\n    /** View and projection camera. */\n    protected _camera!: Camera;\n    /** WebGPU renderer. */\n    protected _renderer!: Renderer;\n    /** Instance-specific semantic map style. */\n    protected _style!: MapStyle;\n    /** Manages the ordered layer stack. */\n    protected _layerManager!: LayerManager;\n\n    /** Keyboard interaction handler. */\n    protected _keyEvents!: KeyEvents;\n    /** Mouse interaction handler. */\n    protected _mouseEvents!: MouseEvents;\n    /** Canvas resize handler. */\n    protected _resizeEvents!: ResizeEvents;\n    /** Public event bus for map events. */\n    protected _mapEvents!: EventEmitter<MapEventRecord>;\n\n    /** Map UI controller. */\n    protected _ui!: AutkMapUi;\n    /** Whether floating UI elements should be built during initialization. */\n    protected _showUi: boolean = true;\n    /** Backing WebGPU canvas. */\n    protected _canvas!: HTMLCanvasElement;\n    /** Active requestAnimationFrame id: the continuous loop's next frame, or the frame requested in on-demand mode. */\n    protected _animationFrameId: number | null = null;\n    /** Whether rendering has started in on-demand mode. */\n    protected _onDemand: boolean = false;\n    /** Indicates whether this map instance has been destroyed. */\n    protected _isDestroyed: boolean = false;\n    /** Set after the first render-loop error to deduplicate repeated frame failures. */\n    protected _renderErrorLogged: boolean = false;\n    /** Flat render path used when terrain mode is disabled. */\n    private _flatRenderPath!: FlatMapRenderPath;\n    /** Active terrain render path, or `null` while using flat rendering. */\n    private _terrainRenderPath: TerrainMapRenderPath | null = null;\n    /** Shared picking coordinator used by both render paths. */\n    private _picking!: MapPickingController;\n\n    /**\n     * Creates an AutkMap instance bound to a canvas element.\n     *\n     * @param canvas Canvas element used as the WebGPU drawing surface.\n     * @param showUi Whether floating UI elements should be shown. Defaults to `true`.\n     * @throws Never throws.\n     */\n    constructor(canvas: HTMLCanvasElement, showUi: boolean = true) {\n        this._canvas = canvas;\n        this._showUi = showUi;\n        this._style = new MapStyle();\n        this._style.setChangeListener(() => {\n            for (const layer of this._layerManager.layers) {\n                layer.makeLayerRenderInfoDirty();\n            }\n            this.requestRender();\n        });\n        this._renderer = new Renderer(canvas, this._style);\n\n        this._camera = new MapCamera(() => this.requestRender());\n        this._layerManager = new LayerManager();\n\n        this._keyEvents = new KeyEvents(this);\n        this._mouseEvents = new MouseEvents(this);\n        this._resizeEvents = new ResizeEvents(this);\n        this._mapEvents = new EventEmitter<MapEventRecord>();\n        this._picking = new MapPickingController(this._renderer, this._layerManager, this._mapEvents);\n        this._flatRenderPath = new FlatMapRenderPath(this._renderer, this._camera, this._layerManager, this._picking);\n\n        this._ui = new AutkMapUi(this);\n    }\n\n    /** View and projection camera. */\n    get camera(): Camera {\n        return this._camera;\n    }\n\n    /** Instance-specific semantic map style. */\n    get style(): MapStyle {\n        return this._style;\n    }\n\n    /** WebGPU renderer. */\n    get renderer(): Renderer {\n        return this._renderer;\n    }\n\n    /** Ordered layer stack manager. */\n    get layerManager(): LayerManager {\n        return this._layerManager;\n    }\n\n    /** Backing WebGPU canvas element. */\n    get canvas(): HTMLCanvasElement {\n        return this._canvas;\n    }\n\n    /** Map UI controller. */\n    get ui(): AutkMapUi {\n        return this._ui;\n    }\n\n    /** Whether optional map controls are enabled; the watermark remains visible. */\n    get showUi(): boolean {\n        return this._showUi;\n    }\n\n    /** Public typed map-event bus (e.g., picking). */\n    get events(): EventEmitter<MapEventRecord> {\n        return this._mapEvents;\n    }\n\n    /** Currently active pick-enabled layer, if any. */\n    get activePickingLayer(): Layer | null {\n        return this._layerManager.layers.find((layer) => layer.layerRenderInfo.isPick) ?? null;\n    }\n\n    /**\n     * Initializes renderer resources, event bindings, and UI.\n     *\n     * @returns Promise that resolves when renderer initialization completes.\n     * @throws If WebGPU is not available or device acquisition fails.\n     * @example\n     * await map.init();\n     */\n    async init() {\n        if (this._isDestroyed) {\n            return;\n        }\n\n        await this._renderer.init();\n\n        this._keyEvents.bindEvents();\n        this._mouseEvents.bindEvents();\n\n        this._resizeEvents.bindEvents();\n        this._resizeEvents.resize();\n\n        this.render();\n\n        if (this._showUi) {\n            this._ui.buildUi();\n        }\n        this._ui.buildBranding();\n    }\n\n    /**\n     * Loads a GeoJSON feature collection as a map layer.\n     *\n     * When `type` is omitted the layer type is inferred from all non-null\n     * geometries in the collection. Implicit inference only works for\n     * collections that resolve to a single geometry family\n     * (Point → 'points', LineString → 'polylines', Polygon → 'polygons').\n     * Mixed-geometry collections must pass an explicit `type`.\n     *\n     * Supported layer types: 'surface', 'water', 'parks', 'roads', 'buildings',\n     * 'points', 'polylines', 'polygons', 'raster'.\n     *\n     * @param id Unique layer identifier.\n     * @param params Load parameters.\n     * @param params.collection Source GeoJSON feature collection.\n     * @param params.type Optional layer type override.\n     * @param params.loadConfig Optional geometry-building configuration applied while loading.\n     * @param params.property Optional value extractor applied immediately as the initial thematic mapping.\n     * @throws Never throws. Errors are logged to the console.\n     */\n    loadCollection(id: string, { collection, type = null, property, loadConfig }: LoadCollectionParams): void {\n        if (!this.layerManager.hasOrigin) {\n            this.layerManager.initializeOrigin(collection);\n        }\n\n        let sType = type ?? this.inferCollectionLayerType(collection, id);\n        if (!sType) { return; }\n\n        switch (sType) {\n            case 'surface':\n            case 'water':\n            case 'parks':\n            case 'polygons':\n                this.createPolygonsLayer(id, collection as FeatureCollection, sType, typeof property === 'string' ? property : undefined);\n                break;\n\n            case 'roads':\n            case 'polylines': {\n                this.createPolylinesLayer(\n                    id,\n                    collection as FeatureCollection,\n                    sType,\n                    typeof property === 'string' ? property : undefined,\n                );\n                break;\n            }\n            case 'points':\n                this.createPointsLayer(id, collection as FeatureCollection, sType, typeof property === 'string' ? property : undefined);\n                break;\n\n            case 'buildings':\n                this.createBuildingsLayer(\n                    id,\n                    collection as FeatureCollection,\n                    sType,\n                    typeof property === 'string' ? property : undefined,\n                    loadConfig?.buildingsZeroHeight,\n                );\n                break;\n\n            case 'raster':\n                if (typeof property !== 'string') { console.error(`Layer \"${id}\": property path string is required for raster layers.`); return; }\n                this.createRasterLayer(id, collection, property);\n                break;\n\n            default:\n                console.error(`Collection of layer ${id} has an unknown layer type: ${sType}.`);\n                break;\n        }\n\n        this._ui.refreshLayerList();\n    }\n\n    /**\n     * Loads a prebuilt 3D triangle mesh directly into the map.\n     *\n     * Mesh coordinates must already be expressed in the map's local coordinate\n     * space, relative to the current shared origin.\n     *\n     * @param id Layer identifier.\n     * @param params Mesh loading parameters.\n     * @param params.geometry Prebuilt mesh geometry chunks.\n     * @param params.components Per-feature mesh component metadata.\n     * @param params.thematic Optional precomputed thematic values.\n     * @param params.type Optional layer type override for the mesh.\n     * @returns Nothing. The mesh layer is created and registered with the map.\n     * @throws If the map origin has not been initialized.\n     */\n    loadMesh(id: string, { geometry, components, thematic, type = 'buildings' }: LoadMeshParams): void {\n        if (!this.layerManager.hasOrigin) {\n            throw new Error(`Layer '${id}': map origin must be initialized before loading a mesh.`);\n        }\n\n        const layerInfo: LayerInfo = {\n            id,\n            zIndex: this._layerManager.computeZindex(type),\n            typeLayer: type,\n        };\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n        const layerData: LayerData = {\n            geometry,\n            components,\n            thematic: thematic ?? components.map(() => ({ value: 0, valid: 1 })),\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n        this._ui.refreshLayerList();\n    }\n\n    /**\n     * Updates the thematic (color-mapped) values of a layer from a feature collection.\n     *\n     * Normalization to `[0, 1]` (required by the GPU shader) and legend label\n     * generation are delegated to `ColorMap` based on the active layer\n     * `colorMap` configuration.\n     *\n     * Thematic values are aligned to rendered components through source feature\n     * metadata captured during triangulation. When both the layer and the input\n     * collection expose feature ids, matching is done by `feature.id`; otherwise\n     * the update falls back to the original feature index order.\n     *\n     * For raster layers the raster texture is rebuilt from `property`.\n     *\n     * @param id Layer identifier.\n     * @param params Update parameters.\n     * @param params.collection Source feature collection.\n     * @param params.property Dot-path accessor resolved from each feature.\n     * @throws Never throws. Errors are logged to the console.\n     */\n    updateThematic(id: string, { collection, property }: UpdateThematicParams): void {\n        const layer = this._layerManager.searchByLayerId(id) as VectorLayer | SpriteLayer | null;\n\n        if (!layer) { return; }\n        if (layer.layerInfo.typeLayer === 'raster') { return; };\n\n        const features = collection.features;\n        if (features.length === 0) { return; }\n\n        const components = layer.components;\n        if (components.length === 0) { return; }\n\n        const propertyResolver = (item: unknown) => valueAtPath(item, property);\n        const sample = features\n            .map(f => propertyResolver(f))\n            .find(v => v !== undefined && v !== null);\n\n        if (sample === undefined || sample === null) {\n            console.warn(`Thematic property not found on layer '${id}': ${property}`);\n            this.updateRenderInfo(id, { renderInfo: { isColorMap: false } });\n            return;\n        }\n\n        const dataType = isNumericLike(sample) ? 'number' : typeof sample;\n        if (dataType !== 'number' && dataType !== 'string') {\n            console.warn(`Unsupported thematic property type on layer '${id}': ${dataType}`);\n            this.updateRenderInfo(id, { renderInfo: { isColorMap: false } });\n            return;\n        }\n\n        let resolvedDomain: ResolvedDomain = [];\n\n        const colorMap = layer.layerRenderInfo.colormap.config;\n        const thematicByFeatureIndex: LayerThematic[] = [];\n        const canMatchById = components.every((component) => component.featureId !== undefined)\n            && features.every((feature) => feature.id !== undefined);\n        const thematicByFeatureId = canMatchById ? new Map<string | number, LayerThematic>() : null;\n\n        const storeThematicValue = (featureIndex: number, value: number, valid: number): boolean => {\n            const thematic = { value, valid };\n            thematicByFeatureIndex[featureIndex] = thematic;\n\n            if (!thematicByFeatureId) {\n                return true;\n            }\n\n            const featureId = features[featureIndex].id as string | number;\n            if (thematicByFeatureId.has(featureId)) {\n                console.error(`Layer '${id}': duplicate feature id '${featureId}' prevents thematic matching.`);\n                return false;\n            }\n\n            thematicByFeatureId.set(featureId, thematic);\n            return true;\n        };\n\n        if (dataType === 'number') {\n            const rawValues = features.map((feature) => {\n                const resolved = propertyResolver(feature);\n                const numeric = Number(resolved);\n                return Number.isFinite(numeric) ? numeric : undefined;\n            });\n            const validValues = rawValues.filter((value): value is number => value !== undefined);\n\n            if (validValues.length === 0) {\n                console.warn(`No valid numeric thematic values found on layer '${id}': ${property}`);\n                this.updateRenderInfo(id, { renderInfo: { isColorMap: false } });\n                return;\n            }\n\n            resolvedDomain = ColorMap.resolveDomainFromData(validValues, colorMap);\n            for (let featureIndex = 0; featureIndex < rawValues.length; featureIndex++) {\n                const rawValue = rawValues[featureIndex];\n                if (!storeThematicValue(featureIndex, rawValue ?? 0, rawValue === undefined ? 0 : 1)) {\n                    return;\n                }\n            }\n        } \n        else if (dataType === 'string') {\n            const rawValues = features.map((feature) => {\n                const resolved = propertyResolver(feature);\n                return resolved === undefined || resolved === null ? undefined : String(resolved);\n            });\n            const validValues = rawValues.filter((value): value is string => value !== undefined);\n\n            if (validValues.length === 0) {\n                console.warn(`No valid categorical thematic values found on layer '${id}': ${property}`);\n                this.updateRenderInfo(id, { renderInfo: { isColorMap: false } });\n                return;\n            }\n\n            const categoricalDomain = ColorMap.resolveDomainFromData(validValues, colorMap) as string[];\n            resolvedDomain = categoricalDomain;\n            for (let featureIndex = 0; featureIndex < rawValues.length; featureIndex++) {\n                const rawValue = rawValues[featureIndex];\n                const categoryIndex = rawValue === undefined ? 0 : categoricalDomain.indexOf(rawValue);\n                const isValid = rawValue !== undefined && categoryIndex >= 0 ? 1 : 0;\n                if (!storeThematicValue(featureIndex, categoryIndex >= 0 ? categoryIndex : 0, isValid)) {\n                    return;\n                }\n            }\n        }\n\n        const thematicData: LayerThematic[] = [];\n        if (thematicByFeatureId) {\n            for (const component of components) {\n                const thematic = thematicByFeatureId.get(component.featureId as string | number);\n                if (!thematic) {\n                    console.error(\n                        `Layer '${id}': missing thematic value for feature id '${String(component.featureId)}'.`\n                    );\n                    return;\n                }\n                thematicData.push(thematic);\n            }\n        } else {\n            for (const component of components) {\n                const thematic = thematicByFeatureIndex[component.featureIndex];\n                if (!thematic) {\n                    console.error(\n                        `Layer '${id}': missing thematic value for source feature index ${component.featureIndex}.`\n                    );\n                    return;\n                }\n                thematicData.push(thematic);\n            }\n        }\n\n        if (!layer.loadThematic(thematicData)) {\n            return;\n        }\n\n        layer.updateLayerRenderInfo({\n            colormap: {\n                ...layer.layerRenderInfo.colormap,\n                computedDomain: resolvedDomain,\n                computedLabels: ColorMap.computeLabels(resolvedDomain),\n            },\n        });\n        this._ui.refreshLegend(layer);\n\n        layer.makeLayerDataDirty();\n    }\n\n    /**\n     * Updates raster layer values and color domain.\n     *\n     * @param id Layer identifier.\n     * @param params Update parameters.\n     * @param params.collection GeoTIFF-derived feature collection.\n     * @param params.property Dot-path accessor for a flat raster band array on feature properties.\n     * @param params.transferFunction Optional opacity transfer-function configuration.\n     * @throws Never throws. Errors are logged to the console.\n     */\n    updateRaster(id: string, { collection, property, transferFunction }: UpdateRasterParams): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!layer || layer.layerInfo.typeLayer !== 'raster') { return; }\n\n        if (collection.features.length === 0) {\n            console.warn(`Raster update skipped for layer '${id}': empty collection.`);\n            return;\n        }\n\n        const props = collection.features[0].properties;\n        if (!props) {\n            console.warn(`Raster update skipped for layer '${id}': invalid raster payload.`);\n            return;\n        }\n\n        const resolved = valueAtPath(props, property);\n        const rasterValues = resolved instanceof Float32Array\n            ? resolved\n            : ArrayBuffer.isView(resolved) && !(resolved instanceof DataView)\n                ? new Float32Array(Array.from(resolved as unknown as ArrayLike<number>, (value: number) => {\n                    const numeric = Number(value);\n                    return Number.isFinite(numeric) ? numeric : Number.NaN;\n                }))\n                : Array.isArray(resolved)\n                    ? new Float32Array(resolved.map((value: unknown) => {\n                        const numeric = Number(value);\n                        return Number.isFinite(numeric) ? numeric : Number.NaN;\n                    }))\n                    : null;\n\n        if (!rasterValues || rasterValues.length === 0) {\n            console.warn(`Raster update skipped for layer '${id}': invalid raster band '${property}'.`);\n            return;\n        }\n\n        const rasterLayer = layer as RasterLayer;\n        const config = layer.layerRenderInfo.colormap.config;\n        const resolvedDomain = ColorMap.resolveDomainFromData(rasterValues, config);\n\n        layer.updateLayerRenderInfo({\n            colormap: {\n                ...layer.layerRenderInfo.colormap,\n                computedDomain: resolvedDomain,\n                computedLabels: ColorMap.computeLabels(resolvedDomain),\n            },\n        });\n        this._ui.refreshLegend(layer);\n\n        if (transferFunction) {\n            rasterLayer.setTransferFunction(transferFunction);\n        }\n\n        rasterLayer.loadRaster(rasterValues);\n        rasterLayer.makeLayerDataDirty();\n    }\n\n    /**\n     * Updates color-map configuration for a layer.\n     *\n     * @param id Layer identifier.\n     * @param params Color-map update parameters.\n     * @returns Nothing. The target layer render configuration is updated in place.\n     * @throws Never throws. Unknown layers are silently ignored.\n     */\n    updateColorMap(id: string, { colorMap }: UpdateColorMapParams): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!layer) { return; }\n\n        const currentConfig = layer.layerRenderInfo.colormap.config;\n\n        const mergedColorMap: ColorMapConfig = {\n            interpolator: colorMap.interpolator ?? currentConfig.interpolator ?? ColorMapInterpolator.SEQ_BLUES,\n            domainSpec: colorMap.domainSpec ?? currentConfig.domainSpec ?? { type: ColorMapDomainStrategy.MIN_MAX },\n        };\n\n        const nextColormap = {\n            ...layer.layerRenderInfo.colormap,\n            config: mergedColorMap,\n        };\n\n        if (layer.layerInfo.typeLayer === 'raster') {\n            const rasterLayer = layer as RasterLayer;\n            const rasterValues = rasterLayer.rasterValues;\n            if (rasterValues.length > 0) {\n                const domain = ColorMap.resolveDomainFromData(rasterValues, mergedColorMap);\n                nextColormap.computedDomain = domain;\n                nextColormap.computedLabels = ColorMap.computeLabels(domain);\n                layer.updateLayerRenderInfo({ colormap: nextColormap });\n                rasterLayer.loadRaster(rasterValues);\n                rasterLayer.makeLayerDataDirty();\n                this._ui.refreshLegend(layer);\n                return;\n            }\n        } else {\n            const vectorLayer = layer as VectorLayer | SpriteLayer;\n            const thematicValues = vectorLayer.thematic;\n            if (thematicValues.length > 0) {\n                const existingDomain = layer.layerRenderInfo.colormap.computedDomain;\n                const domain = Array.isArray(existingDomain)\n                    && existingDomain.length > 0\n                    && existingDomain.every(v => typeof v === 'string')\n                    ? existingDomain\n                    : ColorMap.resolveDomainFromData(thematicValues, mergedColorMap);\n                nextColormap.computedDomain = domain;\n                nextColormap.computedLabels = ColorMap.computeLabels(domain);\n            }\n        }\n\n        layer.updateLayerRenderInfo({ colormap: nextColormap });\n        this._ui.refreshLegend(layer);\n    }\n\n    /**\n     * Updates one or more render properties of a layer.\n     *\n     * @param id Layer identifier.\n     * @param params Render update parameters.\n     * @param params.renderInfo Render properties to update.\n     * @returns Nothing. The target layer render state is updated in place.\n     * @throws Never throws. Unknown layers are silently ignored.\n     */\n    updateRenderInfo(id: string, params: UpdateRenderInfoParams | Partial<LayerRenderInfo>): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!layer) { return; }\n\n        const info = 'renderInfo' in params ? params.renderInfo : params;\n\n        const nextInfo: Partial<LayerRenderInfo> = { ...info };\n\n        let needsLegend = false;\n        let needsLayerList = false;\n\n        if ('isColorMap' in info) {\n            needsLegend = true;\n            needsLayerList = true;\n        }\n        if ('isSkip' in info) {\n            needsLayerList = true;\n        }\n        if ('isPick' in nextInfo) {\n            if (nextInfo.isPick === true) {\n                this.deactivateOtherPickingLayers(id);\n            } else if (nextInfo.isPick === false) {\n                layer.clearHighlightedIds();\n                nextInfo.pickedComps = undefined;\n            }\n            needsLayerList = true;\n        }\n        layer.updateLayerRenderInfo(nextInfo);\n\n        if (needsLegend) { this._ui.refreshLegend(layer); }\n        if (needsLayerList) { this._ui.refreshLayerList(); }\n    }\n\n    /**\n     * Removes all layers matching the provided id.\n     *\n     * @param id Layer identifier.\n     * @returns Nothing. Matching layers are removed from the map.\n     * @throws Never throws. Unknown ids are silently ignored.\n     */\n    removeLayer(id: string): void {\n        const removed = this._layerManager.searchByLayerId(id) !== null;\n        this._layerManager.removeLayerById(id);\n        this._ui.handleLayerRemoved(id);\n        this._ui.refreshLayerList();\n\n        if (removed) {\n            this.requestRender();\n        }\n    }\n\n    /**\n     * Replaces the highlighted selection of a pickable layer.\n     *\n     * @param id Layer identifier.\n     * @param selection Component ids to highlight.\n     * @returns Nothing. Unsupported layers are ignored.\n     * @throws Never throws.\n     */\n    setHighlightedIds(id: string, selection: number[]): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!layer || !layer.supportsHighlight) {\n            return;\n        }\n\n        layer.setHighlightedIds(selection);\n    }\n\n    /**\n     * Clears the highlighted selection of a pickable layer.\n     *\n     * @param id Layer identifier.\n     * @returns Nothing. Unsupported layers are ignored.\n     * @throws Never throws.\n     */\n    clearHighlightedIds(id: string): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!layer || !layer.supportsHighlight) {\n            return;\n        }\n\n        layer.clearHighlightedIds();\n    }\n\n    /**\n     * Toggles skipped rendering for the provided component ids of a vector layer.\n     *\n     * @param id Layer identifier.\n     * @param selection Component ids to skip/unskip.\n     * @returns Nothing. Non-vector layers are ignored.\n     * @throws Never throws.\n     */\n    setSkippedIds(id: string, selection: number[]): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!(layer instanceof VectorLayer)) {\n            return;\n        }\n\n        layer.setSkippedIds(selection);\n    }\n\n    /**\n     * Clears skipped rendering state for a vector layer.\n     *\n     * @param id Layer identifier.\n     * @returns Nothing. Non-vector layers are ignored.\n     * @throws Never throws.\n     */\n    clearSkippedIds(id: string): void {\n        const layer = this._layerManager.searchByLayerId(id);\n        if (!(layer instanceof VectorLayer)) {\n            return;\n        }\n\n        layer.clearSkippedIds();\n    }\n\n    /**\n     * Enables terrain rendering from a raster feature collection.\n     *\n     * The collection is converted to a local-space heightfield and used to\n     * replace the flat render path with the terrain render path.\n     *\n     * @param collection Raster feature collection containing bbox, resolution, and height values.\n     * @param property Dot-path to the raster band used as terrain height.\n     * @returns Nothing. Terrain resources are initialized immediately.\n     * @throws {Error} If the map origin is not initialized or the heightfield input is invalid.\n     * @example\n     * map.enableTerrainMode(elevationCollection, 'bands.elevation');\n     */\n    enableTerrainMode(collection: FeatureCollection<Geometry | null>, property: string): void {\n        if (!this.layerManager.hasOrigin) {\n            throw new Error('Terrain mode requires at least one map layer to initialize the map origin first.');\n        }\n\n        const heightfield = heightfieldFromRaster(collection, property, this.layerManager.origin);\n        this._terrainRenderPath?.destroy();\n        this._terrainRenderPath = new TerrainMapRenderPath(\n            this._renderer,\n            this._camera,\n            this._layerManager,\n            this._picking,\n            this._style,\n            heightfield,\n            () => this.requestRender(),\n        );\n        this.requestRender();\n    }\n\n    /**\n     * Disables terrain rendering and returns the map to the flat render path.\n     *\n     * @returns Nothing. Terrain GPU resources are released when present.\n     * @throws Never throws.\n     * @example\n     * map.disableTerrainMode();\n     */\n    disableTerrainMode(): void {\n        if (!this._terrainRenderPath) {\n            return;\n        }\n\n        this._terrainRenderPath.destroy();\n        this._terrainRenderPath = null;\n        this.requestRender();\n    }\n\n    /**\n     * Updates debug options for the active terrain render path.\n     *\n     * Calls before terrain mode is enabled are ignored.\n     *\n     * @param options Partial terrain debug flags to merge with existing options.\n     * @returns Nothing.\n     * @throws Never throws.\n     * @example\n     * map.updateTerrainDebug({ showMesh: true, enableCulling: false });\n     */\n    updateTerrainDebug(options: Partial<TerrainDebugOptions>): void {\n        if (!this._terrainRenderPath) {\n            return;\n        }\n\n        this._terrainRenderPath.updateDebug(options);\n        this.requestRender();\n    }\n\n    /**\n     * Resets the camera for the active render mode.\n     *\n     * In terrain mode the camera frames the heightfield bounds; otherwise it\n     * returns to the default flat map view.\n     *\n     * @returns Nothing. The camera state and viewport matrices are updated.\n     * @throws Never throws.\n     * @example\n     * map.resetCamera();\n     */\n    resetCamera(): void {\n        (this._terrainRenderPath ?? this._flatRenderPath).resetCamera();\n    }\n\n    /**\n     * Toggles terrain overlay bounds debug rendering.\n     *\n     * The call is ignored with a warning when terrain mode is disabled.\n     *\n     * @returns Nothing.\n     * @throws Never throws.\n     * @example\n     * map.toggleTerrainOverlayBoundsDebug();\n     */\n    toggleTerrainOverlayBoundsDebug(): void {\n        if (!this._terrainRenderPath) {\n            console.warn('Terrain overlay bounds debug requires terrain mode.');\n            return;\n        }\n\n        this._terrainRenderPath.toggleOverlayBoundsDebug();\n        this.requestRender();\n    }\n\n    /**\n     * Starts rendering, either on every frame or only when the picture changes.\n     *\n     * By default it draws once and then only when something changes.\n     * A number, `{ fps }`, or `{ onDemand: false }` starts a continuous loop.\n     * In on-demand mode:\n     * camera navigation and resizing, layer loads, updates and removals, style\n     * changes, picking and terrain changes each request a frame, and changes\n     * made before the next frame are drawn once. Direct mutations are not\n     * observed: mark CPU data or uniforms dirty when necessary, then call\n     * {@link AutkMap.requestRender} to draw the updated resources.\n     *\n     * Calling `draw` again replaces the current mode, so a map that is already\n     * drawing continuously can be switched to on-demand rendering and back.\n     *\n     * @param options Target frames per second for the continuous loop (default `60`, `0` renders as fast as possible), or {@link MapDrawOptions}.\n     * @returns Nothing. Rendering is scheduled via `requestAnimationFrame`.\n     * @throws Never throws.\n     * @example\n     * map.draw();                    // draw only when something changes\n     * map.draw(30);                  // redraw continuously at 30 fps\n     * map.draw({ onDemand: false }); // redraw continuously at 60 fps\n     */\n    draw(options: number | MapDrawOptions = {}) {\n        if (this._isDestroyed) {\n            return;\n        }\n\n        if (this._animationFrameId !== null) {\n            cancelAnimationFrame(this._animationFrameId);\n            this._animationFrameId = null;\n        }\n\n        const settings: MapDrawOptions = typeof options === 'number' ? { fps: options } : options;\n        this._onDemand = settings.onDemand ?? (settings.fps === undefined);\n        if (this._onDemand) {\n            this.requestRender();\n            return;\n        }\n\n        const fps = settings.fps ?? 60;\n        let previousDelta = 0;\n\n        const update = (currentDelta: number) => {\n            if (this._isDestroyed) {\n                this._animationFrameId = null;\n                return;\n            }\n\n            this._animationFrameId = requestAnimationFrame(update);\n            const delta = currentDelta - previousDelta;\n\n            if (fps && delta < 1000 / fps) {\n                return;\n            }\n\n            this.render();\n            previousDelta = currentDelta;\n        };\n\n        this._animationFrameId = requestAnimationFrame(update);\n    }\n\n    /**\n     * Schedules one frame when the map renders on demand.\n     *\n     * Calls made before that frame runs are merged into it, so a burst of\n     * changes is drawn once. The map already requests a frame after every change\n     * it can observe; call this after changing anything else that affects the\n     * picture, such as a layer's GPU resources written directly.\n     *\n     * Does not upload changed CPU buffers or refresh cached uniforms by itself;\n     * use the update APIs or mark the corresponding layer state dirty first.\n     * Has no effect before `draw()`, in continuous mode, or after `destroy()`.\n     *\n     * @returns Nothing. The frame is scheduled via `requestAnimationFrame`.\n     * @throws Never throws.\n     * @example\n     * map.draw({ onDemand: true });\n     * // ...after changing something the map cannot observe:\n     * map.requestRender();\n     */\n    requestRender(): void {\n        if (this._isDestroyed || !this._onDemand || this._animationFrameId !== null) {\n            return;\n        }\n\n        this._animationFrameId = requestAnimationFrame(() => {\n            // Changes during rendering may miss this frame and must schedule the next one.\n            this._animationFrameId = null;\n            if (!this._isDestroyed) {\n                this.render();\n            }\n        });\n    }\n\n    /**\n     * Tears down map resources, event bindings, and GPU allocations.\n     *\n     * @returns Nothing. Repeated calls after destruction are ignored.\n     * @throws Never throws.\n     * @example\n     * map.destroy();\n     */\n    destroy(): void {\n        if (this._isDestroyed) {\n            return;\n        }\n\n        if (this._animationFrameId !== null) {\n            cancelAnimationFrame(this._animationFrameId);\n            this._animationFrameId = null;\n        }\n\n        this._keyEvents.destroyEvents();\n        this._mouseEvents.destroyEvents();\n        this._resizeEvents.destroyEvents();\n        this._terrainRenderPath?.destroy();\n        this._terrainRenderPath = null;\n\n        this._style.setChangeListener(null);\n        this._layerManager.layers.forEach((layer) => {\n            layer.setChangeListener(null);\n            layer.destroy();\n        });\n\n        this._ui.destroy();\n        this._renderer.destroy();\n\n        this._isDestroyed = true;\n    }\n\n    /**\n     * Infers a layer type from a homogeneous collection of vector geometries.\n     *\n     * Returns `null` when the collection is empty, contains only null geometries,\n     * or mixes multiple geometry families that require an explicit layer type.\n     *\n     * @param collection Source feature collection to inspect.\n     * @param layerId Layer identifier used in diagnostics.\n     * @returns Inferred layer family, or `null` when inference fails.\n     */\n    private inferCollectionLayerType(collection: FeatureCollection<Geometry | null>, layerId: string): LayerType | null {\n        const families = new Set<Extract<LayerType, 'points' | 'polygons' | 'polylines'>>();\n        const visitGeometry = (geometry: Geometry | null, featureIndex: number): void => {\n            if (!geometry) {\n                console.warn(`Layer \"${layerId}\": feature ${featureIndex} has null geometry and will be ignored during type inference.`);\n                return;\n            }\n\n            if (geometry.type === 'GeometryCollection') {\n                for (const child of geometry.geometries) {\n                    visitGeometry(child, featureIndex);\n                }\n                return;\n            }\n\n            families.add(mapGeometryTypeToLayerType(geometry.type));\n        };\n\n        for (let index = 0; index < collection.features.length; index++) {\n            const feature = collection.features[index];\n            visitGeometry(feature.geometry, index);\n            if (families.size > 1) {\n                console.error(\n                    `Layer \"${layerId}\": cannot infer layer type from mixed geometry families. Pass an explicit type or split the collection.`\n                );\n                return null;\n            }\n        }\n\n        const [family] = families;\n        if (family) {\n            return family;\n        }\n\n        console.error(`Layer \"${layerId}\": cannot infer layer type from an empty or geometry-less collection.`);\n        return null;\n    }\n\n    /**\n     * Executes one render frame, including normal and picking passes.\n     *\n     * @returns Nothing. Rendering commands are recorded and submitted to the GPU.\n     */\n    private render() {\n        try {\n            this._renderFrame();\n        } catch (error) {\n            if (!this._renderErrorLogged) {\n                console.warn('AutkMap render skipped:', error);\n                this._renderErrorLogged = true;\n            }\n        }\n    }\n\n    /**\n     * Executes one render frame, including normal and picking passes.\n     * \n     * @returns Nothing. Rendering commands are recorded and submitted to the GPU.\n     */\n    private _renderFrame() {\n        this._camera.update();\n        if (this._terrainRenderPath) {\n            this._terrainRenderPath.renderFrame();\n            return;\n        }\n\n        this._flatRenderPath.renderFrame();\n    }\n\n    /**\n     * Clears picking state from every layer except the requested one.\n     *\n     * @param activeLayerId Identifier of the layer that should remain pick-enabled.\n     * @returns Nothing. Other pick-enabled layers are deactivated.\n     */\n    private deactivateOtherPickingLayers(activeLayerId: string): void {\n        this._layerManager.layers.forEach((otherLayer) => {\n            if (otherLayer.layerInfo.id === activeLayerId || !otherLayer.layerRenderInfo.isPick) {\n                return;\n            }\n\n            otherLayer.clearHighlightedIds();\n            otherLayer.updateLayerRenderInfo({ isPick: false, pickedComps: undefined });\n        });\n    }\n\n    /**\n     * Creates a polygon-based vector layer from GeoJSON.\n     *\n     * @param layerName Target layer id.\n     * @param geojson Source feature collection.\n     * @param typeLayer Layer type.\n     * @param property Optional value extractor used to initialize thematic data.\n     * @returns Nothing. The layer is created when triangulation succeeds.\n      */\n    private createPolygonsLayer(layerName: string, geojson: FeatureCollection, typeLayer: LayerType, property?: string) {\n        const layerInfo: LayerInfo = {\n            id: `${layerName}`,\n            zIndex: this._layerManager.computeZindex(typeLayer),\n            typeLayer: typeLayer,\n        };\n\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n\n        const layerMesh = TriangulatorPolygons.buildMesh(geojson, this.layerManager.origin);\n        if (layerMesh[0].length === 0 || layerMesh[1].length === 0) {\n            console.error('Invalid Polygon Layer');\n            return;\n        }\n\n        let layerBorder: [LayerData['border'], LayerData['borderComponents']];\n        if (typeLayer === 'polygons') {\n            layerBorder = TriangulatorPolygons.buildBorder(geojson, this.layerManager.origin);\n            if (!layerBorder[0] || !layerBorder[1] || layerBorder[0].length === 0 || layerBorder[1].length === 0) {\n                console.error('Invalid Polygon Layer border.');\n                return;\n            }\n        } else {\n            layerBorder = [[], []];\n        }\n\n        const layerData = {\n            geometry: layerMesh[0],\n            components: layerMesh[1],\n            border: layerBorder[0],\n            borderComponents: layerBorder[1],\n            thematic: layerMesh[1].map(() => {\n                return {\n                    value: 0,\n                    valid: 1,\n                };\n            }),\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n\n        if (property) {\n            this.updateThematic(layerName, { collection: geojson, property  });\n        }\n    }\n\n    /**\n     * Creates a width-independent centerline layer from GeoJSON for shader expansion.\n     *\n     * @param layerName Target layer id.\n     * @param geojson Source feature collection.\n     * @param typeLayer Layer type.\n     * @param property Optional value extractor used to initialize thematic data.\n     * @returns Nothing. The layer is created when valid centerline data is available.\n      */\n    private createPolylinesLayer(layerName: string, geojson: FeatureCollection, typeLayer: LayerType, property?: string) {\n        const layerInfo: LayerInfo = {\n            id: `${layerName}`,\n            zIndex: this._layerManager.computeZindex(typeLayer),\n            typeLayer: typeLayer,\n        };\n\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n\n        const lines = PolylineBuilder.build(geojson, this.layerManager.origin);\n        if (lines.geometry.length === 0 || lines.components.length === 0) {\n            console.error('Invalid Polyline Layer.');\n            return;\n        }\n        if (typeLayer === 'roads') {\n            layerRenderInfo.polylinesWidthByComponent = new Float32Array(lines.components.map(component =>\n                TriangulatorPolylines.resolveRoadHalfWidth(geojson.features[component.featureIndex]) * 2,\n            ));\n        } else {\n            layerRenderInfo.polylinesWidth = DEFAULT_LINE_WIDTH;\n        }\n\n        const layerData = {\n            geometry: lines.geometry,\n            components: lines.components,\n            polylineAttributes: lines.attributes,\n            thematic: lines.components.map(() => {\n                return {\n                    value: 0,\n                    valid: 1,\n                };\n            }),\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n\n        if (property) {\n            this.updateThematic(layerName, { collection: geojson, property  });\n        }\n    }\n\n    /**\n     * Creates a point-based vector layer from GeoJSON.\n     *\n     * @param layerName Target layer id.\n     * @param geojson Source feature collection.\n     * @param typeLayer Layer type.\n     * @param property Optional value extractor used to initialize thematic data.\n     * @returns Nothing. The layer is created when valid point instances are available.\n      */\n    private createPointsLayer(layerName: string, geojson: FeatureCollection, typeLayer: LayerType, property?: string) {\n        const layerInfo: LayerInfo = {\n            id: `${layerName}`,\n            zIndex: this._layerManager.computeZindex(typeLayer),\n            typeLayer: typeLayer,\n        };\n\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n\n        const pointInstances = TriangulatorPoints.buildInstances(geojson, this.layerManager.origin);\n        if (pointInstances.instances.length === 0 || pointInstances.components.length === 0) {\n            console.error('Invalid Points Layer.');\n            return;\n        }\n\n        const layerData = {\n            geometry: [],\n            components: pointInstances.components,\n            pointInstances: pointInstances.instances,\n            pointInstanceCount: pointInstances.instances.length / 2,\n            thematic: pointInstances.components.map(() => {\n                return {\n                    value: 0,\n                    valid: 1,\n                };\n            }),\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n\n        if (property) {\n            this.updateThematic(layerName, { collection: geojson, property  });\n        }\n    }\n\n    /**\n     * Creates a buildings vector layer from GeoJSON.\n     *\n     * @param layerName Target layer id.\n     * @param geojson Source feature collection.\n     * @param typeLayer Layer type.\n     * @param property Optional value extractor used to initialize thematic data.\n     * @returns Nothing. The layer is created when triangulation succeeds.\n      */\n    private createBuildingsLayer(layerName: string, geojson: FeatureCollection, typeLayer: LayerType, property?: string, buildingsZeroHeight?: boolean) {\n        const layerInfo: LayerInfo = {\n            id: `${layerName}`,\n            zIndex: this._layerManager.computeZindex(typeLayer),\n            typeLayer: 'buildings',\n        };\n\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n\n        const layerMesh = TriangulatorBuildings.buildMesh(geojson, this.layerManager.origin, buildingsZeroHeight);\n        if (layerMesh[0].length === 0 || layerMesh[1].length === 0) {\n            console.error('Invalid Building Layer.');\n            return;\n        }\n\n        const layerData = {\n            geometry: layerMesh[0],\n            components: layerMesh[1],\n            thematic: layerMesh[1].map(() => {\n                return {\n                    value: 0,\n                    valid: 1,\n                };\n            }),\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n\n        if (property) {\n            this.updateThematic(layerName, { collection: geojson, property  });\n        }\n    }\n\n    /**\n     * Creates a raster layer from a GeoTIFF-derived feature collection.\n     *\n     * @param layerName Target layer id.\n     * @param geotiff GeoTIFF-derived feature collection.\n     * @param property Feature-property path selecting the raster band array.\n     * @returns Nothing. The raster layer is created and initialized.\n     */\n    private createRasterLayer(layerName: string, geotiff: FeatureCollection<Geometry | null>, property: string) {\n        const layerInfo: LayerInfo = {\n            id: `${layerName}`,\n            zIndex: this._layerManager.computeZindex('raster'),\n            typeLayer: 'raster',\n        };\n\n        const layerRenderInfo: LayerRenderInfo = {\n            opacity: 1.0,\n            colormap: { config: this.defaultColorMap() },\n            isColorMap: false,\n            isPick: false,\n            isSkip: false,\n        };\n\n        const layerMesh = TriangulatorRaster.buildMesh(geotiff, this.layerManager.origin);\n        if (layerMesh[0].length === 0 || layerMesh[1].length === 0) {\n            console.error('Invalid Feature Layer.');\n            return;\n        }\n\n        const props = geotiff.features[0].properties;\n        if (!props) {\n            console.error('GeoTIFF properties are missing.');\n            return;\n        }\n\n        const layerData: LayerData = {\n            geometry: layerMesh[0],\n            components: layerMesh[1],\n            rasterResX: props.rasterResX,\n            rasterResY: props.rasterResY,\n        };\n\n        this.createLayer(layerInfo, layerRenderInfo, layerData);\n        this.updateRaster(layerName, { collection: geotiff, property  });\n    }\n\n    /**\n     * Creates a layer from the provided information.\n     *\n     * @param layerInfo Metadata describing the layer.\n     * @param layerRenderInfo Initial render configuration.\n     * @param layerData Triangulated geometry/components payload.\n     * @returns Nothing. The layer pipeline is created when layer registration succeeds.\n     */\n    private createLayer(layerInfo: LayerInfo, layerRenderInfo: LayerRenderInfo, layerData: LayerData) {\n        const layer = this._layerManager.addLayer(layerInfo, layerRenderInfo, layerData);\n        if (layer) {\n            layer.createPipeline(this._renderer);\n            // Every later data, render-state, highlight or skip change marks the layer dirty and requests a frame.\n            layer.setChangeListener(() => this.requestRender());\n            this.requestRender();\n        }\n    }\n\n    /**\n     * Returns the default color-map configuration used for newly created layers.\n     *\n     * @returns Default sequential red colormap with min/max numeric domain inference.\n     */\n    private defaultColorMap(): ColorMapConfig {\n        return {\n            interpolator: ColorMapInterpolator.SEQ_REDS,\n            domainSpec: { type: ColorMapDomainStrategy.MIN_MAX },\n        };\n    }\n}\n"],"ignoreList":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,98,107,108,109,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237],"mappings":"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"}