@welldot/render 0.1.0-next.20260509.039db95 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +90 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/configs/render.configs.ts","../src/utils/fgdcTextures.ts","../src/Renderer.ts","../src/configs/render.textures.ts","../src/utils/format.utils.ts","../src/configs/render.classnames.ts","../src/utils/render.utils.ts","../src/utils/d3.utils.ts","../src/utils/geometry.utils.ts","../src/utils/tooltips.utils.ts","../src/renderers/annotation-labels.renderer.ts","../src/renderers/caves.renderer.ts","../src/renderers/construction-labels.renderer.ts","../src/renderers/construction.renderer.ts","../src/renderers/fractures.renderer.ts","../src/renderers/highlights.renderer.ts","../src/renderers/legend.renderer.ts","../src/renderers/lithology.renderer.ts","../src/renderers/unit-labels.renderer.ts","../src/utils/render.styles.ts"],"sourcesContent":["import { easeCubic } from 'd3';\nimport { RenderConfig, WellTheme } from '~/types/render.types';\n\nexport const DEFAULT_WELL_THEME: WellTheme = {\n lithology: { stroke: '#101010', strokeWidth: 1 },\n lithologyTexture: { size: 150, strokeWidth: 0.8, stroke: '#303030' },\n cave: {\n dryStroke: '#333333',\n wetStroke: '#1a6fa8',\n fillOpacity: 0.6,\n contactStrokeWidth: 1.2,\n },\n fracture: {\n dryStroke: '#000000',\n wetStroke: '#1a6fa8',\n swarm: {\n centralStrokeWidth: 1.2,\n sideStrokeWidthBase: 0.6,\n sideStrokeWidthVariance: 0.6,\n },\n single: {\n mainStrokeWidth: 1.8,\n crackStrokeWidth: 0.7,\n },\n },\n cementPad: { stroke: '#303030', strokeWidth: 2 },\n boreHole: {\n fill: '#ffffff',\n stroke: '#191919',\n strokeDasharray: '4, 3',\n opacity: 0.7,\n strokeWidth: 1.2,\n },\n surfaceCase: { stroke: '#000000', strokeWidth: 4 },\n holeFill: { stroke: '#303030', strokeWidth: 2 },\n wellCase: { fill: '#ffffff', stroke: '#303030', strokeWidth: 2 },\n wellScreen: { stroke: '#303030', strokeWidth: 2 },\n conflict: { stroke: '#e52117', strokeWidth: 4 },\n unitLabels: {\n geologicFill: '#f0f0f0',\n aquiferFill: '#dff0ff',\n stroke: '#303030',\n strokeWidth: 0.4,\n fontSize: 5.5,\n fontFamily: 'sans-serif',\n fontWeight: 400,\n },\n constructionLabels: {\n fontSize: 7.5,\n labelFill: '#ffffff',\n labelColor: '#303030',\n fontFamily: 'sans-serif',\n fontWeight: 400,\n },\n labels: {\n dividerStroke: '#888888',\n dividerStrokeWidth: 0.5,\n dividerStrokeDasharray: '2, 2',\n fontSize: 7,\n color: '#333',\n headerFont: 'monospace',\n bodyColor: '#555',\n bodyFont: 'sans-serif',\n scaleFont: 'monospace',\n depthTipFill: '#ffffff',\n depthTipRadius: 2,\n annotationBg: '#ffffff',\n annotationBgOpacity: 0.85,\n annotationRadius: 2,\n headerFontWeight: 600,\n bodyFontWeight: 400,\n },\n legend: {\n borderStrokeWidth: 0.8,\n fractureStrokeWidth: 1.5,\n fractureSideStrokeWidth: 0.8,\n itemStrokeWidth: 0.8,\n fontSize: 7,\n fontFamily: 'sans-serif',\n titleFontWeight: 'bold',\n labelFontWeight: 400,\n },\n};\n\nconst DEFAULT_HIGHLIGHT_CONFIG = {\n stroke: '#e52117',\n strokeWidth: 2,\n fill: 'none',\n fillOpacity: 0,\n padding: 2,\n strokeDasharray: undefined,\n labelFontSize: 7,\n labelPadding: 3,\n labelBackground: '#e52117',\n labelColor: '#ffffff',\n labelRadius: 2,\n} as const;\n\nexport const STATIC_RENDER_CONFIG: RenderConfig = {\n zoom: true,\n pan: true,\n zoomLevel: 1,\n animation: { duration: 600, ease: easeCubic },\n geologic: { xLeft: 20, xRightInset: 300 },\n layout: {\n pocoWidthRatio: 0.21, // construction column occupies 21% of total SVG width\n pocoCenterRatio: -0.39, // construction center x-offset (negative = shift left of SVG centre)\n },\n caves: {\n pathSteps: 40,\n amplitude: {\n ratio: 0.12, // cave contact waviness: 12% of the cave band pixel height\n min: 1,\n max: 5.5,\n },\n },\n fractures: {\n widthMultiplier: 1.2,\n hitBuffer: { single: 8, swarm: 15 },\n swarm: {\n lineCountBase: 3,\n lineCountVariance: 11,\n spread: 18,\n },\n },\n construction: {\n cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n },\n labels: {\n active: true,\n typeLabels: { fracture: 'fratura', cave: 'caverna' },\n depthTipHeight: 11,\n depthTipPadX: 2,\n descriptionXOffset: 20,\n descriptionMaxWidth: 250,\n stackingLineHeight: 10,\n stackingGap: 0,\n fractureLabelLeaderGap: 5,\n lithology: true,\n },\n unitLabels: {\n active: true,\n xOffset: 2,\n stripWidth: 8,\n minHeightForText: 8,\n innerDividerWidth: 1.5,\n outerEdgeWidth: 0.6,\n },\n constructionLabels: {\n active: true,\n xOffset: -12,\n labelRadius: 2,\n labelMaxWidth: 90,\n labels: {\n wellCasePrefix: 'Revest.',\n wellScreenPrefix: 'Filtro',\n wellScreenSlotPrefix: 'Ranhura:',\n },\n },\n textures: {\n pad: { background: '#ffffff', stroke: '#303030' },\n conflict: { stroke: '#E52117' },\n cave_dry: { size: 8, stroke: '#333333', background: '#ffffff' },\n cave_wet: { size: 8, stroke: '#1a6fa8', background: '#ffffff' },\n seal: { background: '#ffffff' },\n gravel_pack: { background: '#ffffff' },\n well_screen: { size: 40, strokeWidth: 2, background: '#ffffff' },\n surface_case: {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n },\n },\n legend: {\n title: 'LEGENDA',\n itemWidth: 110,\n height: 44,\n padding: 4,\n maxWidth: 700,\n borderRadius: 3,\n labels: {\n fractureSingle: 'Fratura simples',\n fractureSwarm: 'Enxame de fraturas',\n fractureWater: \"Entrada d'água\",\n caveDry: 'Caverna seca',\n caveWet: 'Caverna c/ água',\n boreHole: 'Perfuração',\n surfaceCase: 'Tubo guia',\n holeFillGravel: 'Pré-filtro',\n holeFillSeal: 'Vedação',\n wellCase: 'Revestimento',\n wellScreen: 'Filtro',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n\nexport const INTERACTIVE_RENDER_CONFIG: RenderConfig = {\n zoom: true,\n pan: true,\n zoomLevel: 1,\n animation: { duration: 600, ease: easeCubic },\n geologic: { xLeft: 6, xRightInset: 56 },\n layout: {\n pocoWidthRatio: 0.25, // construction column occupies 25% of total SVG width\n pocoCenterRatio: 0.11, // construction center x-offset (positive = shift right of SVG centre)\n },\n caves: {\n pathSteps: 40,\n amplitude: {\n ratio: 0.12, // cave contact waviness: 12% of the cave band pixel height\n min: 1,\n max: 5.5,\n },\n },\n fractures: {\n widthMultiplier: 1.2,\n hitBuffer: { single: 8, swarm: 15 },\n swarm: {\n lineCountBase: 3,\n lineCountVariance: 11,\n spread: 18,\n },\n },\n construction: {\n cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n },\n labels: {\n active: false,\n typeLabels: { fracture: 'fratura', cave: 'caverna' },\n depthTipHeight: 11,\n depthTipPadX: 2,\n descriptionXOffset: 78,\n descriptionMaxWidth: 226,\n stackingLineHeight: 11,\n stackingGap: 0,\n },\n unitLabels: {\n active: false,\n xOffset: 0,\n stripWidth: 8,\n minHeightForText: 8,\n innerDividerWidth: 1.5,\n outerEdgeWidth: 0.6,\n },\n constructionLabels: {\n active: false,\n xOffset: 10,\n labelRadius: 2,\n labels: {\n wellCasePrefix: 'Revest.',\n wellScreenPrefix: 'Filtro',\n wellScreenSlotPrefix: 'Ranhura:',\n },\n },\n textures: {\n pad: { background: '#ffffff', stroke: '#303030' },\n conflict: { stroke: '#E52117' },\n cave_dry: { size: 8, stroke: '#333333', background: '#ffffff' },\n cave_wet: { size: 8, stroke: '#1a6fa8', background: '#ffffff' },\n seal: { background: '#ffffff' },\n gravel_pack: { background: '#ffffff' },\n well_screen: { size: 40, strokeWidth: 2, background: '#ffffff' },\n surface_case: {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n },\n },\n legend: {\n title: 'LEGENDA',\n itemWidth: 110,\n height: 44,\n padding: 4,\n maxWidth: 700,\n borderRadius: 3,\n labels: {\n fractureSingle: 'Fratura simples',\n fractureSwarm: 'Enxame de fraturas',\n fractureWater: \"Entrada d'água\",\n caveDry: 'Caverna seca',\n caveWet: 'Caverna c/ água',\n boreHole: 'Perfuração',\n surfaceCase: 'Tubo guia',\n holeFillGravel: 'Pré-filtro',\n holeFillSeal: 'Vedação',\n wellCase: 'Revestimento',\n wellScreen: 'Filtro',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n","import { TextureCode } from '@welldot/core';\n\n/**\n * Dynamically imports the FGDC texture registry (SVG path data keyed by texture code).\n * Useful for external UIs that need to display texture thumbnails in selection controls.\n */\nexport async function importFgdcTextures(): Promise<{\n [code: TextureCode]: string;\n}> {\n const fgdcTextures = await import('../data/fgdcTextures.json');\n return fgdcTextures.default as { [code: TextureCode]: string };\n}\n","// TODO use only the need parts of d3 instead of importing the whole library, which will reduce bundle size and improve performance\nimport * as d3module from 'd3';\n// eslint-disable-next-line import-x/default\nimport d3tip from 'd3-tip';\n\nimport { defu } from 'defu';\nimport {\n createWellTextures,\n type WellTextures,\n} from './configs/render.textures';\n\nconst d3 = Object.assign(d3module, { tip: d3tip });\n\nimport {\n isWellEmpty,\n type Constructive,\n type SurfaceCase,\n type Units,\n type Well,\n} from '@welldot/core';\nimport { getProfileLastItemsDepths } from '@welldot/utils';\nimport {\n ComponentsClassNames,\n DeepPartial,\n DrawContext,\n DrawGroups,\n Highlights,\n InstanceState,\n RenderConfig,\n SvgInstance,\n SvgSelection,\n WellTheme,\n} from '~/types/render.types';\nimport { getLengthUnit } from '~/utils/format.utils';\nimport { DEFAULT_COMPONENTS_CLASS_NAMES } from './configs/render.classnames';\nimport {\n DEFAULT_WELL_THEME,\n INTERACTIVE_RENDER_CONFIG,\n} from './configs/render.configs';\nimport { drawAnnotationLabels } from './renderers/annotation-labels.renderer';\nimport { drawCaves } from './renderers/caves.renderer';\nimport { drawConstructionLabels } from './renderers/construction-labels.renderer';\nimport { drawConstructive } from './renderers/construction.renderer';\nimport { drawFractures } from './renderers/fractures.renderer';\nimport { drawHighlights } from './renderers/highlights.renderer';\nimport { drawWellLegend } from './renderers/legend.renderer';\nimport { drawLithology } from './renderers/lithology.renderer';\nimport { drawUnitLabels } from './renderers/unit-labels.renderer';\nimport { asSvgElement } from './utils/d3.utils';\nimport { buildSvgStyleBlock } from './utils/render.styles';\nimport {\n filterByDepth,\n populateTooltips,\n preloadFgdcTextures,\n} from './utils/render.utils';\n\n/**\n * SVG-based renderer for geological well profiles.\n *\n * One instance manages one or more SVG panels (multi-panel layouts for long wells).\n * Call `prepareSvg()` once to initialise the DOM and preload textures, then call\n * `draw(profile)` whenever the profile data changes.\n *\n * @example\n * ```ts\n * const renderer = new WellRenderer(\n * [{ selector: '#well-svg', height: 600, width: 300, margins: { top: 20, right: 10, bottom: 20, left: 40 } }],\n * { renderConfig: INTERACTIVE_RENDER_CONFIG },\n * );\n * await renderer.prepareSvg();\n * renderer.draw(profile);\n * ```\n */\nexport class WellRenderer {\n private svgInstances: SvgInstance[] = [];\n private instanceStates: InstanceState[] = [];\n private textures: WellTextures = createWellTextures();\n private onError?: (err: Error) => void;\n\n classes = DEFAULT_COMPONENTS_CLASS_NAMES;\n private renderConfig: RenderConfig = INTERACTIVE_RENDER_CONFIG;\n private theme: WellTheme = DEFAULT_WELL_THEME;\n private units: Units = {\n length: 'm',\n diameter: 'mm',\n };\n\n /**\n * @param svgs - One entry per SVG panel; multi-entry for split-panel layouts.\n * @param options.classNames - Override default BEM CSS class names.\n * @param options.units - Active measurement units (`length` and `diameter`).\n * @param options.renderConfig - Rendering behaviour (zoom, pan, animation, layout). Defaults to `INTERACTIVE_RENDER_CONFIG`.\n * @param options.theme - Visual theme overrides. Merged on top of `DEFAULT_WELL_THEME`.\n * @param options.onError - Called when a draw error occurs (e.g., a renderer throws). Falls back to `console.error` if omitted.\n */\n constructor(\n svgs: SvgInstance[],\n options: {\n classNames?: DeepPartial<ComponentsClassNames>;\n units?: Units;\n renderConfig?: DeepPartial<RenderConfig>;\n theme?: DeepPartial<WellTheme>;\n onError?: (err: Error) => void;\n } = {},\n ) {\n if (svgs.length === 0) {\n console.warn(\n '[WellRenderer] No SVG instances provided. The renderer will be a no-op.',\n );\n return;\n }\n this.svgInstances = svgs;\n if (options.onError) this.onError = options.onError;\n\n if (options.classNames) {\n this.classes = defu(\n options.classNames,\n DEFAULT_COMPONENTS_CLASS_NAMES,\n ) as ComponentsClassNames;\n }\n\n if (options.units) {\n this.units = { ...this.units, ...options.units };\n }\n\n if (options.renderConfig) {\n this.renderConfig = defu(\n options.renderConfig,\n INTERACTIVE_RENDER_CONFIG,\n ) as RenderConfig;\n }\n\n this.theme = defu(options.theme ?? {}, DEFAULT_WELL_THEME) as WellTheme;\n\n this.textures = createWellTextures(this.renderConfig.textures);\n }\n\n private initInstanceSvg(inst: SvgInstance, index: number): InstanceState {\n const clipId = `fractures-clip-${index}`;\n const clipRectId = `fractures-clip-rect-${index}`;\n const { selector, height, width, margins } = inst;\n const svgWidth = width + margins.left + margins.right;\n const svgHeight = height + margins.top + margins.bottom;\n\n const svg = d3.select(selector) as SvgSelection;\n svg.selectAll('*').remove();\n\n svg.attr('height', svgHeight).attr('width', svgWidth);\n\n const defs = svg.append('defs');\n defs.append('style').text(buildSvgStyleBlock(this.theme));\n defs\n .append('clipPath')\n .attr('id', clipId)\n .append('rect')\n .attr('id', clipRectId)\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', 100000)\n .attr('height', 10000);\n\n const poco = svg.append('g').attr('class', this.classes.wellGroup);\n\n const geologic = poco\n .append('g')\n .attr('class', this.classes.geologicGroup)\n .attr('transform', `translate(${margins.left}, ${margins.top})`);\n\n geologic.append('g').attr('class', this.classes.yAxis);\n geologic.append('g').attr('class', this.classes.unitLabels.group);\n geologic.append('g').attr('class', this.classes.lithology.group);\n geologic.append('g').attr('class', this.classes.caves.group);\n geologic.append('g').attr('class', this.classes.labels.lithology.group);\n geologic.append('g').attr('class', this.classes.highlights.geologicGroup);\n\n const construction = poco\n .append('g')\n .attr('class', this.classes.constructionGroup)\n .attr(\n 'transform',\n `translate(${margins.left + width / 2}, ${margins.top})`,\n );\n\n const fracturesGroup = poco\n .append('g')\n .attr('class', this.classes.fractures.group)\n .attr('transform', `translate(${margins.left}, ${margins.top})`)\n .attr('clip-path', `url(#${clipId})`);\n\n fracturesGroup\n .append('g')\n .attr('class', this.classes.highlights.fracturesGroup);\n\n construction\n .append('g')\n .attr('class', this.classes.constructionLabels.group);\n construction.append('g').attr('class', this.classes.cementPad.group);\n construction.append('g').attr('class', this.classes.boreHole.group);\n construction.append('g').attr('class', this.classes.surfaceCase.group);\n construction.append('g').attr('class', this.classes.holeFill.group);\n construction.append('g').attr('class', this.classes.wellCase.group);\n construction.append('g').attr('class', this.classes.wellScreen.group);\n construction.append('g').attr('class', this.classes.conflict.group);\n construction\n .append('g')\n .attr('class', this.classes.highlights.constructionGroup);\n\n Object.values(this.textures).forEach(texture => svg.call(texture));\n\n return { svg, height, width, margins, clipId, clipRectId };\n }\n\n /** Renders a standalone legend into the element matched by `selector`. */\n public renderLegend(selector: string, profile: Well): void {\n drawWellLegend(selector, profile, {\n config: this.renderConfig.legend,\n theme: this.theme,\n classNames: this.classes.legend,\n textures: this.renderConfig.textures,\n });\n }\n\n /**\n * Initialises the SVG DOM structure and preloads FGDC textures.\n * Must be called once before the first `draw()`.\n */\n public async prepareSvg() {\n await preloadFgdcTextures();\n this.instanceStates = this.svgInstances.map((inst, i) =>\n this.initInstanceSvg(inst, i),\n );\n }\n\n /**\n * Renders the well profile into all configured SVG panels.\n * @param profile - The well data to render.\n * @param options.units - Override the instance-level measurement units for this render.\n * @param options.highlights - Highlight overlays to display on top of the profile.\n */\n draw(\n profile: Well,\n options: { units?: Units; highlights?: Highlights } = {},\n ) {\n if (isWellEmpty(profile)) return;\n this.units = { ...this.units, ...options.units };\n const highlights = options.highlights ?? {};\n\n const maxValues = getProfileLastItemsDepths(profile);\n const maxYValues = d3.max(maxValues) || 0;\n\n if (this.instanceStates.length === 1) {\n this.drawLogToInstance(\n this.instanceStates[0],\n profile,\n 0,\n maxYValues,\n highlights,\n );\n return;\n }\n\n const totalHeight =\n this.instanceStates.reduce((s, st) => s + st.height, 0) || 1;\n const yScaleGlobal = d3\n .scaleLinear()\n .domain([0, maxYValues])\n .range([0, totalHeight]);\n\n let currentDepth = 0;\n for (const state of this.instanceStates) {\n const maxSvgDepth = yScaleGlobal.invert(\n yScaleGlobal(currentDepth) + state.height,\n );\n this.drawLogToInstance(\n state,\n profile,\n currentDepth,\n maxSvgDepth,\n highlights,\n );\n currentDepth = maxSvgDepth;\n }\n }\n\n private drawLogToInstance(\n state: InstanceState,\n profile: Well,\n depthFrom: number,\n depthTo: number,\n highlights: Highlights = {},\n ) {\n const svg = state.svg;\n\n const pocoGroup = svg.select(`.${this.classes.wellGroup}`);\n const lithologyGroup = svg.select(`.${this.classes.lithology.group}`);\n const fracturesGroup = svg.select(`.${this.classes.fractures.group}`);\n const cavesGroup = svg.select(`.${this.classes.caves.group}`);\n const lithologyLabelsGroup = svg.select(\n `.${this.classes.labels.lithology.group}`,\n );\n const constructionGroup = svg.select(`.${this.classes.constructionGroup}`);\n const cementPadGroup = svg.select(`.${this.classes.cementPad.group}`);\n const holeGroup = svg.select(`.${this.classes.boreHole.group}`);\n const surfaceCaseGroup = svg.select(`.${this.classes.surfaceCase.group}`);\n const holeFillGroup = svg.select(`.${this.classes.holeFill.group}`);\n const wellCaseGroup = svg.select(`.${this.classes.wellCase.group}`);\n const wellScreenGroup = svg.select(`.${this.classes.wellScreen.group}`);\n const conflictGroup = svg.select(`.${this.classes.conflict.group}`);\n const constructionLabelsGroup = svg.select(\n `.${this.classes.constructionLabels.group}`,\n );\n const highlightsGeologicGroup = svg.select(\n `.${this.classes.highlights.geologicGroup}`,\n );\n const highlightsConstructionGroup = svg.select(\n `.${this.classes.highlights.constructionGroup}`,\n );\n const highlightsFracturesGroup = svg.select(\n `.${this.classes.highlights.fracturesGroup}`,\n );\n const unitLabelsGroup = svg.select(`.${this.classes.unitLabels.group}`);\n\n const svgWidth = state.width + state.margins.left + state.margins.right;\n const svgHeight = state.height + state.margins.top + state.margins.bottom;\n const { pocoWidthRatio, pocoCenterRatio } = this.renderConfig.layout;\n const POCO_WIDTH = svgWidth * pocoWidthRatio;\n const POCO_CENTER = svgWidth * pocoCenterRatio;\n\n const { duration, ease } = this.renderConfig.animation;\n const transition = d3.transition().duration(duration).ease(ease);\n\n const tooltips = populateTooltips(\n svg,\n this.classes,\n this.units,\n this.renderConfig.tooltips,\n );\n\n const { xLeft: geoXLeft, xRightInset: geoXRightInset } =\n this.renderConfig.geologic;\n const geoXRight = svgWidth - geoXRightInset;\n const pocoCenterX = state.width / 2 + POCO_CENTER / 2;\n\n const geologicData = {\n lithology: profile.lithology,\n fractures: profile.fractures,\n caves: profile.caves,\n };\n const constructionData = {\n cement_pad: profile.cement_pad,\n bore_hole: profile.bore_hole,\n hole_fill: profile.hole_fill,\n surface_case: profile.surface_case,\n well_case: profile.well_case,\n well_screen: profile.well_screen,\n reduction: profile.reduction,\n fractures: profile.fractures,\n } as Constructive;\n\n const contentHeight = svgHeight - state.margins.top - state.margins.bottom;\n\n const yScaleLocal = d3\n .scaleLinear()\n .domain([depthFrom, depthTo])\n .range([0, contentHeight]);\n\n const depthFactor = this.units.length === 'ft' ? 3.28084 : 1;\n const yScaleAxis = d3\n .scaleLinear()\n .domain([depthFrom * depthFactor, depthTo * depthFactor])\n .range([0, contentHeight]);\n\n const yAxis = d3\n .axisLeft(yScaleAxis)\n .tickFormat(\n (d: d3module.NumberValue) => `${d}${getLengthUnit(this.units.length)}`,\n );\n\n const gY = svg.select<SVGGElement>(`.${this.classes.yAxis}`).call(yAxis);\n\n gY.select('.domain')\n .attr('stroke', this.theme.labels.color)\n .attr('fill', 'none');\n gY.selectAll('.tick line').attr('stroke', this.theme.labels.color);\n gY.selectAll('.tick text')\n .attr('fill', this.theme.labels.color)\n .attr('stroke', 'none')\n .attr(\n 'font-size',\n this.theme.labels.scaleFontSize ?? this.theme.labels.fontSize,\n )\n .attr(\n 'font-family',\n this.theme.labels.scaleFont ??\n this.theme.labels.bodyFont ??\n 'sans-serif',\n );\n\n type SpanDatum = { from?: number; to?: number; thickness?: number };\n\n const spanY = (d: SpanDatum): number => {\n if (d.thickness) return yScaleLocal(0) - yScaleLocal(d.thickness);\n return yScaleLocal(Math.max(d.from ?? 0, depthFrom));\n };\n\n const spanH = (d: SpanDatum): number => {\n if (d.thickness) return yScaleLocal(d.thickness) - yScaleLocal(0);\n return Math.max(\n 0,\n yScaleLocal(Math.min(d.to ?? 0, depthTo)) -\n yScaleLocal(Math.max(d.from ?? 0, depthFrom)),\n );\n };\n\n const groups: DrawGroups = {\n lithologyGroup,\n unitLabelsGroup,\n cavesGroup,\n fracturesGroup,\n lithologyLabelsGroup,\n constructionGroup,\n constructionLabelsGroup,\n cementPadGroup,\n holeGroup,\n surfaceCaseGroup,\n holeFillGroup,\n wellCaseGroup,\n wellScreenGroup,\n conflictGroup,\n highlightsGeologicGroup,\n highlightsConstructionGroup,\n highlightsFracturesGroup,\n };\n\n const ctx: DrawContext = {\n svg,\n state,\n svgWidth,\n svgHeight,\n POCO_WIDTH,\n POCO_CENTER,\n pocoCenterX,\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale: yScaleLocal,\n transition,\n tooltips,\n renderConfig: this.renderConfig,\n theme: this.theme,\n classes: this.classes,\n textures: this.textures,\n units: this.units,\n constructionData,\n groups,\n };\n\n const inDepth = filterByDepth(depthFrom, depthTo);\n const filteredConstruction = {\n ...constructionData,\n bore_hole: constructionData.bore_hole.filter(inDepth),\n hole_fill: constructionData.hole_fill.filter(inDepth),\n surface_case: constructionData.surface_case.filter(inDepth),\n well_case: constructionData.well_case.filter(inDepth),\n well_screen: constructionData.well_screen.filter(inDepth),\n reduction: constructionData.reduction?.filter(inDepth) ?? [],\n };\n\n const zooming = (e: { transform: d3module.ZoomTransform }): void => {\n const transform = e.transform;\n const zoomedCtx: DrawContext = {\n ...ctx,\n yScale: transform.rescaleY(yScaleLocal),\n };\n\n gY.call(yAxis.scale(transform.rescaleY(yScaleAxis)));\n\n pocoGroup\n .selectAll('rect')\n .attr('y', (d: unknown) => {\n if (!d) return null;\n return transform.applyY(spanY(d as SpanDatum));\n })\n .attr('height', (d: unknown) => {\n if (!d) return null;\n return transform.k * spanH(d as SpanDatum);\n });\n\n // Surface case: update fill rect y/height and side line y1/y2\n surfaceCaseGroup\n .selectAll(`g.${this.classes.surfaceCase.rect}`)\n .each((d: unknown, i, nodes) => {\n if (!d) return;\n const sc = d as SurfaceCase;\n const g = d3.select(nodes[i] as Element);\n const y = transform.applyY(spanY(sc));\n const h = transform.k * spanH(sc);\n g.select('.surface-case-fill').attr('y', y).attr('height', h);\n g.selectAll('.surface-case-side')\n .attr('y1', y)\n .attr('y2', y + h);\n });\n\n // Fractures: recompute transform so rotation pivot tracks the scaled depth\n fracturesGroup\n .selectAll(`g.${this.classes.fractures.item}`)\n .attr('transform', (d: unknown) => {\n if (!d) return null;\n const f = d as { depth: number; dip: number };\n const cx = pocoCenterX;\n const cy = transform.applyY(yScaleLocal(f.depth));\n return `translate(0,${cy}) rotate(${f.dip},${cx},0)`;\n });\n\n // Delegated redraws — unconditional, each renderer self-guards:\n drawCaves(zoomedCtx, geologicData.caves?.filter(inDepth) ?? []);\n drawUnitLabels(zoomedCtx, profile.lithology?.filter(inDepth) ?? []);\n drawAnnotationLabels(zoomedCtx, {\n lithology: profile.lithology?.filter(inDepth) ?? [],\n fractures:\n profile.fractures?.filter(\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n caves: profile.caves?.filter(inDepth) ?? [],\n });\n drawConstructionLabels(zoomedCtx, {\n well_case: constructionData.well_case.filter(inDepth),\n well_screen: constructionData.well_screen.filter(inDepth),\n });\n drawHighlights(zoomedCtx, highlights);\n };\n\n const drawProfile = () => {\n drawLithology(ctx, profile.lithology?.filter(inDepth) ?? []);\n drawUnitLabels(ctx, profile.lithology?.filter(inDepth) ?? []);\n drawAnnotationLabels(ctx, {\n lithology: profile.lithology?.filter(inDepth) ?? [],\n fractures:\n profile.fractures?.filter(\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n caves: profile.caves?.filter(inDepth) ?? [],\n });\n drawCaves(ctx, profile.caves?.filter(inDepth) ?? []);\n drawFractures(\n ctx,\n profile.fractures?.filter(\n // exclusive upper bound: depthTo is the start of the next panel\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n );\n drawConstructive(ctx, filteredConstruction);\n drawConstructionLabels(ctx, {\n well_case: filteredConstruction.well_case,\n well_screen: filteredConstruction.well_screen,\n });\n svg.select(`#${state.clipRectId}`).attr('y', 0).attr('height', svgHeight);\n drawHighlights(ctx, highlights);\n };\n\n try {\n drawProfile();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (this.onError) {\n this.onError(error);\n } else {\n console.error('[WellRenderer] drawProfile failed:', error);\n }\n }\n\n const { zoom: zoomEnabled, pan: panEnabled } = this.renderConfig;\n if (zoomEnabled || panEnabled) {\n const zoomNode = d3.zoom<SVGSVGElement, unknown>();\n if (zoomEnabled || panEnabled) zoomNode.on('zoom', zooming);\n if (!zoomEnabled) zoomNode.scaleExtent([1, 1]);\n if (!panEnabled)\n zoomNode.filter(e => e.type === 'wheel' || e.type === 'dblclick');\n asSvgElement<SVGSVGElement>(svg).call(zoomNode);\n\n const initialZoom = this.renderConfig.zoomLevel ?? 1;\n if (initialZoom !== 1) {\n asSvgElement<SVGSVGElement>(svg).call(\n zoomNode.transform,\n d3.zoomIdentity.scale(initialZoom),\n );\n }\n }\n }\n}\n\nexport default {\n WellRenderer,\n};\n","import textures from 'textures';\n\n// ── Per-texture config types ──────────────────────────────────────────────────\n\nexport type PadTextureConfig = {\n background: string;\n stroke: string;\n};\n\nexport type ConflictTextureConfig = {\n stroke: string;\n};\n\nexport type CaveDryTextureConfig = {\n size: number;\n stroke: string;\n background: string;\n};\n\nexport type CaveWetTextureConfig = {\n size: number;\n stroke: string;\n background: string;\n};\n\nexport type SealTextureConfig = {\n background: string;\n};\n\nexport type GravelPackTextureConfig = {\n size: number;\n background: string;\n};\n\nexport type WellScreenTextureConfig = {\n size: number;\n strokeWidth: number;\n background: string;\n};\n\nexport type SurfaceCaseTextureConfig = {\n orientation: string[];\n size: number;\n strokeWidth: number;\n shapeRendering: string;\n stroke: string;\n background: string;\n};\n\n// ── Aggregate ─────────────────────────────────────────────────────────────────\n\nexport type TexturesConfig = {\n pad?: Partial<PadTextureConfig>;\n conflict?: Partial<ConflictTextureConfig>;\n cave_dry?: Partial<CaveDryTextureConfig>;\n cave_wet?: Partial<CaveWetTextureConfig>;\n seal?: Partial<SealTextureConfig>;\n gravel_pack?: Partial<GravelPackTextureConfig>;\n well_screen?: Partial<WellScreenTextureConfig>;\n surface_case?: Partial<SurfaceCaseTextureConfig>;\n};\n\nexport type WellTextures = {\n pad: ReturnType<typeof textures.lines>;\n conflict: ReturnType<typeof textures.lines>;\n cave_dry: ReturnType<typeof textures.lines>;\n cave_wet: ReturnType<typeof textures.lines>;\n seal: ReturnType<typeof textures.lines>;\n gravel_pack: ReturnType<typeof textures.circles>;\n well_screen: ReturnType<typeof textures.paths>;\n surface_case: ReturnType<typeof textures.lines>;\n};\n\nexport function createWellTextures(cfg?: TexturesConfig): WellTextures {\n const pad: PadTextureConfig = {\n background: '#ffffff',\n stroke: '#303030',\n ...cfg?.pad,\n };\n\n const conflict: ConflictTextureConfig = {\n stroke: '#E52117',\n ...cfg?.conflict,\n };\n\n const cave_dry: CaveDryTextureConfig = {\n size: 8,\n stroke: '#333333',\n background: '#ffffff',\n ...cfg?.cave_dry,\n };\n\n const cave_wet: CaveWetTextureConfig = {\n size: 8,\n stroke: '#1a6fa8',\n background: '#ffffff',\n ...cfg?.cave_wet,\n };\n\n const seal: SealTextureConfig = {\n background: '#ffffff',\n ...cfg?.seal,\n };\n\n const gravel_pack: GravelPackTextureConfig = {\n size: 16,\n background: '#ffffff',\n ...cfg?.gravel_pack,\n };\n\n const well_screen: WellScreenTextureConfig = {\n size: 40,\n strokeWidth: 2,\n background: '#ffffff',\n ...cfg?.well_screen,\n };\n\n const surface_case: SurfaceCaseTextureConfig = {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n ...cfg?.surface_case,\n } as SurfaceCaseTextureConfig;\n\n return {\n pad: textures\n .lines()\n .heavier(10)\n .thinner(1.5)\n .stroke(pad.stroke)\n .background(pad.background),\n conflict: textures.lines().heavier().stroke(conflict.stroke),\n cave_dry: textures\n .lines()\n .size(cave_dry.size)\n .orientation('6/8')\n .heavier(0.3)\n .thinner(0.8)\n .background(cave_dry.background)\n .stroke(cave_dry.stroke),\n cave_wet: textures\n .lines()\n .size(cave_wet.size)\n .orientation('6/8')\n .heavier(0.3)\n .thinner(0.8)\n .background(cave_wet.background)\n .stroke(cave_wet.stroke),\n seal: textures.lines().thicker().background(seal.background),\n gravel_pack: textures\n .circles()\n .size(gravel_pack.size)\n .complement()\n .background(gravel_pack.background),\n well_screen: textures\n .paths()\n .d(s => `M ${s / 4} ${s / 4} l ${s / 2} 0 `)\n .size(well_screen.size)\n .strokeWidth(well_screen.strokeWidth)\n .thicker(2)\n .background(well_screen.background),\n surface_case: (textures.lines() as any)\n .orientation(...surface_case.orientation)\n .size(surface_case.size)\n .strokeWidth(surface_case.strokeWidth)\n .shapeRendering(surface_case.shapeRendering)\n .stroke(surface_case.stroke)\n .background(surface_case.background) as ReturnType<typeof textures.lines>,\n };\n}\n","import type { DiameterUnits, LengthUnits } from '@welldot/core';\n\nconst MM_TO_INCHES = 0.0393701;\nconst M_TO_FT = 3.28084;\n\n/** Formats a depth value in metres to the active length unit string. */\nexport function formatLength(m: number, units: LengthUnits): string {\n return units === 'ft' ? (m * M_TO_FT).toFixed(1) : String(m);\n}\n\n/** Formats a diameter value in millimetres to the active diameter unit string. */\nexport function formatDiameter(mm: number, units: DiameterUnits): string {\n return units === 'inches' ? (mm * MM_TO_INCHES).toFixed(2) : String(mm);\n}\n\n/** Returns the display label for the active length unit (e.g. `\"m\"` or `\"ft\"`). */\nexport function getLengthUnit(units: LengthUnits): string {\n return units === 'ft' ? 'ft' : 'm';\n}\n\n/** Returns the display label for the active diameter unit (e.g. `\"mm\"` or `'\"'`). */\nexport function getDiameterUnit(units: DiameterUnits): string {\n return units === 'inches' ? '\"' : 'mm';\n}\n","import { ComponentsClassNames } from '~/types/render.types';\n\nexport const DEFAULT_COMPONENTS_CLASS_NAMES: ComponentsClassNames = {\n tooltip: {\n root: 'wp-tooltip',\n title: 'wp-tooltip-title',\n primaryInfo: 'wp-tooltip-primary',\n secondaryInfo: 'wp-tooltip-secondary',\n },\n yAxis: 'wp-y-axis',\n wellGroup: 'wp-well-group',\n geologicGroup: 'wp-geologic-group',\n lithology: {\n group: 'lithology-group',\n rect: 'lithology-rect',\n },\n fractures: {\n group: 'fractures-group',\n item: 'fracture-group',\n hitArea: 'fracture-hit',\n line: 'fracture-line',\n polyline: 'fracture-poly',\n },\n caves: {\n group: 'caves-group',\n item: 'cave-group',\n fill: 'cave-fill',\n contact: 'cave-contact',\n },\n constructionGroup: 'construction-group',\n constructionLabels: {\n group: 'construction-labels-group',\n },\n cementPad: {\n group: 'cement-pad',\n item: 'cement-pad-rect',\n },\n boreHole: {\n group: 'hole',\n rect: 'bore-hole-rect',\n },\n surfaceCase: {\n group: 'surface-case',\n rect: 'surface-case-rect',\n },\n holeFill: {\n group: 'hole-fill',\n rect: 'hole-fill-rect',\n },\n wellCase: {\n group: 'well-case',\n rect: 'well-case-rect',\n },\n wellScreen: {\n group: 'well-screen',\n rect: 'well-screen-rect',\n },\n conflict: {\n group: 'conflict',\n rect: 'conflict-rect',\n },\n unitLabels: {\n group: 'unit-labels-group',\n geoRect: 'unit-geo-rect',\n aqRect: 'unit-aq-rect',\n text: 'unit-label-text',\n },\n labels: {\n lithology: {\n group: 'lithology-labels-group',\n depth: 'lithology-depth-tip',\n label: 'lithology-label',\n divider: 'lithology-label-divider',\n },\n },\n legend: {\n border: 'wp-legend-border',\n title: 'wp-legend-title',\n item: 'wp-legend-item',\n label: 'wp-legend-label',\n fracturePoly: 'fracture-poly',\n caveFill: 'cave-fill',\n constructionRect: 'construction-rect',\n },\n highlights: {\n geologicGroup: 'wp-highlights-geologic',\n constructionGroup: 'wp-highlights-construction',\n fracturesGroup: 'wp-highlights-fractures',\n item: 'wp-highlight-item',\n rect: 'wp-highlight-rect',\n label: 'wp-highlight-label',\n labelBg: 'wp-highlight-label-bg',\n },\n};\n","import textures from 'textures';\n\nimport { Lithology } from '@welldot/core';\nimport { Conflict, SvgSelection } from '~/types/render.types';\nimport { importFgdcTextures } from '~/utils/fgdcTextures';\n\n// Re-exports so consumers and tests can still import from this single barrel.\nexport { filterByDepth, getYAxisFunctions } from './d3.utils';\nexport { makeSeededPrng, ptsToSmoothPath, wavyContact } from './geometry.utils';\nexport { populateTooltips } from './tooltips.utils';\n\nlet _fgdcTextures: Record<string, string> = {};\nlet _fgdcTexturesPromise: Promise<void> | null = null;\n\nexport const preloadFgdcTextures = (): Promise<void> => {\n if (!_fgdcTexturesPromise) {\n _fgdcTexturesPromise = importFgdcTextures().then(t => {\n _fgdcTextures = t;\n });\n }\n return _fgdcTexturesPromise;\n};\n\nexport type LithologyTextureOptions = {\n size: number;\n strokeWidth: number;\n stroke: string;\n};\n\n/** Returns a map from \"texture.from\" keys to textures.js fill objects for each lithology entry. */\nexport const getLithologicalFillList = (\n data: Lithology[],\n opts: LithologyTextureOptions,\n) => {\n const uniqueTextureCodes = [...new Set(data.map(d => d.fgdc_texture))];\n const texturesLoaded = Object.fromEntries(\n uniqueTextureCodes\n .filter(code => _fgdcTextures[code])\n .map(code => [code, _fgdcTextures[code]]),\n );\n\n return Object.fromEntries(\n data.map(d => [\n `${d.fgdc_texture}.${d.from}`,\n textures\n .paths()\n .d(() => texturesLoaded[d.fgdc_texture])\n .size(opts.size)\n .strokeWidth(opts.strokeWidth)\n .stroke(opts.stroke)\n .background(d.color),\n ]),\n );\n};\n\n/** Returns a fill-value function for a lithology datum, registering texture patterns on the SVG as needed. */\nexport const getLithologyFill = (\n geologyData: Lithology[],\n svg: SvgSelection,\n opts: LithologyTextureOptions,\n) => {\n const lithologicalFill = getLithologicalFillList(geologyData, opts);\n return (d: Lithology) => {\n const fill = lithologicalFill[`${d.fgdc_texture}.${d.from}`];\n if (!fill.url) return fill;\n svg.call(fill as unknown as (selection: SvgSelection) => void);\n return fill.url();\n };\n};\n\n/** Returns all overlapping depth intervals between two arrays of depth-ranged items, carrying the max diameter of each pair. */\nexport const getConflictAreas = (\n array1: Conflict[],\n array2: Conflict[],\n): Conflict[] =>\n array1.flatMap(item1 =>\n array2\n .filter(item2 => item2.from < item1.to && item2.to > item1.from)\n .map(item2 => ({\n from: Math.max(item2.from, item1.from),\n to: Math.min(item2.to, item1.to),\n diameter: Math.max(item1.diameter, item2.diameter),\n })),\n );\n\n/** Merges overlapping or near-adjacent conflict segments (within `buffer` units) into single spans. */\nexport const mergeConflicts = (\n conflicts: Conflict[],\n buffer: number,\n): Conflict[] => {\n if (conflicts.length === 0) return [];\n\n return [...conflicts]\n .sort((a, b) => a.from - b.from)\n .reduce<Conflict[]>((merged, current) => {\n const last = merged[merged.length - 1];\n if (last && current.from <= last.to + buffer) {\n last.to = Math.max(last.to, current.to);\n return merged;\n }\n merged.push({ ...current });\n return merged;\n }, []);\n};\n\n/**\n * Breaks `text` into lines of at most `maxChars` characters on word boundaries.\n * Always returns at least one element.\n */\nexport function wrapText(text: string, maxChars: number): string[] {\n const words = text.split(' ');\n const lines: string[] = [];\n let line = '';\n for (const word of words) {\n const candidate = line ? `${line} ${word}` : word;\n if (candidate.length > maxChars && line) {\n lines.push(line);\n line = word;\n } else {\n line = candidate;\n }\n }\n if (line) lines.push(line);\n return lines.length ? lines : [''];\n}\n","import type { BaseType, Selection, Transition } from 'd3';\n\nimport type { SvgSelection } from '~/types/render.types';\n\n/**\n * Type-safe wrapper for D3's enter+merge pattern.\n * D3's native `.merge()` widens the element type to `GElement | GElement2`;\n * this helper casts the update selection to match the enter element type\n * so the merged result preserves the concrete element type for subsequent `.attr()` and `.transition()` calls.\n */\nexport function mergeEnter<GEl extends Element, Datum>(\n enter: Selection<GEl, Datum, BaseType, unknown>,\n update: Selection<BaseType, Datum, BaseType, unknown>,\n): Selection<GEl, Datum, BaseType, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (enter as any).merge(update) as Selection<\n GEl,\n Datum,\n BaseType,\n unknown\n >;\n}\n\n/**\n * Type-safe wrapper for applying a shared `Transition` to a typed `Selection`.\n * D3's `Selection.transition(t)` requires the transition's element type to extend\n * the selection's element type; since `DrawContext.transition` uses the broad `BaseType`,\n * a direct call fails the TypeScript check. This helper contains the single cast.\n */\nexport function withTransition<GEl extends Element, Datum>(\n selection: Selection<GEl, Datum, BaseType, unknown>,\n transition: Transition<BaseType, unknown, null, undefined>,\n): Transition<GEl, Datum, BaseType, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (selection as any).transition(transition) as Transition<\n GEl,\n Datum,\n BaseType,\n unknown\n >;\n}\n\n/**\n * Casts a loose `SvgSelection` to a typed SVG element selection.\n * Used when calling D3 behaviors (zoom, axis) that require a concrete element type.\n */\nexport function asSvgElement<GEl extends SVGElement>(\n sel: SvgSelection,\n): Selection<GEl, unknown, HTMLElement, unknown> {\n return sel as unknown as Selection<GEl, unknown, HTMLElement, unknown>;\n}\n\n/** Returns clamped `getHeight` and `getYPos` helpers bound to a D3 scale and optional depth clamp range. */\nexport const getYAxisFunctions = (\n yScale: (value: number) => number,\n clamp?: { from: number; to: number },\n) => {\n const clampFrom = clamp?.from ?? -Infinity;\n const clampTo = clamp?.to ?? Infinity;\n return {\n getHeight: ({ from, to }: { from: number; to: number }) =>\n Math.max(\n 0,\n yScale(Math.min(to, clampTo)) - yScale(Math.max(from, clampFrom)),\n ),\n getYPos: ({ from }: { from: number }) => yScale(Math.max(from, clampFrom)),\n };\n};\n\n/** Returns a predicate that tests whether an interval overlaps the window [depthFrom, depthTo]. */\nexport function filterByDepth(\n depthFrom: number,\n depthTo: number,\n): (l: { from: number; to: number }) => boolean {\n return l => !(l.to <= depthFrom || l.from >= depthTo);\n}\n","/**\n * Builds a wavy horizontal contact line as an array of [x, y] points using a\n * damped random walk, giving a natural geological contact appearance.\n * The 0.75 damping factor ensures the offset returns toward zero rather than\n * drifting unboundedly across the width.\n */\nexport const wavyContact = (\n xLeft: number,\n xRight: number,\n baseY: number,\n amp: number,\n steps: number,\n rng: () => number,\n): [number, number][] => {\n const pts: [number, number][] = [];\n let offset = 0;\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const x = xLeft + t * (xRight - xLeft);\n offset += (rng() - 0.5) * amp * 0.6;\n offset *= 0.75;\n pts.push([x, baseY + offset]);\n }\n return pts;\n};\n\n/**\n * Converts an array of [x, y] points into a smooth SVG cubic-Bézier path string using Catmull-Rom tension (0.35).\n * @param options.omitMoveTo - When true, omits the leading `M x,y` command so the path can be\n * appended directly to an existing path string without repositioning the pen.\n */\nexport const ptsToSmoothPath = (\n pts: [number, number][],\n options: { omitMoveTo?: boolean } = {},\n): string => {\n if (pts.length < 2) return '';\n const n = pts.length;\n const tension = 0.35;\n const segments: string[] = [];\n for (let i = 0; i < n - 1; i++) {\n const p0 = pts[Math.max(0, i - 1)];\n const p1 = pts[i];\n const p2 = pts[i + 1];\n const p3 = pts[Math.min(n - 1, i + 2)];\n const cp1x = p1[0] + (p2[0] - p0[0]) * tension;\n const cp1y = p1[1] + (p2[1] - p0[1]) * tension;\n const cp2x = p2[0] - (p3[0] - p1[0]) * tension;\n const cp2y = p2[1] - (p3[1] - p1[1]) * tension;\n segments.push(\n `C ${cp1x.toFixed(1)},${cp1y.toFixed(1)} ${cp2x.toFixed(1)},${cp2y.toFixed(1)} ${p2[0].toFixed(1)},${p2[1].toFixed(1)}`,\n );\n }\n const body = segments.join(' ');\n return options.omitMoveTo\n ? body\n : `M ${pts[0][0].toFixed(1)},${pts[0][1].toFixed(1)} ${body}`;\n};\n\n/**\n * Seeded Park-Miller LCG PRNG — deterministic so every zoom/redraw produces identical shapes.\n * @param seed - Initial seed value (typically a domain coordinate like depth or cave boundary).\n * @param scramble - Multiplier applied to the seed before entering the LCG cycle.\n * Different values produce visually distinct random distributions for different domains.\n * Default 6271 is used for caves; pass 7919 for fractures.\n */\nexport const makeSeededPrng = (seed: number, scramble = 6271) => {\n let s = Math.abs(seed * scramble) | 1;\n return () => {\n s = (s * 16807) % 2147483647;\n return (s - 1) / 2147483646;\n };\n};\n","// TODO remove this dependency on d3-tip by implementing our own tooltip logic using plain divs and mouse events, which will also allow us to support touch devices\nimport * as d3module from 'd3';\n// eslint-disable-next-line import-x/default\nimport d3tip from 'd3-tip';\nimport sanitizeHtml from 'sanitize-html';\n\nimport type {\n BoreHole,\n Cave,\n CementPad,\n Fracture,\n HoleFill,\n Lithology,\n SurfaceCase,\n Units,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport type {\n ComponentsClassNames,\n SvgSelection,\n TooltipKey,\n} from '~/types/render.types';\nimport { formatDiameter, formatLength } from '~/utils/format.utils';\n\nconst d3 = Object.assign(d3module, { tip: d3tip });\n\ninterface D3Tip {\n attr(name: string, value: string): D3Tip;\n direction(dir: string): D3Tip;\n html(fn: (event: unknown, d: unknown) => string): D3Tip;\n show(...args: unknown[]): void;\n hide(...args: unknown[]): void;\n}\n\n/** Strips all HTML tags from a value before inserting it into tooltip markup. */\nconst esc = (v: unknown): string =>\n sanitizeHtml(String(v ?? ''), { allowedTags: [], allowedAttributes: {} });\n\n/** Initialises d3-tip tooltip instances for each well component, respecting the `tooltipConfig` allow-list. Skips re-initialisation if the SVG was already set up. */\nexport const populateTooltips = (\n svg: SvgSelection,\n customClasses: ComponentsClassNames,\n units: Units,\n tooltipConfig?: TooltipKey[] | false,\n) => {\n type WithNode = { node?: () => Element | null };\n const svgEl =\n typeof (svg as WithNode).node === 'function'\n ? (svg as { node: () => Element | null }).node()\n : null;\n if (svgEl?.getAttribute('data-tooltips-init') === 'true') {\n return {} as Record<\n string,\n { show: (...a: unknown[]) => void; hide: (...a: unknown[]) => void }\n >;\n }\n\n const tipsText = {\n geology: (_: unknown, d: Lithology) => `\n <span class=\"${customClasses.tooltip.title}\">Litologia</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>\n ${d.geologic_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Unidade geológica:</strong> ${esc(d.geologic_unit)}</span>` : ''}\n ${d.aquifer_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Unidade aquífera:</strong> ${esc(d.aquifer_unit)}</span>` : ''}\n `,\n hole: (_: unknown, d: BoreHole) => `\n <span class=\"${customClasses.tooltip.title}\">FURO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n `,\n surfaceCase: (_: unknown, d: SurfaceCase) => `\n <span class=\"${customClasses.tooltip.title}\">TUBO DE BOCA</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n `,\n holeFill: (_: unknown, d: HoleFill) => `\n <span class=\"${customClasses.tooltip.title}\">ESP. ANULAR</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Descrição:</strong> ${esc(d.description)}\n </span>\n `,\n wellCase: (_: unknown, d: WellCase) => `\n <span class=\"${customClasses.tooltip.title}\">REVESTIMENTO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Diâmetro:</strong> ${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Tipo:</strong> ${esc(d.type)}</span>\n `,\n wellScreen: (_: unknown, d: WellScreen) => `\n <span class=\"${customClasses.tooltip.title}\">FILTROS</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Diâmetro:</strong> ${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Tipo:</strong> ${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Ranhura:</strong> ${esc(d.screen_slot_mm)} mm\n </span>\n `,\n conflict: (_: unknown, d: { from: number; to: number }) => `\n <span class=\"${customClasses.tooltip.title}\">CONFLITO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n `,\n fracture: (_: unknown, d: Fracture) => {\n const title = d.swarm ? 'ENXAME DE FRATURAS' : 'FRATURA';\n return `\n <span class=\"${customClasses.tooltip.title}\">${title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\"><strong>Profundidade:</strong> ${esc(formatLength(d.depth, units.length))} ${esc(units.length)}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Entrada d'água:</strong> ${esc(formatLength(d.depth, units.length))} ${esc(units.length)}</span>` : ''}\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Mergulho:</strong> ${esc(d.dip)}°</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Azimute:</strong> ${esc(d.azimuth)}°</span>\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>` : ''}\n `;\n },\n cementPad: (_: unknown, d: CementPad) => `\n <span class=\"${customClasses.tooltip.title}\">LAJE DE PROTEÇÃO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Espessura:</strong>\n ${esc(formatLength(d.thickness, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Largura:</strong> ${esc(formatLength(d.width, units.length))} ${esc(units.length)}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Comprimento:</strong> ${esc(formatLength(d.length, units.length))} ${esc(units.length)}\n </span>\n `,\n cave: (_: unknown, d: Cave) => `\n <span class=\"${customClasses.tooltip.title}\">CAVERNA</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Entrada d'água</strong></span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>` : ''}\n `,\n };\n\n const noop = { show: () => {}, hide: () => {} };\n const tooltips: Record<string, D3Tip | typeof noop> = {};\n\n Object.getOwnPropertyNames(tipsText).forEach(tipTextKey => {\n const enabled =\n tooltipConfig === undefined\n ? true\n : tooltipConfig !== false &&\n (tooltipConfig as string[]).includes(tipTextKey);\n\n if (!enabled) {\n tooltips[tipTextKey] = noop;\n return;\n }\n\n tooltips[tipTextKey] = (d3 as unknown as { tip: () => D3Tip })\n .tip()\n .attr('class', customClasses.tooltip.root)\n .direction('e')\n .html(tipsText[tipTextKey]);\n\n svg.call(\n tooltips[tipTextKey] as unknown as (selection: SvgSelection) => void,\n );\n });\n\n svgEl?.setAttribute('data-tooltips-init', 'true');\n\n return tooltips;\n};\n","import type { AnnotationData, DrawContext } from '~/types/render.types';\nimport { wrapText } from '~/utils/render.utils';\n\ntype AnnotationItem = {\n sortDepth: number;\n baseY: number;\n originX: number;\n originY: number;\n header: string;\n description: string;\n};\n\nfunction activeLabelsSet(\n cfg: boolean | ('lithology' | 'fractures' | 'caves')[],\n): Set<string> {\n if (cfg === false) return new Set<string>();\n if (cfg === true) return new Set(['lithology', 'fractures', 'caves']);\n return new Set(cfg as string[]);\n}\n\nfunction lithologySubSet(\n cfg: boolean | ('depth' | 'description' | 'dividers')[] | undefined,\n): Set<string> {\n if (cfg === false) return new Set<string>();\n if (!cfg || cfg === true)\n return new Set(['depth', 'description', 'dividers']);\n return new Set(cfg as string[]);\n}\n\n/**\n * Renders stacked annotation boxes for lithology/fractures/caves.\n * Items are sorted by depth with overlap-prevention.\n * Returns early if labels are disabled.\n */\nexport function drawAnnotationLabels(\n ctx: DrawContext,\n data: AnnotationData,\n): void {\n if (ctx.renderConfig.labels.active === false) return;\n\n const active = activeLabelsSet(ctx.renderConfig.labels.active);\n const show = lithologySubSet(ctx.renderConfig.labels.lithology);\n const s = ctx.renderConfig.labels;\n const st = ctx.theme.labels;\n\n ctx.groups.lithologyLabelsGroup.selectAll('*').remove();\n\n // ── Depth tips ────────────────────────────────────────────────────────\n if (active.has('lithology') && show.has('depth')) {\n data.lithology\n .filter(d => d.to <= ctx.depthTo)\n .forEach(d => {\n const text = `${d.to}`;\n const approxW = text.length * (st.fontSize * 0.52) + s.depthTipPadX * 2;\n const y = ctx.yScale(d.to) - s.depthTipHeight / 2;\n\n const tipG = ctx.groups.lithologyLabelsGroup\n .append('g')\n .attr('class', ctx.classes.labels.lithology.depth);\n\n tipG\n .append('rect')\n .attr('x', ctx.geoXLeft + 1)\n .attr('y', y)\n .attr('width', approxW)\n .attr('height', s.depthTipHeight)\n .attr('rx', st.depthTipRadius ?? 2)\n .attr('fill', st.depthTipFill ?? 'white')\n .attr('stroke', ctx.theme.lithology.stroke)\n .attr('stroke-width', 0.5);\n\n tipG\n .append('text')\n .attr('class', 'wp-depth-tip-text')\n .attr('fill', ctx.theme.labels.color)\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', ctx.geoXLeft + 1 + s.depthTipPadX)\n .attr('y', y + s.depthTipHeight / 2)\n .attr('dominant-baseline', 'middle')\n .attr('font-size', st.fontSize)\n .text(text);\n });\n }\n\n // ── Build unified annotation items ────────────────────────────────────\n const items: AnnotationItem[] = [];\n\n if (active.has('lithology')) {\n data.lithology\n .filter(d => d.from < ctx.depthTo)\n .forEach(d => {\n items.push({\n sortDepth: d.from,\n baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n originX: ctx.geoXRight,\n originY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n header: `${d.from}–${d.to} m`,\n description: d.description || '',\n });\n });\n }\n\n if (active.has('fractures')) {\n data.fractures\n .filter(d => d.depth >= ctx.depthFrom && d.depth < ctx.depthTo)\n .forEach(d => {\n const typeLabel = d.water_intake ? 'fratura aberta' : 'fratura';\n items.push({\n sortDepth: d.depth,\n baseY: ctx.yScale(d.depth),\n originX: ctx.pocoCenterX,\n originY: ctx.yScale(d.depth),\n header: `${d.depth} m · ${typeLabel}`,\n description: d.description || '',\n });\n });\n }\n\n if (active.has('caves')) {\n data.caves\n .filter(d => d.from < ctx.depthTo)\n .forEach(d => {\n const midDepth = (d.from + d.to) / 2;\n const typeLabel = d.water_intake ? 'caverna úmida' : 'caverna';\n items.push({\n sortDepth: d.from,\n baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n originX: ctx.geoXRight,\n originY: ctx.yScale(Math.max(midDepth, ctx.depthFrom)),\n header: `${d.from}–${d.to} m · ${typeLabel}`,\n description: d.description || '',\n });\n });\n }\n\n items.sort((a, b) => a.sortDepth - b.sortDepth);\n\n // ── Stacking pass ─────────────────────────────────────────────────────\n type LabelPos = { item: AnnotationItem; yLabel: number; estH: number };\n const labelPositions: LabelPos[] = [];\n let currY = 0;\n const charsPerLine = Math.max(\n 1,\n Math.floor(s.descriptionMaxWidth / (st.fontSize * 0.6)),\n );\n\n items.forEach(item => {\n const descLines = Math.ceil((item.description.length || 1) / charsPerLine);\n const estH = (1 + descLines) * s.stackingLineHeight + 4;\n const yLabel = Math.max(item.baseY, currY + s.stackingGap);\n currY = yLabel + estH;\n labelPositions.push({ item, yLabel, estH });\n });\n\n const labelX = ctx.geoXRight + s.descriptionXOffset;\n\n // ── Dividers ──────────────────────────────────────────────────────────\n if (show.has('dividers') && show.has('description')) {\n labelPositions.forEach(({ item, yLabel }) => {\n ctx.groups.lithologyLabelsGroup\n .append('path')\n .attr('class', ctx.classes.labels.lithology.divider)\n .attr('fill', 'none')\n .attr('stroke', ctx.theme.labels.dividerStroke)\n .attr('stroke-width', ctx.theme.labels.dividerStrokeWidth)\n .attr('stroke-dasharray', ctx.theme.labels.dividerStrokeDasharray)\n .attr(\n 'd',\n `M ${item.originX},${item.originY} L ${ctx.geoXRight + 3},${item.originY} L ${labelX},${yLabel}`,\n );\n });\n }\n\n // ── Labels ────────────────────────────────────────────────────────────\n if (show.has('description')) {\n const lineH = s.stackingLineHeight;\n const bgFill = st.annotationBg ?? 'white';\n\n labelPositions.forEach(({ item, yLabel, estH }) => {\n const labelG = ctx.groups.lithologyLabelsGroup\n .append('g')\n .attr('class', ctx.classes.labels.lithology.label)\n .attr('transform', `translate(${labelX},${yLabel})`);\n\n labelG\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', s.descriptionMaxWidth)\n .attr('height', estH)\n .attr('rx', st.annotationRadius ?? 2)\n .attr('fill', bgFill)\n .attr('fill-opacity', st.annotationBgOpacity ?? 0.85)\n .attr('stroke', st.annotationBorderColor ?? 'none');\n\n labelG\n .append('text')\n .attr('class', 'wp-annotation-header')\n .attr('fill', ctx.theme.labels.color)\n .attr('font-weight', st.headerFontWeight ?? 600)\n .attr('font-family', ctx.theme.labels.headerFont)\n .attr('x', 0)\n .attr('y', lineH * 0.85)\n .attr('font-size', st.fontSize)\n .text(item.header);\n\n if (item.description) {\n const lines = wrapText(item.description, charsPerLine);\n const bodyEl = labelG\n .append('text')\n .attr('class', 'wp-annotation-body')\n .attr('fill', ctx.theme.labels.bodyColor)\n .attr('font-weight', st.bodyFontWeight ?? 400)\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', 0)\n .attr('y', lineH * 0.85 + lineH)\n .attr('font-size', st.fontSize);\n lines.forEach((line, i) => {\n bodyEl\n .append('tspan')\n .attr('x', 0)\n .attr('dy', i === 0 ? 0 : lineH)\n .text(line);\n });\n }\n });\n }\n}\n","import { Cave } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport {\n makeSeededPrng,\n ptsToSmoothPath,\n wavyContact,\n} from '~/utils/render.utils';\n\n/**\n * Renders cave bands as wavy closed SVG paths with texture fill.\n *\n * Each cave is drawn as a full-width band whose top and bottom contacts are\n * irregular and wavy rather than straight horizontal lines. Two independent\n * seeded PRNGs ensure the top and bottom contacts are visually uncorrelated.\n * Geometry is fully deterministic via those seeded PRNGs, so every redraw\n * (including zoom) produces identical shapes. Returns early if `data` is empty.\n */\nexport function drawCaves(ctx: DrawContext, data: Cave[]): void {\n if (!data.length) return;\n\n const {\n groups: { cavesGroup },\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale,\n renderConfig,\n theme,\n textures,\n classes,\n tooltips,\n } = ctx;\n\n cavesGroup.selectAll(`g.${classes.caves.item}`).remove();\n\n const rc = renderConfig.caves;\n\n data.forEach(cave => {\n // Two different seeds so top and bottom contacts are visually independent.\n // Multiplying by 100 ensures uniqueness even for small integer coordinates\n // (e.g. from=5, to=10 → seedTop=510; from=10, to=5 → seedTop=1005).\n // The +999 offset on seedBot prevents seedTop == seedBot when from == to.\n const seedTop = cave.from * 100 + cave.to;\n const seedBot = cave.to * 100 + cave.from + 999;\n const rngTop = makeSeededPrng(seedTop);\n const rngBot = makeSeededPrng(seedBot);\n\n const yTop = yScale(Math.max(cave.from, depthFrom));\n const yBot = yScale(Math.min(cave.to, depthTo));\n const span = yBot - yTop; // pixel height of the cave band\n\n const amp = Math.max(\n rc.amplitude.min,\n Math.min(span * rc.amplitude.ratio, rc.amplitude.max),\n );\n\n const topCut = cave.from < depthFrom;\n const botCut = cave.to > depthTo;\n\n const topPts = topCut\n ? ([\n [geoXLeft, yTop],\n [geoXRight, yTop],\n ] as [number, number][])\n : wavyContact(geoXLeft, geoXRight, yTop, amp, rc.pathSteps, rngTop);\n const botPts = botCut\n ? ([\n [geoXLeft, yBot],\n [geoXRight, yBot],\n ] as [number, number][])\n : wavyContact(geoXLeft, geoXRight, yBot, amp, rc.pathSteps, rngBot);\n\n // Smooth path strings for each contact\n const topPath = topCut\n ? `M ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} L ${geoXRight.toFixed(1)},${yTop.toFixed(1)}`\n : ptsToSmoothPath(topPts);\n const botPath = botCut\n ? `M ${geoXLeft.toFixed(1)},${yBot.toFixed(1)} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}`\n : ptsToSmoothPath(botPts);\n\n // Closed filled region:\n // top contact L→R + right vertical edge down\n // + bottom contact R→L (reversed) + left vertical edge up + Z\n const botReversed = botCut\n ? `L ${geoXLeft.toFixed(1)},${yBot.toFixed(1)}`\n : ptsToSmoothPath([...botPts].reverse(), { omitMoveTo: true });\n const closedPath = `${topPath} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}${botReversed} L ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} Z`;\n\n const caveTexture = cave.water_intake\n ? textures.cave_wet\n : textures.cave_dry;\n\n const g = cavesGroup\n .append('g')\n .attr('class', classes.caves.item)\n .datum(cave)\n .style('cursor', 'pointer')\n .on('mouseover', tooltips.cave.show)\n .on('mouseout', tooltips.cave.hide);\n\n const caveStroke = cave.water_intake\n ? theme.cave.wetStroke\n : theme.cave.dryStroke;\n\n g.append('path')\n .attr('class', classes.caves.fill)\n .attr('d', closedPath)\n .attr('fill', caveTexture.url())\n .attr('fill-opacity', theme.cave.fillOpacity)\n .attr('stroke', 'none');\n\n g.append('path')\n .attr('class', classes.caves.contact)\n .attr('d', topPath)\n .attr('fill', 'none')\n .attr('stroke', caveStroke)\n .attr('stroke-width', theme.cave.contactStrokeWidth)\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n\n g.append('path')\n .attr('class', classes.caves.contact)\n .attr('d', botPath)\n .attr('fill', 'none')\n .attr('stroke', caveStroke)\n .attr('stroke-width', theme.cave.contactStrokeWidth)\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n });\n}\n","import * as d3 from 'd3';\n\nimport type { WellCase, WellScreen } from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { DrawContext } from '~/types/render.types';\nimport { formatDiameter, getDiameterUnit } from '~/utils/format.utils';\nimport { wrapText } from '~/utils/render.utils';\n\n/**\n * Renders dimension labels for well cases and screens.\n * Text is word-wrapped if labelMaxWidth is set.\n * An occupancy list prevents overlap between adjacent labels.\n */\nexport function drawConstructionLabels(\n ctx: DrawContext,\n data: { well_case: WellCase[]; well_screen: WellScreen[] },\n): void {\n if (!ctx.renderConfig.constructionLabels.active) return;\n\n ctx.groups.constructionLabelsGroup.selectAll('*').remove();\n\n const clc = ctx.renderConfig.constructionLabels;\n const clct = ctx.theme.constructionLabels;\n const fmtD = (mm: number) => formatDiameter(mm, ctx.units.diameter);\n const dUnit = getDiameterUnit(ctx.units.diameter);\n\n const maxXValues = getProfileDiamValues(ctx.constructionData);\n const xScale = d3\n .scaleLinear()\n .domain([0, d3.max(maxXValues) || 0])\n .range([0, ctx.POCO_WIDTH]);\n\n const occupied: { top: number; bot: number }[] = [];\n\n const placeLabel = (d: WellCase | WellScreen, text: string) => {\n const clampedFrom = Math.max(d.from, ctx.depthFrom);\n const clampedTo = Math.min(d.to, ctx.depthTo);\n if (clampedFrom >= clampedTo) return;\n\n const midY = ctx.yScale((clampedFrom + clampedTo) / 2);\n const leftEdgeX = (ctx.POCO_CENTER - xScale(d.diameter)) / 2;\n const labelRightX = leftEdgeX - clc.xOffset;\n const charW = clct.fontSize * 0.52;\n const lineH = clct.fontSize * 1.35;\n const vertPad = 6;\n\n let lines: string[];\n let boxW: number;\n if (clc.labelMaxWidth !== undefined) {\n const maxChars = Math.max(\n 1,\n Math.floor((clc.labelMaxWidth! - 8) / charW),\n );\n lines = wrapText(text, maxChars);\n boxW = clc.labelMaxWidth;\n } else {\n lines = [text];\n boxW = text.length * charW + 8;\n }\n\n const labelH = lines.length * lineH + vertPad;\n let labelY = midY - labelH / 2;\n\n for (const pos of occupied) {\n if (labelY < pos.bot && labelY + labelH > pos.top) labelY = pos.bot + 2;\n }\n occupied.push({ top: labelY, bot: labelY + labelH });\n\n ctx.groups.constructionLabelsGroup\n .append('rect')\n .attr('x', labelRightX - boxW)\n .attr('y', labelY)\n .attr('width', boxW)\n .attr('height', labelH)\n .attr('rx', clc.labelRadius)\n .attr('fill', clct.labelFill ?? 'white')\n .attr('stroke', clct.labelColor ?? '#303030')\n .attr('stroke-width', 0.5);\n\n const textEl = ctx.groups.constructionLabelsGroup\n .append('text')\n .attr('x', labelRightX - 4)\n .attr('y', labelY + lineH * 0.85)\n .attr('font-size', clct.fontSize)\n .attr('font-family', clct.fontFamily ?? 'sans-serif')\n .attr('font-weight', clct.fontWeight ?? 400)\n .attr('text-anchor', 'end')\n .attr('fill', clct.labelColor ?? '#303030');\n\n lines.forEach((line, i) => {\n textEl\n .append('tspan')\n .attr('x', labelRightX - 4)\n .attr('dy', i === 0 ? 0 : lineH)\n .text(line);\n });\n };\n\n let lastDiam = 0;\n data.well_case\n .filter(item => {\n if (item.diameter !== lastDiam) {\n lastDiam = item.diameter;\n return true;\n }\n return false;\n })\n .forEach(d =>\n placeLabel(\n d,\n `${clc.labels.wellCasePrefix} ${fmtD(d.diameter)}${dUnit} ${d.type}`,\n ),\n );\n\n lastDiam = 0;\n data.well_screen\n .filter(item => {\n if (item.diameter !== lastDiam) {\n lastDiam = item.diameter;\n return true;\n }\n return false;\n })\n .forEach((d: WellScreen) =>\n placeLabel(\n d,\n `${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${d.type} ${clc.labels.wellScreenSlotPrefix} ${fmtD((d as WellScreen).screen_slot_mm)}${dUnit}`,\n ),\n );\n}\n","import * as d3 from 'd3';\n\nimport type {\n BoreHole,\n CementPad,\n Constructive,\n HoleFill,\n SurfaceCase,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { Conflict, DrawContext } from '~/types/render.types';\nimport { mergeEnter, withTransition } from '~/utils/d3.utils';\nimport {\n getConflictAreas,\n getYAxisFunctions,\n mergeConflicts,\n} from '~/utils/render.utils';\n\n/**\n * Renders all well construction components in order: cement pad, bore holes,\n * surface casing, hole fill, well casing, well screen, and conflict zones.\n * The x-scale domain is computed from ctx.constructionData for consistent\n * widths across multi-SVG panels.\n */\nexport function drawConstructive(ctx: DrawContext, data: Constructive): void {\n const { getHeight, getYPos } = getYAxisFunctions(ctx.yScale, {\n from: ctx.depthFrom,\n to: ctx.depthTo,\n });\n\n const maxXValues = getProfileDiamValues(ctx.constructionData);\n const maxXValueConstruction = d3.max(maxXValues) || 0;\n\n const xScale = d3\n .scaleLinear()\n .domain([0, maxXValueConstruction])\n .range([0, ctx.POCO_WIDTH]);\n\n const rcc = ctx.renderConfig.construction;\n\n ctx.groups.constructionGroup\n .selectAll(`.${ctx.classes.cementPad.item}`)\n .remove();\n\n if (data.cement_pad && data.cement_pad.thickness && ctx.depthFrom === 0) {\n const cementPad = ctx.groups.cementPadGroup\n .selectAll('rect')\n .data([data.cement_pad]);\n\n cementPad.exit().remove();\n\n const newCementPad = cementPad\n .enter()\n .append('rect')\n .attr('class', ctx.classes.cementPad.item)\n .attr(\n 'x',\n (d: CementPad) =>\n (ctx.POCO_CENTER -\n xScale((d.width * rcc.cementPad.widthMultiplier * 1000) / 2)) /\n 2,\n )\n .attr('y', (d: CementPad) => {\n return (\n ctx.yScale(0) -\n ctx.yScale(d.thickness * rcc.cementPad.thicknessMultiplier)\n );\n })\n .attr('width', (d: CementPad) =>\n xScale((d.width * rcc.cementPad.widthMultiplier * 1000) / 2),\n )\n .attr('height', (d: CementPad) => {\n return ctx.yScale(d.thickness * rcc.cementPad.thicknessMultiplier);\n })\n .attr('fill', ctx.textures.pad.url())\n .attr('stroke', ctx.theme.cementPad.stroke)\n .attr('stroke-width', ctx.theme.cementPad.strokeWidth);\n\n newCementPad\n .on('mouseover', ctx.tooltips.cementPad.show)\n .on('mouseout', ctx.tooltips.cementPad.hide);\n }\n\n const hole = ctx.groups.holeGroup\n .selectAll(`.${ctx.classes.boreHole.rect}`)\n .data(data.bore_hole);\n\n hole.exit().remove();\n\n const newHole = hole\n .enter()\n .append('rect')\n .attr('class', ctx.classes.boreHole.rect)\n .attr('fill', ctx.theme.boreHole.fill)\n .attr('stroke', ctx.theme.boreHole.stroke)\n .attr('opacity', ctx.theme.boreHole.opacity)\n .attr('stroke-width', ctx.theme.boreHole.strokeWidth)\n .attr('stroke-dasharray', ctx.theme.boreHole.strokeDasharray)\n .on('mouseover', ctx.tooltips.hole.show)\n .on('mouseout', ctx.tooltips.hole.hide);\n\n const mergedHole = mergeEnter(newHole, hole)\n .attr('x', (d: BoreHole) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: BoreHole) => xScale(d.diameter));\n withTransition(mergedHole, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n const surfaceCaseGs = ctx.groups.surfaceCaseGroup\n .selectAll(`g.${ctx.classes.surfaceCase.rect}`)\n .data(data.surface_case);\n\n surfaceCaseGs.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const newSC = surfaceCaseGs\n .enter()\n .append('g')\n .attr('class', ctx.classes.surfaceCase.rect)\n .on('mouseover', ctx.tooltips.surfaceCase.show)\n .on('mouseout', ctx.tooltips.surfaceCase.hide);\n\n newSC\n .append('rect')\n .attr('class', 'surface-case-fill')\n .attr('stroke', 'none');\n newSC\n .append('line')\n .attr('class', 'surface-case-side')\n .attr('stroke', ctx.theme.surfaceCase.stroke)\n .attr('stroke-width', ctx.theme.surfaceCase.strokeWidth);\n newSC\n .append('line')\n .attr('class', 'surface-case-side')\n .attr('stroke', ctx.theme.surfaceCase.stroke)\n .attr('stroke-width', ctx.theme.surfaceCase.strokeWidth);\n\n const mergedSC = mergeEnter(newSC, surfaceCaseGs);\n\n mergedSC.each((d: SurfaceCase, i, nodes) => {\n const x =\n (ctx.POCO_CENTER -\n xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n )) /\n 2;\n const w = xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n );\n const g = d3.select(nodes[i] as Element);\n g.select('.surface-case-fill')\n .attr('x', x)\n .attr('width', w)\n .attr('fill', ctx.textures.surface_case.url());\n const sideNodes = g.selectAll('.surface-case-side').nodes();\n d3.select(sideNodes[0] as Element)\n .attr('x1', x)\n .attr('x2', x);\n d3.select(sideNodes[1] as Element)\n .attr('x1', x + w)\n .attr('x2', x + w);\n });\n\n withTransition(\n mergedSC.select<SVGRectElement>('.surface-case-fill'),\n ctx.transition,\n )\n .attr('y', (d: SurfaceCase) => getYPos(d))\n .attr('height', (d: SurfaceCase) => getHeight(d));\n\n mergedSC\n .selectAll('.surface-case-side')\n .attr('y1', (d: unknown) => getYPos(d as SurfaceCase))\n .attr(\n 'y2',\n (d: unknown) => getYPos(d as SurfaceCase) + getHeight(d as SurfaceCase),\n );\n\n const holeFill = ctx.groups.holeFillGroup\n .selectAll(`.${ctx.classes.holeFill.rect}`)\n .data(data.hole_fill);\n\n holeFill.exit().remove();\n\n const newHoleFill = holeFill\n .enter()\n .append('rect')\n .attr('class', ctx.classes.holeFill.rect)\n .attr('stroke', ctx.theme.holeFill.stroke)\n .attr('stroke-width', ctx.theme.holeFill.strokeWidth)\n .on('mouseover', ctx.tooltips.holeFill.show)\n .on('mouseout', ctx.tooltips.holeFill.hide);\n\n const mergedHoleFill = mergeEnter(newHoleFill, holeFill)\n .attr('x', (d: HoleFill) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: HoleFill) => xScale(d.diameter));\n withTransition(mergedHoleFill, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('fill', (d: HoleFill) => ctx.textures[d.type].url());\n\n const wellCase = ctx.groups.wellCaseGroup\n .selectAll(`.${ctx.classes.wellCase.rect}`)\n .data(data.well_case);\n\n wellCase.exit().remove();\n\n const newWellCase = wellCase\n .enter()\n .append('rect')\n .attr('class', ctx.classes.wellCase.rect)\n .attr('fill', ctx.theme.wellCase.fill)\n .attr('stroke', ctx.theme.wellCase.stroke)\n .attr('stroke-width', ctx.theme.wellCase.strokeWidth)\n .on('mouseover', ctx.tooltips.wellCase.show)\n .on('mouseout', ctx.tooltips.wellCase.hide);\n\n const mergedWellCase = mergeEnter(newWellCase, wellCase)\n .attr('x', (d: WellCase) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellCase) => xScale(d.diameter));\n withTransition(mergedWellCase, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n const wellScreen = ctx.groups.wellScreenGroup\n .selectAll(`.${ctx.classes.wellScreen.rect}`)\n .data(data.well_screen);\n\n wellScreen.exit().remove();\n\n const newWellScreen = wellScreen\n .enter()\n .append('rect')\n .attr('class', ctx.classes.wellScreen.rect)\n .attr('fill', ctx.textures.well_screen.url())\n .attr('stroke', ctx.theme.wellScreen.stroke)\n .attr('stroke-width', ctx.theme.wellScreen.strokeWidth)\n .on('mouseover', ctx.tooltips.wellScreen.show)\n .on('mouseout', ctx.tooltips.wellScreen.hide);\n\n const mergedWellScreen = mergeEnter(newWellScreen, wellScreen)\n .attr('x', (d: WellScreen) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellScreen) => xScale(d.diameter));\n withTransition(mergedWellScreen, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n const conflictAreas: Conflict[] = [];\n conflictAreas.push(...getConflictAreas(data.well_case, data.well_screen));\n conflictAreas.push(...getConflictAreas(data.well_screen, data.well_case));\n\n const mergedConflicts = mergeConflicts(conflictAreas, 1);\n\n const conflict = ctx.groups.conflictGroup\n .selectAll(`.${ctx.classes.conflict.rect}`)\n .data(mergedConflicts);\n\n conflict.exit().remove();\n\n const newConflict = conflict\n .enter()\n .append('rect')\n .attr('class', ctx.classes.conflict.rect)\n .attr('fill', ctx.textures.conflict.url())\n .attr('stroke', ctx.theme.conflict.stroke)\n .attr('stroke-width', ctx.theme.conflict.strokeWidth)\n .on('mouseover', ctx.tooltips.conflict.show)\n .on('mouseout', ctx.tooltips.conflict.hide);\n\n const mergedConflict = mergeEnter(newConflict, conflict)\n .attr('x', (d: Conflict) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: Conflict) => xScale(d.diameter));\n withTransition(mergedConflict, ctx.transition)\n .attr('y', ctx.yScale(0))\n .attr('height', getHeight);\n}\n","import { Fracture } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { makeSeededPrng } from '~/utils/render.utils';\n\nfunction wavyLine(\n rng: () => number,\n steps: number,\n baseY: number,\n jitter: number,\n startInset: number,\n endInset: number,\n): [number, number][] {\n const pts: [number, number][] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const normX = startInset + t * (1 - startInset - endInset);\n const yOffset = baseY + (rng() * 2 - 1) * jitter;\n pts.push([normX, yOffset]);\n }\n return pts;\n}\n\n/**\n * Renders fractures onto the fractures SVG group.\n *\n * Single fractures are drawn as a wavy polyline with small branching cracks.\n * Swarm fractures are drawn as a set of parallel wavy lines (with a thicker\n * central line) connected by short bridge lines. Geometry for each fracture\n * is fully deterministic via a seeded PRNG keyed on the fracture depth.\n * Returns early if `data` is empty.\n */\nexport function drawFractures(ctx: DrawContext, data: Fracture[]): void {\n if (!data.length) return;\n\n const {\n groups: { fracturesGroup },\n POCO_WIDTH,\n pocoCenterX,\n yScale,\n renderConfig,\n theme,\n classes,\n tooltips,\n } = ctx;\n\n fracturesGroup.selectAll(`g.${classes.fractures.item}`).remove();\n\n const rf = renderConfig.fractures;\n const halfWidth = (POCO_WIDTH * rf.widthMultiplier) / 2;\n const xa = pocoCenterX - halfWidth;\n const w = halfWidth * 2;\n\n const normToAbsX = (normX: number) => xa + normX * w;\n\n data.forEach(fracture => {\n const rng = makeSeededPrng(fracture.depth, 7919);\n const cy = yScale(fracture.depth);\n\n const g = fracturesGroup\n .append('g')\n .attr('class', classes.fractures.item)\n .datum(fracture)\n .attr(\n 'transform',\n `translate(0,${cy}) rotate(${fracture.dip},${pocoCenterX},0)`,\n )\n .on('mouseover', tooltips.fracture.show)\n .on('mouseout', tooltips.fracture.hide)\n .style('cursor', 'pointer');\n\n const hitBuffer = fracture.swarm ? rf.hitBuffer.swarm : rf.hitBuffer.single;\n g.append('rect')\n .attr('class', classes.fractures.hitArea)\n .attr('x', xa)\n .attr('y', -hitBuffer)\n .attr('width', w)\n .attr('height', hitBuffer * 2)\n .attr('fill', 'transparent')\n .style('pointer-events', 'all');\n\n const fractureStroke = fracture.water_intake\n ? theme.fracture.wetStroke\n : theme.fracture.dryStroke;\n\n const appendLine = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n sw: number,\n ) =>\n g\n .append('line')\n .attr('class', classes.fractures.line)\n .attr('x1', x1)\n .attr('y1', y1)\n .attr('x2', x2)\n .attr('y2', y2)\n .attr('stroke', fractureStroke)\n .attr('stroke-width', sw)\n .attr('stroke-linecap', 'round');\n\n const appendPolyline = (pts: [number, number][], sw: number) =>\n g\n .append('polyline')\n .attr('class', classes.fractures.polyline)\n .attr(\n 'points',\n pts.map(([nx, dy]) => `${normToAbsX(nx)},${dy}`).join(' '),\n )\n .attr('stroke', fractureStroke)\n .attr('stroke-width', sw)\n .attr('fill', 'none')\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n\n if (fracture.swarm) {\n const lineCount =\n rf.swarm.lineCountBase + Math.round(rng() * rf.swarm.lineCountVariance);\n const halfSpread = rf.swarm.spread / 2;\n\n const bases = Array.from(\n { length: lineCount },\n () => (rng() * 2 - 1) * halfSpread,\n ).sort((a, b) => a - b);\n\n bases.forEach((base, idx) => {\n const isCentral = idx === Math.floor(lineCount / 2);\n const sw = isCentral\n ? theme.fracture.swarm.centralStrokeWidth\n : theme.fracture.swarm.sideStrokeWidthBase +\n rng() * theme.fracture.swarm.sideStrokeWidthVariance;\n const steps = 6 + Math.round(rng() * 3);\n const jitter = 0.8 + rng() * 1.2;\n const insetL = 0.04 + rng() * 0.12;\n const insetR = 0.04 + rng() * 0.12;\n appendPolyline(wavyLine(rng, steps, base, jitter, insetL, insetR), sw);\n });\n\n const bridgeCount = 2 + Math.round(rng() * 2);\n for (let b = 0; b < bridgeCount; b++) {\n const nx = 0.15 + rng() * 0.7;\n const pairIdx = Math.floor(rng() * (bases.length - 1));\n appendLine(\n normToAbsX(nx),\n bases[pairIdx],\n normToAbsX(nx + (rng() - 0.5) * 0.06),\n bases[pairIdx + 1],\n 0.6,\n );\n }\n\n const primaryBase = bases[Math.floor(lineCount / 2)];\n for (let wc = 0; wc < 2; wc++) {\n const nx = 0.2 + rng() * 0.6;\n const len = 3 + rng() * 3;\n const dir = rng() > 0.5 ? -1 : 1;\n appendLine(\n normToAbsX(nx),\n primaryBase,\n normToAbsX(nx + (rng() - 0.5) * 0.04),\n primaryBase + dir * len,\n 0.8,\n );\n }\n } else {\n const steps = 7 + Math.round(rng() * 3);\n const insetL = 0.03 + rng() * 0.08;\n const insetR = 0.03 + rng() * 0.08;\n appendPolyline(\n wavyLine(rng, steps, 0, 2, insetL, insetR),\n theme.fracture.single.mainStrokeWidth,\n );\n\n const crackCount = 2 + Math.round(rng() * 2);\n for (let c = 0; c < crackCount; c++) {\n const nx = insetL + rng() * (1 - insetL - insetR);\n const len = 3.5 + rng() * 3.5;\n const dir = rng() > 0.5 ? 1 : -1;\n appendLine(\n normToAbsX(nx),\n (rng() * 2 - 1) * 1.5,\n normToAbsX(nx + (rng() - 0.5) * 0.03),\n dir * len,\n theme.fracture.single.crackStrokeWidth,\n );\n }\n }\n });\n}\n","import * as d3 from 'd3';\n\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type {\n DrawContext,\n HighlightItem,\n Highlights,\n SvgSelection,\n} from '~/types/render.types';\n\n/**\n * Renders a single highlight overlay rectangle (and optional label) into the\n * given SVG group. Skips items with zero or negative dimensions.\n */\nfunction drawHighlightItem(\n ctx: DrawContext,\n group: SvgSelection,\n x: number,\n y: number,\n w: number,\n h: number,\n label?: string,\n): void {\n if (h <= 0 || w <= 0) return;\n\n const hlConfig = ctx.renderConfig.highlights;\n const pad = hlConfig.padding;\n\n const g = group.append('g').attr('class', ctx.classes.highlights.item);\n\n g.append('rect')\n .attr('class', ctx.classes.highlights.rect)\n .attr('x', x - pad)\n .attr('y', y - pad)\n .attr('width', w + pad * 2)\n .attr('height', h + pad * 2)\n .attr('fill', hlConfig.fill)\n .attr('fill-opacity', hlConfig.fillOpacity)\n .attr('stroke', hlConfig.stroke)\n .attr('stroke-width', hlConfig.strokeWidth)\n .attr('stroke-dasharray', hlConfig.strokeDasharray ?? null)\n .style('pointer-events', 'none');\n\n if (label) {\n const charW = hlConfig.labelFontSize * 0.55;\n const labelW = label.length * charW + hlConfig.labelPadding * 2;\n const labelH = hlConfig.labelFontSize + hlConfig.labelPadding * 2;\n const lx = x - pad;\n const ly = y - pad - labelH;\n\n g.append('rect')\n .attr('class', ctx.classes.highlights.labelBg)\n .attr('x', lx)\n .attr('y', ly)\n .attr('width', labelW)\n .attr('height', labelH)\n .attr('rx', hlConfig.labelRadius)\n .attr('fill', hlConfig.labelBackground)\n .style('pointer-events', 'none');\n\n g.append('text')\n .attr('class', ctx.classes.highlights.label)\n .attr('x', lx + hlConfig.labelPadding)\n .attr('y', ly + labelH - hlConfig.labelPadding)\n .attr('font-size', hlConfig.labelFontSize)\n .attr('fill', hlConfig.labelColor)\n .attr('font-family', 'sans-serif')\n .style('pointer-events', 'none')\n .text(label);\n }\n}\n\n/**\n * Renders colored highlight overlays on any component. Always runs to clear\n * groups on zoom redraws, even if hl is empty. The x-scale domain is computed\n * from ctx.constructionData for consistent widths across multi-SVG panels.\n */\nexport function drawHighlights(ctx: DrawContext, hl: Highlights): void {\n ctx.groups.highlightsGeologicGroup.selectAll('*').remove();\n ctx.groups.highlightsConstructionGroup.selectAll('*').remove();\n ctx.groups.highlightsFracturesGroup.selectAll('*').remove();\n\n // Geologic highlights\n const drawGeoHighlights = (items: HighlightItem[] | undefined) => {\n items?.forEach(h => {\n if (h.from === undefined || h.to === undefined) return;\n const from = Math.max(h.from, ctx.depthFrom);\n const to = Math.min(h.to, ctx.depthTo);\n if (from >= to) return;\n const y = ctx.yScale(from);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsGeologicGroup as SvgSelection,\n ctx.geoXLeft,\n y,\n ctx.geoXRight - ctx.geoXLeft,\n ctx.yScale(to) - y,\n h.label,\n );\n });\n };\n\n drawGeoHighlights(hl.lithology);\n drawGeoHighlights(hl.caves);\n\n // Fracture highlights\n const fractureConfig = ctx.renderConfig.fractures;\n const halfFractureWidth =\n (ctx.POCO_WIDTH * fractureConfig.widthMultiplier) / 2;\n const fracXa = ctx.pocoCenterX - halfFractureWidth;\n const fracW = halfFractureWidth * 2;\n\n hl.fractures?.forEach(h => {\n if (h.depth === undefined) return;\n if (h.depth < ctx.depthFrom || h.depth > ctx.depthTo) return;\n const cy = ctx.yScale(h.depth);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsFracturesGroup as SvgSelection,\n fracXa,\n cy - fractureConfig.hitBuffer.single,\n fracW,\n fractureConfig.hitBuffer.single * 2,\n h.label,\n );\n });\n\n // Construction highlights\n const maxXVals = getProfileDiamValues(ctx.constructionData);\n const xScaleConstr = d3\n .scaleLinear()\n .domain([0, d3.max(maxXVals) || 0])\n .range([0, ctx.POCO_WIDTH]);\n\n const constructionConfig = ctx.renderConfig.construction;\n\n if (\n hl.cement_pad &&\n ctx.depthFrom === 0 &&\n ctx.constructionData.cement_pad?.thickness\n ) {\n const cp = ctx.constructionData.cement_pad;\n const cpPadWidth =\n (cp.width * constructionConfig.cementPad.widthMultiplier * 1000) / 2;\n const cpX = (ctx.POCO_CENTER - xScaleConstr(cpPadWidth)) / 2;\n const cpY =\n ctx.yScale(0) -\n ctx.yScale(\n cp.thickness * constructionConfig.cementPad.thicknessMultiplier,\n );\n const cpW = xScaleConstr(cpPadWidth);\n const cpH = ctx.yScale(\n cp.thickness * constructionConfig.cementPad.thicknessMultiplier,\n );\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsConstructionGroup as SvgSelection,\n cpX,\n cpY,\n cpW,\n cpH,\n hl.cement_pad.label,\n );\n }\n\n const drawConstrHighlights = (\n items: HighlightItem[] | undefined,\n data: { from: number; to: number; diameter: number }[],\n getX: (d: { diameter: number }) => number,\n getW: (d: { diameter: number }) => number,\n ) => {\n items?.forEach(h => {\n if (h.from === undefined || h.to === undefined) return;\n data\n .filter(\n d =>\n d.from < h.to! &&\n d.to > h.from! &&\n (h.diameter === undefined || d.diameter === h.diameter),\n )\n .forEach(d => {\n const from = Math.max(h.from!, ctx.depthFrom);\n const to = Math.min(h.to!, ctx.depthTo);\n if (from >= to) return;\n const y = ctx.yScale(from);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsConstructionGroup as SvgSelection,\n getX(d),\n y,\n getW(d),\n ctx.yScale(to) - y,\n h.label,\n );\n });\n });\n };\n\n const stdX = (d: { diameter: number }) =>\n (ctx.POCO_CENTER - xScaleConstr(d.diameter)) / 2;\n const stdW = (d: { diameter: number }) => xScaleConstr(d.diameter);\n const scPaddingRatio = constructionConfig.surfaceCase.diameterPaddingRatio;\n const scX = (d: { diameter: number }) =>\n (ctx.POCO_CENTER - xScaleConstr(d.diameter + d.diameter * scPaddingRatio)) /\n 2;\n const scW = (d: { diameter: number }) =>\n xScaleConstr(d.diameter + d.diameter * scPaddingRatio);\n\n drawConstrHighlights(\n hl.bore_hole,\n ctx.constructionData.bore_hole,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.surface_case,\n ctx.constructionData.surface_case,\n scX,\n scW,\n );\n drawConstrHighlights(\n hl.hole_fill,\n ctx.constructionData.hole_fill,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.well_case,\n ctx.constructionData.well_case,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.well_screen,\n ctx.constructionData.well_screen,\n stdX,\n stdW,\n );\n}\n","import * as d3module from 'd3';\nimport { defu } from 'defu';\n\nimport { Well } from '@welldot/core';\nimport {\n ComponentsClassNames,\n LegendRenderConfig,\n WellTheme,\n} from '~/types/render.types';\nimport { DEFAULT_COMPONENTS_CLASS_NAMES } from '../configs/render.classnames';\nimport {\n DEFAULT_WELL_THEME,\n INTERACTIVE_RENDER_CONFIG,\n} from '../configs/render.configs';\nimport { TexturesConfig, createWellTextures } from '../configs/render.textures';\nimport { getConflictAreas, mergeConflicts } from '../utils/render.utils';\n\nconst d3 = { ...d3module };\n\ntype LegendItem =\n | { kind: 'fracture'; label: string; swarm: boolean; water_intake: boolean }\n | { kind: 'cave'; label: string; water_intake: boolean }\n | {\n kind: 'construction';\n label: string;\n subKind:\n | 'boreHole'\n | 'surfaceCase'\n | 'holeFillGravel'\n | 'holeFillSeal'\n | 'wellCase'\n | 'wellScreen'\n | 'cementPad'\n | 'conflict';\n };\n\nexport function drawWellLegend(\n selector: string,\n profile: Well,\n options: {\n config?: Partial<LegendRenderConfig>;\n theme?: Partial<WellTheme>;\n classNames?: ComponentsClassNames['legend'];\n textures?: TexturesConfig;\n } = {},\n): void {\n const fractures = profile.fractures ?? [];\n const caves = profile.caves ?? [];\n const boreHoles = profile.bore_hole ?? [];\n const wellCases = profile.well_case ?? [];\n const wellScreens = profile.well_screen ?? [];\n const holeFills = profile.hole_fill ?? [];\n\n const hasSimple = fractures.some(f => !f.swarm && !f.water_intake);\n const hasSwarm = fractures.some(f => f.swarm);\n const hasWaterFx = fractures.some(f => f.water_intake);\n const hasCaveDry = caves.some(c => !c.water_intake);\n const hasCaveWet = caves.some(c => c.water_intake);\n\n const hasBoreHole = boreHoles.length > 0;\n const hasSurfaceCase = (profile.surface_case ?? []).length > 0;\n const hasHoleFillGravel = holeFills.some(h => h.type === 'gravel_pack');\n const hasHoleFillSeal = holeFills.some(h => h.type === 'seal');\n const hasWellCase = wellCases.length > 0;\n const hasWellScreen = wellScreens.length > 0;\n const hasCementPad = !!profile.cement_pad?.thickness;\n const hasConflict =\n mergeConflicts(\n [\n ...getConflictAreas(wellCases, wellScreens),\n ...getConflictAreas(wellScreens, wellCases),\n ],\n 1,\n ).length > 0;\n\n const cfg = defu(\n options.config ?? {},\n INTERACTIVE_RENDER_CONFIG.legend,\n ) as LegendRenderConfig;\n\n const theme = defu(options.theme ?? {}, DEFAULT_WELL_THEME) as WellTheme;\n\n const cls: ComponentsClassNames['legend'] = options.classNames\n ? { ...DEFAULT_COMPONENTS_CLASS_NAMES.legend, ...options.classNames }\n : DEFAULT_COMPONENTS_CLASS_NAMES.legend;\n\n const items: LegendItem[] = [];\n if (hasSimple)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureSingle,\n swarm: false,\n water_intake: false,\n });\n if (hasSwarm)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureSwarm,\n swarm: true,\n water_intake: false,\n });\n if (hasWaterFx)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureWater,\n swarm: false,\n water_intake: true,\n });\n if (hasCaveDry)\n items.push({\n kind: 'cave',\n label: cfg.labels.caveDry,\n water_intake: false,\n });\n if (hasCaveWet)\n items.push({ kind: 'cave', label: cfg.labels.caveWet, water_intake: true });\n\n if (hasCementPad)\n items.push({\n kind: 'construction',\n label: cfg.labels.cementPad,\n subKind: 'cementPad',\n });\n if (hasBoreHole)\n items.push({\n kind: 'construction',\n label: cfg.labels.boreHole,\n subKind: 'boreHole',\n });\n if (hasSurfaceCase)\n items.push({\n kind: 'construction',\n label: cfg.labels.surfaceCase,\n subKind: 'surfaceCase',\n });\n if (hasHoleFillGravel)\n items.push({\n kind: 'construction',\n label: cfg.labels.holeFillGravel,\n subKind: 'holeFillGravel',\n });\n if (hasHoleFillSeal)\n items.push({\n kind: 'construction',\n label: cfg.labels.holeFillSeal,\n subKind: 'holeFillSeal',\n });\n if (hasWellCase)\n items.push({\n kind: 'construction',\n label: cfg.labels.wellCase,\n subKind: 'wellCase',\n });\n if (hasWellScreen)\n items.push({\n kind: 'construction',\n label: cfg.labels.wellScreen,\n subKind: 'wellScreen',\n });\n if (hasConflict)\n items.push({\n kind: 'construction',\n label: cfg.labels.conflict,\n subKind: 'conflict',\n });\n\n const svgEl = d3.select(selector);\n svgEl.selectAll('*').remove();\n\n if (items.length === 0) {\n svgEl.attr('width', 0).attr('height', 0);\n return;\n }\n\n const legendTextures = createWellTextures(options.textures);\n Object.values(legendTextures).forEach(t => svgEl.call(t));\n\n const itemsPerRow = cfg.maxWidth\n ? Math.max(1, Math.floor((cfg.maxWidth - cfg.padding * 2) / cfg.itemWidth))\n : items.length;\n const numRows = Math.ceil(items.length / itemsPerRow);\n const rowWidth = Math.min(items.length, itemsPerRow) * cfg.itemWidth;\n const totalWidth = cfg.padding * 2 + rowWidth;\n const totalHeight = numRows * cfg.height;\n\n svgEl.attr('width', totalWidth).attr('height', totalHeight);\n\n const RC = 'round' as const;\n\n const g = svgEl.append('g').attr('transform', `translate(${cfg.padding}, 2)`);\n\n g.append('rect')\n .attr('class', cls.border)\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', totalWidth - cfg.padding)\n .attr('height', totalHeight - 4)\n .attr('fill', 'white')\n .attr('rx', cfg.borderRadius)\n .attr('stroke-width', theme.legend.borderStrokeWidth);\n\n g.append('text')\n .attr('class', cls.title)\n .attr('x', 4)\n .attr('y', 11)\n .attr('font-size', theme.legend.fontSize)\n .attr('font-family', theme.legend.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.legend.titleFontWeight ?? 'bold')\n .text(`${cfg.title}:`);\n\n const rw = 24;\n const rh = 12;\n\n items.forEach((item, i) => {\n const col = i % itemsPerRow;\n const row = Math.floor(i / itemsPerRow);\n const rowSymY = row * cfg.height + (cfg.height - 4) / 2;\n const cx = col * cfg.itemWidth;\n\n const symG = g.append('g').attr('class', cls.item);\n\n if (item.kind === 'fracture') {\n const color = item.water_intake\n ? theme.fracture.wetStroke\n : theme.fracture.dryStroke;\n\n if (item.swarm) {\n ([-4, 0, 4] as number[]).forEach(offset => {\n symG\n .append('polyline')\n .attr('class', cls.fracturePoly)\n .attr(\n 'points',\n `${cx},${rowSymY + offset} ${cx + 6},${rowSymY + offset - 1} ${cx + 12},${rowSymY + offset + 1} ${cx + 18},${rowSymY + offset - 0.5} ${cx + 24},${rowSymY + offset}`,\n )\n .attr('stroke', color)\n .attr(\n 'stroke-width',\n offset !== 0\n ? theme.legend.fractureSideStrokeWidth\n : theme.legend.fractureStrokeWidth,\n )\n .attr('fill', 'none')\n .attr('stroke-linecap', RC)\n .attr('stroke-linejoin', RC);\n });\n } else {\n symG\n .append('polyline')\n .attr('class', cls.fracturePoly)\n .attr(\n 'points',\n `${cx},${rowSymY} ${cx + 5},${rowSymY - 1.5} ${cx + 11},${rowSymY + 1} ${cx + 17},${rowSymY - 0.5} ${cx + 24},${rowSymY}`,\n )\n .attr('stroke', color)\n .attr('stroke-width', theme.legend.fractureStrokeWidth)\n .attr('fill', 'none')\n .attr('stroke-linecap', RC)\n .attr('stroke-linejoin', RC);\n }\n } else if (item.kind === 'cave') {\n const color = item.water_intake\n ? theme.cave.wetStroke\n : theme.cave.dryStroke;\n const texture = item.water_intake\n ? legendTextures.cave_wet\n : legendTextures.cave_dry;\n\n symG\n .append('rect')\n .attr('class', cls.caveFill)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', texture.url())\n .attr('stroke', color)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n } else if (item.subKind === 'surfaceCase') {\n symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', legendTextures.surface_case.url())\n .attr('stroke', 'none');\n symG\n .append('line')\n .attr('class', cls.constructionRect)\n .attr('x1', cx)\n .attr('x2', cx)\n .attr('y1', rowSymY - rh / 2)\n .attr('y2', rowSymY + rh / 2)\n .attr('stroke', theme.surfaceCase.stroke)\n .attr('stroke-width', 2);\n symG\n .append('line')\n .attr('class', cls.constructionRect)\n .attr('x1', cx + rw)\n .attr('x2', cx + rw)\n .attr('y1', rowSymY - rh / 2)\n .attr('y2', rowSymY + rh / 2)\n .attr('stroke', theme.surfaceCase.stroke)\n .attr('stroke-width', 2);\n } else {\n const symMap: Record<\n string,\n { fill: string; stroke: string; dasharray?: string }\n > = {\n boreHole: {\n fill: theme.boreHole.fill,\n stroke: theme.boreHole.stroke,\n dasharray: theme.boreHole.strokeDasharray,\n },\n holeFillGravel: {\n fill: legendTextures.gravel_pack.url(),\n stroke: theme.holeFill.stroke,\n },\n holeFillSeal: {\n fill: legendTextures.seal.url(),\n stroke: theme.holeFill.stroke,\n },\n wellCase: { fill: theme.wellCase.fill, stroke: theme.wellCase.stroke },\n wellScreen: {\n fill: legendTextures.well_screen.url(),\n stroke: theme.wellScreen.stroke,\n },\n cementPad: {\n fill: legendTextures.pad.url(),\n stroke: theme.cementPad.stroke,\n },\n conflict: {\n fill: legendTextures.conflict.url(),\n stroke: theme.conflict.stroke,\n },\n };\n const sym = symMap[item.subKind];\n\n const symRect = symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', sym.fill)\n .attr('stroke', sym.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n if (sym.dasharray) symRect.attr('stroke-dasharray', sym.dasharray);\n }\n\n g.append('text')\n .attr('class', cls.label)\n .attr('x', cx + 28)\n .attr('y', rowSymY + 3)\n .attr('font-size', theme.legend.fontSize)\n .attr('font-family', theme.legend.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.legend.labelFontWeight ?? 400)\n .text(item.label);\n });\n}\n","import { Lithology } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { mergeEnter, withTransition } from '~/utils/d3.utils';\nimport { getLithologyFill, getYAxisFunctions } from '~/utils/render.utils';\n\n/**\n * Renders lithology rects with FGDC texture fills.\n *\n * Each lithology layer is drawn as a rect spanning `geoXLeft` to `geoXRight`\n * at the depth position determined by `ctx.yScale`. Fill textures are resolved\n * via `getLithologyFill` using the FGDC texture config. Returns early if\n * `data` is empty.\n */\nexport function drawLithology(ctx: DrawContext, data: Lithology[]): void {\n if (!data.length) return;\n\n const {\n groups: { lithologyGroup },\n svg,\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale,\n theme,\n classes,\n tooltips,\n transition,\n } = ctx;\n\n const { getHeight, getYPos } = getYAxisFunctions(yScale, {\n from: depthFrom,\n to: depthTo,\n });\n\n const rects = lithologyGroup\n .selectAll(`.${classes.lithology.rect}`)\n .data(data);\n\n rects.exit().remove();\n\n const newLayers = rects\n .enter()\n .append('rect')\n .attr('class', classes.lithology.rect)\n .attr('x', geoXLeft)\n .attr('width', geoXRight - geoXLeft)\n .attr('stroke', theme.lithology.stroke)\n .attr('stroke-width', theme.lithology.strokeWidth)\n .on('mouseover', tooltips.geology.show)\n .on('mouseout', tooltips.geology.hide);\n\n const merged = mergeEnter(newLayers, rects).attr('y', getYPos);\n withTransition(merged, transition)\n .attr('height', getHeight)\n .attr('fill', getLithologyFill(data, svg, ctx.theme.lithologyTexture));\n}\n","import { Lithology } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\n\n/**\n * Renders geologic_unit and aquifer_unit strip labels to the left of the\n * lithology column.\n *\n * Adjacent layers sharing the same unit value are merged into a single strip\n * segment. Each segment is drawn as a filled rect with divider lines at its\n * top and bottom edges; a rotated text label is added when the segment is tall\n * enough. Returns early if the feature is disabled via\n * `ctx.renderConfig.unitLabels.active` or if `data` is empty.\n */\nexport function drawUnitLabels(ctx: DrawContext, data: Lithology[]): void {\n if (!ctx.renderConfig.unitLabels.active || !data.length) return;\n\n const {\n groups: { unitLabelsGroup },\n depthFrom,\n depthTo,\n yScale,\n renderConfig,\n theme,\n classes,\n } = ctx;\n\n unitLabelsGroup.selectAll('*').remove();\n\n const ru = renderConfig.unitLabels;\n const rut = theme.unitLabels;\n const sw = ru.stripWidth;\n\n const groupByField = (field: 'geologic_unit' | 'aquifer_unit') => {\n const groups: { unit: string; from: number; to: number }[] = [];\n for (const layer of data) {\n const unit = layer[field];\n if (!unit) continue;\n const from = Math.max(layer.from, depthFrom);\n const to = Math.min(layer.to, depthTo);\n if (from >= to) continue;\n const last = groups[groups.length - 1];\n if (last && last.unit === unit) {\n last.to = to;\n } else groups.push({ unit, from, to });\n }\n return groups;\n };\n\n const hasGeo = data.some(d => d.geologic_unit);\n const hasAq = data.some(d => d.aquifer_unit);\n\n // Strips start at ru.xOffset (geologic group coordinates).\n // When both exist: geo at xOffset, aq at xOffset + stripWidth + 1.\n const geoX = ru.xOffset;\n const aqX = hasGeo && hasAq ? ru.xOffset + sw + 1 : ru.xOffset;\n\n const drawStrip = (\n groups: { unit: string; from: number; to: number }[],\n stripX: number,\n rectClass: string,\n fillColor: string,\n ) => {\n groups.forEach((group, idx) => {\n const yTop = yScale(group.from);\n const yBot = yScale(group.to);\n const height = yBot - yTop;\n if (height < 1) return;\n\n const isFirst = idx === 0;\n const isLast = idx === groups.length - 1;\n\n unitLabelsGroup\n .append('rect')\n .attr('class', rectClass)\n .attr('x', stripX)\n .attr('y', yTop)\n .attr('width', sw)\n .attr('height', height)\n .attr('fill', fillColor)\n .attr('stroke', rut.stroke)\n .attr('stroke-width', rut.strokeWidth);\n\n const appendEdge = (y: number, strokeWidth: number) =>\n unitLabelsGroup\n .append('line')\n .attr('class', 'unit-divider-line')\n .attr('x1', stripX)\n .attr('x2', stripX + sw)\n .attr('y1', y)\n .attr('y2', y)\n .attr('stroke', rut.stroke)\n .attr('stroke-width', strokeWidth);\n\n appendEdge(yTop, isFirst ? ru.outerEdgeWidth : ru.innerDividerWidth);\n appendEdge(yBot, isLast ? ru.outerEdgeWidth : ru.innerDividerWidth);\n\n if (height >= ru.minHeightForText) {\n const maxChars = Math.floor(height / (rut.fontSize * 0.55));\n const label =\n group.unit.length > maxChars\n ? `${group.unit.slice(0, maxChars - 1)}…`\n : group.unit;\n\n unitLabelsGroup\n .append('text')\n .attr('class', classes.unitLabels.text)\n .attr(\n 'transform',\n `translate(${(stripX + sw / 2).toFixed(1)},${((yTop + yBot) / 2).toFixed(1)}) rotate(-90)`,\n )\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'middle')\n .attr('font-size', rut.fontSize)\n .attr('font-family', rut.fontFamily ?? 'sans-serif')\n .attr('font-weight', rut.fontWeight ?? 400)\n .attr('fill', rut.stroke)\n .text(label);\n }\n });\n };\n\n if (hasGeo)\n drawStrip(\n groupByField('geologic_unit'),\n geoX,\n classes.unitLabels.geoRect,\n rut.geologicFill,\n );\n if (hasAq)\n drawStrip(\n groupByField('aquifer_unit'),\n aqX,\n classes.unitLabels.aqRect,\n rut.aquiferFill,\n );\n}\n","import sanitizeHtml from 'sanitize-html';\nimport { WellTheme } from '~/types/render.types';\n\n/** Strips all HTML/CSS-breaking characters from a theme string value before CSS injection. */\nconst sanitizeCssValue = (v: unknown): string =>\n sanitizeHtml(String(v ?? ''), { allowedTags: [], allowedAttributes: {} });\n\nexport function buildSvgStyleBlock(theme: WellTheme): string {\n const { labels, lithology } = theme;\n const s = sanitizeCssValue;\n return [\n `.wp-lithology-depth-tip{border:0.5px solid ${s(lithology.stroke)};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n `.wp-annotation-label{font-size:${s(labels.fontSize)}px}`,\n `.wp-annotation-header{font-weight:${s(labels.headerFontWeight ?? 600)};font-family:${s(labels.headerFont)};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n `.wp-annotation-body{font-weight:${s(labels.bodyFontWeight ?? 400)};font-family:${s(labels.bodyFont ?? 'sans-serif')};font-size:${s(labels.fontSize)}px;color:${s(labels.bodyColor)}}`,\n `.wp-depth-tip-text{font-family:${s(labels.bodyFont ?? 'sans-serif')};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n ].join('');\n}\n"],"mappings":"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","names":["d3module","d3tip","defu","textures","textures","textures","d3","d3","getProfileDiamValues","getProfileDiamValues","d3","getProfileDiamValues","d3module","d3","d3module","sanitizeHtml","d3","d3module","d3tip","defu"]}
|
|
1
|
+
{"version":3,"sources":["../src/configs/render.configs.ts","../src/utils/fgdcTextures.ts","../src/Renderer.ts","../src/configs/render.textures.ts","../src/utils/format.utils.ts","../src/configs/render.classnames.ts","../src/utils/render.utils.ts","../src/utils/d3.utils.ts","../src/utils/geometry.utils.ts","../src/utils/tooltips.utils.ts","../src/renderers/annotation-labels.renderer.ts","../src/renderers/caves.renderer.ts","../src/renderers/construction-labels.renderer.ts","../src/renderers/construction.renderer.ts","../src/renderers/fractures.renderer.ts","../src/renderers/highlights.renderer.ts","../src/renderers/legend.renderer.ts","../src/renderers/lithology.renderer.ts","../src/renderers/unit-labels.renderer.ts","../src/utils/render.styles.ts"],"sourcesContent":["import { easeCubic } from 'd3';\nimport { RenderConfig, WellTheme } from '~/types/render.types';\n\nexport const DEFAULT_WELL_THEME: WellTheme = {\n lithology: { stroke: '#101010', strokeWidth: 1 },\n lithologyTexture: { size: 150, strokeWidth: 0.8, stroke: '#303030' },\n cave: {\n dryStroke: '#333333',\n wetStroke: '#1a6fa8',\n fillOpacity: 0.6,\n contactStrokeWidth: 1.2,\n },\n fracture: {\n dryStroke: '#000000',\n wetStroke: '#1a6fa8',\n swarm: {\n centralStrokeWidth: 1.2,\n sideStrokeWidthBase: 0.6,\n sideStrokeWidthVariance: 0.6,\n },\n single: {\n mainStrokeWidth: 1.8,\n crackStrokeWidth: 0.7,\n },\n },\n cementPad: { stroke: '#303030', strokeWidth: 2 },\n boreHole: {\n fill: '#ffffff',\n stroke: '#191919',\n strokeDasharray: '4, 3',\n opacity: 0.7,\n strokeWidth: 1.2,\n },\n surfaceCase: { stroke: '#000000', strokeWidth: 4 },\n holeFill: { stroke: '#303030', strokeWidth: 2 },\n wellCase: { fill: '#ffffff', stroke: '#303030', strokeWidth: 2 },\n wellScreen: { stroke: '#303030', strokeWidth: 2 },\n conflict: { stroke: '#e52117', strokeWidth: 4 },\n unitLabels: {\n geologicFill: '#f0f0f0',\n aquiferFill: '#dff0ff',\n stroke: '#303030',\n strokeWidth: 0.4,\n fontSize: 5.5,\n fontFamily: 'sans-serif',\n fontWeight: 400,\n },\n constructionLabels: {\n fontSize: 7.5,\n labelFill: '#ffffff',\n labelColor: '#303030',\n fontFamily: 'sans-serif',\n fontWeight: 400,\n },\n labels: {\n dividerStroke: '#888888',\n dividerStrokeWidth: 0.5,\n dividerStrokeDasharray: '2, 2',\n fontSize: 7,\n color: '#333',\n headerFont: 'monospace',\n bodyColor: '#555',\n bodyFont: 'sans-serif',\n scaleFont: 'monospace',\n depthTipFill: '#ffffff',\n depthTipRadius: 2,\n annotationBg: '#ffffff',\n annotationBgOpacity: 0.85,\n annotationRadius: 2,\n headerFontWeight: 600,\n bodyFontWeight: 400,\n },\n legend: {\n borderStrokeWidth: 0.8,\n fractureStrokeWidth: 1.5,\n fractureSideStrokeWidth: 0.8,\n itemStrokeWidth: 0.8,\n fontSize: 7,\n fontFamily: 'sans-serif',\n titleFontWeight: 'bold',\n labelFontWeight: 400,\n },\n};\n\nconst DEFAULT_HIGHLIGHT_CONFIG = {\n stroke: '#e52117',\n strokeWidth: 2,\n fill: 'none',\n fillOpacity: 0,\n padding: 2,\n strokeDasharray: undefined,\n labelFontSize: 7,\n labelPadding: 3,\n labelBackground: '#e52117',\n labelColor: '#ffffff',\n labelRadius: 2,\n} as const;\n\nexport const STATIC_RENDER_CONFIG: RenderConfig = {\n zoom: true,\n pan: true,\n zoomLevel: 1,\n animation: { duration: 600, ease: easeCubic },\n geologic: { xLeft: 20, xRightInset: 300 },\n layout: {\n pocoWidthRatio: 0.21, // construction column occupies 21% of total SVG width\n pocoCenterRatio: -0.39, // construction center x-offset (negative = shift left of SVG centre)\n },\n caves: {\n pathSteps: 40,\n amplitude: {\n ratio: 0.12, // cave contact waviness: 12% of the cave band pixel height\n min: 1,\n max: 5.5,\n },\n },\n fractures: {\n widthMultiplier: 1.2,\n hitBuffer: { single: 8, swarm: 15 },\n swarm: {\n lineCountBase: 3,\n lineCountVariance: 11,\n spread: 18,\n },\n },\n construction: {\n cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n },\n labels: {\n active: true,\n typeLabels: { fracture: 'fratura', cave: 'caverna' },\n depthTipHeight: 11,\n depthTipPadX: 2,\n descriptionXOffset: 20,\n descriptionMaxWidth: 250,\n stackingLineHeight: 10,\n stackingGap: 0,\n fractureLabelLeaderGap: 5,\n lithology: true,\n },\n unitLabels: {\n active: true,\n xOffset: 2,\n stripWidth: 8,\n minHeightForText: 8,\n innerDividerWidth: 1.5,\n outerEdgeWidth: 0.6,\n },\n constructionLabels: {\n active: true,\n xOffset: -12,\n labelRadius: 2,\n labelMaxWidth: 90,\n labels: {\n wellCasePrefix: 'Revest.',\n wellScreenPrefix: 'Filtro',\n wellScreenSlotPrefix: 'Ranhura:',\n },\n },\n textures: {\n pad: { background: '#ffffff', stroke: '#303030' },\n conflict: { stroke: '#E52117' },\n cave_dry: { size: 8, stroke: '#333333', background: '#ffffff' },\n cave_wet: { size: 8, stroke: '#1a6fa8', background: '#ffffff' },\n seal: { background: '#ffffff' },\n gravel_pack: { background: '#ffffff' },\n well_screen: { size: 40, strokeWidth: 2, background: '#ffffff' },\n surface_case: {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n },\n },\n legend: {\n title: 'LEGENDA',\n itemWidth: 110,\n height: 44,\n padding: 4,\n maxWidth: 700,\n borderRadius: 3,\n labels: {\n fractureSingle: 'Fratura simples',\n fractureSwarm: 'Enxame de fraturas',\n fractureWater: \"Entrada d'água\",\n caveDry: 'Caverna seca',\n caveWet: 'Caverna c/ água',\n boreHole: 'Perfuração',\n surfaceCase: 'Tubo guia',\n holeFillGravel: 'Pré-filtro',\n holeFillSeal: 'Vedação',\n wellCase: 'Revestimento',\n wellScreen: 'Filtro',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n\nexport const INTERACTIVE_RENDER_CONFIG: RenderConfig = {\n zoom: true,\n pan: true,\n zoomLevel: 1,\n animation: { duration: 600, ease: easeCubic },\n geologic: { xLeft: 6, xRightInset: 56 },\n layout: {\n pocoWidthRatio: 0.25, // construction column occupies 25% of total SVG width\n pocoCenterRatio: 0.11, // construction center x-offset (positive = shift right of SVG centre)\n },\n caves: {\n pathSteps: 40,\n amplitude: {\n ratio: 0.12, // cave contact waviness: 12% of the cave band pixel height\n min: 1,\n max: 5.5,\n },\n },\n fractures: {\n widthMultiplier: 1.2,\n hitBuffer: { single: 8, swarm: 15 },\n swarm: {\n lineCountBase: 3,\n lineCountVariance: 11,\n spread: 18,\n },\n },\n construction: {\n cementPad: { widthMultiplier: 0.9, thicknessMultiplier: 1.3 },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n },\n labels: {\n active: false,\n typeLabels: { fracture: 'fratura', cave: 'caverna' },\n depthTipHeight: 11,\n depthTipPadX: 2,\n descriptionXOffset: 78,\n descriptionMaxWidth: 226,\n stackingLineHeight: 11,\n stackingGap: 0,\n },\n unitLabels: {\n active: false,\n xOffset: 0,\n stripWidth: 8,\n minHeightForText: 8,\n innerDividerWidth: 1.5,\n outerEdgeWidth: 0.6,\n },\n constructionLabels: {\n active: false,\n xOffset: 10,\n labelRadius: 2,\n labels: {\n wellCasePrefix: 'Revest.',\n wellScreenPrefix: 'Filtro',\n wellScreenSlotPrefix: 'Ranhura:',\n },\n },\n textures: {\n pad: { background: '#ffffff', stroke: '#303030' },\n conflict: { stroke: '#E52117' },\n cave_dry: { size: 8, stroke: '#333333', background: '#ffffff' },\n cave_wet: { size: 8, stroke: '#1a6fa8', background: '#ffffff' },\n seal: { background: '#ffffff' },\n gravel_pack: { background: '#ffffff' },\n well_screen: { size: 40, strokeWidth: 2, background: '#ffffff' },\n surface_case: {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n },\n },\n legend: {\n title: 'LEGENDA',\n itemWidth: 110,\n height: 44,\n padding: 4,\n maxWidth: 700,\n borderRadius: 3,\n labels: {\n fractureSingle: 'Fratura simples',\n fractureSwarm: 'Enxame de fraturas',\n fractureWater: \"Entrada d'água\",\n caveDry: 'Caverna seca',\n caveWet: 'Caverna c/ água',\n boreHole: 'Perfuração',\n surfaceCase: 'Tubo guia',\n holeFillGravel: 'Pré-filtro',\n holeFillSeal: 'Vedação',\n wellCase: 'Revestimento',\n wellScreen: 'Filtro',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n","import { TextureCode } from '@welldot/core';\n\n/**\n * Dynamically imports the FGDC texture registry (SVG path data keyed by texture code).\n * Useful for external UIs that need to display texture thumbnails in selection controls.\n */\nexport async function importFgdcTextures(): Promise<{\n [code: TextureCode]: string;\n}> {\n const fgdcTextures = await import('../data/fgdcTextures.json');\n return fgdcTextures.default as { [code: TextureCode]: string };\n}\n","// TODO use only the need parts of d3 instead of importing the whole library, which will reduce bundle size and improve performance\nimport * as d3module from 'd3';\n// eslint-disable-next-line import-x/default\nimport d3tip from 'd3-tip';\n\nimport { defu } from 'defu';\nimport {\n createWellTextures,\n type WellTextures,\n} from './configs/render.textures';\n\nconst d3 = Object.assign(d3module, { tip: d3tip });\n\nimport {\n isWellEmpty,\n type Constructive,\n type SurfaceCase,\n type Units,\n type Well,\n} from '@welldot/core';\nimport { getProfileLastItemsDepths } from '@welldot/utils';\nimport {\n ComponentsClassNames,\n DeepPartial,\n DrawContext,\n DrawGroups,\n Highlights,\n InstanceState,\n RenderConfig,\n SvgInstance,\n SvgSelection,\n WellTheme,\n} from '~/types/render.types';\nimport { getLengthUnit } from '~/utils/format.utils';\nimport { DEFAULT_COMPONENTS_CLASS_NAMES } from './configs/render.classnames';\nimport {\n DEFAULT_WELL_THEME,\n INTERACTIVE_RENDER_CONFIG,\n} from './configs/render.configs';\nimport { drawAnnotationLabels } from './renderers/annotation-labels.renderer';\nimport { drawCaves } from './renderers/caves.renderer';\nimport { drawConstructionLabels } from './renderers/construction-labels.renderer';\nimport { drawConstructive } from './renderers/construction.renderer';\nimport { drawFractures } from './renderers/fractures.renderer';\nimport { drawHighlights } from './renderers/highlights.renderer';\nimport { drawWellLegend } from './renderers/legend.renderer';\nimport { drawLithology } from './renderers/lithology.renderer';\nimport { drawUnitLabels } from './renderers/unit-labels.renderer';\nimport { asSvgElement } from './utils/d3.utils';\nimport { buildSvgStyleBlock } from './utils/render.styles';\nimport {\n filterByDepth,\n populateTooltips,\n preloadFgdcTextures,\n} from './utils/render.utils';\n\n/**\n * SVG-based renderer for geological well profiles.\n *\n * One instance manages one or more SVG panels (multi-panel layouts for long wells).\n * Call `prepareSvg()` once to initialise the DOM and preload textures, then call\n * `draw(profile)` whenever the profile data changes.\n *\n * @example\n * ```ts\n * const renderer = new WellRenderer(\n * [{ selector: '#well-svg', height: 600, width: 300, margins: { top: 20, right: 10, bottom: 20, left: 40 } }],\n * { renderConfig: INTERACTIVE_RENDER_CONFIG },\n * );\n * await renderer.prepareSvg();\n * renderer.draw(profile);\n * ```\n */\nexport class WellRenderer {\n private svgInstances: SvgInstance[] = [];\n private instanceStates: InstanceState[] = [];\n private textures: WellTextures = createWellTextures();\n private onError?: (err: Error) => void;\n\n classes = DEFAULT_COMPONENTS_CLASS_NAMES;\n private renderConfig: RenderConfig = INTERACTIVE_RENDER_CONFIG;\n private theme: WellTheme = DEFAULT_WELL_THEME;\n private units: Units = {\n length: 'm',\n diameter: 'mm',\n };\n\n /**\n * @param svgs - One entry per SVG panel; multi-entry for split-panel layouts.\n * @param options.classNames - Override default BEM CSS class names.\n * @param options.units - Active measurement units (`length` and `diameter`).\n * @param options.renderConfig - Rendering behaviour (zoom, pan, animation, layout). Defaults to `INTERACTIVE_RENDER_CONFIG`.\n * @param options.theme - Visual theme overrides. Merged on top of `DEFAULT_WELL_THEME`.\n * @param options.onError - Called when a draw error occurs (e.g., a renderer throws). Falls back to `console.error` if omitted.\n */\n constructor(\n svgs: SvgInstance[],\n options: {\n classNames?: DeepPartial<ComponentsClassNames>;\n units?: Units;\n renderConfig?: DeepPartial<RenderConfig>;\n theme?: DeepPartial<WellTheme>;\n onError?: (err: Error) => void;\n } = {},\n ) {\n if (svgs.length === 0) {\n console.warn(\n '[WellRenderer] No SVG instances provided. The renderer will be a no-op.',\n );\n return;\n }\n this.svgInstances = svgs;\n if (options.onError) this.onError = options.onError;\n\n if (options.classNames) {\n this.classes = defu(\n options.classNames,\n DEFAULT_COMPONENTS_CLASS_NAMES,\n ) as ComponentsClassNames;\n }\n\n if (options.units) {\n this.units = { ...this.units, ...options.units };\n }\n\n if (options.renderConfig) {\n this.renderConfig = defu(\n options.renderConfig,\n INTERACTIVE_RENDER_CONFIG,\n ) as RenderConfig;\n }\n\n this.theme = defu(options.theme ?? {}, DEFAULT_WELL_THEME) as WellTheme;\n\n this.textures = createWellTextures(this.renderConfig.textures);\n }\n\n private initInstanceSvg(inst: SvgInstance, index: number): InstanceState {\n const clipId = `fractures-clip-${index}`;\n const clipRectId = `fractures-clip-rect-${index}`;\n const { selector, height, width, margins } = inst;\n const svgWidth = width + margins.left + margins.right;\n const svgHeight = height + margins.top + margins.bottom;\n\n const svg = d3.select(selector) as SvgSelection;\n svg.selectAll('*').remove();\n\n svg.attr('height', svgHeight).attr('width', svgWidth);\n\n const defs = svg.append('defs');\n defs.append('style').text(buildSvgStyleBlock(this.theme));\n defs\n .append('clipPath')\n .attr('id', clipId)\n .append('rect')\n .attr('id', clipRectId)\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', 100000)\n .attr('height', 10000);\n\n const poco = svg.append('g').attr('class', this.classes.wellGroup);\n\n const geologic = poco\n .append('g')\n .attr('class', this.classes.geologicGroup)\n .attr('transform', `translate(${margins.left}, ${margins.top})`);\n\n geologic.append('g').attr('class', this.classes.yAxis);\n geologic.append('g').attr('class', this.classes.unitLabels.group);\n geologic.append('g').attr('class', this.classes.lithology.group);\n geologic.append('g').attr('class', this.classes.caves.group);\n geologic.append('g').attr('class', this.classes.labels.lithology.group);\n geologic.append('g').attr('class', this.classes.highlights.geologicGroup);\n\n const construction = poco\n .append('g')\n .attr('class', this.classes.constructionGroup)\n .attr(\n 'transform',\n `translate(${margins.left + width / 2}, ${margins.top})`,\n );\n\n const fracturesGroup = poco\n .append('g')\n .attr('class', this.classes.fractures.group)\n .attr('transform', `translate(${margins.left}, ${margins.top})`)\n .attr('clip-path', `url(#${clipId})`);\n\n fracturesGroup\n .append('g')\n .attr('class', this.classes.highlights.fracturesGroup);\n\n construction\n .append('g')\n .attr('class', this.classes.constructionLabels.group);\n construction.append('g').attr('class', this.classes.cementPad.group);\n construction.append('g').attr('class', this.classes.boreHole.group);\n construction.append('g').attr('class', this.classes.surfaceCase.group);\n construction.append('g').attr('class', this.classes.holeFill.group);\n construction.append('g').attr('class', this.classes.wellCase.group);\n construction.append('g').attr('class', this.classes.wellScreen.group);\n construction.append('g').attr('class', this.classes.conflict.group);\n construction\n .append('g')\n .attr('class', this.classes.highlights.constructionGroup);\n\n Object.values(this.textures).forEach(texture => svg.call(texture));\n\n return { svg, height, width, margins, clipId, clipRectId };\n }\n\n /** Renders a standalone legend into the element matched by `selector`. */\n public renderLegend(selector: string, profile: Well): void {\n drawWellLegend(selector, profile, {\n config: this.renderConfig.legend,\n theme: this.theme,\n classNames: this.classes.legend,\n textures: this.renderConfig.textures,\n });\n }\n\n /**\n * Initialises the SVG DOM structure and preloads FGDC textures.\n * Must be called once before the first `draw()`.\n */\n public async prepareSvg() {\n await preloadFgdcTextures();\n this.instanceStates = this.svgInstances.map((inst, i) =>\n this.initInstanceSvg(inst, i),\n );\n }\n\n /**\n * Renders the well profile into all configured SVG panels.\n * @param profile - The well data to render.\n * @param options.units - Override the instance-level measurement units for this render.\n * @param options.highlights - Highlight overlays to display on top of the profile.\n */\n draw(\n profile: Well,\n options: { units?: Units; highlights?: Highlights } = {},\n ) {\n if (isWellEmpty(profile)) return;\n this.units = { ...this.units, ...options.units };\n const highlights = options.highlights ?? {};\n\n const maxValues = getProfileLastItemsDepths(profile);\n const maxYValues = d3.max(maxValues) || 0;\n\n if (this.instanceStates.length === 1) {\n this.drawLogToInstance(\n this.instanceStates[0],\n profile,\n 0,\n maxYValues,\n highlights,\n );\n return;\n }\n\n const totalHeight =\n this.instanceStates.reduce((s, st) => s + st.height, 0) || 1;\n const yScaleGlobal = d3\n .scaleLinear()\n .domain([0, maxYValues])\n .range([0, totalHeight]);\n\n let currentDepth = 0;\n for (const state of this.instanceStates) {\n const maxSvgDepth = yScaleGlobal.invert(\n yScaleGlobal(currentDepth) + state.height,\n );\n this.drawLogToInstance(\n state,\n profile,\n currentDepth,\n maxSvgDepth,\n highlights,\n );\n currentDepth = maxSvgDepth;\n }\n }\n\n private drawLogToInstance(\n state: InstanceState,\n profile: Well,\n depthFrom: number,\n depthTo: number,\n highlights: Highlights = {},\n ) {\n const svg = state.svg;\n\n const pocoGroup = svg.select(`.${this.classes.wellGroup}`);\n const lithologyGroup = svg.select(`.${this.classes.lithology.group}`);\n const fracturesGroup = svg.select(`.${this.classes.fractures.group}`);\n const cavesGroup = svg.select(`.${this.classes.caves.group}`);\n const lithologyLabelsGroup = svg.select(\n `.${this.classes.labels.lithology.group}`,\n );\n const constructionGroup = svg.select(`.${this.classes.constructionGroup}`);\n const cementPadGroup = svg.select(`.${this.classes.cementPad.group}`);\n const holeGroup = svg.select(`.${this.classes.boreHole.group}`);\n const surfaceCaseGroup = svg.select(`.${this.classes.surfaceCase.group}`);\n const holeFillGroup = svg.select(`.${this.classes.holeFill.group}`);\n const wellCaseGroup = svg.select(`.${this.classes.wellCase.group}`);\n const wellScreenGroup = svg.select(`.${this.classes.wellScreen.group}`);\n const conflictGroup = svg.select(`.${this.classes.conflict.group}`);\n const constructionLabelsGroup = svg.select(\n `.${this.classes.constructionLabels.group}`,\n );\n const highlightsGeologicGroup = svg.select(\n `.${this.classes.highlights.geologicGroup}`,\n );\n const highlightsConstructionGroup = svg.select(\n `.${this.classes.highlights.constructionGroup}`,\n );\n const highlightsFracturesGroup = svg.select(\n `.${this.classes.highlights.fracturesGroup}`,\n );\n const unitLabelsGroup = svg.select(`.${this.classes.unitLabels.group}`);\n\n const svgWidth = state.width + state.margins.left + state.margins.right;\n const svgHeight = state.height + state.margins.top + state.margins.bottom;\n const { pocoWidthRatio, pocoCenterRatio } = this.renderConfig.layout;\n const POCO_WIDTH = svgWidth * pocoWidthRatio;\n const POCO_CENTER = svgWidth * pocoCenterRatio;\n\n const { duration, ease } = this.renderConfig.animation;\n const transition = d3.transition().duration(duration).ease(ease);\n\n const tooltips = populateTooltips(\n svg,\n this.classes,\n this.units,\n this.renderConfig.tooltips,\n );\n\n const { xLeft: geoXLeft, xRightInset: geoXRightInset } =\n this.renderConfig.geologic;\n const geoXRight = svgWidth - geoXRightInset;\n const pocoCenterX = state.width / 2 + POCO_CENTER / 2;\n\n const geologicData = {\n lithology: profile.lithology,\n fractures: profile.fractures,\n caves: profile.caves,\n };\n const constructionData = {\n cement_pad: profile.cement_pad,\n bore_hole: profile.bore_hole,\n hole_fill: profile.hole_fill,\n surface_case: profile.surface_case,\n well_case: profile.well_case,\n well_screen: profile.well_screen,\n reduction: profile.reduction,\n fractures: profile.fractures,\n } as Constructive;\n\n const contentHeight = svgHeight - state.margins.top - state.margins.bottom;\n\n const yScaleLocal = d3\n .scaleLinear()\n .domain([depthFrom, depthTo])\n .range([0, contentHeight]);\n\n const depthFactor = this.units.length === 'ft' ? 3.28084 : 1;\n const yScaleAxis = d3\n .scaleLinear()\n .domain([depthFrom * depthFactor, depthTo * depthFactor])\n .range([0, contentHeight]);\n\n const yAxis = d3\n .axisLeft(yScaleAxis)\n .tickFormat(\n (d: d3module.NumberValue) => `${d}${getLengthUnit(this.units.length)}`,\n );\n\n const gY = svg.select<SVGGElement>(`.${this.classes.yAxis}`).call(yAxis);\n\n gY.select('.domain')\n .attr('stroke', this.theme.labels.color)\n .attr('fill', 'none');\n gY.selectAll('.tick line').attr('stroke', this.theme.labels.color);\n gY.selectAll('.tick text')\n .attr('fill', this.theme.labels.color)\n .attr('stroke', 'none')\n .attr(\n 'font-size',\n this.theme.labels.scaleFontSize ?? this.theme.labels.fontSize,\n )\n .attr(\n 'font-family',\n this.theme.labels.scaleFont ??\n this.theme.labels.bodyFont ??\n 'sans-serif',\n );\n\n type SpanDatum = { from?: number; to?: number; thickness?: number };\n\n const spanY = (d: SpanDatum): number => {\n if (d.thickness) return yScaleLocal(0) - yScaleLocal(d.thickness);\n return yScaleLocal(Math.max(d.from ?? 0, depthFrom));\n };\n\n const spanH = (d: SpanDatum): number => {\n if (d.thickness) return yScaleLocal(d.thickness) - yScaleLocal(0);\n return Math.max(\n 0,\n yScaleLocal(Math.min(d.to ?? 0, depthTo)) -\n yScaleLocal(Math.max(d.from ?? 0, depthFrom)),\n );\n };\n\n const groups: DrawGroups = {\n lithologyGroup,\n unitLabelsGroup,\n cavesGroup,\n fracturesGroup,\n lithologyLabelsGroup,\n constructionGroup,\n constructionLabelsGroup,\n cementPadGroup,\n holeGroup,\n surfaceCaseGroup,\n holeFillGroup,\n wellCaseGroup,\n wellScreenGroup,\n conflictGroup,\n highlightsGeologicGroup,\n highlightsConstructionGroup,\n highlightsFracturesGroup,\n };\n\n const ctx: DrawContext = {\n svg,\n state,\n svgWidth,\n svgHeight,\n POCO_WIDTH,\n POCO_CENTER,\n pocoCenterX,\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale: yScaleLocal,\n transition,\n tooltips,\n renderConfig: this.renderConfig,\n theme: this.theme,\n classes: this.classes,\n textures: this.textures,\n units: this.units,\n constructionData,\n groups,\n };\n\n const inDepth = filterByDepth(depthFrom, depthTo);\n const filteredConstruction = {\n ...constructionData,\n bore_hole: constructionData.bore_hole.filter(inDepth),\n hole_fill: constructionData.hole_fill.filter(inDepth),\n surface_case: constructionData.surface_case.filter(inDepth),\n well_case: constructionData.well_case.filter(inDepth),\n well_screen: constructionData.well_screen.filter(inDepth),\n reduction: constructionData.reduction?.filter(inDepth) ?? [],\n };\n\n const zooming = (e: { transform: d3module.ZoomTransform }): void => {\n const transform = e.transform;\n const zoomedCtx: DrawContext = {\n ...ctx,\n yScale: transform.rescaleY(yScaleLocal),\n };\n\n gY.call(yAxis.scale(transform.rescaleY(yScaleAxis)));\n\n pocoGroup\n .selectAll('rect')\n .attr('y', (d: unknown) => {\n if (!d) return null;\n return transform.applyY(spanY(d as SpanDatum));\n })\n .attr('height', (d: unknown) => {\n if (!d) return null;\n return transform.k * spanH(d as SpanDatum);\n });\n\n // Surface case: update fill rect y/height and side line y1/y2\n surfaceCaseGroup\n .selectAll(`g.${this.classes.surfaceCase.rect}`)\n .each((d: unknown, i, nodes) => {\n if (!d) return;\n const sc = d as SurfaceCase;\n const g = d3.select(nodes[i] as Element);\n const y = transform.applyY(spanY(sc));\n const h = transform.k * spanH(sc);\n g.select('.surface-case-fill').attr('y', y).attr('height', h);\n g.selectAll('.surface-case-side')\n .attr('y1', y)\n .attr('y2', y + h);\n });\n\n // Fractures: recompute transform so rotation pivot tracks the scaled depth\n fracturesGroup\n .selectAll(`g.${this.classes.fractures.item}`)\n .attr('transform', (d: unknown) => {\n if (!d) return null;\n const f = d as { depth: number; dip: number };\n const cx = pocoCenterX;\n const cy = transform.applyY(yScaleLocal(f.depth));\n return `translate(0,${cy}) rotate(${f.dip},${cx},0)`;\n });\n\n // Delegated redraws — unconditional, each renderer self-guards:\n drawCaves(zoomedCtx, geologicData.caves?.filter(inDepth) ?? []);\n drawUnitLabels(zoomedCtx, profile.lithology?.filter(inDepth) ?? []);\n drawAnnotationLabels(zoomedCtx, {\n lithology: profile.lithology?.filter(inDepth) ?? [],\n fractures:\n profile.fractures?.filter(\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n caves: profile.caves?.filter(inDepth) ?? [],\n });\n drawConstructionLabels(zoomedCtx, {\n well_case: constructionData.well_case.filter(inDepth),\n well_screen: constructionData.well_screen.filter(inDepth),\n });\n drawHighlights(zoomedCtx, highlights);\n };\n\n const drawProfile = () => {\n drawLithology(ctx, profile.lithology?.filter(inDepth) ?? []);\n drawUnitLabels(ctx, profile.lithology?.filter(inDepth) ?? []);\n drawAnnotationLabels(ctx, {\n lithology: profile.lithology?.filter(inDepth) ?? [],\n fractures:\n profile.fractures?.filter(\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n caves: profile.caves?.filter(inDepth) ?? [],\n });\n drawCaves(ctx, profile.caves?.filter(inDepth) ?? []);\n drawFractures(\n ctx,\n profile.fractures?.filter(\n // exclusive upper bound: depthTo is the start of the next panel\n f => f.depth >= depthFrom && f.depth < depthTo,\n ) ?? [],\n );\n drawConstructive(ctx, filteredConstruction);\n drawConstructionLabels(ctx, {\n well_case: filteredConstruction.well_case,\n well_screen: filteredConstruction.well_screen,\n });\n svg.select(`#${state.clipRectId}`).attr('y', 0).attr('height', svgHeight);\n drawHighlights(ctx, highlights);\n };\n\n try {\n drawProfile();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (this.onError) {\n this.onError(error);\n } else {\n console.error('[WellRenderer] drawProfile failed:', error);\n }\n }\n\n const { zoom: zoomEnabled, pan: panEnabled } = this.renderConfig;\n if (zoomEnabled || panEnabled) {\n const zoomNode = d3.zoom<SVGSVGElement, unknown>();\n if (zoomEnabled || panEnabled) zoomNode.on('zoom', zooming);\n if (!zoomEnabled) zoomNode.scaleExtent([1, 1]);\n if (!panEnabled)\n zoomNode.filter(e => e.type === 'wheel' || e.type === 'dblclick');\n asSvgElement<SVGSVGElement>(svg).call(zoomNode);\n\n const initialZoom = this.renderConfig.zoomLevel ?? 1;\n if (initialZoom !== 1) {\n asSvgElement<SVGSVGElement>(svg).call(\n zoomNode.transform,\n d3.zoomIdentity.scale(initialZoom),\n );\n }\n }\n }\n}\n\nexport default {\n WellRenderer,\n};\n","import textures from 'textures';\n\n// ── Per-texture config types ──────────────────────────────────────────────────\n\nexport type PadTextureConfig = {\n background: string;\n stroke: string;\n};\n\nexport type ConflictTextureConfig = {\n stroke: string;\n};\n\nexport type CaveDryTextureConfig = {\n size: number;\n stroke: string;\n background: string;\n};\n\nexport type CaveWetTextureConfig = {\n size: number;\n stroke: string;\n background: string;\n};\n\nexport type SealTextureConfig = {\n background: string;\n};\n\nexport type GravelPackTextureConfig = {\n size: number;\n background: string;\n};\n\nexport type WellScreenTextureConfig = {\n size: number;\n strokeWidth: number;\n background: string;\n};\n\nexport type SurfaceCaseTextureConfig = {\n orientation: string[];\n size: number;\n strokeWidth: number;\n shapeRendering: string;\n stroke: string;\n background: string;\n};\n\n// ── Aggregate ─────────────────────────────────────────────────────────────────\n\nexport type TexturesConfig = {\n pad?: Partial<PadTextureConfig>;\n conflict?: Partial<ConflictTextureConfig>;\n cave_dry?: Partial<CaveDryTextureConfig>;\n cave_wet?: Partial<CaveWetTextureConfig>;\n seal?: Partial<SealTextureConfig>;\n gravel_pack?: Partial<GravelPackTextureConfig>;\n well_screen?: Partial<WellScreenTextureConfig>;\n surface_case?: Partial<SurfaceCaseTextureConfig>;\n};\n\nexport type WellTextures = {\n pad: ReturnType<typeof textures.lines>;\n conflict: ReturnType<typeof textures.lines>;\n cave_dry: ReturnType<typeof textures.lines>;\n cave_wet: ReturnType<typeof textures.lines>;\n seal: ReturnType<typeof textures.lines>;\n gravel_pack: ReturnType<typeof textures.circles>;\n well_screen: ReturnType<typeof textures.paths>;\n surface_case: ReturnType<typeof textures.lines>;\n};\n\nexport function createWellTextures(cfg?: TexturesConfig): WellTextures {\n const pad: PadTextureConfig = {\n background: '#ffffff',\n stroke: '#303030',\n ...cfg?.pad,\n };\n\n const conflict: ConflictTextureConfig = {\n stroke: '#E52117',\n ...cfg?.conflict,\n };\n\n const cave_dry: CaveDryTextureConfig = {\n size: 8,\n stroke: '#333333',\n background: '#ffffff',\n ...cfg?.cave_dry,\n };\n\n const cave_wet: CaveWetTextureConfig = {\n size: 8,\n stroke: '#1a6fa8',\n background: '#ffffff',\n ...cfg?.cave_wet,\n };\n\n const seal: SealTextureConfig = {\n background: '#ffffff',\n ...cfg?.seal,\n };\n\n const gravel_pack: GravelPackTextureConfig = {\n size: 16,\n background: '#ffffff',\n ...cfg?.gravel_pack,\n };\n\n const well_screen: WellScreenTextureConfig = {\n size: 40,\n strokeWidth: 2,\n background: '#ffffff',\n ...cfg?.well_screen,\n };\n\n const surface_case: SurfaceCaseTextureConfig = {\n orientation: ['vertical', 'horizontal'],\n size: 4,\n strokeWidth: 1,\n shapeRendering: 'crispEdges',\n stroke: '#303030',\n background: '#fff',\n ...cfg?.surface_case,\n } as SurfaceCaseTextureConfig;\n\n return {\n pad: textures\n .lines()\n .heavier(10)\n .thinner(1.5)\n .stroke(pad.stroke)\n .background(pad.background),\n conflict: textures.lines().heavier().stroke(conflict.stroke),\n cave_dry: textures\n .lines()\n .size(cave_dry.size)\n .orientation('6/8')\n .heavier(0.3)\n .thinner(0.8)\n .background(cave_dry.background)\n .stroke(cave_dry.stroke),\n cave_wet: textures\n .lines()\n .size(cave_wet.size)\n .orientation('6/8')\n .heavier(0.3)\n .thinner(0.8)\n .background(cave_wet.background)\n .stroke(cave_wet.stroke),\n seal: textures.lines().thicker().background(seal.background),\n gravel_pack: textures\n .circles()\n .size(gravel_pack.size)\n .complement()\n .background(gravel_pack.background),\n well_screen: textures\n .paths()\n .d(s => `M ${s / 4} ${s / 4} l ${s / 2} 0 `)\n .size(well_screen.size)\n .strokeWidth(well_screen.strokeWidth)\n .thicker(2)\n .background(well_screen.background),\n surface_case: (textures.lines() as any)\n .orientation(...surface_case.orientation)\n .size(surface_case.size)\n .strokeWidth(surface_case.strokeWidth)\n .shapeRendering(surface_case.shapeRendering)\n .stroke(surface_case.stroke)\n .background(surface_case.background) as ReturnType<typeof textures.lines>,\n };\n}\n","import type { DiameterUnits, LengthUnits } from '@welldot/core';\n\nconst MM_TO_INCHES = 0.0393701;\nconst M_TO_FT = 3.28084;\n\n/** Formats a depth value in metres to the active length unit string. */\nexport function formatLength(m: number, units: LengthUnits): string {\n return units === 'ft' ? (m * M_TO_FT).toFixed(1) : String(m);\n}\n\n/** Formats a diameter value in millimetres to the active diameter unit string. */\nexport function formatDiameter(mm: number, units: DiameterUnits): string {\n return units === 'inches' ? (mm * MM_TO_INCHES).toFixed(2) : String(mm);\n}\n\n/** Returns the display label for the active length unit (e.g. `\"m\"` or `\"ft\"`). */\nexport function getLengthUnit(units: LengthUnits): string {\n return units === 'ft' ? 'ft' : 'm';\n}\n\n/** Returns the display label for the active diameter unit (e.g. `\"mm\"` or `'\"'`). */\nexport function getDiameterUnit(units: DiameterUnits): string {\n return units === 'inches' ? '\"' : 'mm';\n}\n","import { ComponentsClassNames } from '~/types/render.types';\n\nexport const DEFAULT_COMPONENTS_CLASS_NAMES: ComponentsClassNames = {\n tooltip: {\n root: 'wp-tooltip',\n title: 'wp-tooltip-title',\n primaryInfo: 'wp-tooltip-primary',\n secondaryInfo: 'wp-tooltip-secondary',\n },\n yAxis: 'wp-y-axis',\n wellGroup: 'wp-well-group',\n geologicGroup: 'wp-geologic-group',\n lithology: {\n group: 'lithology-group',\n rect: 'lithology-rect',\n },\n fractures: {\n group: 'fractures-group',\n item: 'fracture-group',\n hitArea: 'fracture-hit',\n line: 'fracture-line',\n polyline: 'fracture-poly',\n },\n caves: {\n group: 'caves-group',\n item: 'cave-group',\n fill: 'cave-fill',\n contact: 'cave-contact',\n },\n constructionGroup: 'construction-group',\n constructionLabels: {\n group: 'construction-labels-group',\n },\n cementPad: {\n group: 'cement-pad',\n item: 'cement-pad-rect',\n },\n boreHole: {\n group: 'hole',\n rect: 'bore-hole-rect',\n },\n surfaceCase: {\n group: 'surface-case',\n rect: 'surface-case-rect',\n },\n holeFill: {\n group: 'hole-fill',\n rect: 'hole-fill-rect',\n },\n wellCase: {\n group: 'well-case',\n rect: 'well-case-rect',\n },\n wellScreen: {\n group: 'well-screen',\n rect: 'well-screen-rect',\n },\n conflict: {\n group: 'conflict',\n rect: 'conflict-rect',\n },\n unitLabels: {\n group: 'unit-labels-group',\n geoRect: 'unit-geo-rect',\n aqRect: 'unit-aq-rect',\n text: 'unit-label-text',\n },\n labels: {\n lithology: {\n group: 'lithology-labels-group',\n depth: 'lithology-depth-tip',\n label: 'lithology-label',\n divider: 'lithology-label-divider',\n },\n },\n legend: {\n border: 'wp-legend-border',\n title: 'wp-legend-title',\n item: 'wp-legend-item',\n label: 'wp-legend-label',\n fracturePoly: 'fracture-poly',\n caveFill: 'cave-fill',\n constructionRect: 'construction-rect',\n },\n highlights: {\n geologicGroup: 'wp-highlights-geologic',\n constructionGroup: 'wp-highlights-construction',\n fracturesGroup: 'wp-highlights-fractures',\n item: 'wp-highlight-item',\n rect: 'wp-highlight-rect',\n label: 'wp-highlight-label',\n labelBg: 'wp-highlight-label-bg',\n },\n};\n","import textures from 'textures';\n\nimport { Lithology } from '@welldot/core';\nimport { Conflict, SvgSelection } from '~/types/render.types';\nimport { importFgdcTextures } from '~/utils/fgdcTextures';\n\n// Re-exports so consumers and tests can still import from this single barrel.\nexport { filterByDepth, getYAxisFunctions } from './d3.utils';\nexport { makeSeededPrng, ptsToSmoothPath, wavyContact } from './geometry.utils';\nexport { populateTooltips } from './tooltips.utils';\n\nlet _fgdcTextures: Record<string, string> = {};\nlet _fgdcTexturesPromise: Promise<void> | null = null;\n\nexport const preloadFgdcTextures = (): Promise<void> => {\n if (!_fgdcTexturesPromise) {\n _fgdcTexturesPromise = importFgdcTextures().then(t => {\n _fgdcTextures = t;\n });\n }\n return _fgdcTexturesPromise;\n};\n\nexport type LithologyTextureOptions = {\n size: number;\n strokeWidth: number;\n stroke: string;\n};\n\n/** Returns a map from \"texture.from\" keys to textures.js fill objects for each lithology entry. */\nexport const getLithologicalFillList = (\n data: Lithology[],\n opts: LithologyTextureOptions,\n) => {\n const uniqueTextureCodes = [...new Set(data.map(d => d.fgdc_texture))];\n const texturesLoaded = Object.fromEntries(\n uniqueTextureCodes\n .filter(code => {\n const path = _fgdcTextures[code];\n return path && path !== '-' && /^[Mm]/.test(path);\n })\n .map(code => [code, _fgdcTextures[code]]),\n );\n\n return Object.fromEntries(\n data.map(d => {\n const pathData = texturesLoaded[d.fgdc_texture];\n if (!pathData) return [`${d.fgdc_texture}.${d.from}`, d.color];\n return [\n `${d.fgdc_texture}.${d.from}`,\n textures\n .paths()\n .d(() => pathData)\n .size(opts.size)\n .strokeWidth(opts.strokeWidth)\n .stroke(opts.stroke)\n .background(d.color),\n ];\n }),\n );\n};\n\n/** Returns a fill-value function for a lithology datum, registering texture patterns on the SVG as needed. */\nexport const getLithologyFill = (\n geologyData: Lithology[],\n svg: SvgSelection,\n opts: LithologyTextureOptions,\n) => {\n const lithologicalFill = getLithologicalFillList(geologyData, opts);\n return (d: Lithology) => {\n const fill = lithologicalFill[`${d.fgdc_texture}.${d.from}`];\n if (!fill.url) return fill;\n svg.call(fill as unknown as (selection: SvgSelection) => void);\n return fill.url();\n };\n};\n\n/** Returns all overlapping depth intervals between two arrays of depth-ranged items, carrying the max diameter of each pair. */\nexport const getConflictAreas = (\n array1: Conflict[],\n array2: Conflict[],\n): Conflict[] =>\n array1.flatMap(item1 =>\n array2\n .filter(item2 => item2.from < item1.to && item2.to > item1.from)\n .map(item2 => ({\n from: Math.max(item2.from, item1.from),\n to: Math.min(item2.to, item1.to),\n diameter: Math.max(item1.diameter, item2.diameter),\n })),\n );\n\n/** Merges overlapping or near-adjacent conflict segments (within `buffer` units) into single spans. */\nexport const mergeConflicts = (\n conflicts: Conflict[],\n buffer: number,\n): Conflict[] => {\n if (conflicts.length === 0) return [];\n\n return [...conflicts]\n .sort((a, b) => a.from - b.from)\n .reduce<Conflict[]>((merged, current) => {\n const last = merged[merged.length - 1];\n if (last && current.from <= last.to + buffer) {\n last.to = Math.max(last.to, current.to);\n return merged;\n }\n merged.push({ ...current });\n return merged;\n }, []);\n};\n\n/**\n * Breaks `text` into lines of at most `maxChars` characters on word boundaries.\n * Always returns at least one element.\n */\nexport function wrapText(text: string, maxChars: number): string[] {\n const words = text.split(' ');\n const lines: string[] = [];\n let line = '';\n for (const word of words) {\n const candidate = line ? `${line} ${word}` : word;\n if (candidate.length > maxChars && line) {\n lines.push(line);\n line = word;\n } else {\n line = candidate;\n }\n }\n if (line) lines.push(line);\n return lines.length ? lines : [''];\n}\n","import type { BaseType, Selection, Transition } from 'd3';\n\nimport type { SvgSelection } from '~/types/render.types';\n\n/**\n * Type-safe wrapper for D3's enter+merge pattern.\n * D3's native `.merge()` widens the element type to `GElement | GElement2`;\n * this helper casts the update selection to match the enter element type\n * so the merged result preserves the concrete element type for subsequent `.attr()` and `.transition()` calls.\n */\nexport function mergeEnter<GEl extends Element, Datum>(\n enter: Selection<GEl, Datum, BaseType, unknown>,\n update: Selection<BaseType, Datum, BaseType, unknown>,\n): Selection<GEl, Datum, BaseType, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (enter as any).merge(update) as Selection<\n GEl,\n Datum,\n BaseType,\n unknown\n >;\n}\n\n/**\n * Type-safe wrapper for applying a shared `Transition` to a typed `Selection`.\n * D3's `Selection.transition(t)` requires the transition's element type to extend\n * the selection's element type; since `DrawContext.transition` uses the broad `BaseType`,\n * a direct call fails the TypeScript check. This helper contains the single cast.\n */\nexport function withTransition<GEl extends Element, Datum>(\n selection: Selection<GEl, Datum, BaseType, unknown>,\n transition: Transition<BaseType, unknown, null, undefined>,\n): Transition<GEl, Datum, BaseType, unknown> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (selection as any).transition(transition) as Transition<\n GEl,\n Datum,\n BaseType,\n unknown\n >;\n}\n\n/**\n * Casts a loose `SvgSelection` to a typed SVG element selection.\n * Used when calling D3 behaviors (zoom, axis) that require a concrete element type.\n */\nexport function asSvgElement<GEl extends SVGElement>(\n sel: SvgSelection,\n): Selection<GEl, unknown, HTMLElement, unknown> {\n return sel as unknown as Selection<GEl, unknown, HTMLElement, unknown>;\n}\n\n/** Returns clamped `getHeight` and `getYPos` helpers bound to a D3 scale and optional depth clamp range. */\nexport const getYAxisFunctions = (\n yScale: (value: number) => number,\n clamp?: { from: number; to: number },\n) => {\n const clampFrom = clamp?.from ?? -Infinity;\n const clampTo = clamp?.to ?? Infinity;\n return {\n getHeight: ({ from, to }: { from: number; to: number }) =>\n Math.max(\n 0,\n yScale(Math.min(to, clampTo)) - yScale(Math.max(from, clampFrom)),\n ),\n getYPos: ({ from }: { from: number }) => yScale(Math.max(from, clampFrom)),\n };\n};\n\nfunction hashStr(s: string): string {\n let h = 5381;\n for (let i = 0; i < s.length; i++) {\n h = Math.imul(h, 33) ^ s.charCodeAt(i);\n }\n return (h >>> 0).toString(36);\n}\n\n/**\n * Returns a stable D3 data-join key for a depth-ranged datum by hashing its\n * non-depth fields. Keys survive `reorderComponentsDepth` because `from`/`to`\n * are excluded. Keys are sorted before serialization so field declaration order\n * in the type does not affect the result.\n */\nexport function stableLayerKey<T extends { from: number; to: number }>(\n d: T,\n): string {\n const { from: _f, to: _t, ...rest } = d as Record<string, unknown>;\n const sortedKeys = Object.keys(rest).sort();\n return hashStr(JSON.stringify(rest, sortedKeys));\n}\n\n/** Returns a predicate that tests whether an interval overlaps the window [depthFrom, depthTo]. */\nexport function filterByDepth(\n depthFrom: number,\n depthTo: number,\n): (l: { from: number; to: number }) => boolean {\n return l => !(l.to <= depthFrom || l.from >= depthTo);\n}\n","/**\n * Builds a wavy horizontal contact line as an array of [x, y] points using a\n * damped random walk, giving a natural geological contact appearance.\n * The 0.75 damping factor ensures the offset returns toward zero rather than\n * drifting unboundedly across the width.\n */\nexport const wavyContact = (\n xLeft: number,\n xRight: number,\n baseY: number,\n amp: number,\n steps: number,\n rng: () => number,\n): [number, number][] => {\n const pts: [number, number][] = [];\n let offset = 0;\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const x = xLeft + t * (xRight - xLeft);\n offset += (rng() - 0.5) * amp * 0.6;\n offset *= 0.75;\n pts.push([x, baseY + offset]);\n }\n return pts;\n};\n\n/**\n * Converts an array of [x, y] points into a smooth SVG cubic-Bézier path string using Catmull-Rom tension (0.35).\n * @param options.omitMoveTo - When true, omits the leading `M x,y` command so the path can be\n * appended directly to an existing path string without repositioning the pen.\n */\nexport const ptsToSmoothPath = (\n pts: [number, number][],\n options: { omitMoveTo?: boolean } = {},\n): string => {\n if (pts.length < 2) return '';\n const n = pts.length;\n const tension = 0.35;\n const segments: string[] = [];\n for (let i = 0; i < n - 1; i++) {\n const p0 = pts[Math.max(0, i - 1)];\n const p1 = pts[i];\n const p2 = pts[i + 1];\n const p3 = pts[Math.min(n - 1, i + 2)];\n const cp1x = p1[0] + (p2[0] - p0[0]) * tension;\n const cp1y = p1[1] + (p2[1] - p0[1]) * tension;\n const cp2x = p2[0] - (p3[0] - p1[0]) * tension;\n const cp2y = p2[1] - (p3[1] - p1[1]) * tension;\n segments.push(\n `C ${cp1x.toFixed(1)},${cp1y.toFixed(1)} ${cp2x.toFixed(1)},${cp2y.toFixed(1)} ${p2[0].toFixed(1)},${p2[1].toFixed(1)}`,\n );\n }\n const body = segments.join(' ');\n return options.omitMoveTo\n ? body\n : `M ${pts[0][0].toFixed(1)},${pts[0][1].toFixed(1)} ${body}`;\n};\n\n/**\n * Seeded Park-Miller LCG PRNG — deterministic so every zoom/redraw produces identical shapes.\n * @param seed - Initial seed value (typically a domain coordinate like depth or cave boundary).\n * @param scramble - Multiplier applied to the seed before entering the LCG cycle.\n * Different values produce visually distinct random distributions for different domains.\n * Default 6271 is used for caves; pass 7919 for fractures.\n */\nexport const makeSeededPrng = (seed: number, scramble = 6271) => {\n let s = Math.abs(seed * scramble) | 1;\n return () => {\n s = (s * 16807) % 2147483647;\n return (s - 1) / 2147483646;\n };\n};\n","// TODO remove this dependency on d3-tip by implementing our own tooltip logic using plain divs and mouse events, which will also allow us to support touch devices\nimport * as d3module from 'd3';\n// eslint-disable-next-line import-x/default\nimport d3tip from 'd3-tip';\nimport sanitizeHtml from 'sanitize-html';\n\nimport type {\n BoreHole,\n Cave,\n CementPad,\n Fracture,\n HoleFill,\n Lithology,\n SurfaceCase,\n Units,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport type {\n ComponentsClassNames,\n SvgSelection,\n TooltipKey,\n} from '~/types/render.types';\nimport { formatDiameter, formatLength } from '~/utils/format.utils';\n\nconst d3 = Object.assign(d3module, { tip: d3tip });\n\ninterface D3Tip {\n attr(name: string, value: string): D3Tip;\n direction(dir: string): D3Tip;\n html(fn: (event: unknown, d: unknown) => string): D3Tip;\n show(...args: unknown[]): void;\n hide(...args: unknown[]): void;\n}\n\n/** Strips all HTML tags from a value before inserting it into tooltip markup. */\nconst esc = (v: unknown): string =>\n sanitizeHtml(String(v ?? ''), { allowedTags: [], allowedAttributes: {} });\n\nconst _tooltipCache = new WeakMap<\n Element,\n Record<string, D3Tip | { show: () => void; hide: () => void }>\n>();\n\n/** Initialises d3-tip tooltip instances for each well component, respecting the `tooltipConfig` allow-list. Caches instances per SVG element to prevent duplicate DOM nodes on re-render. */\nexport const populateTooltips = (\n svg: SvgSelection,\n customClasses: ComponentsClassNames,\n units: Units,\n tooltipConfig?: TooltipKey[] | false,\n) => {\n type WithNode = { node?: () => Element | null };\n const svgEl =\n typeof (svg as WithNode).node === 'function'\n ? (svg as { node: () => Element | null }).node()\n : null;\n if (svgEl && _tooltipCache.has(svgEl)) {\n return _tooltipCache.get(svgEl)!;\n }\n\n const tipsText = {\n geology: (_: unknown, d: Lithology) => `\n <span class=\"${customClasses.tooltip.title}\">Litologia</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>\n ${d.geologic_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Unidade geológica:</strong> ${esc(d.geologic_unit)}</span>` : ''}\n ${d.aquifer_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Unidade aquífera:</strong> ${esc(d.aquifer_unit)}</span>` : ''}\n `,\n hole: (_: unknown, d: BoreHole) => `\n <span class=\"${customClasses.tooltip.title}\">FURO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n `,\n surfaceCase: (_: unknown, d: SurfaceCase) => `\n <span class=\"${customClasses.tooltip.title}\">TUBO DE BOCA</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n `,\n holeFill: (_: unknown, d: HoleFill) => `\n <span class=\"${customClasses.tooltip.title}\">ESP. ANULAR</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Diâmetro:</strong>${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Descrição:</strong> ${esc(d.description)}\n </span>\n `,\n wellCase: (_: unknown, d: WellCase) => `\n <span class=\"${customClasses.tooltip.title}\">REVESTIMENTO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Diâmetro:</strong> ${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Tipo:</strong> ${esc(d.type)}</span>\n `,\n wellScreen: (_: unknown, d: WellScreen) => `\n <span class=\"${customClasses.tooltip.title}\">FILTROS</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Diâmetro:</strong> ${esc(formatDiameter(d.diameter, units.diameter))} ${esc(units.diameter)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Tipo:</strong> ${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Ranhura:</strong> ${esc(d.screen_slot_mm)} mm\n </span>\n `,\n conflict: (_: unknown, d: { from: number; to: number }) => `\n <span class=\"${customClasses.tooltip.title}\">CONFLITO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n `,\n fracture: (_: unknown, d: Fracture) => {\n const title = d.swarm ? 'ENXAME DE FRATURAS' : 'FRATURA';\n return `\n <span class=\"${customClasses.tooltip.title}\">${title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\"><strong>Profundidade:</strong> ${esc(formatLength(d.depth, units.length))} ${esc(units.length)}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Entrada d'água:</strong> ${esc(formatLength(d.depth, units.length))} ${esc(units.length)}</span>` : ''}\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Mergulho:</strong> ${esc(d.dip)}°</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Azimute:</strong> ${esc(d.azimuth)}°</span>\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>` : ''}\n `;\n },\n cementPad: (_: unknown, d: CementPad) => `\n <span class=\"${customClasses.tooltip.title}\">LAJE DE PROTEÇÃO</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Espessura:</strong>\n ${esc(formatLength(d.thickness, units.length))} ${esc(units.length)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Largura:</strong> ${esc(formatLength(d.width, units.length))} ${esc(units.length)}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>Comprimento:</strong> ${esc(formatLength(d.length, units.length))} ${esc(units.length)}\n </span>\n `,\n cave: (_: unknown, d: Cave) => `\n <span class=\"${customClasses.tooltip.title}\">CAVERNA</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">De ${esc(formatLength(d.from, units.length))} ${esc(units.length)} até ${esc(formatLength(d.to, units.length))} ${esc(units.length)}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Entrada d'água</strong></span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>Descrição:</strong> ${esc(d.description)}</span>` : ''}\n `,\n };\n\n const noop = { show: () => {}, hide: () => {} };\n const tooltips: Record<string, D3Tip | typeof noop> = {};\n\n Object.getOwnPropertyNames(tipsText).forEach(tipTextKey => {\n const enabled =\n tooltipConfig === undefined\n ? true\n : tooltipConfig !== false &&\n (tooltipConfig as string[]).includes(tipTextKey);\n\n if (!enabled) {\n tooltips[tipTextKey] = noop;\n return;\n }\n\n tooltips[tipTextKey] = (d3 as unknown as { tip: () => D3Tip })\n .tip()\n .attr('class', customClasses.tooltip.root)\n .direction('e')\n .html(tipsText[tipTextKey]);\n\n svg.call(\n tooltips[tipTextKey] as unknown as (selection: SvgSelection) => void,\n );\n });\n\n svgEl?.setAttribute('data-tooltips-init', 'true');\n if (svgEl) _tooltipCache.set(svgEl, tooltips);\n\n return tooltips;\n};\n","import type { AnnotationData, DrawContext } from '~/types/render.types';\nimport { wrapText } from '~/utils/render.utils';\n\ntype AnnotationItem = {\n sortDepth: number;\n baseY: number;\n originX: number;\n originY: number;\n header: string;\n description: string;\n};\n\nfunction activeLabelsSet(\n cfg: boolean | ('lithology' | 'fractures' | 'caves')[],\n): Set<string> {\n if (cfg === false) return new Set<string>();\n if (cfg === true) return new Set(['lithology', 'fractures', 'caves']);\n return new Set(cfg as string[]);\n}\n\nfunction lithologySubSet(\n cfg: boolean | ('depth' | 'description' | 'dividers')[] | undefined,\n): Set<string> {\n if (cfg === false) return new Set<string>();\n if (!cfg || cfg === true)\n return new Set(['depth', 'description', 'dividers']);\n return new Set(cfg as string[]);\n}\n\n/**\n * Renders stacked annotation boxes for lithology/fractures/caves.\n * Items are sorted by depth with overlap-prevention.\n * Returns early if labels are disabled.\n */\nexport function drawAnnotationLabels(\n ctx: DrawContext,\n data: AnnotationData,\n): void {\n if (ctx.renderConfig.labels.active === false) return;\n\n const active = activeLabelsSet(ctx.renderConfig.labels.active);\n const show = lithologySubSet(ctx.renderConfig.labels.lithology);\n const s = ctx.renderConfig.labels;\n const st = ctx.theme.labels;\n\n ctx.groups.lithologyLabelsGroup.selectAll('*').remove();\n\n // ── Depth tips ────────────────────────────────────────────────────────\n if (active.has('lithology') && show.has('depth')) {\n data.lithology\n .filter(d => d.to <= ctx.depthTo)\n .forEach(d => {\n const text = `${d.to}`;\n const approxW = text.length * (st.fontSize * 0.52) + s.depthTipPadX * 2;\n const y = ctx.yScale(d.to) - s.depthTipHeight / 2;\n\n const tipG = ctx.groups.lithologyLabelsGroup\n .append('g')\n .attr('class', ctx.classes.labels.lithology.depth);\n\n tipG\n .append('rect')\n .attr('x', ctx.geoXLeft + 1)\n .attr('y', y)\n .attr('width', approxW)\n .attr('height', s.depthTipHeight)\n .attr('rx', st.depthTipRadius ?? 2)\n .attr('fill', st.depthTipFill ?? 'white')\n .attr('stroke', ctx.theme.lithology.stroke)\n .attr('stroke-width', 0.5);\n\n tipG\n .append('text')\n .attr('class', 'wp-depth-tip-text')\n .attr('fill', ctx.theme.labels.color)\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', ctx.geoXLeft + 1 + s.depthTipPadX)\n .attr('y', y + s.depthTipHeight / 2)\n .attr('dominant-baseline', 'middle')\n .attr('font-size', st.fontSize)\n .text(text);\n });\n }\n\n // ── Build unified annotation items ────────────────────────────────────\n const items: AnnotationItem[] = [];\n\n if (active.has('lithology')) {\n data.lithology\n .filter(d => d.from < ctx.depthTo)\n .forEach(d => {\n items.push({\n sortDepth: d.from,\n baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n originX: ctx.geoXRight,\n originY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n header: `${d.from}–${d.to} m`,\n description: d.description || '',\n });\n });\n }\n\n if (active.has('fractures')) {\n data.fractures\n .filter(d => d.depth >= ctx.depthFrom && d.depth < ctx.depthTo)\n .forEach(d => {\n const typeLabel = d.water_intake ? 'fratura aberta' : 'fratura';\n items.push({\n sortDepth: d.depth,\n baseY: ctx.yScale(d.depth),\n originX: ctx.pocoCenterX,\n originY: ctx.yScale(d.depth),\n header: `${d.depth} m · ${typeLabel}`,\n description: d.description || '',\n });\n });\n }\n\n if (active.has('caves')) {\n data.caves\n .filter(d => d.from < ctx.depthTo)\n .forEach(d => {\n const midDepth = (d.from + d.to) / 2;\n const typeLabel = d.water_intake ? 'caverna úmida' : 'caverna';\n items.push({\n sortDepth: d.from,\n baseY: ctx.yScale(Math.max(d.from, ctx.depthFrom)),\n originX: ctx.geoXRight,\n originY: ctx.yScale(Math.max(midDepth, ctx.depthFrom)),\n header: `${d.from}–${d.to} m · ${typeLabel}`,\n description: d.description || '',\n });\n });\n }\n\n items.sort((a, b) => a.sortDepth - b.sortDepth);\n\n // ── Stacking pass ─────────────────────────────────────────────────────\n type LabelPos = { item: AnnotationItem; yLabel: number; estH: number };\n const labelPositions: LabelPos[] = [];\n let currY = 0;\n const charsPerLine = Math.max(\n 1,\n Math.floor(s.descriptionMaxWidth / (st.fontSize * 0.6)),\n );\n\n items.forEach(item => {\n const descLines = Math.ceil((item.description.length || 1) / charsPerLine);\n const estH = (1 + descLines) * s.stackingLineHeight + 4;\n const yLabel = Math.max(item.baseY, currY + s.stackingGap);\n currY = yLabel + estH;\n labelPositions.push({ item, yLabel, estH });\n });\n\n const labelX = ctx.geoXRight + s.descriptionXOffset;\n\n // ── Dividers ──────────────────────────────────────────────────────────\n if (show.has('dividers') && show.has('description')) {\n labelPositions.forEach(({ item, yLabel }) => {\n ctx.groups.lithologyLabelsGroup\n .append('path')\n .attr('class', ctx.classes.labels.lithology.divider)\n .attr('fill', 'none')\n .attr('stroke', ctx.theme.labels.dividerStroke)\n .attr('stroke-width', ctx.theme.labels.dividerStrokeWidth)\n .attr('stroke-dasharray', ctx.theme.labels.dividerStrokeDasharray)\n .attr(\n 'd',\n `M ${item.originX},${item.originY} L ${ctx.geoXRight + 3},${item.originY} L ${labelX},${yLabel}`,\n );\n });\n }\n\n // ── Labels ────────────────────────────────────────────────────────────\n if (show.has('description')) {\n const lineH = s.stackingLineHeight;\n const bgFill = st.annotationBg ?? 'white';\n\n labelPositions.forEach(({ item, yLabel, estH }) => {\n const labelG = ctx.groups.lithologyLabelsGroup\n .append('g')\n .attr('class', ctx.classes.labels.lithology.label)\n .attr('transform', `translate(${labelX},${yLabel})`);\n\n labelG\n .append('rect')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', s.descriptionMaxWidth)\n .attr('height', estH)\n .attr('rx', st.annotationRadius ?? 2)\n .attr('fill', bgFill)\n .attr('fill-opacity', st.annotationBgOpacity ?? 0.85)\n .attr('stroke', st.annotationBorderColor ?? 'none');\n\n labelG\n .append('text')\n .attr('class', 'wp-annotation-header')\n .attr('fill', ctx.theme.labels.color)\n .attr('font-weight', st.headerFontWeight ?? 600)\n .attr('font-family', ctx.theme.labels.headerFont)\n .attr('x', 0)\n .attr('y', lineH * 0.85)\n .attr('font-size', st.fontSize)\n .text(item.header);\n\n if (item.description) {\n const lines = wrapText(item.description, charsPerLine);\n const bodyEl = labelG\n .append('text')\n .attr('class', 'wp-annotation-body')\n .attr('fill', ctx.theme.labels.bodyColor)\n .attr('font-weight', st.bodyFontWeight ?? 400)\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', 0)\n .attr('y', lineH * 0.85 + lineH)\n .attr('font-size', st.fontSize);\n lines.forEach((line, i) => {\n bodyEl\n .append('tspan')\n .attr('x', 0)\n .attr('dy', i === 0 ? 0 : lineH)\n .text(line);\n });\n }\n });\n }\n}\n","import { Cave } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport {\n makeSeededPrng,\n ptsToSmoothPath,\n wavyContact,\n} from '~/utils/render.utils';\n\n/**\n * Renders cave bands as wavy closed SVG paths with texture fill.\n *\n * Each cave is drawn as a full-width band whose top and bottom contacts are\n * irregular and wavy rather than straight horizontal lines. Two independent\n * seeded PRNGs ensure the top and bottom contacts are visually uncorrelated.\n * Geometry is fully deterministic via those seeded PRNGs, so every redraw\n * (including zoom) produces identical shapes. Returns early if `data` is empty.\n */\nexport function drawCaves(ctx: DrawContext, data: Cave[]): void {\n if (!data.length) return;\n\n const {\n groups: { cavesGroup },\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale,\n renderConfig,\n theme,\n textures,\n classes,\n tooltips,\n } = ctx;\n\n cavesGroup.selectAll(`g.${classes.caves.item}`).remove();\n\n const rc = renderConfig.caves;\n\n data.forEach(cave => {\n // Two different seeds so top and bottom contacts are visually independent.\n // Multiplying by 100 ensures uniqueness even for small integer coordinates\n // (e.g. from=5, to=10 → seedTop=510; from=10, to=5 → seedTop=1005).\n // The +999 offset on seedBot prevents seedTop == seedBot when from == to.\n const seedTop = cave.from * 100 + cave.to;\n const seedBot = cave.to * 100 + cave.from + 999;\n const rngTop = makeSeededPrng(seedTop);\n const rngBot = makeSeededPrng(seedBot);\n\n const yTop = yScale(Math.max(cave.from, depthFrom));\n const yBot = yScale(Math.min(cave.to, depthTo));\n const span = yBot - yTop; // pixel height of the cave band\n\n const amp = Math.max(\n rc.amplitude.min,\n Math.min(span * rc.amplitude.ratio, rc.amplitude.max),\n );\n\n const topCut = cave.from < depthFrom;\n const botCut = cave.to > depthTo;\n\n const topPts = topCut\n ? ([\n [geoXLeft, yTop],\n [geoXRight, yTop],\n ] as [number, number][])\n : wavyContact(geoXLeft, geoXRight, yTop, amp, rc.pathSteps, rngTop);\n const botPts = botCut\n ? ([\n [geoXLeft, yBot],\n [geoXRight, yBot],\n ] as [number, number][])\n : wavyContact(geoXLeft, geoXRight, yBot, amp, rc.pathSteps, rngBot);\n\n // Smooth path strings for each contact\n const topPath = topCut\n ? `M ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} L ${geoXRight.toFixed(1)},${yTop.toFixed(1)}`\n : ptsToSmoothPath(topPts);\n const botPath = botCut\n ? `M ${geoXLeft.toFixed(1)},${yBot.toFixed(1)} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}`\n : ptsToSmoothPath(botPts);\n\n // Closed filled region:\n // top contact L→R + right vertical edge down\n // + bottom contact R→L (reversed) + left vertical edge up + Z\n const botReversed = botCut\n ? `L ${geoXLeft.toFixed(1)},${yBot.toFixed(1)}`\n : ptsToSmoothPath([...botPts].reverse(), { omitMoveTo: true });\n const closedPath = `${topPath} L ${geoXRight.toFixed(1)},${yBot.toFixed(1)}${botReversed} L ${geoXLeft.toFixed(1)},${yTop.toFixed(1)} Z`;\n\n const caveTexture = cave.water_intake\n ? textures.cave_wet\n : textures.cave_dry;\n\n const g = cavesGroup\n .append('g')\n .attr('class', classes.caves.item)\n .datum(cave)\n .style('cursor', 'pointer')\n .on('mouseover', tooltips.cave.show)\n .on('mouseout', tooltips.cave.hide);\n\n const caveStroke = cave.water_intake\n ? theme.cave.wetStroke\n : theme.cave.dryStroke;\n\n g.append('path')\n .attr('class', classes.caves.fill)\n .attr('d', closedPath)\n .attr('fill', caveTexture.url())\n .attr('fill-opacity', theme.cave.fillOpacity)\n .attr('stroke', 'none');\n\n g.append('path')\n .attr('class', classes.caves.contact)\n .attr('d', topPath)\n .attr('fill', 'none')\n .attr('stroke', caveStroke)\n .attr('stroke-width', theme.cave.contactStrokeWidth)\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n\n g.append('path')\n .attr('class', classes.caves.contact)\n .attr('d', botPath)\n .attr('fill', 'none')\n .attr('stroke', caveStroke)\n .attr('stroke-width', theme.cave.contactStrokeWidth)\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n });\n}\n","import * as d3 from 'd3';\n\nimport type { WellCase, WellScreen } from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { DrawContext } from '~/types/render.types';\nimport { formatDiameter, getDiameterUnit } from '~/utils/format.utils';\nimport { wrapText } from '~/utils/render.utils';\n\n/**\n * Renders dimension labels for well cases and screens.\n * Text is word-wrapped if labelMaxWidth is set.\n * An occupancy list prevents overlap between adjacent labels.\n */\nexport function drawConstructionLabels(\n ctx: DrawContext,\n data: { well_case: WellCase[]; well_screen: WellScreen[] },\n): void {\n if (!ctx.renderConfig.constructionLabels.active) return;\n\n ctx.groups.constructionLabelsGroup.selectAll('*').remove();\n\n const clc = ctx.renderConfig.constructionLabels;\n const clct = ctx.theme.constructionLabels;\n const fmtD = (mm: number) => formatDiameter(mm, ctx.units.diameter);\n const dUnit = getDiameterUnit(ctx.units.diameter);\n\n const maxXValues = getProfileDiamValues(ctx.constructionData);\n const xScale = d3\n .scaleLinear()\n .domain([0, d3.max(maxXValues) || 0])\n .range([0, ctx.POCO_WIDTH]);\n\n const occupied: { top: number; bot: number }[] = [];\n\n const placeLabel = (d: WellCase | WellScreen, text: string) => {\n const clampedFrom = Math.max(d.from, ctx.depthFrom);\n const clampedTo = Math.min(d.to, ctx.depthTo);\n if (clampedFrom >= clampedTo) return;\n\n const midY = ctx.yScale((clampedFrom + clampedTo) / 2);\n const leftEdgeX = (ctx.POCO_CENTER - xScale(d.diameter)) / 2;\n const labelRightX = leftEdgeX - clc.xOffset;\n const charW = clct.fontSize * 0.52;\n const lineH = clct.fontSize * 1.35;\n const vertPad = 6;\n\n let lines: string[];\n let boxW: number;\n if (clc.labelMaxWidth !== undefined) {\n const maxChars = Math.max(\n 1,\n Math.floor((clc.labelMaxWidth! - 8) / charW),\n );\n lines = wrapText(text, maxChars);\n boxW = clc.labelMaxWidth;\n } else {\n lines = [text];\n boxW = text.length * charW + 8;\n }\n\n const labelH = lines.length * lineH + vertPad;\n let labelY = midY - labelH / 2;\n\n for (const pos of occupied) {\n if (labelY < pos.bot && labelY + labelH > pos.top) labelY = pos.bot + 2;\n }\n occupied.push({ top: labelY, bot: labelY + labelH });\n\n ctx.groups.constructionLabelsGroup\n .append('rect')\n .attr('x', labelRightX - boxW)\n .attr('y', labelY)\n .attr('width', boxW)\n .attr('height', labelH)\n .attr('rx', clc.labelRadius)\n .attr('fill', clct.labelFill ?? 'white')\n .attr('stroke', clct.labelColor ?? '#303030')\n .attr('stroke-width', 0.5);\n\n const textEl = ctx.groups.constructionLabelsGroup\n .append('text')\n .attr('x', labelRightX - 4)\n .attr('y', labelY + lineH * 0.85)\n .attr('font-size', clct.fontSize)\n .attr('font-family', clct.fontFamily ?? 'sans-serif')\n .attr('font-weight', clct.fontWeight ?? 400)\n .attr('text-anchor', 'end')\n .attr('fill', clct.labelColor ?? '#303030');\n\n lines.forEach((line, i) => {\n textEl\n .append('tspan')\n .attr('x', labelRightX - 4)\n .attr('dy', i === 0 ? 0 : lineH)\n .text(line);\n });\n };\n\n let lastDiam = 0;\n data.well_case\n .filter(item => {\n if (item.diameter !== lastDiam) {\n lastDiam = item.diameter;\n return true;\n }\n return false;\n })\n .forEach(d =>\n placeLabel(\n d,\n `${clc.labels.wellCasePrefix} ${fmtD(d.diameter)}${dUnit} ${d.type}`,\n ),\n );\n\n lastDiam = 0;\n data.well_screen\n .filter(item => {\n if (item.diameter !== lastDiam) {\n lastDiam = item.diameter;\n return true;\n }\n return false;\n })\n .forEach((d: WellScreen) =>\n placeLabel(\n d,\n `${clc.labels.wellScreenPrefix} ${fmtD(d.diameter)}${dUnit} ${d.type} ${clc.labels.wellScreenSlotPrefix} ${fmtD((d as WellScreen).screen_slot_mm)}${dUnit}`,\n ),\n );\n}\n","import * as d3 from 'd3';\n\nimport type {\n BoreHole,\n CementPad,\n Constructive,\n HoleFill,\n SurfaceCase,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { Conflict, DrawContext } from '~/types/render.types';\nimport { stableLayerKey, withTransition } from '~/utils/d3.utils';\nimport {\n getConflictAreas,\n getYAxisFunctions,\n mergeConflicts,\n} from '~/utils/render.utils';\n\n/**\n * Renders all well construction components in order: cement pad, bore holes,\n * surface casing, hole fill, well casing, well screen, and conflict zones.\n * The x-scale domain is computed from ctx.constructionData for consistent\n * widths across multi-SVG panels.\n */\nexport function drawConstructive(ctx: DrawContext, data: Constructive): void {\n const { getHeight, getYPos } = getYAxisFunctions(ctx.yScale, {\n from: ctx.depthFrom,\n to: ctx.depthTo,\n });\n\n const maxXValues = getProfileDiamValues(ctx.constructionData);\n const maxXValueConstruction = d3.max(maxXValues) || 0;\n\n const xScale = d3\n .scaleLinear()\n .domain([0, maxXValueConstruction])\n .range([0, ctx.POCO_WIDTH]);\n\n const rcc = ctx.renderConfig.construction;\n\n ctx.groups.constructionGroup\n .selectAll(`.${ctx.classes.cementPad.item}`)\n .remove();\n\n if (data.cement_pad && data.cement_pad.thickness && ctx.depthFrom === 0) {\n const cementPad = ctx.groups.cementPadGroup\n .selectAll('rect')\n .data([data.cement_pad]);\n\n cementPad.exit().remove();\n\n const newCementPad = cementPad\n .enter()\n .append('rect')\n .attr('class', ctx.classes.cementPad.item)\n .attr(\n 'x',\n (d: CementPad) =>\n (ctx.POCO_CENTER -\n xScale((d.width * rcc.cementPad.widthMultiplier * 1000) / 2)) /\n 2,\n )\n .attr('y', (d: CementPad) => {\n return (\n ctx.yScale(0) -\n ctx.yScale(d.thickness * rcc.cementPad.thicknessMultiplier)\n );\n })\n .attr('width', (d: CementPad) =>\n xScale((d.width * rcc.cementPad.widthMultiplier * 1000) / 2),\n )\n .attr('height', (d: CementPad) => {\n return ctx.yScale(d.thickness * rcc.cementPad.thicknessMultiplier);\n })\n .attr('fill', ctx.textures.pad.url())\n .attr('stroke', ctx.theme.cementPad.stroke)\n .attr('stroke-width', ctx.theme.cementPad.strokeWidth);\n\n newCementPad\n .on('mouseover', ctx.tooltips.cementPad.show)\n .on('mouseout', ctx.tooltips.cementPad.hide);\n }\n\n // --- bore_hole ---\n // Key by diameter (identity of the hole segment, not its position).\n // reorderComponentsDepth changes from/to after any mutation, so depth-based\n // keys would prevent smooth UPDATE transitions for unchanged segments.\n\n const hole = ctx.groups.holeGroup\n .selectAll<SVGRectElement, BoreHole>(`.${ctx.classes.boreHole.rect}`)\n .data(data.bore_hole, stableLayerKey);\n\n hole.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newHole = hole\n .enter()\n .append('rect')\n .attr('class', ctx.classes.boreHole.rect)\n .attr('fill', ctx.theme.boreHole.fill)\n .attr('stroke', ctx.theme.boreHole.stroke)\n .attr('stroke-width', ctx.theme.boreHole.strokeWidth)\n .attr('stroke-dasharray', ctx.theme.boreHole.strokeDasharray)\n .attr('x', (d: BoreHole) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: BoreHole) => xScale(d.diameter))\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('opacity', 0)\n .on('mouseover', ctx.tooltips.hole.show)\n .on('mouseout', ctx.tooltips.hole.hide);\n\n withTransition(newHole, ctx.transition).attr(\n 'opacity',\n ctx.theme.boreHole.opacity,\n );\n\n // x/width set immediately (diameter unchanged for updates); only y/height animate\n hole\n .attr('x', (d: BoreHole) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: BoreHole) => xScale(d.diameter));\n withTransition(hole, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n // --- surface_case ---\n\n const surfaceCaseGs = ctx.groups.surfaceCaseGroup\n .selectAll<SVGGElement, SurfaceCase>(`g.${ctx.classes.surfaceCase.rect}`)\n .data(data.surface_case, stableLayerKey);\n\n surfaceCaseGs.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const newSC = surfaceCaseGs\n .enter()\n .append('g')\n .attr('class', ctx.classes.surfaceCase.rect)\n .style('opacity', 0)\n .on('mouseover', ctx.tooltips.surfaceCase.show)\n .on('mouseout', ctx.tooltips.surfaceCase.hide);\n\n newSC\n .append('rect')\n .attr('class', 'surface-case-fill')\n .attr('stroke', 'none');\n newSC\n .append('line')\n .attr('class', 'surface-case-side')\n .attr('stroke', ctx.theme.surfaceCase.stroke)\n .attr('stroke-width', ctx.theme.surfaceCase.strokeWidth);\n newSC\n .append('line')\n .attr('class', 'surface-case-side')\n .attr('stroke', ctx.theme.surfaceCase.stroke)\n .attr('stroke-width', ctx.theme.surfaceCase.strokeWidth);\n\n newSC.each((d: SurfaceCase, i, nodes) => {\n const x =\n (ctx.POCO_CENTER -\n xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n )) /\n 2;\n const w = xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n );\n const g = d3.select(nodes[i] as Element);\n g.select('.surface-case-fill')\n .attr('x', x)\n .attr('width', w)\n .attr('fill', ctx.textures.surface_case.url())\n .attr('y', getYPos(d))\n .attr('height', getHeight(d));\n const sideNodes = g.selectAll('.surface-case-side').nodes();\n d3.select(sideNodes[0] as Element)\n .attr('x1', x)\n .attr('x2', x)\n .attr('y1', getYPos(d))\n .attr('y2', getYPos(d) + getHeight(d));\n d3.select(sideNodes[1] as Element)\n .attr('x1', x + w)\n .attr('x2', x + w)\n .attr('y1', getYPos(d))\n .attr('y2', getYPos(d) + getHeight(d));\n });\n\n withTransition(newSC, ctx.transition).style('opacity', 1);\n\n surfaceCaseGs.each((d: SurfaceCase, i, nodes) => {\n const x =\n (ctx.POCO_CENTER -\n xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n )) /\n 2;\n const w = xScale(\n d.diameter + d.diameter * rcc.surfaceCase.diameterPaddingRatio,\n );\n const g = d3.select(nodes[i] as Element);\n g.select('.surface-case-fill')\n .attr('x', x)\n .attr('width', w)\n .attr('fill', ctx.textures.surface_case.url());\n const sideNodes = g.selectAll('.surface-case-side').nodes();\n d3.select(sideNodes[0] as Element)\n .attr('x1', x)\n .attr('x2', x);\n d3.select(sideNodes[1] as Element)\n .attr('x1', x + w)\n .attr('x2', x + w);\n });\n\n withTransition(\n surfaceCaseGs.select<SVGRectElement>('.surface-case-fill'),\n ctx.transition,\n )\n .attr('y', (d: SurfaceCase) => getYPos(d))\n .attr('height', (d: SurfaceCase) => getHeight(d));\n\n withTransition(\n surfaceCaseGs.selectAll<SVGLineElement, SurfaceCase>('.surface-case-side'),\n ctx.transition,\n )\n .attr('y1', (d: unknown) => getYPos(d as SurfaceCase))\n .attr(\n 'y2',\n (d: unknown) => getYPos(d as SurfaceCase) + getHeight(d as SurfaceCase),\n );\n\n // --- hole_fill ---\n\n const holeFill = ctx.groups.holeFillGroup\n .selectAll<SVGRectElement, HoleFill>(`.${ctx.classes.holeFill.rect}`)\n .data(data.hole_fill, stableLayerKey);\n\n holeFill.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newHoleFill = holeFill\n .enter()\n .append('rect')\n .attr('class', ctx.classes.holeFill.rect)\n .attr('stroke', ctx.theme.holeFill.stroke)\n .attr('stroke-width', ctx.theme.holeFill.strokeWidth)\n .attr('x', (d: HoleFill) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: HoleFill) => xScale(d.diameter))\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('fill', (d: HoleFill) => ctx.textures[d.type].url())\n .attr('opacity', 0)\n .on('mouseover', ctx.tooltips.holeFill.show)\n .on('mouseout', ctx.tooltips.holeFill.hide);\n\n withTransition(newHoleFill, ctx.transition).attr('opacity', 1);\n\n holeFill\n .attr('x', (d: HoleFill) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: HoleFill) => xScale(d.diameter))\n .attr('fill', (d: HoleFill) => ctx.textures[d.type].url());\n withTransition(holeFill, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n // --- well_case ---\n\n const wellCase = ctx.groups.wellCaseGroup\n .selectAll<SVGRectElement, WellCase>(`.${ctx.classes.wellCase.rect}`)\n .data(data.well_case, stableLayerKey);\n\n wellCase.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newWellCase = wellCase\n .enter()\n .append('rect')\n .attr('class', ctx.classes.wellCase.rect)\n .attr('fill', ctx.theme.wellCase.fill)\n .attr('stroke', ctx.theme.wellCase.stroke)\n .attr('stroke-width', ctx.theme.wellCase.strokeWidth)\n .attr('x', (d: WellCase) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellCase) => xScale(d.diameter))\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('opacity', 0)\n .on('mouseover', ctx.tooltips.wellCase.show)\n .on('mouseout', ctx.tooltips.wellCase.hide);\n\n withTransition(newWellCase, ctx.transition).attr('opacity', 1);\n\n wellCase\n .attr('x', (d: WellCase) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellCase) => xScale(d.diameter));\n withTransition(wellCase, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n // --- well_screen ---\n\n const wellScreen = ctx.groups.wellScreenGroup\n .selectAll<SVGRectElement, WellScreen>(`.${ctx.classes.wellScreen.rect}`)\n .data(data.well_screen, stableLayerKey);\n\n wellScreen.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newWellScreen = wellScreen\n .enter()\n .append('rect')\n .attr('class', ctx.classes.wellScreen.rect)\n .attr('fill', ctx.textures.well_screen.url())\n .attr('stroke', ctx.theme.wellScreen.stroke)\n .attr('stroke-width', ctx.theme.wellScreen.strokeWidth)\n .attr('x', (d: WellScreen) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellScreen) => xScale(d.diameter))\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('opacity', 0)\n .on('mouseover', ctx.tooltips.wellScreen.show)\n .on('mouseout', ctx.tooltips.wellScreen.hide);\n\n withTransition(newWellScreen, ctx.transition).attr('opacity', 1);\n\n wellScreen\n .attr('x', (d: WellScreen) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: WellScreen) => xScale(d.diameter));\n withTransition(wellScreen, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n\n // --- conflict zones ---\n // Conflicts are derived data (not directly edited), so depth-based keys are fine here.\n\n const conflictAreas: Conflict[] = [];\n conflictAreas.push(...getConflictAreas(data.well_case, data.well_screen));\n conflictAreas.push(...getConflictAreas(data.well_screen, data.well_case));\n\n const mergedConflicts = mergeConflicts(conflictAreas, 1);\n\n const conflict = ctx.groups.conflictGroup\n .selectAll<SVGRectElement, Conflict>(`.${ctx.classes.conflict.rect}`)\n .data(mergedConflicts, (d: Conflict) => `${d.from}_${d.to}_${d.diameter}`);\n\n conflict.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newConflict = conflict\n .enter()\n .append('rect')\n .attr('class', ctx.classes.conflict.rect)\n .attr('fill', ctx.textures.conflict.url())\n .attr('stroke', ctx.theme.conflict.stroke)\n .attr('stroke-width', ctx.theme.conflict.strokeWidth)\n .attr('x', (d: Conflict) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: Conflict) => xScale(d.diameter))\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('opacity', 0)\n .on('mouseover', ctx.tooltips.conflict.show)\n .on('mouseout', ctx.tooltips.conflict.hide);\n\n withTransition(newConflict, ctx.transition).attr('opacity', 1);\n\n conflict\n .attr('x', (d: Conflict) => (ctx.POCO_CENTER - xScale(d.diameter)) / 2)\n .attr('width', (d: Conflict) => xScale(d.diameter));\n withTransition(conflict, ctx.transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n}\n","import { Fracture } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { makeSeededPrng } from '~/utils/render.utils';\n\nfunction wavyLine(\n rng: () => number,\n steps: number,\n baseY: number,\n jitter: number,\n startInset: number,\n endInset: number,\n): [number, number][] {\n const pts: [number, number][] = [];\n for (let i = 0; i < steps; i++) {\n const t = i / (steps - 1);\n const normX = startInset + t * (1 - startInset - endInset);\n const yOffset = baseY + (rng() * 2 - 1) * jitter;\n pts.push([normX, yOffset]);\n }\n return pts;\n}\n\n/**\n * Renders fractures onto the fractures SVG group.\n *\n * Single fractures are drawn as a wavy polyline with small branching cracks.\n * Swarm fractures are drawn as a set of parallel wavy lines (with a thicker\n * central line) connected by short bridge lines. Geometry for each fracture\n * is fully deterministic via a seeded PRNG keyed on the fracture depth.\n * Returns early if `data` is empty.\n */\nexport function drawFractures(ctx: DrawContext, data: Fracture[]): void {\n if (!data.length) return;\n\n const {\n groups: { fracturesGroup },\n POCO_WIDTH,\n pocoCenterX,\n yScale,\n renderConfig,\n theme,\n classes,\n tooltips,\n } = ctx;\n\n fracturesGroup.selectAll(`g.${classes.fractures.item}`).remove();\n\n const rf = renderConfig.fractures;\n const halfWidth = (POCO_WIDTH * rf.widthMultiplier) / 2;\n const xa = pocoCenterX - halfWidth;\n const w = halfWidth * 2;\n\n const normToAbsX = (normX: number) => xa + normX * w;\n\n data.forEach(fracture => {\n const rng = makeSeededPrng(fracture.depth, 7919);\n const cy = yScale(fracture.depth);\n\n const g = fracturesGroup\n .append('g')\n .attr('class', classes.fractures.item)\n .datum(fracture)\n .attr(\n 'transform',\n `translate(0,${cy}) rotate(${fracture.dip},${pocoCenterX},0)`,\n )\n .on('mouseover', tooltips.fracture.show)\n .on('mouseout', tooltips.fracture.hide)\n .style('cursor', 'pointer');\n\n const hitBuffer = fracture.swarm ? rf.hitBuffer.swarm : rf.hitBuffer.single;\n g.append('rect')\n .attr('class', classes.fractures.hitArea)\n .attr('x', xa)\n .attr('y', -hitBuffer)\n .attr('width', w)\n .attr('height', hitBuffer * 2)\n .attr('fill', 'transparent')\n .style('pointer-events', 'all');\n\n const fractureStroke = fracture.water_intake\n ? theme.fracture.wetStroke\n : theme.fracture.dryStroke;\n\n const appendLine = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n sw: number,\n ) =>\n g\n .append('line')\n .attr('class', classes.fractures.line)\n .attr('x1', x1)\n .attr('y1', y1)\n .attr('x2', x2)\n .attr('y2', y2)\n .attr('stroke', fractureStroke)\n .attr('stroke-width', sw)\n .attr('stroke-linecap', 'round');\n\n const appendPolyline = (pts: [number, number][], sw: number) =>\n g\n .append('polyline')\n .attr('class', classes.fractures.polyline)\n .attr(\n 'points',\n pts.map(([nx, dy]) => `${normToAbsX(nx)},${dy}`).join(' '),\n )\n .attr('stroke', fractureStroke)\n .attr('stroke-width', sw)\n .attr('fill', 'none')\n .attr('stroke-linecap', 'round')\n .attr('stroke-linejoin', 'round');\n\n if (fracture.swarm) {\n const lineCount =\n rf.swarm.lineCountBase + Math.round(rng() * rf.swarm.lineCountVariance);\n const halfSpread = rf.swarm.spread / 2;\n\n const bases = Array.from(\n { length: lineCount },\n () => (rng() * 2 - 1) * halfSpread,\n ).sort((a, b) => a - b);\n\n bases.forEach((base, idx) => {\n const isCentral = idx === Math.floor(lineCount / 2);\n const sw = isCentral\n ? theme.fracture.swarm.centralStrokeWidth\n : theme.fracture.swarm.sideStrokeWidthBase +\n rng() * theme.fracture.swarm.sideStrokeWidthVariance;\n const steps = 6 + Math.round(rng() * 3);\n const jitter = 0.8 + rng() * 1.2;\n const insetL = 0.04 + rng() * 0.12;\n const insetR = 0.04 + rng() * 0.12;\n appendPolyline(wavyLine(rng, steps, base, jitter, insetL, insetR), sw);\n });\n\n const bridgeCount = 2 + Math.round(rng() * 2);\n for (let b = 0; b < bridgeCount; b++) {\n const nx = 0.15 + rng() * 0.7;\n const pairIdx = Math.floor(rng() * (bases.length - 1));\n appendLine(\n normToAbsX(nx),\n bases[pairIdx],\n normToAbsX(nx + (rng() - 0.5) * 0.06),\n bases[pairIdx + 1],\n 0.6,\n );\n }\n\n const primaryBase = bases[Math.floor(lineCount / 2)];\n for (let wc = 0; wc < 2; wc++) {\n const nx = 0.2 + rng() * 0.6;\n const len = 3 + rng() * 3;\n const dir = rng() > 0.5 ? -1 : 1;\n appendLine(\n normToAbsX(nx),\n primaryBase,\n normToAbsX(nx + (rng() - 0.5) * 0.04),\n primaryBase + dir * len,\n 0.8,\n );\n }\n } else {\n const steps = 7 + Math.round(rng() * 3);\n const insetL = 0.03 + rng() * 0.08;\n const insetR = 0.03 + rng() * 0.08;\n appendPolyline(\n wavyLine(rng, steps, 0, 2, insetL, insetR),\n theme.fracture.single.mainStrokeWidth,\n );\n\n const crackCount = 2 + Math.round(rng() * 2);\n for (let c = 0; c < crackCount; c++) {\n const nx = insetL + rng() * (1 - insetL - insetR);\n const len = 3.5 + rng() * 3.5;\n const dir = rng() > 0.5 ? 1 : -1;\n appendLine(\n normToAbsX(nx),\n (rng() * 2 - 1) * 1.5,\n normToAbsX(nx + (rng() - 0.5) * 0.03),\n dir * len,\n theme.fracture.single.crackStrokeWidth,\n );\n }\n }\n });\n}\n","import * as d3 from 'd3';\n\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type {\n DrawContext,\n HighlightItem,\n Highlights,\n SvgSelection,\n} from '~/types/render.types';\n\n/**\n * Renders a single highlight overlay rectangle (and optional label) into the\n * given SVG group. Skips items with zero or negative dimensions.\n */\nfunction drawHighlightItem(\n ctx: DrawContext,\n group: SvgSelection,\n x: number,\n y: number,\n w: number,\n h: number,\n label?: string,\n): void {\n if (h <= 0 || w <= 0) return;\n\n const hlConfig = ctx.renderConfig.highlights;\n const pad = hlConfig.padding;\n\n const g = group.append('g').attr('class', ctx.classes.highlights.item);\n\n g.append('rect')\n .attr('class', ctx.classes.highlights.rect)\n .attr('x', x - pad)\n .attr('y', y - pad)\n .attr('width', w + pad * 2)\n .attr('height', h + pad * 2)\n .attr('fill', hlConfig.fill)\n .attr('fill-opacity', hlConfig.fillOpacity)\n .attr('stroke', hlConfig.stroke)\n .attr('stroke-width', hlConfig.strokeWidth)\n .attr('stroke-dasharray', hlConfig.strokeDasharray ?? null)\n .style('pointer-events', 'none');\n\n if (label) {\n const charW = hlConfig.labelFontSize * 0.55;\n const labelW = label.length * charW + hlConfig.labelPadding * 2;\n const labelH = hlConfig.labelFontSize + hlConfig.labelPadding * 2;\n const lx = x - pad;\n const ly = y - pad - labelH;\n\n g.append('rect')\n .attr('class', ctx.classes.highlights.labelBg)\n .attr('x', lx)\n .attr('y', ly)\n .attr('width', labelW)\n .attr('height', labelH)\n .attr('rx', hlConfig.labelRadius)\n .attr('fill', hlConfig.labelBackground)\n .style('pointer-events', 'none');\n\n g.append('text')\n .attr('class', ctx.classes.highlights.label)\n .attr('x', lx + hlConfig.labelPadding)\n .attr('y', ly + labelH - hlConfig.labelPadding)\n .attr('font-size', hlConfig.labelFontSize)\n .attr('fill', hlConfig.labelColor)\n .attr('font-family', 'sans-serif')\n .style('pointer-events', 'none')\n .text(label);\n }\n}\n\n/**\n * Renders colored highlight overlays on any component. Always runs to clear\n * groups on zoom redraws, even if hl is empty. The x-scale domain is computed\n * from ctx.constructionData for consistent widths across multi-SVG panels.\n */\nexport function drawHighlights(ctx: DrawContext, hl: Highlights): void {\n ctx.groups.highlightsGeologicGroup.selectAll('*').remove();\n ctx.groups.highlightsConstructionGroup.selectAll('*').remove();\n ctx.groups.highlightsFracturesGroup.selectAll('*').remove();\n\n // Geologic highlights\n const drawGeoHighlights = (items: HighlightItem[] | undefined) => {\n items?.forEach(h => {\n if (h.from === undefined || h.to === undefined) return;\n const from = Math.max(h.from, ctx.depthFrom);\n const to = Math.min(h.to, ctx.depthTo);\n if (from >= to) return;\n const y = ctx.yScale(from);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsGeologicGroup as SvgSelection,\n ctx.geoXLeft,\n y,\n ctx.geoXRight - ctx.geoXLeft,\n ctx.yScale(to) - y,\n h.label,\n );\n });\n };\n\n drawGeoHighlights(hl.lithology);\n drawGeoHighlights(hl.caves);\n\n // Fracture highlights\n const fractureConfig = ctx.renderConfig.fractures;\n const halfFractureWidth =\n (ctx.POCO_WIDTH * fractureConfig.widthMultiplier) / 2;\n const fracXa = ctx.pocoCenterX - halfFractureWidth;\n const fracW = halfFractureWidth * 2;\n\n hl.fractures?.forEach(h => {\n if (h.depth === undefined) return;\n if (h.depth < ctx.depthFrom || h.depth > ctx.depthTo) return;\n const cy = ctx.yScale(h.depth);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsFracturesGroup as SvgSelection,\n fracXa,\n cy - fractureConfig.hitBuffer.single,\n fracW,\n fractureConfig.hitBuffer.single * 2,\n h.label,\n );\n });\n\n // Construction highlights\n const maxXVals = getProfileDiamValues(ctx.constructionData);\n const xScaleConstr = d3\n .scaleLinear()\n .domain([0, d3.max(maxXVals) || 0])\n .range([0, ctx.POCO_WIDTH]);\n\n const constructionConfig = ctx.renderConfig.construction;\n\n if (\n hl.cement_pad &&\n ctx.depthFrom === 0 &&\n ctx.constructionData.cement_pad?.thickness\n ) {\n const cp = ctx.constructionData.cement_pad;\n const cpPadWidth =\n (cp.width * constructionConfig.cementPad.widthMultiplier * 1000) / 2;\n const cpX = (ctx.POCO_CENTER - xScaleConstr(cpPadWidth)) / 2;\n const cpY =\n ctx.yScale(0) -\n ctx.yScale(\n cp.thickness * constructionConfig.cementPad.thicknessMultiplier,\n );\n const cpW = xScaleConstr(cpPadWidth);\n const cpH = ctx.yScale(\n cp.thickness * constructionConfig.cementPad.thicknessMultiplier,\n );\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsConstructionGroup as SvgSelection,\n cpX,\n cpY,\n cpW,\n cpH,\n hl.cement_pad.label,\n );\n }\n\n const drawConstrHighlights = (\n items: HighlightItem[] | undefined,\n data: { from: number; to: number; diameter: number }[],\n getX: (d: { diameter: number }) => number,\n getW: (d: { diameter: number }) => number,\n ) => {\n items?.forEach(h => {\n if (h.from === undefined || h.to === undefined) return;\n data\n .filter(\n d =>\n d.from < h.to! &&\n d.to > h.from! &&\n (h.diameter === undefined || d.diameter === h.diameter),\n )\n .forEach(d => {\n const from = Math.max(h.from!, ctx.depthFrom);\n const to = Math.min(h.to!, ctx.depthTo);\n if (from >= to) return;\n const y = ctx.yScale(from);\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsConstructionGroup as SvgSelection,\n getX(d),\n y,\n getW(d),\n ctx.yScale(to) - y,\n h.label,\n );\n });\n });\n };\n\n const stdX = (d: { diameter: number }) =>\n (ctx.POCO_CENTER - xScaleConstr(d.diameter)) / 2;\n const stdW = (d: { diameter: number }) => xScaleConstr(d.diameter);\n const scPaddingRatio = constructionConfig.surfaceCase.diameterPaddingRatio;\n const scX = (d: { diameter: number }) =>\n (ctx.POCO_CENTER - xScaleConstr(d.diameter + d.diameter * scPaddingRatio)) /\n 2;\n const scW = (d: { diameter: number }) =>\n xScaleConstr(d.diameter + d.diameter * scPaddingRatio);\n\n drawConstrHighlights(\n hl.bore_hole,\n ctx.constructionData.bore_hole,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.surface_case,\n ctx.constructionData.surface_case,\n scX,\n scW,\n );\n drawConstrHighlights(\n hl.hole_fill,\n ctx.constructionData.hole_fill,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.well_case,\n ctx.constructionData.well_case,\n stdX,\n stdW,\n );\n drawConstrHighlights(\n hl.well_screen,\n ctx.constructionData.well_screen,\n stdX,\n stdW,\n );\n}\n","import * as d3module from 'd3';\nimport { defu } from 'defu';\n\nimport { Well } from '@welldot/core';\nimport {\n ComponentsClassNames,\n LegendRenderConfig,\n WellTheme,\n} from '~/types/render.types';\nimport { DEFAULT_COMPONENTS_CLASS_NAMES } from '../configs/render.classnames';\nimport {\n DEFAULT_WELL_THEME,\n INTERACTIVE_RENDER_CONFIG,\n} from '../configs/render.configs';\nimport { TexturesConfig, createWellTextures } from '../configs/render.textures';\nimport { getConflictAreas, mergeConflicts } from '../utils/render.utils';\n\nconst d3 = { ...d3module };\n\ntype LegendItem =\n | { kind: 'fracture'; label: string; swarm: boolean; water_intake: boolean }\n | { kind: 'cave'; label: string; water_intake: boolean }\n | {\n kind: 'construction';\n label: string;\n subKind:\n | 'boreHole'\n | 'surfaceCase'\n | 'holeFillGravel'\n | 'holeFillSeal'\n | 'wellCase'\n | 'wellScreen'\n | 'cementPad'\n | 'conflict';\n };\n\nexport function drawWellLegend(\n selector: string,\n profile: Well,\n options: {\n config?: Partial<LegendRenderConfig>;\n theme?: Partial<WellTheme>;\n classNames?: ComponentsClassNames['legend'];\n textures?: TexturesConfig;\n } = {},\n): void {\n const fractures = profile.fractures ?? [];\n const caves = profile.caves ?? [];\n const boreHoles = profile.bore_hole ?? [];\n const wellCases = profile.well_case ?? [];\n const wellScreens = profile.well_screen ?? [];\n const holeFills = profile.hole_fill ?? [];\n\n const hasSimple = fractures.some(f => !f.swarm && !f.water_intake);\n const hasSwarm = fractures.some(f => f.swarm);\n const hasWaterFx = fractures.some(f => f.water_intake);\n const hasCaveDry = caves.some(c => !c.water_intake);\n const hasCaveWet = caves.some(c => c.water_intake);\n\n const hasBoreHole = boreHoles.length > 0;\n const hasSurfaceCase = (profile.surface_case ?? []).length > 0;\n const hasHoleFillGravel = holeFills.some(h => h.type === 'gravel_pack');\n const hasHoleFillSeal = holeFills.some(h => h.type === 'seal');\n const hasWellCase = wellCases.length > 0;\n const hasWellScreen = wellScreens.length > 0;\n const hasCementPad = !!profile.cement_pad?.thickness;\n const hasConflict =\n mergeConflicts(\n [\n ...getConflictAreas(wellCases, wellScreens),\n ...getConflictAreas(wellScreens, wellCases),\n ],\n 1,\n ).length > 0;\n\n const cfg = defu(\n options.config ?? {},\n INTERACTIVE_RENDER_CONFIG.legend,\n ) as LegendRenderConfig;\n\n const theme = defu(options.theme ?? {}, DEFAULT_WELL_THEME) as WellTheme;\n\n const cls: ComponentsClassNames['legend'] = options.classNames\n ? { ...DEFAULT_COMPONENTS_CLASS_NAMES.legend, ...options.classNames }\n : DEFAULT_COMPONENTS_CLASS_NAMES.legend;\n\n const items: LegendItem[] = [];\n if (hasSimple)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureSingle,\n swarm: false,\n water_intake: false,\n });\n if (hasSwarm)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureSwarm,\n swarm: true,\n water_intake: false,\n });\n if (hasWaterFx)\n items.push({\n kind: 'fracture',\n label: cfg.labels.fractureWater,\n swarm: false,\n water_intake: true,\n });\n if (hasCaveDry)\n items.push({\n kind: 'cave',\n label: cfg.labels.caveDry,\n water_intake: false,\n });\n if (hasCaveWet)\n items.push({ kind: 'cave', label: cfg.labels.caveWet, water_intake: true });\n\n if (hasCementPad)\n items.push({\n kind: 'construction',\n label: cfg.labels.cementPad,\n subKind: 'cementPad',\n });\n if (hasBoreHole)\n items.push({\n kind: 'construction',\n label: cfg.labels.boreHole,\n subKind: 'boreHole',\n });\n if (hasSurfaceCase)\n items.push({\n kind: 'construction',\n label: cfg.labels.surfaceCase,\n subKind: 'surfaceCase',\n });\n if (hasHoleFillGravel)\n items.push({\n kind: 'construction',\n label: cfg.labels.holeFillGravel,\n subKind: 'holeFillGravel',\n });\n if (hasHoleFillSeal)\n items.push({\n kind: 'construction',\n label: cfg.labels.holeFillSeal,\n subKind: 'holeFillSeal',\n });\n if (hasWellCase)\n items.push({\n kind: 'construction',\n label: cfg.labels.wellCase,\n subKind: 'wellCase',\n });\n if (hasWellScreen)\n items.push({\n kind: 'construction',\n label: cfg.labels.wellScreen,\n subKind: 'wellScreen',\n });\n if (hasConflict)\n items.push({\n kind: 'construction',\n label: cfg.labels.conflict,\n subKind: 'conflict',\n });\n\n const svgEl = d3.select(selector);\n svgEl.selectAll('*').remove();\n\n if (items.length === 0) {\n svgEl.attr('width', 0).attr('height', 0);\n return;\n }\n\n const legendTextures = createWellTextures(options.textures);\n Object.values(legendTextures).forEach(t => svgEl.call(t));\n\n const itemsPerRow = cfg.maxWidth\n ? Math.max(1, Math.floor((cfg.maxWidth - cfg.padding * 2) / cfg.itemWidth))\n : items.length;\n const numRows = Math.ceil(items.length / itemsPerRow);\n const rowWidth = Math.min(items.length, itemsPerRow) * cfg.itemWidth;\n const totalWidth = cfg.padding * 2 + rowWidth;\n const totalHeight = numRows * cfg.height;\n\n svgEl.attr('width', totalWidth).attr('height', totalHeight);\n\n const RC = 'round' as const;\n\n const g = svgEl.append('g').attr('transform', `translate(${cfg.padding}, 2)`);\n\n g.append('rect')\n .attr('class', cls.border)\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', totalWidth - cfg.padding)\n .attr('height', totalHeight - 4)\n .attr('fill', 'white')\n .attr('rx', cfg.borderRadius)\n .attr('stroke-width', theme.legend.borderStrokeWidth);\n\n g.append('text')\n .attr('class', cls.title)\n .attr('x', 4)\n .attr('y', 11)\n .attr('font-size', theme.legend.fontSize)\n .attr('font-family', theme.legend.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.legend.titleFontWeight ?? 'bold')\n .text(`${cfg.title}:`);\n\n const rw = 24;\n const rh = 12;\n\n items.forEach((item, i) => {\n const col = i % itemsPerRow;\n const row = Math.floor(i / itemsPerRow);\n const rowSymY = row * cfg.height + (cfg.height - 4) / 2;\n const cx = col * cfg.itemWidth;\n\n const symG = g.append('g').attr('class', cls.item);\n\n if (item.kind === 'fracture') {\n const color = item.water_intake\n ? theme.fracture.wetStroke\n : theme.fracture.dryStroke;\n\n if (item.swarm) {\n ([-4, 0, 4] as number[]).forEach(offset => {\n symG\n .append('polyline')\n .attr('class', cls.fracturePoly)\n .attr(\n 'points',\n `${cx},${rowSymY + offset} ${cx + 6},${rowSymY + offset - 1} ${cx + 12},${rowSymY + offset + 1} ${cx + 18},${rowSymY + offset - 0.5} ${cx + 24},${rowSymY + offset}`,\n )\n .attr('stroke', color)\n .attr(\n 'stroke-width',\n offset !== 0\n ? theme.legend.fractureSideStrokeWidth\n : theme.legend.fractureStrokeWidth,\n )\n .attr('fill', 'none')\n .attr('stroke-linecap', RC)\n .attr('stroke-linejoin', RC);\n });\n } else {\n symG\n .append('polyline')\n .attr('class', cls.fracturePoly)\n .attr(\n 'points',\n `${cx},${rowSymY} ${cx + 5},${rowSymY - 1.5} ${cx + 11},${rowSymY + 1} ${cx + 17},${rowSymY - 0.5} ${cx + 24},${rowSymY}`,\n )\n .attr('stroke', color)\n .attr('stroke-width', theme.legend.fractureStrokeWidth)\n .attr('fill', 'none')\n .attr('stroke-linecap', RC)\n .attr('stroke-linejoin', RC);\n }\n } else if (item.kind === 'cave') {\n const color = item.water_intake\n ? theme.cave.wetStroke\n : theme.cave.dryStroke;\n const texture = item.water_intake\n ? legendTextures.cave_wet\n : legendTextures.cave_dry;\n\n symG\n .append('rect')\n .attr('class', cls.caveFill)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', texture.url())\n .attr('stroke', color)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n } else if (item.subKind === 'surfaceCase') {\n symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', legendTextures.surface_case.url())\n .attr('stroke', 'none');\n symG\n .append('line')\n .attr('class', cls.constructionRect)\n .attr('x1', cx)\n .attr('x2', cx)\n .attr('y1', rowSymY - rh / 2)\n .attr('y2', rowSymY + rh / 2)\n .attr('stroke', theme.surfaceCase.stroke)\n .attr('stroke-width', 2);\n symG\n .append('line')\n .attr('class', cls.constructionRect)\n .attr('x1', cx + rw)\n .attr('x2', cx + rw)\n .attr('y1', rowSymY - rh / 2)\n .attr('y2', rowSymY + rh / 2)\n .attr('stroke', theme.surfaceCase.stroke)\n .attr('stroke-width', 2);\n } else {\n const symMap: Record<\n string,\n { fill: string; stroke: string; dasharray?: string }\n > = {\n boreHole: {\n fill: theme.boreHole.fill,\n stroke: theme.boreHole.stroke,\n dasharray: theme.boreHole.strokeDasharray,\n },\n holeFillGravel: {\n fill: legendTextures.gravel_pack.url(),\n stroke: theme.holeFill.stroke,\n },\n holeFillSeal: {\n fill: legendTextures.seal.url(),\n stroke: theme.holeFill.stroke,\n },\n wellCase: { fill: theme.wellCase.fill, stroke: theme.wellCase.stroke },\n wellScreen: {\n fill: legendTextures.well_screen.url(),\n stroke: theme.wellScreen.stroke,\n },\n cementPad: {\n fill: legendTextures.pad.url(),\n stroke: theme.cementPad.stroke,\n },\n conflict: {\n fill: legendTextures.conflict.url(),\n stroke: theme.conflict.stroke,\n },\n };\n const sym = symMap[item.subKind];\n\n const symRect = symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', cx)\n .attr('y', rowSymY - rh / 2)\n .attr('width', rw)\n .attr('height', rh)\n .attr('fill', sym.fill)\n .attr('stroke', sym.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n if (sym.dasharray) symRect.attr('stroke-dasharray', sym.dasharray);\n }\n\n g.append('text')\n .attr('class', cls.label)\n .attr('x', cx + 28)\n .attr('y', rowSymY + 3)\n .attr('font-size', theme.legend.fontSize)\n .attr('font-family', theme.legend.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.legend.labelFontWeight ?? 400)\n .text(item.label);\n });\n}\n","import { Lithology } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { stableLayerKey, withTransition } from '~/utils/d3.utils';\nimport { getLithologyFill, getYAxisFunctions } from '~/utils/render.utils';\n\nexport function drawLithology(ctx: DrawContext, data: Lithology[]): void {\n if (!data.length) return;\n\n const {\n groups: { lithologyGroup },\n svg,\n geoXLeft,\n geoXRight,\n depthFrom,\n depthTo,\n yScale,\n theme,\n classes,\n tooltips,\n transition,\n } = ctx;\n\n const { getHeight, getYPos } = getYAxisFunctions(yScale, {\n from: depthFrom,\n to: depthTo,\n });\n\n // Precompute fill before data join so it is available for both enter and update.\n const fillFn = getLithologyFill(data, svg, ctx.theme.lithologyTexture);\n\n // Key by content (not depth) so layers keep their DOM identity when depths are\n // reordered after an add/delete — depth values change, rock type identity does not.\n const rects = lithologyGroup\n .selectAll<SVGRectElement, Lithology>(`.${classes.lithology.rect}`)\n .data(data, stableLayerKey);\n\n // EXIT: collapse in place, then remove\n rects.exit().transition(transition).attr('height', 0).remove();\n\n // ENTER: position and fill set immediately; fade in via opacity only\n const newLayers = rects\n .enter()\n .append('rect')\n .attr('class', classes.lithology.rect)\n .attr('x', geoXLeft)\n .attr('width', geoXRight - geoXLeft)\n .attr('stroke', theme.lithology.stroke)\n .attr('stroke-width', theme.lithology.strokeWidth)\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('fill', fillFn)\n .attr('opacity', 0)\n .on('mouseover', tooltips.geology.show)\n .on('mouseout', tooltips.geology.hide);\n\n withTransition(newLayers, transition).attr('opacity', 1);\n\n // UPDATE: fill set immediately (avoids string interpolation glitch); animate y and height\n rects.attr('fill', fillFn);\n withTransition(rects, transition)\n .attr('y', getYPos)\n .attr('height', getHeight);\n}\n","import { Lithology } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\n\n/**\n * Renders geologic_unit and aquifer_unit strip labels to the left of the\n * lithology column.\n *\n * Adjacent layers sharing the same unit value are merged into a single strip\n * segment. Each segment is drawn as a filled rect with divider lines at its\n * top and bottom edges; a rotated text label is added when the segment is tall\n * enough. Returns early if the feature is disabled via\n * `ctx.renderConfig.unitLabels.active` or if `data` is empty.\n */\nexport function drawUnitLabels(ctx: DrawContext, data: Lithology[]): void {\n if (!ctx.renderConfig.unitLabels.active || !data.length) return;\n\n const {\n groups: { unitLabelsGroup },\n depthFrom,\n depthTo,\n yScale,\n renderConfig,\n theme,\n classes,\n } = ctx;\n\n unitLabelsGroup.selectAll('*').remove();\n\n const ru = renderConfig.unitLabels;\n const rut = theme.unitLabels;\n const sw = ru.stripWidth;\n\n const groupByField = (field: 'geologic_unit' | 'aquifer_unit') => {\n const groups: { unit: string; from: number; to: number }[] = [];\n for (const layer of data) {\n const unit = layer[field];\n if (!unit) continue;\n const from = Math.max(layer.from, depthFrom);\n const to = Math.min(layer.to, depthTo);\n if (from >= to) continue;\n const last = groups[groups.length - 1];\n if (last && last.unit === unit) {\n last.to = to;\n } else groups.push({ unit, from, to });\n }\n return groups;\n };\n\n const hasGeo = data.some(d => d.geologic_unit);\n const hasAq = data.some(d => d.aquifer_unit);\n\n // Strips start at ru.xOffset (geologic group coordinates).\n // When both exist: geo at xOffset, aq at xOffset + stripWidth + 1.\n const geoX = ru.xOffset;\n const aqX = hasGeo && hasAq ? ru.xOffset + sw + 1 : ru.xOffset;\n\n const drawStrip = (\n groups: { unit: string; from: number; to: number }[],\n stripX: number,\n rectClass: string,\n fillColor: string,\n ) => {\n groups.forEach((group, idx) => {\n const yTop = yScale(group.from);\n const yBot = yScale(group.to);\n const height = yBot - yTop;\n if (height < 1) return;\n\n const isFirst = idx === 0;\n const isLast = idx === groups.length - 1;\n\n unitLabelsGroup\n .append('rect')\n .attr('class', rectClass)\n .attr('x', stripX)\n .attr('y', yTop)\n .attr('width', sw)\n .attr('height', height)\n .attr('fill', fillColor)\n .attr('stroke', rut.stroke)\n .attr('stroke-width', rut.strokeWidth);\n\n const appendEdge = (y: number, strokeWidth: number) =>\n unitLabelsGroup\n .append('line')\n .attr('class', 'unit-divider-line')\n .attr('x1', stripX)\n .attr('x2', stripX + sw)\n .attr('y1', y)\n .attr('y2', y)\n .attr('stroke', rut.stroke)\n .attr('stroke-width', strokeWidth);\n\n appendEdge(yTop, isFirst ? ru.outerEdgeWidth : ru.innerDividerWidth);\n appendEdge(yBot, isLast ? ru.outerEdgeWidth : ru.innerDividerWidth);\n\n if (height >= ru.minHeightForText) {\n const maxChars = Math.floor(height / (rut.fontSize * 0.55));\n const label =\n group.unit.length > maxChars\n ? `${group.unit.slice(0, maxChars - 1)}…`\n : group.unit;\n\n unitLabelsGroup\n .append('text')\n .attr('class', classes.unitLabels.text)\n .attr(\n 'transform',\n `translate(${(stripX + sw / 2).toFixed(1)},${((yTop + yBot) / 2).toFixed(1)}) rotate(-90)`,\n )\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'middle')\n .attr('font-size', rut.fontSize)\n .attr('font-family', rut.fontFamily ?? 'sans-serif')\n .attr('font-weight', rut.fontWeight ?? 400)\n .attr('fill', rut.stroke)\n .text(label);\n }\n });\n };\n\n if (hasGeo)\n drawStrip(\n groupByField('geologic_unit'),\n geoX,\n classes.unitLabels.geoRect,\n rut.geologicFill,\n );\n if (hasAq)\n drawStrip(\n groupByField('aquifer_unit'),\n aqX,\n classes.unitLabels.aqRect,\n rut.aquiferFill,\n );\n}\n","import sanitizeHtml from 'sanitize-html';\nimport { WellTheme } from '~/types/render.types';\n\n/** Strips all HTML/CSS-breaking characters from a theme string value before CSS injection. */\nconst sanitizeCssValue = (v: unknown): string =>\n sanitizeHtml(String(v ?? ''), { allowedTags: [], allowedAttributes: {} });\n\nexport function buildSvgStyleBlock(theme: WellTheme): string {\n const { labels, lithology } = theme;\n const s = sanitizeCssValue;\n return [\n `.wp-lithology-depth-tip{border:0.5px solid ${s(lithology.stroke)};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n `.wp-annotation-label{font-size:${s(labels.fontSize)}px}`,\n `.wp-annotation-header{font-weight:${s(labels.headerFontWeight ?? 600)};font-family:${s(labels.headerFont)};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n `.wp-annotation-body{font-weight:${s(labels.bodyFontWeight ?? 400)};font-family:${s(labels.bodyFont ?? 'sans-serif')};font-size:${s(labels.fontSize)}px;color:${s(labels.bodyColor)}}`,\n `.wp-depth-tip-text{font-family:${s(labels.bodyFont ?? 'sans-serif')};font-size:${s(labels.fontSize)}px;color:${s(labels.color)}}`,\n ].join('');\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAGnB,IAAM,qBAAgC;AAAA,EAC3C,WAAW,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC/C,kBAAkB,EAAE,MAAM,KAAK,aAAa,KAAK,QAAQ,UAAU;AAAA,EACnE,MAAM;AAAA,IACJ,WAAW;AAAA,IACX,WAAW;AAAA,IACX,aAAa;AAAA,IACb,oBAAoB;AAAA,EACtB;AAAA,EACA,UAAU;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX,OAAO;AAAA,MACL,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,yBAAyB;AAAA,IAC3B;AAAA,IACA,QAAQ;AAAA,MACN,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,IACpB;AAAA,EACF;AAAA,EACA,WAAW,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC/C,UAAU;AAAA,IACR,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA,aAAa,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EACjD,UAAU,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC9C,UAAU,EAAE,MAAM,WAAW,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC/D,YAAY,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EAChD,UAAU,EAAE,QAAQ,WAAW,aAAa,EAAE;AAAA,EAC9C,YAAY;AAAA,IACV,cAAc;AAAA,IACd,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,oBAAoB;AAAA,IAClB,UAAU;AAAA,IACV,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,QAAQ;AAAA,IACN,eAAe;AAAA,IACf,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,UAAU;AAAA,IACV,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,WAAW;AAAA,IACX,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,EAClB;AAAA,EACA,QAAQ;AAAA,IACN,mBAAmB;AAAA,IACnB,qBAAqB;AAAA,IACrB,yBAAyB;AAAA,IACzB,iBAAiB;AAAA,IACjB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,EACnB;AACF;AAEA,IAAM,2BAA2B;AAAA,EAC/B,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,aAAa;AACf;AAEO,IAAM,uBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,WAAW,EAAE,UAAU,KAAK,MAAM,UAAU;AAAA,EAC5C,UAAU,EAAE,OAAO,IAAI,aAAa,IAAI;AAAA,EACxC,QAAQ;AAAA,IACN,gBAAgB;AAAA;AAAA,IAChB,iBAAiB;AAAA;AAAA,EACnB;AAAA,EACA,OAAO;AAAA,IACL,WAAW;AAAA,IACX,WAAW;AAAA,MACT,OAAO;AAAA;AAAA,MACP,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,iBAAiB;AAAA,IACjB,WAAW,EAAE,QAAQ,GAAG,OAAO,GAAG;AAAA,IAClC,OAAO;AAAA,MACL,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,WAAW,EAAE,iBAAiB,KAAK,qBAAqB,IAAI;AAAA,IAC5D,aAAa,EAAE,sBAAsB,IAAI;AAAA,EAC3C;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,YAAY,EAAE,UAAU,WAAW,MAAM,UAAU;AAAA,IACnD,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,oBAAoB;AAAA,IACpB,aAAa;AAAA,IACb,wBAAwB;AAAA,IACxB,WAAW;AAAA,EACb;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB;AAAA,EACA,oBAAoB;AAAA,IAClB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,aAAa;AAAA,IACb,eAAe;AAAA,IACf,QAAQ;AAAA,MACN,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,IACxB;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,KAAK,EAAE,YAAY,WAAW,QAAQ,UAAU;AAAA,IAChD,UAAU,EAAE,QAAQ,UAAU;AAAA,IAC9B,UAAU,EAAE,MAAM,GAAG,QAAQ,WAAW,YAAY,UAAU;AAAA,IAC9D,UAAU,EAAE,MAAM,GAAG,QAAQ,WAAW,YAAY,UAAU;AAAA,IAC9D,MAAM,EAAE,YAAY,UAAU;AAAA,IAC9B,aAAa,EAAE,YAAY,UAAU;AAAA,IACrC,aAAa,EAAE,MAAM,IAAI,aAAa,GAAG,YAAY,UAAU;AAAA,IAC/D,cAAc;AAAA,MACZ,aAAa,CAAC,YAAY,YAAY;AAAA,MACtC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,cAAc;AAAA,IACd,QAAQ;AAAA,MACN,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,YAAY;AACd;AAEO,IAAM,4BAA0C;AAAA,EACrD,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA,EACX,WAAW,EAAE,UAAU,KAAK,MAAM,UAAU;AAAA,EAC5C,UAAU,EAAE,OAAO,GAAG,aAAa,GAAG;AAAA,EACtC,QAAQ;AAAA,IACN,gBAAgB;AAAA;AAAA,IAChB,iBAAiB;AAAA;AAAA,EACnB;AAAA,EACA,OAAO;AAAA,IACL,WAAW;AAAA,IACX,WAAW;AAAA,MACT,OAAO;AAAA;AAAA,MACP,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,iBAAiB;AAAA,IACjB,WAAW,EAAE,QAAQ,GAAG,OAAO,GAAG;AAAA,IAClC,OAAO;AAAA,MACL,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ,WAAW,EAAE,iBAAiB,KAAK,qBAAqB,IAAI;AAAA,IAC5D,aAAa,EAAE,sBAAsB,IAAI;AAAA,EAC3C;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,YAAY,EAAE,UAAU,WAAW,MAAM,UAAU;AAAA,IACnD,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,qBAAqB;AAAA,IACrB,oBAAoB;AAAA,IACpB,aAAa;AAAA,EACf;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,EAClB;AAAA,EACA,oBAAoB;AAAA,IAClB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,sBAAsB;AAAA,IACxB;AAAA,EACF;AAAA,EACA,UAAU;AAAA,IACR,KAAK,EAAE,YAAY,WAAW,QAAQ,UAAU;AAAA,IAChD,UAAU,EAAE,QAAQ,UAAU;AAAA,IAC9B,UAAU,EAAE,MAAM,GAAG,QAAQ,WAAW,YAAY,UAAU;AAAA,IAC9D,UAAU,EAAE,MAAM,GAAG,QAAQ,WAAW,YAAY,UAAU;AAAA,IAC9D,MAAM,EAAE,YAAY,UAAU;AAAA,IAC9B,aAAa,EAAE,YAAY,UAAU;AAAA,IACrC,aAAa,EAAE,MAAM,IAAI,aAAa,GAAG,YAAY,UAAU;AAAA,IAC/D,cAAc;AAAA,MACZ,aAAa,CAAC,YAAY,YAAY;AAAA,MACtC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,UAAU;AAAA,IACV,cAAc;AAAA,IACd,QAAQ;AAAA,MACN,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,eAAe;AAAA,MACf,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU;AAAA,MACV,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA,YAAY;AACd;;;ACzSA,eAAsB,qBAEnB;AACD,QAAM,eAAe,MAAM,OAAO,4BAA2B;AAC7D,SAAO,aAAa;AACtB;;;ACVA,YAAYA,eAAc;AAE1B,OAAOC,YAAW;AAElB,SAAS,QAAAC,aAAY;;;ACLrB,OAAO,cAAc;AAyEd,SAAS,mBAAmB,KAAoC;AACrE,QAAM,MAAwB;AAAA,IAC5B,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,WAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,WAAiC;AAAA,IACrC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,WAAiC;AAAA,IACrC,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,OAA0B;AAAA,IAC9B,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,cAAuC;AAAA,IAC3C,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,cAAuC;AAAA,IAC3C,MAAM;AAAA,IACN,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,QAAM,eAAyC;AAAA,IAC7C,aAAa,CAAC,YAAY,YAAY;AAAA,IACtC,MAAM;AAAA,IACN,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG,KAAK;AAAA,EACV;AAEA,SAAO;AAAA,IACL,KAAK,SACF,MAAM,EACN,QAAQ,EAAE,EACV,QAAQ,GAAG,EACX,OAAO,IAAI,MAAM,EACjB,WAAW,IAAI,UAAU;AAAA,IAC5B,UAAU,SAAS,MAAM,EAAE,QAAQ,EAAE,OAAO,SAAS,MAAM;AAAA,IAC3D,UAAU,SACP,MAAM,EACN,KAAK,SAAS,IAAI,EAClB,YAAY,KAAK,EACjB,QAAQ,GAAG,EACX,QAAQ,GAAG,EACX,WAAW,SAAS,UAAU,EAC9B,OAAO,SAAS,MAAM;AAAA,IACzB,UAAU,SACP,MAAM,EACN,KAAK,SAAS,IAAI,EAClB,YAAY,KAAK,EACjB,QAAQ,GAAG,EACX,QAAQ,GAAG,EACX,WAAW,SAAS,UAAU,EAC9B,OAAO,SAAS,MAAM;AAAA,IACzB,MAAM,SAAS,MAAM,EAAE,QAAQ,EAAE,WAAW,KAAK,UAAU;AAAA,IAC3D,aAAa,SACV,QAAQ,EACR,KAAK,YAAY,IAAI,EACrB,WAAW,EACX,WAAW,YAAY,UAAU;AAAA,IACpC,aAAa,SACV,MAAM,EACN,EAAE,OAAK,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAC1C,KAAK,YAAY,IAAI,EACrB,YAAY,YAAY,WAAW,EACnC,QAAQ,CAAC,EACT,WAAW,YAAY,UAAU;AAAA,IACpC,cAAe,SAAS,MAAM,EAC3B,YAAY,GAAG,aAAa,WAAW,EACvC,KAAK,aAAa,IAAI,EACtB,YAAY,aAAa,WAAW,EACpC,eAAe,aAAa,cAAc,EAC1C,OAAO,aAAa,MAAM,EAC1B,WAAW,aAAa,UAAU;AAAA,EACvC;AACF;;;AD/JA;AAAA,EACE;AAAA,OAKK;AACP,SAAS,iCAAiC;;;AElB1C,IAAM,eAAe;AACrB,IAAM,UAAU;AAGT,SAAS,aAAa,GAAW,OAA4B;AAClE,SAAO,UAAU,QAAQ,IAAI,SAAS,QAAQ,CAAC,IAAI,OAAO,CAAC;AAC7D;AAGO,SAAS,eAAe,IAAY,OAA8B;AACvE,SAAO,UAAU,YAAY,KAAK,cAAc,QAAQ,CAAC,IAAI,OAAO,EAAE;AACxE;AAGO,SAAS,cAAc,OAA4B;AACxD,SAAO,UAAU,OAAO,OAAO;AACjC;AAGO,SAAS,gBAAgB,OAA8B;AAC5D,SAAO,UAAU,WAAW,MAAM;AACpC;;;ACrBO,IAAM,iCAAuD;AAAA,EAClE,SAAS;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AAAA,EACA,OAAO;AAAA,EACP,WAAW;AAAA,EACX,eAAe;AAAA,EACf,WAAW;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,aAAa;AAAA,IACX,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,UAAU;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAAA,EACA,YAAY;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,MAAM;AAAA,EACR;AAAA,EACA,QAAQ;AAAA,IACN,WAAW;AAAA,MACT,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,MAAM;AAAA,IACN,OAAO;AAAA,IACP,cAAc;AAAA,IACd,UAAU;AAAA,IACV,kBAAkB;AAAA,EACpB;AAAA,EACA,YAAY;AAAA,IACV,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,EACX;AACF;;;AC7FA,OAAOC,eAAc;;;AC6Bd,SAAS,eACd,WACA,YAC2C;AAE3C,SAAQ,UAAkB,WAAW,UAAU;AAMjD;AAMO,SAAS,aACd,KAC+C;AAC/C,SAAO;AACT;AAGO,IAAM,oBAAoB,CAC/B,QACA,UACG;AACH,QAAM,YAAY,OAAO,QAAQ;AACjC,QAAM,UAAU,OAAO,MAAM;AAC7B,SAAO;AAAA,IACL,WAAW,CAAC,EAAE,MAAM,GAAG,MACrB,KAAK;AAAA,MACH;AAAA,MACA,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAAA,IAClE;AAAA,IACF,SAAS,CAAC,EAAE,KAAK,MAAwB,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAAA,EAC3E;AACF;AAEA,SAAS,QAAQ,GAAmB;AAClC,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,QAAI,KAAK,KAAK,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC;AAAA,EACvC;AACA,UAAQ,MAAM,GAAG,SAAS,EAAE;AAC9B;AAQO,SAAS,eACd,GACQ;AACR,QAAM,EAAE,MAAM,IAAI,IAAI,IAAI,GAAG,KAAK,IAAI;AACtC,QAAM,aAAa,OAAO,KAAK,IAAI,EAAE,KAAK;AAC1C,SAAO,QAAQ,KAAK,UAAU,MAAM,UAAU,CAAC;AACjD;AAGO,SAAS,cACd,WACA,SAC8C;AAC9C,SAAO,OAAK,EAAE,EAAE,MAAM,aAAa,EAAE,QAAQ;AAC/C;;;AC3FO,IAAM,cAAc,CACzB,OACA,QACA,OACA,KACA,OACA,QACuB;AACvB,QAAM,MAA0B,CAAC;AACjC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,KAAK,QAAQ;AACvB,UAAM,IAAI,QAAQ,KAAK,SAAS;AAChC,eAAW,IAAI,IAAI,OAAO,MAAM;AAChC,cAAU;AACV,QAAI,KAAK,CAAC,GAAG,QAAQ,MAAM,CAAC;AAAA,EAC9B;AACA,SAAO;AACT;AAOO,IAAM,kBAAkB,CAC7B,KACA,UAAoC,CAAC,MAC1B;AACX,MAAI,IAAI,SAAS,EAAG,QAAO;AAC3B,QAAM,IAAI,IAAI;AACd,QAAM,UAAU;AAChB,QAAM,WAAqB,CAAC;AAC5B,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;AAC9B,UAAM,KAAK,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACjC,UAAM,KAAK,IAAI,CAAC;AAChB,UAAM,KAAK,IAAI,IAAI,CAAC;AACpB,UAAM,KAAK,IAAI,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AACrC,UAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AACvC,UAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AACvC,UAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AACvC,UAAM,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK;AACvC,aAAS;AAAA,MACP,KAAK,KAAK,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,IACvH;AAAA,EACF;AACA,QAAM,OAAO,SAAS,KAAK,GAAG;AAC9B,SAAO,QAAQ,aACX,OACA,KAAK,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI;AAC/D;AASO,IAAM,iBAAiB,CAAC,MAAc,WAAW,SAAS;AAC/D,MAAI,IAAI,KAAK,IAAI,OAAO,QAAQ,IAAI;AACpC,SAAO,MAAM;AACX,QAAK,IAAI,QAAS;AAClB,YAAQ,IAAI,KAAK;AAAA,EACnB;AACF;;;ACtEA,YAAY,cAAc;AAE1B,OAAO,WAAW;AAClB,OAAO,kBAAkB;AAqBzB,IAAM,KAAK,OAAO,OAAO,UAAU,EAAE,KAAK,MAAM,CAAC;AAWjD,IAAM,MAAM,CAAC,MACX,aAAa,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,mBAAmB,CAAC,EAAE,CAAC;AAE1E,IAAM,gBAAgB,oBAAI,QAGxB;AAGK,IAAM,mBAAmB,CAC9B,KACA,eACA,OACA,kBACG;AAEH,QAAM,QACJ,OAAQ,IAAiB,SAAS,aAC7B,IAAuC,KAAK,IAC7C;AACN,MAAI,SAAS,cAAc,IAAI,KAAK,GAAG;AACrC,WAAO,cAAc,IAAI,KAAK;AAAA,EAChC;AAEA,QAAM,WAAW;AAAA,IACf,SAAS,CAAC,GAAY,MAAiB;AAAA,uBACpB,cAAc,QAAQ,KAAK;AAAA,uBAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,uBACvK,cAAc,QAAQ,aAAa,uCAAiC,IAAI,EAAE,WAAW,CAAC;AAAA,UACnG,EAAE,gBAAgB,gBAAgB,cAAc,QAAQ,aAAa,4CAAyC,IAAI,EAAE,aAAa,CAAC,YAAY,EAAE;AAAA,UAChJ,EAAE,eAAe,gBAAgB,cAAc,QAAQ,aAAa,2CAAwC,IAAI,EAAE,YAAY,CAAC,YAAY,EAAE;AAAA;AAAA,IAEnJ,MAAM,CAAC,GAAY,MAAgB;AAAA,uBAChB,cAAc,QAAQ,KAAK;AAAA,uBAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,uBACvK,cAAc,QAAQ,aAAa,kCAA+B,IAAI,eAAe,EAAE,UAAU,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA;AAAA,IAE3J,aAAa,CAAC,GAAY,MAAmB;AAAA,2BACtB,cAAc,QAAQ,KAAK;AAAA,2BAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,2BACvK,cAAc,QAAQ,aAAa,kCAA+B,IAAI,eAAe,EAAE,UAAU,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA;AAAA,IAE/J,UAAU,CAAC,GAAY,MAAgB;AAAA,yBAClB,cAAc,QAAQ,KAAK;AAAA,yBAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,yBACvK,cAAc,QAAQ,aAAa,kCAA+B,IAAI,eAAe,EAAE,UAAU,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA,yBACxI,cAAc,QAAQ,aAAa;AAAA,gDAClB,IAAI,EAAE,WAAW,CAAC;AAAA;AAAA;AAAA,IAGxD,UAAU,CAAC,GAAY,MAAgB;AAAA,yBAClB,cAAc,QAAQ,KAAK;AAAA,6BACvB,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,6BACvK,cAAc,QAAQ,aAAa;AAAA,gDACnB,IAAI,eAAe,EAAE,UAAU,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA;AAAA,6BAEtF,cAAc,QAAQ,aAAa,4BAA4B,IAAI,EAAE,IAAI,CAAC;AAAA;AAAA,IAEnG,YAAY,CAAC,GAAY,MAAkB;AAAA,yBACtB,cAAc,QAAQ,KAAK;AAAA,6BACvB,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,6BACvK,cAAc,QAAQ,aAAa;AAAA,gDACnB,IAAI,eAAe,EAAE,UAAU,MAAM,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,QAAQ,CAAC;AAAA,6BACtF,cAAc,QAAQ,aAAa,4BAA4B,IAAI,EAAE,IAAI,CAAC;AAAA,6BAC1E,cAAc,QAAQ,aAAa;AAAA,4CACpB,IAAI,EAAE,cAAc,CAAC;AAAA;AAAA;AAAA,IAG7D,UAAU,CAAC,GAAY,MAAoC;AAAA,yBACtC,cAAc,QAAQ,KAAK;AAAA,yBAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA;AAAA,IAE5L,UAAU,CAAC,GAAY,MAAgB;AACrC,YAAM,QAAQ,EAAE,QAAQ,uBAAuB;AAC/C,aAAO;AAAA,yBACY,cAAc,QAAQ,KAAK,KAAK,KAAK;AAAA,yBACrC,cAAc,QAAQ,WAAW,oCAAoC,IAAI,aAAa,EAAE,OAAO,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,YAC/I,EAAE,eAAe,gBAAgB,cAAc,QAAQ,aAAa,yCAAsC,IAAI,aAAa,EAAE,OAAO,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,YAAY,EAAE;AAAA,yBACxK,cAAc,QAAQ,aAAa,gCAAgC,IAAI,EAAE,GAAG,CAAC;AAAA,yBAC7E,cAAc,QAAQ,aAAa,+BAA+B,IAAI,EAAE,OAAO,CAAC;AAAA,YAC7F,EAAE,cAAc,gBAAgB,cAAc,QAAQ,aAAa,uCAAiC,IAAI,EAAE,WAAW,CAAC,YAAY,EAAE;AAAA;AAAA,IAE5I;AAAA,IACA,WAAW,CAAC,GAAY,MAAiB;AAAA,yBACpB,cAAc,QAAQ,KAAK;AAAA,yBAC3B,cAAc,QAAQ,WAAW,KAAK,IAAI,EAAE,IAAI,CAAC;AAAA,yBACjD,cAAc,QAAQ,aAAa;AAAA,YAChD,IAAI,aAAa,EAAE,WAAW,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,yBACpD,cAAc,QAAQ,aAAa;AAAA,wCACpB,IAAI,aAAa,EAAE,OAAO,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA;AAAA,yBAE5E,cAAc,QAAQ,aAAa;AAAA,4CAChB,IAAI,aAAa,EAAE,QAAQ,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA;AAAA;AAAA,IAGtG,MAAM,CAAC,GAAY,MAAY;AAAA,yBACV,cAAc,QAAQ,KAAK;AAAA,yBAC3B,cAAc,QAAQ,WAAW,QAAQ,IAAI,aAAa,EAAE,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC,WAAQ,IAAI,aAAa,EAAE,IAAI,MAAM,MAAM,CAAC,CAAC,IAAI,IAAI,MAAM,MAAM,CAAC;AAAA,YACpL,EAAE,eAAe,gBAAgB,cAAc,QAAQ,aAAa,gDAA6C,EAAE;AAAA,YACnH,EAAE,cAAc,gBAAgB,cAAc,QAAQ,aAAa,uCAAiC,IAAI,EAAE,WAAW,CAAC,YAAY,EAAE;AAAA;AAAA,EAE9I;AAEA,QAAM,OAAO,EAAE,MAAM,MAAM;AAAA,EAAC,GAAG,MAAM,MAAM;AAAA,EAAC,EAAE;AAC9C,QAAM,WAAgD,CAAC;AAEvD,SAAO,oBAAoB,QAAQ,EAAE,QAAQ,gBAAc;AACzD,UAAM,UACJ,kBAAkB,SACd,OACA,kBAAkB,SACjB,cAA2B,SAAS,UAAU;AAErD,QAAI,CAAC,SAAS;AACZ,eAAS,UAAU,IAAI;AACvB;AAAA,IACF;AAEA,aAAS,UAAU,IAAK,GACrB,IAAI,EACJ,KAAK,SAAS,cAAc,QAAQ,IAAI,EACxC,UAAU,GAAG,EACb,KAAK,SAAS,UAAU,CAAC;AAE5B,QAAI;AAAA,MACF,SAAS,UAAU;AAAA,IACrB;AAAA,EACF,CAAC;AAED,SAAO,aAAa,sBAAsB,MAAM;AAChD,MAAI,MAAO,eAAc,IAAI,OAAO,QAAQ;AAE5C,SAAO;AACT;;;AH9JA,IAAI,gBAAwC,CAAC;AAC7C,IAAI,uBAA6C;AAE1C,IAAM,sBAAsB,MAAqB;AACtD,MAAI,CAAC,sBAAsB;AACzB,2BAAuB,mBAAmB,EAAE,KAAK,OAAK;AACpD,sBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AACA,SAAO;AACT;AASO,IAAM,0BAA0B,CACrC,MACA,SACG;AACH,QAAM,qBAAqB,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,OAAK,EAAE,YAAY,CAAC,CAAC;AACrE,QAAM,iBAAiB,OAAO;AAAA,IAC5B,mBACG,OAAO,UAAQ;AACd,YAAM,OAAO,cAAc,IAAI;AAC/B,aAAO,QAAQ,SAAS,OAAO,QAAQ,KAAK,IAAI;AAAA,IAClD,CAAC,EACA,IAAI,UAAQ,CAAC,MAAM,cAAc,IAAI,CAAC,CAAC;AAAA,EAC5C;AAEA,SAAO,OAAO;AAAA,IACZ,KAAK,IAAI,OAAK;AACZ,YAAM,WAAW,eAAe,EAAE,YAAY;AAC9C,UAAI,CAAC,SAAU,QAAO,CAAC,GAAG,EAAE,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE,KAAK;AAC7D,aAAO;AAAA,QACL,GAAG,EAAE,YAAY,IAAI,EAAE,IAAI;AAAA,QAC3BC,UACG,MAAM,EACN,EAAE,MAAM,QAAQ,EAChB,KAAK,KAAK,IAAI,EACd,YAAY,KAAK,WAAW,EAC5B,OAAO,KAAK,MAAM,EAClB,WAAW,EAAE,KAAK;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGO,IAAM,mBAAmB,CAC9B,aACA,KACA,SACG;AACH,QAAM,mBAAmB,wBAAwB,aAAa,IAAI;AAClE,SAAO,CAAC,MAAiB;AACvB,UAAM,OAAO,iBAAiB,GAAG,EAAE,YAAY,IAAI,EAAE,IAAI,EAAE;AAC3D,QAAI,CAAC,KAAK,IAAK,QAAO;AACtB,QAAI,KAAK,IAAoD;AAC7D,WAAO,KAAK,IAAI;AAAA,EAClB;AACF;AAGO,IAAM,mBAAmB,CAC9B,QACA,WAEA,OAAO;AAAA,EAAQ,WACb,OACG,OAAO,WAAS,MAAM,OAAO,MAAM,MAAM,MAAM,KAAK,MAAM,IAAI,EAC9D,IAAI,YAAU;AAAA,IACb,MAAM,KAAK,IAAI,MAAM,MAAM,MAAM,IAAI;AAAA,IACrC,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,EAAE;AAAA,IAC/B,UAAU,KAAK,IAAI,MAAM,UAAU,MAAM,QAAQ;AAAA,EACnD,EAAE;AACN;AAGK,IAAM,iBAAiB,CAC5B,WACA,WACe;AACf,MAAI,UAAU,WAAW,EAAG,QAAO,CAAC;AAEpC,SAAO,CAAC,GAAG,SAAS,EACjB,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAC9B,OAAmB,CAAC,QAAQ,YAAY;AACvC,UAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,QAAI,QAAQ,QAAQ,QAAQ,KAAK,KAAK,QAAQ;AAC5C,WAAK,KAAK,KAAK,IAAI,KAAK,IAAI,QAAQ,EAAE;AACtC,aAAO;AAAA,IACT;AACA,WAAO,KAAK,EAAE,GAAG,QAAQ,CAAC;AAC1B,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACT;AAMO,SAAS,SAAS,MAAc,UAA4B;AACjE,QAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO;AACX,aAAW,QAAQ,OAAO;AACxB,UAAM,YAAY,OAAO,GAAG,IAAI,IAAI,IAAI,KAAK;AAC7C,QAAI,UAAU,SAAS,YAAY,MAAM;AACvC,YAAM,KAAK,IAAI;AACf,aAAO;AAAA,IACT,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,KAAM,OAAM,KAAK,IAAI;AACzB,SAAO,MAAM,SAAS,QAAQ,CAAC,EAAE;AACnC;;;AIvHA,SAAS,gBACP,KACa;AACb,MAAI,QAAQ,MAAO,QAAO,oBAAI,IAAY;AAC1C,MAAI,QAAQ,KAAM,QAAO,oBAAI,IAAI,CAAC,aAAa,aAAa,OAAO,CAAC;AACpE,SAAO,IAAI,IAAI,GAAe;AAChC;AAEA,SAAS,gBACP,KACa;AACb,MAAI,QAAQ,MAAO,QAAO,oBAAI,IAAY;AAC1C,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO,oBAAI,IAAI,CAAC,SAAS,eAAe,UAAU,CAAC;AACrD,SAAO,IAAI,IAAI,GAAe;AAChC;AAOO,SAAS,qBACd,KACA,MACM;AACN,MAAI,IAAI,aAAa,OAAO,WAAW,MAAO;AAE9C,QAAM,SAAS,gBAAgB,IAAI,aAAa,OAAO,MAAM;AAC7D,QAAM,OAAO,gBAAgB,IAAI,aAAa,OAAO,SAAS;AAC9D,QAAM,IAAI,IAAI,aAAa;AAC3B,QAAM,KAAK,IAAI,MAAM;AAErB,MAAI,OAAO,qBAAqB,UAAU,GAAG,EAAE,OAAO;AAGtD,MAAI,OAAO,IAAI,WAAW,KAAK,KAAK,IAAI,OAAO,GAAG;AAChD,SAAK,UACF,OAAO,OAAK,EAAE,MAAM,IAAI,OAAO,EAC/B,QAAQ,OAAK;AACZ,YAAM,OAAO,GAAG,EAAE,EAAE;AACpB,YAAM,UAAU,KAAK,UAAU,GAAG,WAAW,QAAQ,EAAE,eAAe;AACtE,YAAM,IAAI,IAAI,OAAO,EAAE,EAAE,IAAI,EAAE,iBAAiB;AAEhD,YAAM,OAAO,IAAI,OAAO,qBACrB,OAAO,GAAG,EACV,KAAK,SAAS,IAAI,QAAQ,OAAO,UAAU,KAAK;AAEnD,WACG,OAAO,MAAM,EACb,KAAK,KAAK,IAAI,WAAW,CAAC,EAC1B,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,OAAO,EACrB,KAAK,UAAU,EAAE,cAAc,EAC/B,KAAK,MAAM,GAAG,kBAAkB,CAAC,EACjC,KAAK,QAAQ,GAAG,gBAAgB,OAAO,EACvC,KAAK,UAAU,IAAI,MAAM,UAAU,MAAM,EACzC,KAAK,gBAAgB,GAAG;AAE3B,WACG,OAAO,MAAM,EACb,KAAK,SAAS,mBAAmB,EACjC,KAAK,QAAQ,IAAI,MAAM,OAAO,KAAK,EACnC,KAAK,eAAe,IAAI,MAAM,OAAO,YAAY,YAAY,EAC7D,KAAK,KAAK,IAAI,WAAW,IAAI,EAAE,YAAY,EAC3C,KAAK,KAAK,IAAI,EAAE,iBAAiB,CAAC,EAClC,KAAK,qBAAqB,QAAQ,EAClC,KAAK,aAAa,GAAG,QAAQ,EAC7B,KAAK,IAAI;AAAA,IACd,CAAC;AAAA,EACL;AAGA,QAAM,QAA0B,CAAC;AAEjC,MAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,SAAK,UACF,OAAO,OAAK,EAAE,OAAO,IAAI,OAAO,EAChC,QAAQ,OAAK;AACZ,YAAM,KAAK;AAAA,QACT,WAAW,EAAE;AAAA,QACb,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;AAAA,QACjD,SAAS,IAAI;AAAA,QACb,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;AAAA,QACnD,QAAQ,GAAG,EAAE,IAAI,SAAI,EAAE,EAAE;AAAA,QACzB,aAAa,EAAE,eAAe;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACL;AAEA,MAAI,OAAO,IAAI,WAAW,GAAG;AAC3B,SAAK,UACF,OAAO,OAAK,EAAE,SAAS,IAAI,aAAa,EAAE,QAAQ,IAAI,OAAO,EAC7D,QAAQ,OAAK;AACZ,YAAM,YAAY,EAAE,eAAe,mBAAmB;AACtD,YAAM,KAAK;AAAA,QACT,WAAW,EAAE;AAAA,QACb,OAAO,IAAI,OAAO,EAAE,KAAK;AAAA,QACzB,SAAS,IAAI;AAAA,QACb,SAAS,IAAI,OAAO,EAAE,KAAK;AAAA,QAC3B,QAAQ,GAAG,EAAE,KAAK,WAAQ,SAAS;AAAA,QACnC,aAAa,EAAE,eAAe;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACL;AAEA,MAAI,OAAO,IAAI,OAAO,GAAG;AACvB,SAAK,MACF,OAAO,OAAK,EAAE,OAAO,IAAI,OAAO,EAChC,QAAQ,OAAK;AACZ,YAAM,YAAY,EAAE,OAAO,EAAE,MAAM;AACnC,YAAM,YAAY,EAAE,eAAe,qBAAkB;AACrD,YAAM,KAAK;AAAA,QACT,WAAW,EAAE;AAAA,QACb,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;AAAA,QACjD,SAAS,IAAI;AAAA,QACb,SAAS,IAAI,OAAO,KAAK,IAAI,UAAU,IAAI,SAAS,CAAC;AAAA,QACrD,QAAQ,GAAG,EAAE,IAAI,SAAI,EAAE,EAAE,WAAQ,SAAS;AAAA,QAC1C,aAAa,EAAE,eAAe;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AAAA,EACL;AAEA,QAAM,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAI9C,QAAM,iBAA6B,CAAC;AACpC,MAAI,QAAQ;AACZ,QAAM,eAAe,KAAK;AAAA,IACxB;AAAA,IACA,KAAK,MAAM,EAAE,uBAAuB,GAAG,WAAW,IAAI;AAAA,EACxD;AAEA,QAAM,QAAQ,UAAQ;AACpB,UAAM,YAAY,KAAK,MAAM,KAAK,YAAY,UAAU,KAAK,YAAY;AACzE,UAAM,QAAQ,IAAI,aAAa,EAAE,qBAAqB;AACtD,UAAM,SAAS,KAAK,IAAI,KAAK,OAAO,QAAQ,EAAE,WAAW;AACzD,YAAQ,SAAS;AACjB,mBAAe,KAAK,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EAC5C,CAAC;AAED,QAAM,SAAS,IAAI,YAAY,EAAE;AAGjC,MAAI,KAAK,IAAI,UAAU,KAAK,KAAK,IAAI,aAAa,GAAG;AACnD,mBAAe,QAAQ,CAAC,EAAE,MAAM,OAAO,MAAM;AAC3C,UAAI,OAAO,qBACR,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,OAAO,UAAU,OAAO,EAClD,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,IAAI,MAAM,OAAO,aAAa,EAC7C,KAAK,gBAAgB,IAAI,MAAM,OAAO,kBAAkB,EACxD,KAAK,oBAAoB,IAAI,MAAM,OAAO,sBAAsB,EAChE;AAAA,QACC;AAAA,QACA,KAAK,KAAK,OAAO,IAAI,KAAK,OAAO,MAAM,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO,MAAM,MAAM,IAAI,MAAM;AAAA,MAChG;AAAA,IACJ,CAAC;AAAA,EACH;AAGA,MAAI,KAAK,IAAI,aAAa,GAAG;AAC3B,UAAM,QAAQ,EAAE;AAChB,UAAM,SAAS,GAAG,gBAAgB;AAElC,mBAAe,QAAQ,CAAC,EAAE,MAAM,QAAQ,KAAK,MAAM;AACjD,YAAM,SAAS,IAAI,OAAO,qBACvB,OAAO,GAAG,EACV,KAAK,SAAS,IAAI,QAAQ,OAAO,UAAU,KAAK,EAChD,KAAK,aAAa,aAAa,MAAM,IAAI,MAAM,GAAG;AAErD,aACG,OAAO,MAAM,EACb,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,EAAE,mBAAmB,EACnC,KAAK,UAAU,IAAI,EACnB,KAAK,MAAM,GAAG,oBAAoB,CAAC,EACnC,KAAK,QAAQ,MAAM,EACnB,KAAK,gBAAgB,GAAG,uBAAuB,IAAI,EACnD,KAAK,UAAU,GAAG,yBAAyB,MAAM;AAEpD,aACG,OAAO,MAAM,EACb,KAAK,SAAS,sBAAsB,EACpC,KAAK,QAAQ,IAAI,MAAM,OAAO,KAAK,EACnC,KAAK,eAAe,GAAG,oBAAoB,GAAG,EAC9C,KAAK,eAAe,IAAI,MAAM,OAAO,UAAU,EAC/C,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,QAAQ,IAAI,EACtB,KAAK,aAAa,GAAG,QAAQ,EAC7B,KAAK,KAAK,MAAM;AAEnB,UAAI,KAAK,aAAa;AACpB,cAAM,QAAQ,SAAS,KAAK,aAAa,YAAY;AACrD,cAAM,SAAS,OACZ,OAAO,MAAM,EACb,KAAK,SAAS,oBAAoB,EAClC,KAAK,QAAQ,IAAI,MAAM,OAAO,SAAS,EACvC,KAAK,eAAe,GAAG,kBAAkB,GAAG,EAC5C,KAAK,eAAe,IAAI,MAAM,OAAO,YAAY,YAAY,EAC7D,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,QAAQ,OAAO,KAAK,EAC9B,KAAK,aAAa,GAAG,QAAQ;AAChC,cAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,iBACG,OAAO,OAAO,EACd,KAAK,KAAK,CAAC,EACX,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK,EAC9B,KAAK,IAAI;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClNO,SAAS,UAAU,KAAkB,MAAoB;AAC9D,MAAI,CAAC,KAAK,OAAQ;AAElB,QAAM;AAAA,IACJ,QAAQ,EAAE,WAAW;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAAC;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,aAAW,UAAU,KAAK,QAAQ,MAAM,IAAI,EAAE,EAAE,OAAO;AAEvD,QAAM,KAAK,aAAa;AAExB,OAAK,QAAQ,UAAQ;AAKnB,UAAM,UAAU,KAAK,OAAO,MAAM,KAAK;AACvC,UAAM,UAAU,KAAK,KAAK,MAAM,KAAK,OAAO;AAC5C,UAAM,SAAS,eAAe,OAAO;AACrC,UAAM,SAAS,eAAe,OAAO;AAErC,UAAM,OAAO,OAAO,KAAK,IAAI,KAAK,MAAM,SAAS,CAAC;AAClD,UAAM,OAAO,OAAO,KAAK,IAAI,KAAK,IAAI,OAAO,CAAC;AAC9C,UAAM,OAAO,OAAO;AAEpB,UAAM,MAAM,KAAK;AAAA,MACf,GAAG,UAAU;AAAA,MACb,KAAK,IAAI,OAAO,GAAG,UAAU,OAAO,GAAG,UAAU,GAAG;AAAA,IACtD;AAEA,UAAM,SAAS,KAAK,OAAO;AAC3B,UAAM,SAAS,KAAK,KAAK;AAEzB,UAAM,SAAS,SACV;AAAA,MACC,CAAC,UAAU,IAAI;AAAA,MACf,CAAC,WAAW,IAAI;AAAA,IAClB,IACA,YAAY,UAAU,WAAW,MAAM,KAAK,GAAG,WAAW,MAAM;AACpE,UAAM,SAAS,SACV;AAAA,MACC,CAAC,UAAU,IAAI;AAAA,MACf,CAAC,WAAW,IAAI;AAAA,IAClB,IACA,YAAY,UAAU,WAAW,MAAM,KAAK,GAAG,WAAW,MAAM;AAGpE,UAAM,UAAU,SACZ,KAAK,SAAS,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM,UAAU,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,KACxF,gBAAgB,MAAM;AAC1B,UAAM,UAAU,SACZ,KAAK,SAAS,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM,UAAU,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,KACxF,gBAAgB,MAAM;AAK1B,UAAM,cAAc,SAChB,KAAK,SAAS,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,KAC3C,gBAAgB,CAAC,GAAG,MAAM,EAAE,QAAQ,GAAG,EAAE,YAAY,KAAK,CAAC;AAC/D,UAAM,aAAa,GAAG,OAAO,MAAM,UAAU,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,GAAG,WAAW,MAAM,SAAS,QAAQ,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AAEpI,UAAM,cAAc,KAAK,eACrBA,UAAS,WACTA,UAAS;AAEb,UAAM,IAAI,WACP,OAAO,GAAG,EACV,KAAK,SAAS,QAAQ,MAAM,IAAI,EAChC,MAAM,IAAI,EACV,MAAM,UAAU,SAAS,EACzB,GAAG,aAAa,SAAS,KAAK,IAAI,EAClC,GAAG,YAAY,SAAS,KAAK,IAAI;AAEpC,UAAM,aAAa,KAAK,eACpB,MAAM,KAAK,YACX,MAAM,KAAK;AAEf,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,QAAQ,MAAM,IAAI,EAChC,KAAK,KAAK,UAAU,EACpB,KAAK,QAAQ,YAAY,IAAI,CAAC,EAC9B,KAAK,gBAAgB,MAAM,KAAK,WAAW,EAC3C,KAAK,UAAU,MAAM;AAExB,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,QAAQ,MAAM,OAAO,EACnC,KAAK,KAAK,OAAO,EACjB,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,MAAM,KAAK,kBAAkB,EAClD,KAAK,kBAAkB,OAAO,EAC9B,KAAK,mBAAmB,OAAO;AAElC,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,QAAQ,MAAM,OAAO,EACnC,KAAK,KAAK,OAAO,EACjB,KAAK,QAAQ,MAAM,EACnB,KAAK,UAAU,UAAU,EACzB,KAAK,gBAAgB,MAAM,KAAK,kBAAkB,EAClD,KAAK,kBAAkB,OAAO,EAC9B,KAAK,mBAAmB,OAAO;AAAA,EACpC,CAAC;AACH;;;AClIA,YAAYC,SAAQ;AAGpB,SAAS,4BAA4B;AAU9B,SAAS,uBACd,KACA,MACM;AACN,MAAI,CAAC,IAAI,aAAa,mBAAmB,OAAQ;AAEjD,MAAI,OAAO,wBAAwB,UAAU,GAAG,EAAE,OAAO;AAEzD,QAAM,MAAM,IAAI,aAAa;AAC7B,QAAM,OAAO,IAAI,MAAM;AACvB,QAAM,OAAO,CAAC,OAAe,eAAe,IAAI,IAAI,MAAM,QAAQ;AAClE,QAAM,QAAQ,gBAAgB,IAAI,MAAM,QAAQ;AAEhD,QAAM,aAAa,qBAAqB,IAAI,gBAAgB;AAC5D,QAAM,SACH,gBAAY,EACZ,OAAO,CAAC,GAAM,QAAI,UAAU,KAAK,CAAC,CAAC,EACnC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC;AAE5B,QAAM,WAA2C,CAAC;AAElD,QAAM,aAAa,CAAC,GAA0B,SAAiB;AAC7D,UAAM,cAAc,KAAK,IAAI,EAAE,MAAM,IAAI,SAAS;AAClD,UAAM,YAAY,KAAK,IAAI,EAAE,IAAI,IAAI,OAAO;AAC5C,QAAI,eAAe,UAAW;AAE9B,UAAM,OAAO,IAAI,QAAQ,cAAc,aAAa,CAAC;AACrD,UAAM,aAAa,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK;AAC3D,UAAM,cAAc,YAAY,IAAI;AACpC,UAAM,QAAQ,KAAK,WAAW;AAC9B,UAAM,QAAQ,KAAK,WAAW;AAC9B,UAAM,UAAU;AAEhB,QAAI;AACJ,QAAI;AACJ,QAAI,IAAI,kBAAkB,QAAW;AACnC,YAAM,WAAW,KAAK;AAAA,QACpB;AAAA,QACA,KAAK,OAAO,IAAI,gBAAiB,KAAK,KAAK;AAAA,MAC7C;AACA,cAAQ,SAAS,MAAM,QAAQ;AAC/B,aAAO,IAAI;AAAA,IACb,OAAO;AACL,cAAQ,CAAC,IAAI;AACb,aAAO,KAAK,SAAS,QAAQ;AAAA,IAC/B;AAEA,UAAM,SAAS,MAAM,SAAS,QAAQ;AACtC,QAAI,SAAS,OAAO,SAAS;AAE7B,eAAW,OAAO,UAAU;AAC1B,UAAI,SAAS,IAAI,OAAO,SAAS,SAAS,IAAI,IAAK,UAAS,IAAI,MAAM;AAAA,IACxE;AACA,aAAS,KAAK,EAAE,KAAK,QAAQ,KAAK,SAAS,OAAO,CAAC;AAEnD,QAAI,OAAO,wBACR,OAAO,MAAM,EACb,KAAK,KAAK,cAAc,IAAI,EAC5B,KAAK,KAAK,MAAM,EAChB,KAAK,SAAS,IAAI,EAClB,KAAK,UAAU,MAAM,EACrB,KAAK,MAAM,IAAI,WAAW,EAC1B,KAAK,QAAQ,KAAK,aAAa,OAAO,EACtC,KAAK,UAAU,KAAK,cAAc,SAAS,EAC3C,KAAK,gBAAgB,GAAG;AAE3B,UAAM,SAAS,IAAI,OAAO,wBACvB,OAAO,MAAM,EACb,KAAK,KAAK,cAAc,CAAC,EACzB,KAAK,KAAK,SAAS,QAAQ,IAAI,EAC/B,KAAK,aAAa,KAAK,QAAQ,EAC/B,KAAK,eAAe,KAAK,cAAc,YAAY,EACnD,KAAK,eAAe,KAAK,cAAc,GAAG,EAC1C,KAAK,eAAe,KAAK,EACzB,KAAK,QAAQ,KAAK,cAAc,SAAS;AAE5C,UAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,aACG,OAAO,OAAO,EACd,KAAK,KAAK,cAAc,CAAC,EACzB,KAAK,MAAM,MAAM,IAAI,IAAI,KAAK,EAC9B,KAAK,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AAEA,MAAI,WAAW;AACf,OAAK,UACF,OAAO,UAAQ;AACd,QAAI,KAAK,aAAa,UAAU;AAC9B,iBAAW,KAAK;AAChB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC,EACA;AAAA,IAAQ,OACP;AAAA,MACE;AAAA,MACA,GAAG,IAAI,OAAO,cAAc,IAAI,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI;AAAA,IACpE;AAAA,EACF;AAEF,aAAW;AACX,OAAK,YACF,OAAO,UAAQ;AACd,QAAI,KAAK,aAAa,UAAU;AAC9B,iBAAW,KAAK;AAChB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC,EACA;AAAA,IAAQ,CAAC,MACR;AAAA,MACE;AAAA,MACA,GAAG,IAAI,OAAO,gBAAgB,IAAI,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,IAAI,EAAE,IAAI,IAAI,IAAI,OAAO,oBAAoB,IAAI,KAAM,EAAiB,cAAc,CAAC,GAAG,KAAK;AAAA,IAC3J;AAAA,EACF;AACJ;;;ACjIA,YAAYC,SAAQ;AAWpB,SAAS,wBAAAC,6BAA4B;AAe9B,SAAS,iBAAiB,KAAkB,MAA0B;AAC3E,QAAM,EAAE,WAAW,QAAQ,IAAI,kBAAkB,IAAI,QAAQ;AAAA,IAC3D,MAAM,IAAI;AAAA,IACV,IAAI,IAAI;AAAA,EACV,CAAC;AAED,QAAM,aAAaC,sBAAqB,IAAI,gBAAgB;AAC5D,QAAM,wBAA2B,QAAI,UAAU,KAAK;AAEpD,QAAM,SACH,gBAAY,EACZ,OAAO,CAAC,GAAG,qBAAqB,CAAC,EACjC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC;AAE5B,QAAM,MAAM,IAAI,aAAa;AAE7B,MAAI,OAAO,kBACR,UAAU,IAAI,IAAI,QAAQ,UAAU,IAAI,EAAE,EAC1C,OAAO;AAEV,MAAI,KAAK,cAAc,KAAK,WAAW,aAAa,IAAI,cAAc,GAAG;AACvE,UAAM,YAAY,IAAI,OAAO,eAC1B,UAAU,MAAM,EAChB,KAAK,CAAC,KAAK,UAAU,CAAC;AAEzB,cAAU,KAAK,EAAE,OAAO;AAExB,UAAM,eAAe,UAClB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,UAAU,IAAI,EACxC;AAAA,MACC;AAAA,MACA,CAAC,OACE,IAAI,cACH,OAAQ,EAAE,QAAQ,IAAI,UAAU,kBAAkB,MAAQ,CAAC,KAC7D;AAAA,IACJ,EACC,KAAK,KAAK,CAAC,MAAiB;AAC3B,aACE,IAAI,OAAO,CAAC,IACZ,IAAI,OAAO,EAAE,YAAY,IAAI,UAAU,mBAAmB;AAAA,IAE9D,CAAC,EACA;AAAA,MAAK;AAAA,MAAS,CAAC,MACd,OAAQ,EAAE,QAAQ,IAAI,UAAU,kBAAkB,MAAQ,CAAC;AAAA,IAC7D,EACC,KAAK,UAAU,CAAC,MAAiB;AAChC,aAAO,IAAI,OAAO,EAAE,YAAY,IAAI,UAAU,mBAAmB;AAAA,IACnE,CAAC,EACA,KAAK,QAAQ,IAAI,SAAS,IAAI,IAAI,CAAC,EACnC,KAAK,UAAU,IAAI,MAAM,UAAU,MAAM,EACzC,KAAK,gBAAgB,IAAI,MAAM,UAAU,WAAW;AAEvD,iBACG,GAAG,aAAa,IAAI,SAAS,UAAU,IAAI,EAC3C,GAAG,YAAY,IAAI,SAAS,UAAU,IAAI;AAAA,EAC/C;AAOA,QAAM,OAAO,IAAI,OAAO,UACrB,UAAoC,IAAI,IAAI,QAAQ,SAAS,IAAI,EAAE,EACnE,KAAK,KAAK,WAAW,cAAc;AAEtC,OAAK,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAEhE,QAAM,UAAU,KACb,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,SAAS,IAAI,EACvC,KAAK,QAAQ,IAAI,MAAM,SAAS,IAAI,EACpC,KAAK,UAAU,IAAI,MAAM,SAAS,MAAM,EACxC,KAAK,gBAAgB,IAAI,MAAM,SAAS,WAAW,EACnD,KAAK,oBAAoB,IAAI,MAAM,SAAS,eAAe,EAC3D,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC,EACjD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,IAAI,SAAS,KAAK,IAAI,EACtC,GAAG,YAAY,IAAI,SAAS,KAAK,IAAI;AAExC,iBAAe,SAAS,IAAI,UAAU,EAAE;AAAA,IACtC;AAAA,IACA,IAAI,MAAM,SAAS;AAAA,EACrB;AAGA,OACG,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC;AACpD,iBAAe,MAAM,IAAI,UAAU,EAChC,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAI3B,QAAM,gBAAgB,IAAI,OAAO,iBAC9B,UAAoC,KAAK,IAAI,QAAQ,YAAY,IAAI,EAAE,EACvE,KAAK,KAAK,cAAc,cAAc;AAEzC,gBAAc,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC,EAAE,OAAO;AAE3E,QAAM,QAAQ,cACX,MAAM,EACN,OAAO,GAAG,EACV,KAAK,SAAS,IAAI,QAAQ,YAAY,IAAI,EAC1C,MAAM,WAAW,CAAC,EAClB,GAAG,aAAa,IAAI,SAAS,YAAY,IAAI,EAC7C,GAAG,YAAY,IAAI,SAAS,YAAY,IAAI;AAE/C,QACG,OAAO,MAAM,EACb,KAAK,SAAS,mBAAmB,EACjC,KAAK,UAAU,MAAM;AACxB,QACG,OAAO,MAAM,EACb,KAAK,SAAS,mBAAmB,EACjC,KAAK,UAAU,IAAI,MAAM,YAAY,MAAM,EAC3C,KAAK,gBAAgB,IAAI,MAAM,YAAY,WAAW;AACzD,QACG,OAAO,MAAM,EACb,KAAK,SAAS,mBAAmB,EACjC,KAAK,UAAU,IAAI,MAAM,YAAY,MAAM,EAC3C,KAAK,gBAAgB,IAAI,MAAM,YAAY,WAAW;AAEzD,QAAM,KAAK,CAAC,GAAgB,GAAG,UAAU;AACvC,UAAM,KACH,IAAI,cACH;AAAA,MACE,EAAE,WAAW,EAAE,WAAW,IAAI,YAAY;AAAA,IAC5C,KACF;AACF,UAAM,IAAI;AAAA,MACR,EAAE,WAAW,EAAE,WAAW,IAAI,YAAY;AAAA,IAC5C;AACA,UAAM,IAAO,WAAO,MAAM,CAAC,CAAY;AACvC,MAAE,OAAO,oBAAoB,EAC1B,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,CAAC,EACf,KAAK,QAAQ,IAAI,SAAS,aAAa,IAAI,CAAC,EAC5C,KAAK,KAAK,QAAQ,CAAC,CAAC,EACpB,KAAK,UAAU,UAAU,CAAC,CAAC;AAC9B,UAAM,YAAY,EAAE,UAAU,oBAAoB,EAAE,MAAM;AAC1D,IAAG,WAAO,UAAU,CAAC,CAAY,EAC9B,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,QAAQ,CAAC,CAAC,EACrB,KAAK,MAAM,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC;AACvC,IAAG,WAAO,UAAU,CAAC,CAAY,EAC9B,KAAK,MAAM,IAAI,CAAC,EAChB,KAAK,MAAM,IAAI,CAAC,EAChB,KAAK,MAAM,QAAQ,CAAC,CAAC,EACrB,KAAK,MAAM,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC;AAAA,EACzC,CAAC;AAED,iBAAe,OAAO,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAExD,gBAAc,KAAK,CAAC,GAAgB,GAAG,UAAU;AAC/C,UAAM,KACH,IAAI,cACH;AAAA,MACE,EAAE,WAAW,EAAE,WAAW,IAAI,YAAY;AAAA,IAC5C,KACF;AACF,UAAM,IAAI;AAAA,MACR,EAAE,WAAW,EAAE,WAAW,IAAI,YAAY;AAAA,IAC5C;AACA,UAAM,IAAO,WAAO,MAAM,CAAC,CAAY;AACvC,MAAE,OAAO,oBAAoB,EAC1B,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,CAAC,EACf,KAAK,QAAQ,IAAI,SAAS,aAAa,IAAI,CAAC;AAC/C,UAAM,YAAY,EAAE,UAAU,oBAAoB,EAAE,MAAM;AAC1D,IAAG,WAAO,UAAU,CAAC,CAAY,EAC9B,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC;AACf,IAAG,WAAO,UAAU,CAAC,CAAY,EAC9B,KAAK,MAAM,IAAI,CAAC,EAChB,KAAK,MAAM,IAAI,CAAC;AAAA,EACrB,CAAC;AAED;AAAA,IACE,cAAc,OAAuB,oBAAoB;AAAA,IACzD,IAAI;AAAA,EACN,EACG,KAAK,KAAK,CAAC,MAAmB,QAAQ,CAAC,CAAC,EACxC,KAAK,UAAU,CAAC,MAAmB,UAAU,CAAC,CAAC;AAElD;AAAA,IACE,cAAc,UAAuC,oBAAoB;AAAA,IACzE,IAAI;AAAA,EACN,EACG,KAAK,MAAM,CAAC,MAAe,QAAQ,CAAgB,CAAC,EACpD;AAAA,IACC;AAAA,IACA,CAAC,MAAe,QAAQ,CAAgB,IAAI,UAAU,CAAgB;AAAA,EACxE;AAIF,QAAM,WAAW,IAAI,OAAO,cACzB,UAAoC,IAAI,IAAI,QAAQ,SAAS,IAAI,EAAE,EACnE,KAAK,KAAK,WAAW,cAAc;AAEtC,WAAS,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAEpE,QAAM,cAAc,SACjB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,SAAS,IAAI,EACvC,KAAK,UAAU,IAAI,MAAM,SAAS,MAAM,EACxC,KAAK,gBAAgB,IAAI,MAAM,SAAS,WAAW,EACnD,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC,EACjD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,QAAQ,CAAC,MAAgB,IAAI,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,EACxD,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,IAAI,SAAS,SAAS,IAAI,EAC1C,GAAG,YAAY,IAAI,SAAS,SAAS,IAAI;AAE5C,iBAAe,aAAa,IAAI,UAAU,EAAE,KAAK,WAAW,CAAC;AAE7D,WACG,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC,EACjD,KAAK,QAAQ,CAAC,MAAgB,IAAI,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC;AAC3D,iBAAe,UAAU,IAAI,UAAU,EACpC,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAI3B,QAAM,WAAW,IAAI,OAAO,cACzB,UAAoC,IAAI,IAAI,QAAQ,SAAS,IAAI,EAAE,EACnE,KAAK,KAAK,WAAW,cAAc;AAEtC,WAAS,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAEpE,QAAM,cAAc,SACjB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,SAAS,IAAI,EACvC,KAAK,QAAQ,IAAI,MAAM,SAAS,IAAI,EACpC,KAAK,UAAU,IAAI,MAAM,SAAS,MAAM,EACxC,KAAK,gBAAgB,IAAI,MAAM,SAAS,WAAW,EACnD,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC,EACjD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,IAAI,SAAS,SAAS,IAAI,EAC1C,GAAG,YAAY,IAAI,SAAS,SAAS,IAAI;AAE5C,iBAAe,aAAa,IAAI,UAAU,EAAE,KAAK,WAAW,CAAC;AAE7D,WACG,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC;AACpD,iBAAe,UAAU,IAAI,UAAU,EACpC,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAI3B,QAAM,aAAa,IAAI,OAAO,gBAC3B,UAAsC,IAAI,IAAI,QAAQ,WAAW,IAAI,EAAE,EACvE,KAAK,KAAK,aAAa,cAAc;AAExC,aAAW,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAEtE,QAAM,gBAAgB,WACnB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,WAAW,IAAI,EACzC,KAAK,QAAQ,IAAI,SAAS,YAAY,IAAI,CAAC,EAC3C,KAAK,UAAU,IAAI,MAAM,WAAW,MAAM,EAC1C,KAAK,gBAAgB,IAAI,MAAM,WAAW,WAAW,EACrD,KAAK,KAAK,CAAC,OAAmB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACvE,KAAK,SAAS,CAAC,MAAkB,OAAO,EAAE,QAAQ,CAAC,EACnD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,IAAI,SAAS,WAAW,IAAI,EAC5C,GAAG,YAAY,IAAI,SAAS,WAAW,IAAI;AAE9C,iBAAe,eAAe,IAAI,UAAU,EAAE,KAAK,WAAW,CAAC;AAE/D,aACG,KAAK,KAAK,CAAC,OAAmB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACvE,KAAK,SAAS,CAAC,MAAkB,OAAO,EAAE,QAAQ,CAAC;AACtD,iBAAe,YAAY,IAAI,UAAU,EACtC,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAK3B,QAAM,gBAA4B,CAAC;AACnC,gBAAc,KAAK,GAAG,iBAAiB,KAAK,WAAW,KAAK,WAAW,CAAC;AACxE,gBAAc,KAAK,GAAG,iBAAiB,KAAK,aAAa,KAAK,SAAS,CAAC;AAExE,QAAM,kBAAkB,eAAe,eAAe,CAAC;AAEvD,QAAM,WAAW,IAAI,OAAO,cACzB,UAAoC,IAAI,IAAI,QAAQ,SAAS,IAAI,EAAE,EACnE,KAAK,iBAAiB,CAAC,MAAgB,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;AAE3E,WAAS,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAEpE,QAAM,cAAc,SACjB,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,SAAS,IAAI,EACvC,KAAK,QAAQ,IAAI,SAAS,SAAS,IAAI,CAAC,EACxC,KAAK,UAAU,IAAI,MAAM,SAAS,MAAM,EACxC,KAAK,gBAAgB,IAAI,MAAM,SAAS,WAAW,EACnD,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC,EACjD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,IAAI,SAAS,SAAS,IAAI,EAC1C,GAAG,YAAY,IAAI,SAAS,SAAS,IAAI;AAE5C,iBAAe,aAAa,IAAI,UAAU,EAAE,KAAK,WAAW,CAAC;AAE7D,WACG,KAAK,KAAK,CAAC,OAAiB,IAAI,cAAc,OAAO,EAAE,QAAQ,KAAK,CAAC,EACrE,KAAK,SAAS,CAAC,MAAgB,OAAO,EAAE,QAAQ,CAAC;AACpD,iBAAe,UAAU,IAAI,UAAU,EACpC,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAC7B;;;ACxWA,SAAS,SACP,KACA,OACA,OACA,QACA,YACA,UACoB;AACpB,QAAM,MAA0B,CAAC;AACjC,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,KAAK,QAAQ;AACvB,UAAM,QAAQ,aAAa,KAAK,IAAI,aAAa;AACjD,UAAM,UAAU,SAAS,IAAI,IAAI,IAAI,KAAK;AAC1C,QAAI,KAAK,CAAC,OAAO,OAAO,CAAC;AAAA,EAC3B;AACA,SAAO;AACT;AAWO,SAAS,cAAc,KAAkB,MAAwB;AACtE,MAAI,CAAC,KAAK,OAAQ;AAElB,QAAM;AAAA,IACJ,QAAQ,EAAE,eAAe;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,iBAAe,UAAU,KAAK,QAAQ,UAAU,IAAI,EAAE,EAAE,OAAO;AAE/D,QAAM,KAAK,aAAa;AACxB,QAAM,YAAa,aAAa,GAAG,kBAAmB;AACtD,QAAM,KAAK,cAAc;AACzB,QAAM,IAAI,YAAY;AAEtB,QAAM,aAAa,CAAC,UAAkB,KAAK,QAAQ;AAEnD,OAAK,QAAQ,cAAY;AACvB,UAAM,MAAM,eAAe,SAAS,OAAO,IAAI;AAC/C,UAAM,KAAK,OAAO,SAAS,KAAK;AAEhC,UAAM,IAAI,eACP,OAAO,GAAG,EACV,KAAK,SAAS,QAAQ,UAAU,IAAI,EACpC,MAAM,QAAQ,EACd;AAAA,MACC;AAAA,MACA,eAAe,EAAE,YAAY,SAAS,GAAG,IAAI,WAAW;AAAA,IAC1D,EACC,GAAG,aAAa,SAAS,SAAS,IAAI,EACtC,GAAG,YAAY,SAAS,SAAS,IAAI,EACrC,MAAM,UAAU,SAAS;AAE5B,UAAM,YAAY,SAAS,QAAQ,GAAG,UAAU,QAAQ,GAAG,UAAU;AACrE,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,QAAQ,UAAU,OAAO,EACvC,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,CAAC,SAAS,EACpB,KAAK,SAAS,CAAC,EACf,KAAK,UAAU,YAAY,CAAC,EAC5B,KAAK,QAAQ,aAAa,EAC1B,MAAM,kBAAkB,KAAK;AAEhC,UAAM,iBAAiB,SAAS,eAC5B,MAAM,SAAS,YACf,MAAM,SAAS;AAEnB,UAAM,aAAa,CACjB,IACA,IACA,IACA,IACA,OAEA,EACG,OAAO,MAAM,EACb,KAAK,SAAS,QAAQ,UAAU,IAAI,EACpC,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,EAAE,EACb,KAAK,UAAU,cAAc,EAC7B,KAAK,gBAAgB,EAAE,EACvB,KAAK,kBAAkB,OAAO;AAEnC,UAAM,iBAAiB,CAAC,KAAyB,OAC/C,EACG,OAAO,UAAU,EACjB,KAAK,SAAS,QAAQ,UAAU,QAAQ,EACxC;AAAA,MACC;AAAA,MACA,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,GAAG;AAAA,IAC3D,EACC,KAAK,UAAU,cAAc,EAC7B,KAAK,gBAAgB,EAAE,EACvB,KAAK,QAAQ,MAAM,EACnB,KAAK,kBAAkB,OAAO,EAC9B,KAAK,mBAAmB,OAAO;AAEpC,QAAI,SAAS,OAAO;AAClB,YAAM,YACJ,GAAG,MAAM,gBAAgB,KAAK,MAAM,IAAI,IAAI,GAAG,MAAM,iBAAiB;AACxE,YAAM,aAAa,GAAG,MAAM,SAAS;AAErC,YAAM,QAAQ,MAAM;AAAA,QAClB,EAAE,QAAQ,UAAU;AAAA,QACpB,OAAO,IAAI,IAAI,IAAI,KAAK;AAAA,MAC1B,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAEtB,YAAM,QAAQ,CAAC,MAAM,QAAQ;AAC3B,cAAM,YAAY,QAAQ,KAAK,MAAM,YAAY,CAAC;AAClD,cAAM,KAAK,YACP,MAAM,SAAS,MAAM,qBACrB,MAAM,SAAS,MAAM,sBACrB,IAAI,IAAI,MAAM,SAAS,MAAM;AACjC,cAAM,QAAQ,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC;AACtC,cAAM,SAAS,MAAM,IAAI,IAAI;AAC7B,cAAM,SAAS,OAAO,IAAI,IAAI;AAC9B,cAAM,SAAS,OAAO,IAAI,IAAI;AAC9B,uBAAe,SAAS,KAAK,OAAO,MAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE;AAAA,MACvE,CAAC;AAED,YAAM,cAAc,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC;AAC5C,eAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,cAAM,KAAK,OAAO,IAAI,IAAI;AAC1B,cAAM,UAAU,KAAK,MAAM,IAAI,KAAK,MAAM,SAAS,EAAE;AACrD;AAAA,UACE,WAAW,EAAE;AAAA,UACb,MAAM,OAAO;AAAA,UACb,WAAW,MAAM,IAAI,IAAI,OAAO,IAAI;AAAA,UACpC,MAAM,UAAU,CAAC;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAEA,YAAM,cAAc,MAAM,KAAK,MAAM,YAAY,CAAC,CAAC;AACnD,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,cAAM,KAAK,MAAM,IAAI,IAAI;AACzB,cAAM,MAAM,IAAI,IAAI,IAAI;AACxB,cAAM,MAAM,IAAI,IAAI,MAAM,KAAK;AAC/B;AAAA,UACE,WAAW,EAAE;AAAA,UACb;AAAA,UACA,WAAW,MAAM,IAAI,IAAI,OAAO,IAAI;AAAA,UACpC,cAAc,MAAM;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,YAAM,QAAQ,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC;AACtC,YAAM,SAAS,OAAO,IAAI,IAAI;AAC9B,YAAM,SAAS,OAAO,IAAI,IAAI;AAC9B;AAAA,QACE,SAAS,KAAK,OAAO,GAAG,GAAG,QAAQ,MAAM;AAAA,QACzC,MAAM,SAAS,OAAO;AAAA,MACxB;AAEA,YAAM,aAAa,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC;AAC3C,eAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,cAAM,KAAK,SAAS,IAAI,KAAK,IAAI,SAAS;AAC1C,cAAM,MAAM,MAAM,IAAI,IAAI;AAC1B,cAAM,MAAM,IAAI,IAAI,MAAM,IAAI;AAC9B;AAAA,UACE,WAAW,EAAE;AAAA,WACZ,IAAI,IAAI,IAAI,KAAK;AAAA,UAClB,WAAW,MAAM,IAAI,IAAI,OAAO,IAAI;AAAA,UACpC,MAAM;AAAA,UACN,MAAM,SAAS,OAAO;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AC7LA,YAAYC,SAAQ;AAEpB,SAAS,wBAAAC,6BAA4B;AAYrC,SAAS,kBACP,KACA,OACA,GACA,GACA,GACA,GACA,OACM;AACN,MAAI,KAAK,KAAK,KAAK,EAAG;AAEtB,QAAM,WAAW,IAAI,aAAa;AAClC,QAAM,MAAM,SAAS;AAErB,QAAM,IAAI,MAAM,OAAO,GAAG,EAAE,KAAK,SAAS,IAAI,QAAQ,WAAW,IAAI;AAErE,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,QAAQ,WAAW,IAAI,EACzC,KAAK,KAAK,IAAI,GAAG,EACjB,KAAK,KAAK,IAAI,GAAG,EACjB,KAAK,SAAS,IAAI,MAAM,CAAC,EACzB,KAAK,UAAU,IAAI,MAAM,CAAC,EAC1B,KAAK,QAAQ,SAAS,IAAI,EAC1B,KAAK,gBAAgB,SAAS,WAAW,EACzC,KAAK,UAAU,SAAS,MAAM,EAC9B,KAAK,gBAAgB,SAAS,WAAW,EACzC,KAAK,oBAAoB,SAAS,mBAAmB,IAAI,EACzD,MAAM,kBAAkB,MAAM;AAEjC,MAAI,OAAO;AACT,UAAM,QAAQ,SAAS,gBAAgB;AACvC,UAAM,SAAS,MAAM,SAAS,QAAQ,SAAS,eAAe;AAC9D,UAAM,SAAS,SAAS,gBAAgB,SAAS,eAAe;AAChE,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,IAAI,MAAM;AAErB,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,QAAQ,WAAW,OAAO,EAC5C,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,EAAE,EACZ,KAAK,SAAS,MAAM,EACpB,KAAK,UAAU,MAAM,EACrB,KAAK,MAAM,SAAS,WAAW,EAC/B,KAAK,QAAQ,SAAS,eAAe,EACrC,MAAM,kBAAkB,MAAM;AAEjC,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,QAAQ,WAAW,KAAK,EAC1C,KAAK,KAAK,KAAK,SAAS,YAAY,EACpC,KAAK,KAAK,KAAK,SAAS,SAAS,YAAY,EAC7C,KAAK,aAAa,SAAS,aAAa,EACxC,KAAK,QAAQ,SAAS,UAAU,EAChC,KAAK,eAAe,YAAY,EAChC,MAAM,kBAAkB,MAAM,EAC9B,KAAK,KAAK;AAAA,EACf;AACF;AAOO,SAAS,eAAe,KAAkB,IAAsB;AACrE,MAAI,OAAO,wBAAwB,UAAU,GAAG,EAAE,OAAO;AACzD,MAAI,OAAO,4BAA4B,UAAU,GAAG,EAAE,OAAO;AAC7D,MAAI,OAAO,yBAAyB,UAAU,GAAG,EAAE,OAAO;AAG1D,QAAM,oBAAoB,CAAC,UAAuC;AAChE,WAAO,QAAQ,OAAK;AAClB,UAAI,EAAE,SAAS,UAAa,EAAE,OAAO,OAAW;AAChD,YAAM,OAAO,KAAK,IAAI,EAAE,MAAM,IAAI,SAAS;AAC3C,YAAM,KAAK,KAAK,IAAI,EAAE,IAAI,IAAI,OAAO;AACrC,UAAI,QAAQ,GAAI;AAChB,YAAM,IAAI,IAAI,OAAO,IAAI;AACzB;AAAA,QACE;AAAA,QACA,IAAI,OAAO;AAAA,QACX,IAAI;AAAA,QACJ;AAAA,QACA,IAAI,YAAY,IAAI;AAAA,QACpB,IAAI,OAAO,EAAE,IAAI;AAAA,QACjB,EAAE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,oBAAkB,GAAG,SAAS;AAC9B,oBAAkB,GAAG,KAAK;AAG1B,QAAM,iBAAiB,IAAI,aAAa;AACxC,QAAM,oBACH,IAAI,aAAa,eAAe,kBAAmB;AACtD,QAAM,SAAS,IAAI,cAAc;AACjC,QAAM,QAAQ,oBAAoB;AAElC,KAAG,WAAW,QAAQ,OAAK;AACzB,QAAI,EAAE,UAAU,OAAW;AAC3B,QAAI,EAAE,QAAQ,IAAI,aAAa,EAAE,QAAQ,IAAI,QAAS;AACtD,UAAM,KAAK,IAAI,OAAO,EAAE,KAAK;AAC7B;AAAA,MACE;AAAA,MACA,IAAI,OAAO;AAAA,MACX;AAAA,MACA,KAAK,eAAe,UAAU;AAAA,MAC9B;AAAA,MACA,eAAe,UAAU,SAAS;AAAA,MAClC,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAGD,QAAM,WAAWA,sBAAqB,IAAI,gBAAgB;AAC1D,QAAM,eACH,gBAAY,EACZ,OAAO,CAAC,GAAM,QAAI,QAAQ,KAAK,CAAC,CAAC,EACjC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC;AAE5B,QAAM,qBAAqB,IAAI,aAAa;AAE5C,MACE,GAAG,cACH,IAAI,cAAc,KAClB,IAAI,iBAAiB,YAAY,WACjC;AACA,UAAM,KAAK,IAAI,iBAAiB;AAChC,UAAM,aACH,GAAG,QAAQ,mBAAmB,UAAU,kBAAkB,MAAQ;AACrE,UAAM,OAAO,IAAI,cAAc,aAAa,UAAU,KAAK;AAC3D,UAAM,MACJ,IAAI,OAAO,CAAC,IACZ,IAAI;AAAA,MACF,GAAG,YAAY,mBAAmB,UAAU;AAAA,IAC9C;AACF,UAAM,MAAM,aAAa,UAAU;AACnC,UAAM,MAAM,IAAI;AAAA,MACd,GAAG,YAAY,mBAAmB,UAAU;AAAA,IAC9C;AACA;AAAA,MACE;AAAA,MACA,IAAI,OAAO;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,WAAW;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,uBAAuB,CAC3B,OACA,MACA,MACA,SACG;AACH,WAAO,QAAQ,OAAK;AAClB,UAAI,EAAE,SAAS,UAAa,EAAE,OAAO,OAAW;AAChD,WACG;AAAA,QACC,OACE,EAAE,OAAO,EAAE,MACX,EAAE,KAAK,EAAE,SACR,EAAE,aAAa,UAAa,EAAE,aAAa,EAAE;AAAA,MAClD,EACC,QAAQ,OAAK;AACZ,cAAM,OAAO,KAAK,IAAI,EAAE,MAAO,IAAI,SAAS;AAC5C,cAAM,KAAK,KAAK,IAAI,EAAE,IAAK,IAAI,OAAO;AACtC,YAAI,QAAQ,GAAI;AAChB,cAAM,IAAI,IAAI,OAAO,IAAI;AACzB;AAAA,UACE;AAAA,UACA,IAAI,OAAO;AAAA,UACX,KAAK,CAAC;AAAA,UACN;AAAA,UACA,KAAK,CAAC;AAAA,UACN,IAAI,OAAO,EAAE,IAAI;AAAA,UACjB,EAAE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACL,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,CAAC,OACX,IAAI,cAAc,aAAa,EAAE,QAAQ,KAAK;AACjD,QAAM,OAAO,CAAC,MAA4B,aAAa,EAAE,QAAQ;AACjE,QAAM,iBAAiB,mBAAmB,YAAY;AACtD,QAAM,MAAM,CAAC,OACV,IAAI,cAAc,aAAa,EAAE,WAAW,EAAE,WAAW,cAAc,KACxE;AACF,QAAM,MAAM,CAAC,MACX,aAAa,EAAE,WAAW,EAAE,WAAW,cAAc;AAEvD;AAAA,IACE,GAAG;AAAA,IACH,IAAI,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE,GAAG;AAAA,IACH,IAAI,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE,GAAG;AAAA,IACH,IAAI,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE,GAAG;AAAA,IACH,IAAI,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACA;AAAA,IACE,GAAG;AAAA,IACH,IAAI,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACF;;;AC9OA,YAAYC,eAAc;AAC1B,SAAS,YAAY;AAgBrB,IAAMC,MAAK,EAAE,GAAGC,UAAS;AAmBlB,SAAS,eACd,UACA,SACA,UAKI,CAAC,GACC;AACN,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,QAAM,QAAQ,QAAQ,SAAS,CAAC;AAChC,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,QAAM,cAAc,QAAQ,eAAe,CAAC;AAC5C,QAAM,YAAY,QAAQ,aAAa,CAAC;AAExC,QAAM,YAAY,UAAU,KAAK,OAAK,CAAC,EAAE,SAAS,CAAC,EAAE,YAAY;AACjE,QAAM,WAAW,UAAU,KAAK,OAAK,EAAE,KAAK;AAC5C,QAAM,aAAa,UAAU,KAAK,OAAK,EAAE,YAAY;AACrD,QAAM,aAAa,MAAM,KAAK,OAAK,CAAC,EAAE,YAAY;AAClD,QAAM,aAAa,MAAM,KAAK,OAAK,EAAE,YAAY;AAEjD,QAAM,cAAc,UAAU,SAAS;AACvC,QAAM,kBAAkB,QAAQ,gBAAgB,CAAC,GAAG,SAAS;AAC7D,QAAM,oBAAoB,UAAU,KAAK,OAAK,EAAE,SAAS,aAAa;AACtE,QAAM,kBAAkB,UAAU,KAAK,OAAK,EAAE,SAAS,MAAM;AAC7D,QAAM,cAAc,UAAU,SAAS;AACvC,QAAM,gBAAgB,YAAY,SAAS;AAC3C,QAAM,eAAe,CAAC,CAAC,QAAQ,YAAY;AAC3C,QAAM,cACJ;AAAA,IACE;AAAA,MACE,GAAG,iBAAiB,WAAW,WAAW;AAAA,MAC1C,GAAG,iBAAiB,aAAa,SAAS;AAAA,IAC5C;AAAA,IACA;AAAA,EACF,EAAE,SAAS;AAEb,QAAM,MAAM;AAAA,IACV,QAAQ,UAAU,CAAC;AAAA,IACnB,0BAA0B;AAAA,EAC5B;AAEA,QAAM,QAAQ,KAAK,QAAQ,SAAS,CAAC,GAAG,kBAAkB;AAE1D,QAAM,MAAsC,QAAQ,aAChD,EAAE,GAAG,+BAA+B,QAAQ,GAAG,QAAQ,WAAW,IAClE,+BAA+B;AAEnC,QAAM,QAAsB,CAAC;AAC7B,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,OAAO;AAAA,MACP,cAAc;AAAA,IAChB,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,cAAc;AAAA,IAChB,CAAC;AACH,MAAI;AACF,UAAM,KAAK,EAAE,MAAM,QAAQ,OAAO,IAAI,OAAO,SAAS,cAAc,KAAK,CAAC;AAE5E,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AACH,MAAI;AACF,UAAM,KAAK;AAAA,MACT,MAAM;AAAA,MACN,OAAO,IAAI,OAAO;AAAA,MAClB,SAAS;AAAA,IACX,CAAC;AAEH,QAAM,QAAQD,IAAG,OAAO,QAAQ;AAChC,QAAM,UAAU,GAAG,EAAE,OAAO;AAE5B,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,KAAK,SAAS,CAAC,EAAE,KAAK,UAAU,CAAC;AACvC;AAAA,EACF;AAEA,QAAM,iBAAiB,mBAAmB,QAAQ,QAAQ;AAC1D,SAAO,OAAO,cAAc,EAAE,QAAQ,OAAK,MAAM,KAAK,CAAC,CAAC;AAExD,QAAM,cAAc,IAAI,WACpB,KAAK,IAAI,GAAG,KAAK,OAAO,IAAI,WAAW,IAAI,UAAU,KAAK,IAAI,SAAS,CAAC,IACxE,MAAM;AACV,QAAM,UAAU,KAAK,KAAK,MAAM,SAAS,WAAW;AACpD,QAAM,WAAW,KAAK,IAAI,MAAM,QAAQ,WAAW,IAAI,IAAI;AAC3D,QAAM,aAAa,IAAI,UAAU,IAAI;AACrC,QAAM,cAAc,UAAU,IAAI;AAElC,QAAM,KAAK,SAAS,UAAU,EAAE,KAAK,UAAU,WAAW;AAE1D,QAAM,KAAK;AAEX,QAAM,IAAI,MAAM,OAAO,GAAG,EAAE,KAAK,aAAa,aAAa,IAAI,OAAO,MAAM;AAE5E,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,MAAM,EACxB,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,aAAa,IAAI,OAAO,EACtC,KAAK,UAAU,cAAc,CAAC,EAC9B,KAAK,QAAQ,OAAO,EACpB,KAAK,MAAM,IAAI,YAAY,EAC3B,KAAK,gBAAgB,MAAM,OAAO,iBAAiB;AAEtD,IAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,KAAK,EACvB,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,EAAE,EACZ,KAAK,aAAa,MAAM,OAAO,QAAQ,EACvC,KAAK,eAAe,MAAM,OAAO,cAAc,YAAY,EAC3D,KAAK,eAAe,MAAM,OAAO,mBAAmB,MAAM,EAC1D,KAAK,GAAG,IAAI,KAAK,GAAG;AAEvB,QAAM,KAAK;AACX,QAAM,KAAK;AAEX,QAAM,QAAQ,CAAC,MAAM,MAAM;AACzB,UAAM,MAAM,IAAI;AAChB,UAAM,MAAM,KAAK,MAAM,IAAI,WAAW;AACtC,UAAM,UAAU,MAAM,IAAI,UAAU,IAAI,SAAS,KAAK;AACtD,UAAM,KAAK,MAAM,IAAI;AAErB,UAAM,OAAO,EAAE,OAAO,GAAG,EAAE,KAAK,SAAS,IAAI,IAAI;AAEjD,QAAI,KAAK,SAAS,YAAY;AAC5B,YAAM,QAAQ,KAAK,eACf,MAAM,SAAS,YACf,MAAM,SAAS;AAEnB,UAAI,KAAK,OAAO;AACd,QAAC,CAAC,IAAI,GAAG,CAAC,EAAe,QAAQ,YAAU;AACzC,eACG,OAAO,UAAU,EACjB,KAAK,SAAS,IAAI,YAAY,EAC9B;AAAA,YACC;AAAA,YACA,GAAG,EAAE,IAAI,UAAU,MAAM,IAAI,KAAK,CAAC,IAAI,UAAU,SAAS,CAAC,IAAI,KAAK,EAAE,IAAI,UAAU,SAAS,CAAC,IAAI,KAAK,EAAE,IAAI,UAAU,SAAS,GAAG,IAAI,KAAK,EAAE,IAAI,UAAU,MAAM;AAAA,UACpK,EACC,KAAK,UAAU,KAAK,EACpB;AAAA,YACC;AAAA,YACA,WAAW,IACP,MAAM,OAAO,0BACb,MAAM,OAAO;AAAA,UACnB,EACC,KAAK,QAAQ,MAAM,EACnB,KAAK,kBAAkB,EAAE,EACzB,KAAK,mBAAmB,EAAE;AAAA,QAC/B,CAAC;AAAA,MACH,OAAO;AACL,aACG,OAAO,UAAU,EACjB,KAAK,SAAS,IAAI,YAAY,EAC9B;AAAA,UACC;AAAA,UACA,GAAG,EAAE,IAAI,OAAO,IAAI,KAAK,CAAC,IAAI,UAAU,GAAG,IAAI,KAAK,EAAE,IAAI,UAAU,CAAC,IAAI,KAAK,EAAE,IAAI,UAAU,GAAG,IAAI,KAAK,EAAE,IAAI,OAAO;AAAA,QACzH,EACC,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,MAAM,OAAO,mBAAmB,EACrD,KAAK,QAAQ,MAAM,EACnB,KAAK,kBAAkB,EAAE,EACzB,KAAK,mBAAmB,EAAE;AAAA,MAC/B;AAAA,IACF,WAAW,KAAK,SAAS,QAAQ;AAC/B,YAAM,QAAQ,KAAK,eACf,MAAM,KAAK,YACX,MAAM,KAAK;AACf,YAAM,UAAU,KAAK,eACjB,eAAe,WACf,eAAe;AAEnB,WACG,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,QAAQ,EAC1B,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,UAAU,KAAK,CAAC,EAC1B,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,EAAE,EACjB,KAAK,QAAQ,QAAQ,IAAI,CAAC,EAC1B,KAAK,UAAU,KAAK,EACpB,KAAK,gBAAgB,MAAM,OAAO,eAAe;AAAA,IACtD,WAAW,KAAK,YAAY,eAAe;AACzC,WACG,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,gBAAgB,EAClC,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,UAAU,KAAK,CAAC,EAC1B,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,EAAE,EACjB,KAAK,QAAQ,eAAe,aAAa,IAAI,CAAC,EAC9C,KAAK,UAAU,MAAM;AACxB,WACG,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,gBAAgB,EAClC,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,EAAE,EACb,KAAK,MAAM,UAAU,KAAK,CAAC,EAC3B,KAAK,MAAM,UAAU,KAAK,CAAC,EAC3B,KAAK,UAAU,MAAM,YAAY,MAAM,EACvC,KAAK,gBAAgB,CAAC;AACzB,WACG,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,gBAAgB,EAClC,KAAK,MAAM,KAAK,EAAE,EAClB,KAAK,MAAM,KAAK,EAAE,EAClB,KAAK,MAAM,UAAU,KAAK,CAAC,EAC3B,KAAK,MAAM,UAAU,KAAK,CAAC,EAC3B,KAAK,UAAU,MAAM,YAAY,MAAM,EACvC,KAAK,gBAAgB,CAAC;AAAA,IAC3B,OAAO;AACL,YAAM,SAGF;AAAA,QACF,UAAU;AAAA,UACR,MAAM,MAAM,SAAS;AAAA,UACrB,QAAQ,MAAM,SAAS;AAAA,UACvB,WAAW,MAAM,SAAS;AAAA,QAC5B;AAAA,QACA,gBAAgB;AAAA,UACd,MAAM,eAAe,YAAY,IAAI;AAAA,UACrC,QAAQ,MAAM,SAAS;AAAA,QACzB;AAAA,QACA,cAAc;AAAA,UACZ,MAAM,eAAe,KAAK,IAAI;AAAA,UAC9B,QAAQ,MAAM,SAAS;AAAA,QACzB;AAAA,QACA,UAAU,EAAE,MAAM,MAAM,SAAS,MAAM,QAAQ,MAAM,SAAS,OAAO;AAAA,QACrE,YAAY;AAAA,UACV,MAAM,eAAe,YAAY,IAAI;AAAA,UACrC,QAAQ,MAAM,WAAW;AAAA,QAC3B;AAAA,QACA,WAAW;AAAA,UACT,MAAM,eAAe,IAAI,IAAI;AAAA,UAC7B,QAAQ,MAAM,UAAU;AAAA,QAC1B;AAAA,QACA,UAAU;AAAA,UACR,MAAM,eAAe,SAAS,IAAI;AAAA,UAClC,QAAQ,MAAM,SAAS;AAAA,QACzB;AAAA,MACF;AACA,YAAM,MAAM,OAAO,KAAK,OAAO;AAE/B,YAAM,UAAU,KACb,OAAO,MAAM,EACb,KAAK,SAAS,IAAI,gBAAgB,EAClC,KAAK,KAAK,EAAE,EACZ,KAAK,KAAK,UAAU,KAAK,CAAC,EAC1B,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,EAAE,EACjB,KAAK,QAAQ,IAAI,IAAI,EACrB,KAAK,UAAU,IAAI,MAAM,EACzB,KAAK,gBAAgB,MAAM,OAAO,eAAe;AACpD,UAAI,IAAI,UAAW,SAAQ,KAAK,oBAAoB,IAAI,SAAS;AAAA,IACnE;AAEA,MAAE,OAAO,MAAM,EACZ,KAAK,SAAS,IAAI,KAAK,EACvB,KAAK,KAAK,KAAK,EAAE,EACjB,KAAK,KAAK,UAAU,CAAC,EACrB,KAAK,aAAa,MAAM,OAAO,QAAQ,EACvC,KAAK,eAAe,MAAM,OAAO,cAAc,YAAY,EAC3D,KAAK,eAAe,MAAM,OAAO,mBAAmB,GAAG,EACvD,KAAK,KAAK,KAAK;AAAA,EACpB,CAAC;AACH;;;ACrWO,SAAS,cAAc,KAAkB,MAAyB;AACvE,MAAI,CAAC,KAAK,OAAQ;AAElB,QAAM;AAAA,IACJ,QAAQ,EAAE,eAAe;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,EAAE,WAAW,QAAQ,IAAI,kBAAkB,QAAQ;AAAA,IACvD,MAAM;AAAA,IACN,IAAI;AAAA,EACN,CAAC;AAGD,QAAM,SAAS,iBAAiB,MAAM,KAAK,IAAI,MAAM,gBAAgB;AAIrE,QAAM,QAAQ,eACX,UAAqC,IAAI,QAAQ,UAAU,IAAI,EAAE,EACjE,KAAK,MAAM,cAAc;AAG5B,QAAM,KAAK,EAAE,WAAW,UAAU,EAAE,KAAK,UAAU,CAAC,EAAE,OAAO;AAG7D,QAAM,YAAY,MACf,MAAM,EACN,OAAO,MAAM,EACb,KAAK,SAAS,QAAQ,UAAU,IAAI,EACpC,KAAK,KAAK,QAAQ,EAClB,KAAK,SAAS,YAAY,QAAQ,EAClC,KAAK,UAAU,MAAM,UAAU,MAAM,EACrC,KAAK,gBAAgB,MAAM,UAAU,WAAW,EAChD,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS,EACxB,KAAK,QAAQ,MAAM,EACnB,KAAK,WAAW,CAAC,EACjB,GAAG,aAAa,SAAS,QAAQ,IAAI,EACrC,GAAG,YAAY,SAAS,QAAQ,IAAI;AAEvC,iBAAe,WAAW,UAAU,EAAE,KAAK,WAAW,CAAC;AAGvD,QAAM,KAAK,QAAQ,MAAM;AACzB,iBAAe,OAAO,UAAU,EAC7B,KAAK,KAAK,OAAO,EACjB,KAAK,UAAU,SAAS;AAC7B;;;ACjDO,SAAS,eAAe,KAAkB,MAAyB;AACxE,MAAI,CAAC,IAAI,aAAa,WAAW,UAAU,CAAC,KAAK,OAAQ;AAEzD,QAAM;AAAA,IACJ,QAAQ,EAAE,gBAAgB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,kBAAgB,UAAU,GAAG,EAAE,OAAO;AAEtC,QAAM,KAAK,aAAa;AACxB,QAAM,MAAM,MAAM;AAClB,QAAM,KAAK,GAAG;AAEd,QAAM,eAAe,CAAC,UAA4C;AAChE,UAAM,SAAuD,CAAC;AAC9D,eAAW,SAAS,MAAM;AACxB,YAAM,OAAO,MAAM,KAAK;AACxB,UAAI,CAAC,KAAM;AACX,YAAM,OAAO,KAAK,IAAI,MAAM,MAAM,SAAS;AAC3C,YAAM,KAAK,KAAK,IAAI,MAAM,IAAI,OAAO;AACrC,UAAI,QAAQ,GAAI;AAChB,YAAM,OAAO,OAAO,OAAO,SAAS,CAAC;AACrC,UAAI,QAAQ,KAAK,SAAS,MAAM;AAC9B,aAAK,KAAK;AAAA,MACZ,MAAO,QAAO,KAAK,EAAE,MAAM,MAAM,GAAG,CAAC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,KAAK,KAAK,OAAK,EAAE,aAAa;AAC7C,QAAM,QAAQ,KAAK,KAAK,OAAK,EAAE,YAAY;AAI3C,QAAM,OAAO,GAAG;AAChB,QAAM,MAAM,UAAU,QAAQ,GAAG,UAAU,KAAK,IAAI,GAAG;AAEvD,QAAM,YAAY,CAChB,QACA,QACA,WACA,cACG;AACH,WAAO,QAAQ,CAAC,OAAO,QAAQ;AAC7B,YAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,YAAM,OAAO,OAAO,MAAM,EAAE;AAC5B,YAAM,SAAS,OAAO;AACtB,UAAI,SAAS,EAAG;AAEhB,YAAM,UAAU,QAAQ;AACxB,YAAM,SAAS,QAAQ,OAAO,SAAS;AAEvC,sBACG,OAAO,MAAM,EACb,KAAK,SAAS,SAAS,EACvB,KAAK,KAAK,MAAM,EAChB,KAAK,KAAK,IAAI,EACd,KAAK,SAAS,EAAE,EAChB,KAAK,UAAU,MAAM,EACrB,KAAK,QAAQ,SAAS,EACtB,KAAK,UAAU,IAAI,MAAM,EACzB,KAAK,gBAAgB,IAAI,WAAW;AAEvC,YAAM,aAAa,CAAC,GAAW,gBAC7B,gBACG,OAAO,MAAM,EACb,KAAK,SAAS,mBAAmB,EACjC,KAAK,MAAM,MAAM,EACjB,KAAK,MAAM,SAAS,EAAE,EACtB,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,CAAC,EACZ,KAAK,UAAU,IAAI,MAAM,EACzB,KAAK,gBAAgB,WAAW;AAErC,iBAAW,MAAM,UAAU,GAAG,iBAAiB,GAAG,iBAAiB;AACnE,iBAAW,MAAM,SAAS,GAAG,iBAAiB,GAAG,iBAAiB;AAElE,UAAI,UAAU,GAAG,kBAAkB;AACjC,cAAM,WAAW,KAAK,MAAM,UAAU,IAAI,WAAW,KAAK;AAC1D,cAAM,QACJ,MAAM,KAAK,SAAS,WAChB,GAAG,MAAM,KAAK,MAAM,GAAG,WAAW,CAAC,CAAC,WACpC,MAAM;AAEZ,wBACG,OAAO,MAAM,EACb,KAAK,SAAS,QAAQ,WAAW,IAAI,EACrC;AAAA,UACC;AAAA,UACA,cAAc,SAAS,KAAK,GAAG,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAAA,QAC7E,EACC,KAAK,eAAe,QAAQ,EAC5B,KAAK,qBAAqB,QAAQ,EAClC,KAAK,aAAa,IAAI,QAAQ,EAC9B,KAAK,eAAe,IAAI,cAAc,YAAY,EAClD,KAAK,eAAe,IAAI,cAAc,GAAG,EACzC,KAAK,QAAQ,IAAI,MAAM,EACvB,KAAK,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAAA,EACH;AAEA,MAAI;AACF;AAAA,MACE,aAAa,eAAe;AAAA,MAC5B;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB,IAAI;AAAA,IACN;AACF,MAAI;AACF;AAAA,MACE,aAAa,cAAc;AAAA,MAC3B;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB,IAAI;AAAA,IACN;AACJ;;;ACvIA,OAAOE,mBAAkB;AAIzB,IAAM,mBAAmB,CAAC,MACxBA,cAAa,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,CAAC,GAAG,mBAAmB,CAAC,EAAE,CAAC;AAEnE,SAAS,mBAAmB,OAA0B;AAC3D,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,IAAI;AACV,SAAO;AAAA,IACL,8CAA8C,EAAE,UAAU,MAAM,CAAC,cAAc,EAAE,OAAO,QAAQ,CAAC,YAAY,EAAE,OAAO,KAAK,CAAC;AAAA,IAC5H,kCAAkC,EAAE,OAAO,QAAQ,CAAC;AAAA,IACpD,qCAAqC,EAAE,OAAO,oBAAoB,GAAG,CAAC,gBAAgB,EAAE,OAAO,UAAU,CAAC,cAAc,EAAE,OAAO,QAAQ,CAAC,YAAY,EAAE,OAAO,KAAK,CAAC;AAAA,IACrK,mCAAmC,EAAE,OAAO,kBAAkB,GAAG,CAAC,gBAAgB,EAAE,OAAO,YAAY,YAAY,CAAC,cAAc,EAAE,OAAO,QAAQ,CAAC,YAAY,EAAE,OAAO,SAAS,CAAC;AAAA,IACnL,kCAAkC,EAAE,OAAO,YAAY,YAAY,CAAC,cAAc,EAAE,OAAO,QAAQ,CAAC,YAAY,EAAE,OAAO,KAAK,CAAC;AAAA,EACjI,EAAE,KAAK,EAAE;AACX;;;AjBNA,IAAMC,MAAK,OAAO,OAAOC,WAAU,EAAE,KAAKC,OAAM,CAAC;AA8D1C,IAAM,eAAN,MAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBxB,YACE,MACA,UAMI,CAAC,GACL;AA9BF,SAAQ,eAA8B,CAAC;AACvC,SAAQ,iBAAkC,CAAC;AAC3C,SAAQ,WAAyB,mBAAmB;AAGpD,mBAAU;AACV,SAAQ,eAA6B;AACrC,SAAQ,QAAmB;AAC3B,SAAQ,QAAe;AAAA,MACrB,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAoBE,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ;AAAA,QACN;AAAA,MACF;AACA;AAAA,IACF;AACA,SAAK,eAAe;AACpB,QAAI,QAAQ,QAAS,MAAK,UAAU,QAAQ;AAE5C,QAAI,QAAQ,YAAY;AACtB,WAAK,UAAUC;AAAA,QACb,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,OAAO;AACjB,WAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,QAAQ,MAAM;AAAA,IACjD;AAEA,QAAI,QAAQ,cAAc;AACxB,WAAK,eAAeA;AAAA,QAClB,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQA,MAAK,QAAQ,SAAS,CAAC,GAAG,kBAAkB;AAEzD,SAAK,WAAW,mBAAmB,KAAK,aAAa,QAAQ;AAAA,EAC/D;AAAA,EAEQ,gBAAgB,MAAmB,OAA8B;AACvE,UAAM,SAAS,kBAAkB,KAAK;AACtC,UAAM,aAAa,uBAAuB,KAAK;AAC/C,UAAM,EAAE,UAAU,QAAQ,OAAO,QAAQ,IAAI;AAC7C,UAAM,WAAW,QAAQ,QAAQ,OAAO,QAAQ;AAChD,UAAM,YAAY,SAAS,QAAQ,MAAM,QAAQ;AAEjD,UAAM,MAAMH,IAAG,OAAO,QAAQ;AAC9B,QAAI,UAAU,GAAG,EAAE,OAAO;AAE1B,QAAI,KAAK,UAAU,SAAS,EAAE,KAAK,SAAS,QAAQ;AAEpD,UAAM,OAAO,IAAI,OAAO,MAAM;AAC9B,SAAK,OAAO,OAAO,EAAE,KAAK,mBAAmB,KAAK,KAAK,CAAC;AACxD,SACG,OAAO,UAAU,EACjB,KAAK,MAAM,MAAM,EACjB,OAAO,MAAM,EACb,KAAK,MAAM,UAAU,EACrB,KAAK,KAAK,CAAC,EACX,KAAK,KAAK,CAAC,EACX,KAAK,SAAS,GAAM,EACpB,KAAK,UAAU,GAAK;AAEvB,UAAM,OAAO,IAAI,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,SAAS;AAEjE,UAAM,WAAW,KACd,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,aAAa,EACxC,KAAK,aAAa,aAAa,QAAQ,IAAI,KAAK,QAAQ,GAAG,GAAG;AAEjE,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,KAAK;AACrD,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,WAAW,KAAK;AAChE,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,UAAU,KAAK;AAC/D,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,MAAM,KAAK;AAC3D,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,OAAO,UAAU,KAAK;AACtE,aAAS,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,WAAW,aAAa;AAExE,UAAM,eAAe,KAClB,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,iBAAiB,EAC5C;AAAA,MACC;AAAA,MACA,aAAa,QAAQ,OAAO,QAAQ,CAAC,KAAK,QAAQ,GAAG;AAAA,IACvD;AAEF,UAAM,iBAAiB,KACpB,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,UAAU,KAAK,EAC1C,KAAK,aAAa,aAAa,QAAQ,IAAI,KAAK,QAAQ,GAAG,GAAG,EAC9D,KAAK,aAAa,QAAQ,MAAM,GAAG;AAEtC,mBACG,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,WAAW,cAAc;AAEvD,iBACG,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,mBAAmB,KAAK;AACtD,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,UAAU,KAAK;AACnE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK;AAClE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,YAAY,KAAK;AACrE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK;AAClE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK;AAClE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,WAAW,KAAK;AACpE,iBAAa,OAAO,GAAG,EAAE,KAAK,SAAS,KAAK,QAAQ,SAAS,KAAK;AAClE,iBACG,OAAO,GAAG,EACV,KAAK,SAAS,KAAK,QAAQ,WAAW,iBAAiB;AAE1D,WAAO,OAAO,KAAK,QAAQ,EAAE,QAAQ,aAAW,IAAI,KAAK,OAAO,CAAC;AAEjE,WAAO,EAAE,KAAK,QAAQ,OAAO,SAAS,QAAQ,WAAW;AAAA,EAC3D;AAAA;AAAA,EAGO,aAAa,UAAkB,SAAqB;AACzD,mBAAe,UAAU,SAAS;AAAA,MAChC,QAAQ,KAAK,aAAa;AAAA,MAC1B,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK,QAAQ;AAAA,MACzB,UAAU,KAAK,aAAa;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,aAAa;AACxB,UAAM,oBAAoB;AAC1B,SAAK,iBAAiB,KAAK,aAAa;AAAA,MAAI,CAAC,MAAM,MACjD,KAAK,gBAAgB,MAAM,CAAC;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KACE,SACA,UAAsD,CAAC,GACvD;AACA,QAAI,YAAY,OAAO,EAAG;AAC1B,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,QAAQ,MAAM;AAC/C,UAAM,aAAa,QAAQ,cAAc,CAAC;AAE1C,UAAM,YAAY,0BAA0B,OAAO;AACnD,UAAM,aAAaA,IAAG,IAAI,SAAS,KAAK;AAExC,QAAI,KAAK,eAAe,WAAW,GAAG;AACpC,WAAK;AAAA,QACH,KAAK,eAAe,CAAC;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,cACJ,KAAK,eAAe,OAAO,CAAC,GAAG,OAAO,IAAI,GAAG,QAAQ,CAAC,KAAK;AAC7D,UAAM,eAAeA,IAClB,YAAY,EACZ,OAAO,CAAC,GAAG,UAAU,CAAC,EACtB,MAAM,CAAC,GAAG,WAAW,CAAC;AAEzB,QAAI,eAAe;AACnB,eAAW,SAAS,KAAK,gBAAgB;AACvC,YAAM,cAAc,aAAa;AAAA,QAC/B,aAAa,YAAY,IAAI,MAAM;AAAA,MACrC;AACA,WAAK;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,qBAAe;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,kBACN,OACA,SACA,WACA,SACA,aAAyB,CAAC,GAC1B;AACA,UAAM,MAAM,MAAM;AAElB,UAAM,YAAY,IAAI,OAAO,IAAI,KAAK,QAAQ,SAAS,EAAE;AACzD,UAAM,iBAAiB,IAAI,OAAO,IAAI,KAAK,QAAQ,UAAU,KAAK,EAAE;AACpE,UAAM,iBAAiB,IAAI,OAAO,IAAI,KAAK,QAAQ,UAAU,KAAK,EAAE;AACpE,UAAM,aAAa,IAAI,OAAO,IAAI,KAAK,QAAQ,MAAM,KAAK,EAAE;AAC5D,UAAM,uBAAuB,IAAI;AAAA,MAC/B,IAAI,KAAK,QAAQ,OAAO,UAAU,KAAK;AAAA,IACzC;AACA,UAAM,oBAAoB,IAAI,OAAO,IAAI,KAAK,QAAQ,iBAAiB,EAAE;AACzE,UAAM,iBAAiB,IAAI,OAAO,IAAI,KAAK,QAAQ,UAAU,KAAK,EAAE;AACpE,UAAM,YAAY,IAAI,OAAO,IAAI,KAAK,QAAQ,SAAS,KAAK,EAAE;AAC9D,UAAM,mBAAmB,IAAI,OAAO,IAAI,KAAK,QAAQ,YAAY,KAAK,EAAE;AACxE,UAAM,gBAAgB,IAAI,OAAO,IAAI,KAAK,QAAQ,SAAS,KAAK,EAAE;AAClE,UAAM,gBAAgB,IAAI,OAAO,IAAI,KAAK,QAAQ,SAAS,KAAK,EAAE;AAClE,UAAM,kBAAkB,IAAI,OAAO,IAAI,KAAK,QAAQ,WAAW,KAAK,EAAE;AACtE,UAAM,gBAAgB,IAAI,OAAO,IAAI,KAAK,QAAQ,SAAS,KAAK,EAAE;AAClE,UAAM,0BAA0B,IAAI;AAAA,MAClC,IAAI,KAAK,QAAQ,mBAAmB,KAAK;AAAA,IAC3C;AACA,UAAM,0BAA0B,IAAI;AAAA,MAClC,IAAI,KAAK,QAAQ,WAAW,aAAa;AAAA,IAC3C;AACA,UAAM,8BAA8B,IAAI;AAAA,MACtC,IAAI,KAAK,QAAQ,WAAW,iBAAiB;AAAA,IAC/C;AACA,UAAM,2BAA2B,IAAI;AAAA,MACnC,IAAI,KAAK,QAAQ,WAAW,cAAc;AAAA,IAC5C;AACA,UAAM,kBAAkB,IAAI,OAAO,IAAI,KAAK,QAAQ,WAAW,KAAK,EAAE;AAEtE,UAAM,WAAW,MAAM,QAAQ,MAAM,QAAQ,OAAO,MAAM,QAAQ;AAClE,UAAM,YAAY,MAAM,SAAS,MAAM,QAAQ,MAAM,MAAM,QAAQ;AACnE,UAAM,EAAE,gBAAgB,gBAAgB,IAAI,KAAK,aAAa;AAC9D,UAAM,aAAa,WAAW;AAC9B,UAAM,cAAc,WAAW;AAE/B,UAAM,EAAE,UAAU,KAAK,IAAI,KAAK,aAAa;AAC7C,UAAM,aAAaA,IAAG,WAAW,EAAE,SAAS,QAAQ,EAAE,KAAK,IAAI;AAE/D,UAAM,WAAW;AAAA,MACf;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,aAAa;AAAA,IACpB;AAEA,UAAM,EAAE,OAAO,UAAU,aAAa,eAAe,IACnD,KAAK,aAAa;AACpB,UAAM,YAAY,WAAW;AAC7B,UAAM,cAAc,MAAM,QAAQ,IAAI,cAAc;AAEpD,UAAM,eAAe;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,OAAO,QAAQ;AAAA,IACjB;AACA,UAAM,mBAAmB;AAAA,MACvB,YAAY,QAAQ;AAAA,MACpB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,MACnB,cAAc,QAAQ;AAAA,MACtB,WAAW,QAAQ;AAAA,MACnB,aAAa,QAAQ;AAAA,MACrB,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,IACrB;AAEA,UAAM,gBAAgB,YAAY,MAAM,QAAQ,MAAM,MAAM,QAAQ;AAEpE,UAAM,cAAcA,IACjB,YAAY,EACZ,OAAO,CAAC,WAAW,OAAO,CAAC,EAC3B,MAAM,CAAC,GAAG,aAAa,CAAC;AAE3B,UAAM,cAAc,KAAK,MAAM,WAAW,OAAO,UAAU;AAC3D,UAAM,aAAaA,IAChB,YAAY,EACZ,OAAO,CAAC,YAAY,aAAa,UAAU,WAAW,CAAC,EACvD,MAAM,CAAC,GAAG,aAAa,CAAC;AAE3B,UAAM,QAAQA,IACX,SAAS,UAAU,EACnB;AAAA,MACC,CAAC,MAA4B,GAAG,CAAC,GAAG,cAAc,KAAK,MAAM,MAAM,CAAC;AAAA,IACtE;AAEF,UAAM,KAAK,IAAI,OAAoB,IAAI,KAAK,QAAQ,KAAK,EAAE,EAAE,KAAK,KAAK;AAEvE,OAAG,OAAO,SAAS,EAChB,KAAK,UAAU,KAAK,MAAM,OAAO,KAAK,EACtC,KAAK,QAAQ,MAAM;AACtB,OAAG,UAAU,YAAY,EAAE,KAAK,UAAU,KAAK,MAAM,OAAO,KAAK;AACjE,OAAG,UAAU,YAAY,EACtB,KAAK,QAAQ,KAAK,MAAM,OAAO,KAAK,EACpC,KAAK,UAAU,MAAM,EACrB;AAAA,MACC;AAAA,MACA,KAAK,MAAM,OAAO,iBAAiB,KAAK,MAAM,OAAO;AAAA,IACvD,EACC;AAAA,MACC;AAAA,MACA,KAAK,MAAM,OAAO,aAChB,KAAK,MAAM,OAAO,YAClB;AAAA,IACJ;AAIF,UAAM,QAAQ,CAAC,MAAyB;AACtC,UAAI,EAAE,UAAW,QAAO,YAAY,CAAC,IAAI,YAAY,EAAE,SAAS;AAChE,aAAO,YAAY,KAAK,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;AAAA,IACrD;AAEA,UAAM,QAAQ,CAAC,MAAyB;AACtC,UAAI,EAAE,UAAW,QAAO,YAAY,EAAE,SAAS,IAAI,YAAY,CAAC;AAChE,aAAO,KAAK;AAAA,QACV;AAAA,QACA,YAAY,KAAK,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IACtC,YAAY,KAAK,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;AAAA,MAChD;AAAA,IACF;AAEA,UAAM,SAAqB;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,MAAmB;AAAA,MACvB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,cAAc,KAAK;AAAA,MACnB,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ;AAAA,MACA;AAAA,IACF;AAEA,UAAM,UAAU,cAAc,WAAW,OAAO;AAChD,UAAM,uBAAuB;AAAA,MAC3B,GAAG;AAAA,MACH,WAAW,iBAAiB,UAAU,OAAO,OAAO;AAAA,MACpD,WAAW,iBAAiB,UAAU,OAAO,OAAO;AAAA,MACpD,cAAc,iBAAiB,aAAa,OAAO,OAAO;AAAA,MAC1D,WAAW,iBAAiB,UAAU,OAAO,OAAO;AAAA,MACpD,aAAa,iBAAiB,YAAY,OAAO,OAAO;AAAA,MACxD,WAAW,iBAAiB,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,IAC7D;AAEA,UAAM,UAAU,CAAC,MAAmD;AAClE,YAAM,YAAY,EAAE;AACpB,YAAM,YAAyB;AAAA,QAC7B,GAAG;AAAA,QACH,QAAQ,UAAU,SAAS,WAAW;AAAA,MACxC;AAEA,SAAG,KAAK,MAAM,MAAM,UAAU,SAAS,UAAU,CAAC,CAAC;AAEnD,gBACG,UAAU,MAAM,EAChB,KAAK,KAAK,CAAC,MAAe;AACzB,YAAI,CAAC,EAAG,QAAO;AACf,eAAO,UAAU,OAAO,MAAM,CAAc,CAAC;AAAA,MAC/C,CAAC,EACA,KAAK,UAAU,CAAC,MAAe;AAC9B,YAAI,CAAC,EAAG,QAAO;AACf,eAAO,UAAU,IAAI,MAAM,CAAc;AAAA,MAC3C,CAAC;AAGH,uBACG,UAAU,KAAK,KAAK,QAAQ,YAAY,IAAI,EAAE,EAC9C,KAAK,CAAC,GAAY,GAAG,UAAU;AAC9B,YAAI,CAAC,EAAG;AACR,cAAM,KAAK;AACX,cAAM,IAAIA,IAAG,OAAO,MAAM,CAAC,CAAY;AACvC,cAAM,IAAI,UAAU,OAAO,MAAM,EAAE,CAAC;AACpC,cAAM,IAAI,UAAU,IAAI,MAAM,EAAE;AAChC,UAAE,OAAO,oBAAoB,EAAE,KAAK,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC;AAC5D,UAAE,UAAU,oBAAoB,EAC7B,KAAK,MAAM,CAAC,EACZ,KAAK,MAAM,IAAI,CAAC;AAAA,MACrB,CAAC;AAGH,qBACG,UAAU,KAAK,KAAK,QAAQ,UAAU,IAAI,EAAE,EAC5C,KAAK,aAAa,CAAC,MAAe;AACjC,YAAI,CAAC,EAAG,QAAO;AACf,cAAM,IAAI;AACV,cAAM,KAAK;AACX,cAAM,KAAK,UAAU,OAAO,YAAY,EAAE,KAAK,CAAC;AAChD,eAAO,eAAe,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE;AAAA,MACjD,CAAC;AAGH,gBAAU,WAAW,aAAa,OAAO,OAAO,OAAO,KAAK,CAAC,CAAC;AAC9D,qBAAe,WAAW,QAAQ,WAAW,OAAO,OAAO,KAAK,CAAC,CAAC;AAClE,2BAAqB,WAAW;AAAA,QAC9B,WAAW,QAAQ,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,QAClD,WACE,QAAQ,WAAW;AAAA,UACjB,OAAK,EAAE,SAAS,aAAa,EAAE,QAAQ;AAAA,QACzC,KAAK,CAAC;AAAA,QACR,OAAO,QAAQ,OAAO,OAAO,OAAO,KAAK,CAAC;AAAA,MAC5C,CAAC;AACD,6BAAuB,WAAW;AAAA,QAChC,WAAW,iBAAiB,UAAU,OAAO,OAAO;AAAA,QACpD,aAAa,iBAAiB,YAAY,OAAO,OAAO;AAAA,MAC1D,CAAC;AACD,qBAAe,WAAW,UAAU;AAAA,IACtC;AAEA,UAAM,cAAc,MAAM;AACxB,oBAAc,KAAK,QAAQ,WAAW,OAAO,OAAO,KAAK,CAAC,CAAC;AAC3D,qBAAe,KAAK,QAAQ,WAAW,OAAO,OAAO,KAAK,CAAC,CAAC;AAC5D,2BAAqB,KAAK;AAAA,QACxB,WAAW,QAAQ,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,QAClD,WACE,QAAQ,WAAW;AAAA,UACjB,OAAK,EAAE,SAAS,aAAa,EAAE,QAAQ;AAAA,QACzC,KAAK,CAAC;AAAA,QACR,OAAO,QAAQ,OAAO,OAAO,OAAO,KAAK,CAAC;AAAA,MAC5C,CAAC;AACD,gBAAU,KAAK,QAAQ,OAAO,OAAO,OAAO,KAAK,CAAC,CAAC;AACnD;AAAA,QACE;AAAA,QACA,QAAQ,WAAW;AAAA;AAAA,UAEjB,OAAK,EAAE,SAAS,aAAa,EAAE,QAAQ;AAAA,QACzC,KAAK,CAAC;AAAA,MACR;AACA,uBAAiB,KAAK,oBAAoB;AAC1C,6BAAuB,KAAK;AAAA,QAC1B,WAAW,qBAAqB;AAAA,QAChC,aAAa,qBAAqB;AAAA,MACpC,CAAC;AACD,UAAI,OAAO,IAAI,MAAM,UAAU,EAAE,EAAE,KAAK,KAAK,CAAC,EAAE,KAAK,UAAU,SAAS;AACxE,qBAAe,KAAK,UAAU;AAAA,IAChC;AAEA,QAAI;AACF,kBAAY;AAAA,IACd,SAAS,KAAK;AACZ,YAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAChE,UAAI,KAAK,SAAS;AAChB,aAAK,QAAQ,KAAK;AAAA,MACpB,OAAO;AACL,gBAAQ,MAAM,sCAAsC,KAAK;AAAA,MAC3D;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,aAAa,KAAK,WAAW,IAAI,KAAK;AACpD,QAAI,eAAe,YAAY;AAC7B,YAAM,WAAWA,IAAG,KAA6B;AACjD,UAAI,eAAe,WAAY,UAAS,GAAG,QAAQ,OAAO;AAC1D,UAAI,CAAC,YAAa,UAAS,YAAY,CAAC,GAAG,CAAC,CAAC;AAC7C,UAAI,CAAC;AACH,iBAAS,OAAO,OAAK,EAAE,SAAS,WAAW,EAAE,SAAS,UAAU;AAClE,mBAA4B,GAAG,EAAE,KAAK,QAAQ;AAE9C,YAAM,cAAc,KAAK,aAAa,aAAa;AACnD,UAAI,gBAAgB,GAAG;AACrB,qBAA4B,GAAG,EAAE;AAAA,UAC/B,SAAS;AAAA,UACTA,IAAG,aAAa,MAAM,WAAW;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["d3module","d3tip","defu","textures","textures","textures","d3","d3","getProfileDiamValues","getProfileDiamValues","d3","getProfileDiamValues","d3module","d3","d3module","sanitizeHtml","d3","d3module","d3tip","defu"]}
|