@welldot/render 0.2.3 → 0.3.0-next.20261015.d7c7365

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/configs/render.configs.ts","../src/utils/format.utils.ts","../src/utils/fgdcTextures.ts","../src/Renderer.ts","../src/configs/render.textures.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/utils/key.utils.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 {\n RenderConfig,\n RenderLabelPack,\n RenderLocalizedText,\n TooltipLabels,\n WellTheme,\n} from '~/types/render.types';\nimport { resolveRenderLabel } from '~/utils/format.utils';\n\n/**\n * Canonical, paired-locale source for every string `@welldot/render` draws\n * (construction-label prefixes, legend entries, tooltip titles/fields,\n * fracture/cave type words). `pt` values must match the literals historically\n * hardcoded in `tooltips.utils.ts`/`annotation-labels.renderer.ts` exactly —\n * this is the single source of truth `applyRenderLocale()` resolves from.\n */\nexport const RENDER_LABELS: RenderLabelPack = {\n constructionLabels: {\n wellCasePrefix: { pt: 'Revest.', en: 'Casing' },\n wellScreenPrefix: { pt: 'Filtro', en: 'Screen' },\n wellScreenSlotPrefix: { pt: 'Ranhura:', en: 'Slot:' },\n },\n legend: {\n title: { pt: 'LEGENDA', en: 'LEGEND' },\n labels: {\n fractureSingle: { pt: 'Fratura simples', en: 'Single fracture' },\n fractureSwarm: { pt: 'Enxame de fraturas', en: 'Fracture swarm' },\n fractureWater: { pt: \"Entrada d'água\", en: 'Water intake' },\n caveDry: { pt: 'Caverna seca', en: 'Dry cave' },\n caveWet: { pt: 'Caverna c/ água', en: 'Wet cave' },\n boreHole: { pt: 'Perfuração', en: 'Borehole' },\n surfaceCase: { pt: 'Tubo guia', en: 'Surface casing' },\n holeFillGravel: { pt: 'Pré-filtro', en: 'Gravel pack' },\n holeFillSeal: { pt: 'Vedação', en: 'Seal' },\n wellCase: { pt: 'Revestimento', en: 'Casing' },\n wellScreen: { pt: 'Filtro', en: 'Screen' },\n reduction: { pt: 'Redução', en: 'Reduction' },\n cementPad: { pt: 'Laje de cimento', en: 'Cement pad' },\n conflict: { pt: 'Conflito', en: 'Conflict' },\n },\n },\n tooltipLabels: {\n common: {\n from: { pt: 'De', en: 'From' },\n to: { pt: 'até', en: 'to' },\n description: { pt: 'Descrição:', en: 'Description:' },\n diameter: { pt: 'Diâmetro:', en: 'Diameter:' },\n type: { pt: 'Tipo:', en: 'Type:' },\n },\n geology: {\n title: { pt: 'Litologia', en: 'Lithology' },\n geologicUnit: { pt: 'Unidade geológica:', en: 'Geologic unit:' },\n aquiferUnit: { pt: 'Unidade aquífera:', en: 'Aquifer unit:' },\n },\n hole: { title: { pt: 'FURO', en: 'BOREHOLE' } },\n surfaceCase: { title: { pt: 'TUBO DE BOCA', en: 'SURFACE CASING' } },\n holeFill: { title: { pt: 'ESP. ANULAR', en: 'ANNULAR SPACE' } },\n wellCase: { title: { pt: 'REVESTIMENTO', en: 'CASING' } },\n wellScreen: {\n title: { pt: 'FILTROS', en: 'SCREENS' },\n slot: { pt: 'Ranhura:', en: 'Slot:' },\n },\n reduction: { title: { pt: 'REDUÇÃO', en: 'REDUCTION' } },\n conflict: { title: { pt: 'CONFLITO', en: 'CONFLICT' } },\n fracture: {\n title: { pt: 'FRATURA', en: 'FRACTURE' },\n titleSwarm: { pt: 'ENXAME DE FRATURAS', en: 'FRACTURE SWARM' },\n depth: { pt: 'Profundidade:', en: 'Depth:' },\n waterIntake: { pt: \"Entrada d'água:\", en: 'Water intake:' },\n dip: { pt: 'Mergulho:', en: 'Dip:' },\n azimuth: { pt: 'Azimute:', en: 'Azimuth:' },\n },\n cementPad: {\n title: { pt: 'LAJE DE PROTEÇÃO', en: 'PROTECTION SLAB' },\n thickness: { pt: 'Espessura:', en: 'Thickness:' },\n width: { pt: 'Largura:', en: 'Width:' },\n length: { pt: 'Comprimento:', en: 'Length:' },\n },\n cave: {\n title: { pt: 'CAVERNA', en: 'CAVE' },\n waterIntake: { pt: \"Entrada d'água\", en: 'Water intake' },\n },\n },\n typeLabels: {\n fracture: { pt: 'fratura', en: 'fracture' },\n fractureWater: { pt: 'fratura aberta', en: 'open fracture' },\n cave: { pt: 'caverna', en: 'cave' },\n caveWater: { pt: 'caverna úmida', en: 'wet cave' },\n },\n};\n\n/** Resolves every `RenderLocalizedText` leaf of a flat group to a plain string for `locale`. */\nfunction resolveGroup<G extends Record<string, RenderLocalizedText>>(\n group: G,\n locale: 'en' | 'pt',\n): { [K in keyof G]: string } {\n const result = {} as { [K in keyof G]: string };\n for (const key in group) {\n result[key] = resolveRenderLabel(group[key], locale);\n }\n return result;\n}\n\n/** Resolves `RENDER_LABELS.tooltipLabels` to the plain-string shape `RenderConfig.tooltipLabels` expects. */\nfunction resolveTooltipLabels(locale: 'en' | 'pt'): TooltipLabels {\n const t = RENDER_LABELS.tooltipLabels;\n return {\n common: resolveGroup(t.common, locale),\n geology: resolveGroup(t.geology, locale),\n hole: resolveGroup(t.hole, locale),\n surfaceCase: resolveGroup(t.surfaceCase, locale),\n holeFill: resolveGroup(t.holeFill, locale),\n wellCase: resolveGroup(t.wellCase, locale),\n wellScreen: resolveGroup(t.wellScreen, locale),\n reduction: resolveGroup(t.reduction, locale),\n conflict: resolveGroup(t.conflict, locale),\n fracture: resolveGroup(t.fracture, locale),\n cementPad: resolveGroup(t.cementPad, locale),\n cave: resolveGroup(t.cave, locale),\n };\n}\n\n/**\n * Returns a copy of `config` with `constructionLabels.labels`, `legend.labels`,\n * `tooltipLabels`, and `labels.typeLabels` resolved from `RENDER_LABELS` for\n * `locale`. Every other field of `config` is preserved unchanged.\n */\nexport function applyRenderLocale(\n config: RenderConfig,\n locale: 'en' | 'pt',\n): RenderConfig {\n return {\n ...config,\n constructionLabels: {\n ...config.constructionLabels,\n labels: resolveGroup(RENDER_LABELS.constructionLabels, locale),\n },\n legend: {\n ...config.legend,\n title: resolveRenderLabel(RENDER_LABELS.legend.title, locale),\n labels: resolveGroup(RENDER_LABELS.legend.labels, locale),\n },\n tooltipLabels: resolveTooltipLabels(locale),\n labels: {\n ...config.labels,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, locale),\n },\n };\n}\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 reduction: { fill: '#ffffff', 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 maxZoomScale: 150,\n minZoomScale: 0,\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 tooltipLabels: resolveTooltipLabels('pt'),\n labels: {\n active: true,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, 'pt'),\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 reduction: 'Redução',\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 maxZoomScale: 150,\n minZoomScale: 0,\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 tooltipLabels: resolveTooltipLabels('pt'),\n labels: {\n active: false,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, 'pt'),\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 reduction: 'Redução',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n","import type { DiameterUnits, LengthUnits } from '@welldot/core';\nimport { formatNumber } from '@welldot/utils';\nimport type { RenderLocalizedText } from '~/types/render.types';\n\nconst MM_TO_INCHES = 0.0393701;\nconst M_TO_FT = 3.28084;\n\n/**\n * Formats a depth value in metres to the active length unit string, rounded\n * (never raw floating-point) and using the target locale's decimal separator.\n */\nexport function formatLength(\n m: number,\n units: LengthUnits,\n locale: 'en' | 'pt',\n): string {\n return units === 'ft'\n ? formatNumber(m * M_TO_FT, { maximumFractionDigits: 1, locale })\n : formatNumber(m, { maximumFractionDigits: 2, locale });\n}\n\n/**\n * Formats a diameter value in millimetres to the active diameter unit\n * string, rounded (never raw floating-point) and using the target locale's\n * decimal separator.\n */\nexport function formatDiameter(\n mm: number,\n units: DiameterUnits,\n locale: 'en' | 'pt',\n): string {\n return units === 'inches'\n ? formatNumber(mm * MM_TO_INCHES, { maximumFractionDigits: 2, locale })\n : formatNumber(mm, { maximumFractionDigits: 2, locale });\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/**\n * Returns the display symbol for the active diameter unit. `mm` is\n * locale-invariant; `inches` is `'\"'` unless `locale` is `'en'`, in which\n * case it's `'in.'`. Omitting `locale` preserves the historical `'\"'` default.\n */\nexport function getDiameterUnit(\n units: DiameterUnits,\n locale?: 'en' | 'pt',\n): string {\n if (units !== 'inches') return 'mm';\n return locale === 'en' ? 'in.' : '\"';\n}\n\n/**\n * Resolves a paired-locale render label to a plain string. A bare string is\n * returned as-is (locale-invariant); for the `{ pt, en }` object form, `pt`\n * is always the fallback — mirrors the org-wide `resolveLanguageText()` contract.\n */\nexport function resolveRenderLabel(\n value: RenderLocalizedText,\n locale: 'en' | 'pt',\n): string {\n if (typeof value === 'string') return value;\n return locale === 'en' && value.en ? value.en : value.pt;\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 = { ...d3module, tip: d3tip };\n\nimport {\n isWellEmpty,\n type Constructive,\n type Reduction,\n type SurfaceCase,\n type Units,\n type Well,\n} from '@welldot/core';\nimport {\n formatNumber,\n getProfileDiamValues,\n getProfileLastItemsDepths,\n} from '@welldot/utils';\nimport {\n ComponentsClassNames,\n DeepPartial,\n DrawContext,\n DrawGroups,\n Highlights,\n InstanceState,\n RenderableWell,\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 private onZoom?: (scale: number) => 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 private locale: 'en' | 'pt' = 'pt';\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.locale - Locale for renderer-drawn text (diameter symbol, and any `RenderConfig` fields resolved via `applyRenderLocale`). Defaults to `'pt'`, matching the package's historical output.\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 * @param options.onZoom - Called with the current zoom scale (`1` = initial/fit) whenever the user zooms or pans, and whenever `zoomBy`/`resetZoom` are called. No-op if `renderConfig.zoom`/`pan` are both disabled.\n */\n constructor(\n svgs: SvgInstance[],\n options: {\n classNames?: DeepPartial<ComponentsClassNames>;\n units?: Units;\n locale?: 'en' | 'pt';\n renderConfig?: DeepPartial<RenderConfig>;\n theme?: DeepPartial<WellTheme>;\n onError?: (err: Error) => void;\n onZoom?: (scale: number) => 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 if (options.onZoom) this.onZoom = options.onZoom;\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.locale) {\n this.locale = options.locale;\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.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.reduction.group);\n construction.append('g').attr('class', this.classes.conflict.group);\n construction\n .append('g')\n .attr('class', this.classes.constructionLabels.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 * Multiplies the current zoom scale by `factor` (e.g. `1.25` to zoom in,\n * `1 / 1.25` to zoom out) on every panel. No-op if both `renderConfig.zoom`\n * and `renderConfig.pan` are disabled (no zoom behavior was attached).\n */\n public zoomBy(factor: number): void {\n for (const state of this.instanceStates) {\n if (!state.zoomNode) continue;\n asSvgElement<SVGSVGElement>(state.svg)\n .transition()\n .call(state.zoomNode.scaleBy, factor);\n }\n }\n\n /**\n * Resets zoom/pan on every panel back to `renderConfig.zoomLevel`\n * (defaults to `1`, i.e. the initial fit-to-container view).\n */\n public resetZoom(): void {\n const target = d3.zoomIdentity.scale(this.renderConfig.zoomLevel ?? 1);\n for (const state of this.instanceStates) {\n if (!state.zoomNode) continue;\n asSvgElement<SVGSVGElement>(state.svg)\n .transition()\n .call(state.zoomNode.transform, target);\n }\n }\n\n /**\n * Current zoom scale factor of the first panel (`1` = initial/fit).\n * Returns `1` if zoom/pan is disabled or `prepareSvg()` hasn't run yet.\n */\n public getZoomScale(): number {\n const node = this.instanceStates[0]?.svg.node();\n return node ? d3.zoomTransform(node as Element).k : 1;\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.locale - Override the instance-level locale for this render.\n * @param options.highlights - Highlight overlays to display on top of the profile.\n */\n draw(\n profile: RenderableWell,\n options: {\n units?: Units;\n locale?: 'en' | 'pt';\n highlights?: Highlights;\n } = {},\n ) {\n if (isWellEmpty(profile)) return;\n\n if (profile.version !== 2) {\n console.warn(\n `[WellRenderer] Received a .well file with version ${profile.version ?? 'unknown'}. ` +\n `Only v2 is supported. Normalize with deserializeWell() from @welldot/core before rendering.`,\n );\n }\n\n this.units = { ...this.units, ...options.units };\n if (options.locale) {\n this.locale = options.locale;\n }\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: RenderableWell,\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 reductionGroup = svg.select(`.${this.classes.reduction.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 this.renderConfig.tooltipLabels,\n this.locale,\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.axisLeft(yScaleAxis).tickFormat(\n (d: d3module.NumberValue) =>\n `${formatNumber(Number(d), {\n maximumFractionDigits: this.units.length === 'ft' ? 1 : 2,\n locale: this.locale,\n })}${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 reductionGroup,\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 locale: this.locale,\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 // Reduction: recompute trapezoid points (x is zoom-invariant, only y moves)\n const maxXValsReduction = getProfileDiamValues(constructionData);\n const xScaleReduction = d3\n .scaleLinear()\n .domain([0, d3.max(maxXValsReduction) || 0])\n .range([0, POCO_WIDTH]);\n\n reductionGroup\n .selectAll(`polygon.${this.classes.reduction.item}`)\n .attr('points', (d: unknown) => {\n const r = d as Reduction;\n const yTop = transform.applyY(spanY(r));\n const yBot = yTop + transform.k * spanH(r);\n const xTopLeft = (POCO_CENTER - xScaleReduction(r.diam_from)) / 2;\n const xTopRight = (POCO_CENTER + xScaleReduction(r.diam_from)) / 2;\n const xBotLeft = (POCO_CENTER - xScaleReduction(r.diam_to)) / 2;\n const xBotRight = (POCO_CENTER + xScaleReduction(r.diam_to)) / 2;\n return `${xTopLeft},${yTop} ${xTopRight},${yTop} ${xBotRight},${yBot} ${xBotLeft},${yBot}`;\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 this.onZoom?.(transform.k);\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 zoomNode.scaleExtent(\n zoomEnabled\n ? [\n this.renderConfig.minZoomScale ?? 0,\n this.renderConfig.maxZoomScale ?? Infinity,\n ]\n : [1, 1],\n );\n if (!panEnabled)\n zoomNode.filter(e => e.type === 'wheel' || e.type === 'dblclick');\n asSvgElement<SVGSVGElement>(svg).call(zoomNode);\n state.zoomNode = 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 { 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 reduction: {\n group: 'reduction',\n item: 'reduction-poly',\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 textureKey = (d: Lithology) => String(d.texture.code);\n const isFgdc = (d: Lithology) =>\n !d.texture.vocabulary || d.texture.vocabulary === 'fgdc';\n\n const uniqueTextureCodes = [...new Set(data.filter(isFgdc).map(textureKey))];\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 key = textureKey(d);\n const pathData = isFgdc(d) ? texturesLoaded[key] : undefined;\n if (!pathData) return [`${key}.${d.from}`, d.color];\n return [\n `${key}.${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[`${String(d.texture.code)}.${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\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 Reduction,\n SurfaceCase,\n Units,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport { formatNumber } from '@welldot/utils';\nimport type {\n ComponentsClassNames,\n SvgSelection,\n TooltipKey,\n TooltipLabels,\n} from '~/types/render.types';\nimport {\n formatDiameter,\n formatLength,\n getDiameterUnit,\n getLengthUnit,\n} from '~/utils/format.utils';\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\ntype CachedTooltips = Record<\n string,\n D3Tip | { show: () => void; hide: () => void }\n>;\n\nconst _tooltipCache = new WeakMap<\n Element,\n { signature: string; tooltips: CachedTooltips }\n>();\n\n/**\n * Initialises d3-tip tooltip instances for each well component, respecting the\n * `tooltipConfig` allow-list. Caches instances per SVG element to prevent\n * duplicate DOM nodes on re-render, but only while `units`/`tooltipConfig`/\n * `labels`/`locale` are unchanged — a redraw after any of those change (e.g.\n * the user switches unit or language) regenerates the tooltip content instead\n * of returning stale HTML from the first render.\n */\nexport const populateTooltips = (\n svg: SvgSelection,\n customClasses: ComponentsClassNames,\n units: Units,\n tooltipConfig: TooltipKey[] | false | undefined,\n labels: TooltipLabels,\n locale: 'en' | 'pt',\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 const signature = JSON.stringify({ units, tooltipConfig, labels, locale });\n const cached = svgEl ? _tooltipCache.get(svgEl) : undefined;\n if (cached && cached.signature === signature) {\n return cached.tooltips;\n }\n\n const tipsText = {\n geology: (_: unknown, d: Lithology) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.geology.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>\n ${d.geologic_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.geology.geologicUnit}</strong> ${esc(d.geologic_unit)}</span>` : ''}\n ${d.aquifer_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.geology.aquiferUnit}</strong> ${esc(d.aquifer_unit)}</span>` : ''}\n `,\n hole: (_: unknown, d: BoreHole) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.hole.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n `,\n surfaceCase: (_: unknown, d: SurfaceCase) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.surfaceCase.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n `,\n holeFill: (_: unknown, d: HoleFill) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.holeFill.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.description}</strong> ${esc(d.description)}\n </span>\n `,\n wellCase: (_: unknown, d: WellCase) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.wellCase.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>\n `,\n wellScreen: (_: unknown, d: WellScreen) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.wellScreen.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.wellScreen.slot}</strong> ${esc(formatNumber(d.screen_slot, { maximumFractionDigits: 2, locale }))} mm\n </span>\n `,\n reduction: (_: unknown, d: Reduction) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.reduction.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diam_from, units.diameter, locale))} → ${esc(formatDiameter(d.diam_to, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(d.type)}</span>\n `,\n conflict: (_: unknown, d: { from: number; to: number }) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.conflict.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n `,\n fracture: (_: unknown, d: Fracture) => {\n const title = d.swarm\n ? labels.fracture.titleSwarm\n : labels.fracture.title;\n return `\n <span class=\"${customClasses.tooltip.title}\">${title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\"><strong>${labels.fracture.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.waterIntake}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ''}\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.dip}</strong> ${esc(d.dip)}°</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.azimuth}</strong> ${esc(d.azimuth)}°</span>\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ''}\n `;\n },\n cementPad: (_: unknown, d: CementPad) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.cementPad.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${esc(d.type)}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.cementPad.thickness}</strong>\n ${esc(formatLength(d.thickness, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.cementPad.width}</strong> ${esc(formatLength(d.width, units.length, locale))} ${esc(getLengthUnit(units.length))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.cementPad.length}</strong> ${esc(formatLength(d.length, units.length, locale))} ${esc(getLengthUnit(units.length))}\n </span>\n `,\n cave: (_: unknown, d: Cave) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.cave.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.cave.waterIntake}</strong></span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</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] = (d3tip as unknown as () => D3Tip)()\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, { signature, tooltips });\n\n return tooltips;\n};\n","import type { AnnotationData, DrawContext } from '~/types/render.types';\nimport { formatLength, getLengthUnit } from '~/utils/format.utils';\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 = `${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`;\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: `${formatLength(d.from, ctx.units.length, ctx.locale)}–${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`,\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\n ? (ctx.renderConfig.labels.typeLabels?.fractureWater ??\n 'fratura aberta')\n : (ctx.renderConfig.labels.typeLabels?.fracture ?? '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: `${formatLength(d.depth, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} · ${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\n ? (ctx.renderConfig.labels.typeLabels?.caveWater ?? 'caverna úmida')\n : (ctx.renderConfig.labels.typeLabels?.cave ?? '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: `${formatLength(d.from, ctx.units.length, ctx.locale)}–${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} · ${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 * as d3 from 'd3';\n\nimport { Cave } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { mergeEnter } from '~/utils/d3.utils';\nimport { makeIntervalKey } from '~/utils/key.utils';\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 const rc = renderConfig.caves;\n\n const groups = cavesGroup\n .selectAll(`g.${classes.caves.item}`)\n .data(data, makeIntervalKey('cave'));\n\n groups.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const entered = groups\n .enter()\n .append('g')\n .attr('class', classes.caves.item)\n .style('cursor', 'pointer')\n .on('mouseover', tooltips.cave.show)\n .on('mouseout', tooltips.cave.hide)\n .style('opacity', 0);\n\n const merged = mergeEnter(entered, groups);\n\n merged.each(function (cave) {\n const g = d3.select(this);\n g.selectAll('*').remove();\n\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;\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 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 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 merged.transition(ctx.transition).style('opacity', 1);\n}\n","/**\n * Factory for D3 key functions on interval features (`from`/`to`).\n * Format: `${type}:${from}:${to}:${i}` — type scopes the key,\n * coordinates provide semantic stability, index breaks ties for\n * features sharing identical depth positions.\n *\n * Accepts `unknown` datum so the returned function is compatible with\n * both typed and untyped D3 selections without extra casts at call sites.\n */\nexport const makeIntervalKey =\n (type: string) =>\n (d: unknown, _i: number): string => {\n const { key, from, to } = d as {\n key?: string | number;\n from: number;\n to: number;\n };\n return key ? `${key}` : `${type}:${from}:${to}`;\n };\n\n/**\n * Factory for D3 key functions on point features (`depth`).\n * Format: `${type}:${depth}:${i}`.\n */\nexport const makePointKey =\n (type: string) =>\n (d: unknown, i: number): string => {\n const { key, depth } = d as {\n key?: string | number;\n depth: number;\n };\n return key ? `${key}` : `${type}:${depth}:${i}`;\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) =>\n formatDiameter(mm, ctx.units.diameter, ctx.locale);\n const dUnit = getDiameterUnit(ctx.units.diameter, ctx.locale);\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)}${dUnit}`,\n ),\n );\n}\n","import * as d3 from 'd3';\n\nimport type {\n BoreHole,\n CementPad,\n Constructive,\n HoleFill,\n Reduction,\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 { makeIntervalKey } from '~/utils/key.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 // Enter selections have datum:unknown; cast getYPos once so it can be used\n // as a ValueFn without triggering TS errors at each call site.\n const yPos = getYPos as (d: unknown) => number;\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], () => '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\n const hole = ctx.groups.holeGroup\n .selectAll(`.${ctx.classes.boreHole.rect}`)\n .data(data.bore_hole, makeIntervalKey('bore_hole'));\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('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 .attr('y', yPos)\n .attr('height', 0);\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 // ── Surface case ───────────────────────────────────────────────────────────\n\n const surfaceCaseGs = ctx.groups.surfaceCaseGroup\n .selectAll(`g.${ctx.classes.surfaceCase.rect}`)\n .data(data.surface_case, makeIntervalKey('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 .attr('y', yPos)\n .attr('height', 0);\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 // ── Hole fill ──────────────────────────────────────────────────────────────\n\n const holeFill = ctx.groups.holeFillGroup\n .selectAll(`.${ctx.classes.holeFill.rect}`)\n .data(data.hole_fill, makeIntervalKey('hole_fill'));\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 .on('mouseover', ctx.tooltips.holeFill.show)\n .on('mouseout', ctx.tooltips.holeFill.hide)\n .attr('y', yPos)\n .attr('height', 0);\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 // ── Well case ──────────────────────────────────────────────────────────────\n\n const wellCase = ctx.groups.wellCaseGroup\n .selectAll(`.${ctx.classes.wellCase.rect}`)\n .data(data.well_case, makeIntervalKey('well_case'));\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 .on('mouseover', ctx.tooltips.wellCase.show)\n .on('mouseout', ctx.tooltips.wellCase.hide)\n .attr('y', yPos)\n .attr('height', 0);\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 // ── Well screen ────────────────────────────────────────────────────────────\n\n const wellScreen = ctx.groups.wellScreenGroup\n .selectAll(`.${ctx.classes.wellScreen.rect}`)\n .data(data.well_screen, makeIntervalKey('well_screen'));\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 .on('mouseover', ctx.tooltips.wellScreen.show)\n .on('mouseout', ctx.tooltips.wellScreen.hide)\n .attr('y', yPos)\n .attr('height', 0);\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 // ── Reduction ──────────────────────────────────────────────────────────────\n\n const reductionPoints = (\n d: Reduction,\n yTop: number,\n yBot: number,\n ): string => {\n const xTopLeft = (ctx.POCO_CENTER - xScale(d.diam_from)) / 2;\n const xTopRight = (ctx.POCO_CENTER + xScale(d.diam_from)) / 2;\n const xBotLeft = (ctx.POCO_CENTER - xScale(d.diam_to)) / 2;\n const xBotRight = (ctx.POCO_CENTER + xScale(d.diam_to)) / 2;\n return `${xTopLeft},${yTop} ${xTopRight},${yTop} ${xBotRight},${yBot} ${xBotLeft},${yBot}`;\n };\n\n const reduction = ctx.groups.reductionGroup\n .selectAll(`.${ctx.classes.reduction.item}`)\n .data(data.reduction, makeIntervalKey('reduction'));\n\n reduction.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const collapsedPoints = (d: unknown): string => {\n const r = d as Reduction;\n const y = getYPos(r);\n return reductionPoints(r, y, y);\n };\n\n const newReduction = reduction\n .enter()\n .append('polygon')\n .attr('class', ctx.classes.reduction.item)\n .attr('fill', ctx.theme.reduction.fill)\n .attr('stroke', ctx.theme.reduction.stroke)\n .attr('stroke-width', ctx.theme.reduction.strokeWidth)\n .on('mouseover', ctx.tooltips.reduction.show)\n .on('mouseout', ctx.tooltips.reduction.hide)\n .attr('points', collapsedPoints);\n\n const mergedReduction = mergeEnter(newReduction, reduction);\n withTransition(mergedReduction, ctx.transition).attr(\n 'points',\n (d: Reduction) => reductionPoints(d, getYPos(d), getYPos(d) + getHeight(d)),\n );\n\n // ── Conflict zones ─────────────────────────────────────────────────────────\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, makeIntervalKey('conflict'));\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 .on('mouseover', ctx.tooltips.conflict.show)\n .on('mouseout', ctx.tooltips.conflict.hide)\n .attr('y', ctx.yScale(0))\n .attr('height', 0);\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 * as d3 from 'd3';\n\nimport { Fracture } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { mergeEnter } from '~/utils/d3.utils';\nimport { makePointKey } from '~/utils/key.utils';\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 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 const groups = fracturesGroup\n .selectAll(`g.${classes.fractures.item}`)\n .data(data, makePointKey('fracture'));\n\n groups.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const entered = groups\n .enter()\n .append('g')\n .attr('class', classes.fractures.item)\n .on('mouseover', tooltips.fracture.show)\n .on('mouseout', tooltips.fracture.hide)\n .style('cursor', 'pointer')\n .style('opacity', 0);\n\n const merged = mergeEnter(entered, groups);\n\n merged.attr(\n 'transform',\n fracture =>\n `translate(0,${yScale(fracture.depth)}) rotate(${fracture.dip},${pocoCenterX},0)`,\n );\n\n merged.each(function (fracture) {\n const g = d3.select(this);\n g.selectAll('*').remove();\n\n const rng = makeSeededPrng(fracture.depth, 7919);\n const hitBuffer = fracture.swarm ? rf.hitBuffer.swarm : rf.hitBuffer.single;\n\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 merged.transition(ctx.transition).style('opacity', 1);\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 drawConstrHighlights(\n hl.reduction,\n ctx.constructionData.reduction.map(d => ({\n from: d.from,\n to: d.to,\n diameter: Math.max(d.diam_from, d.diam_to),\n })),\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 | 'reduction'\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 reductions = profile.reduction ?? [];\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 hasReduction = reductions.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 (hasReduction)\n items.push({\n kind: 'construction',\n label: cfg.labels.reduction,\n subKind: 'reduction',\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 if (item.subKind === 'reduction') {\n const topW = rw * 0.5;\n const y1 = rowSymY - rh / 2;\n const y2 = rowSymY + rh / 2;\n const midX = cx + rw / 2;\n symG\n .append('polygon')\n .attr('class', cls.constructionRect)\n .attr(\n 'points',\n `${midX - topW / 2},${y1} ${midX + topW / 2},${y1} ${cx + rw},${y2} ${cx},${y2}`,\n )\n .attr('fill', theme.reduction.fill)\n .attr('stroke', theme.reduction.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\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 { makeIntervalKey } from '~/utils/key.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, makeIntervalKey('lithology'));\n\n rects.exit().transition(transition).attr('height', 0).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 .attr('y', getYPos)\n .attr('height', 0);\n\n const merged = mergeEnter(newLayers, rects);\n withTransition(merged, transition)\n .attr('y', getYPos)\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 `.wp-tooltip{position:absolute;z-index:1000;display:flex;flex-direction:column;gap:2px;max-width:240px;padding:8px 10px;border-radius:6px;background:${s(labels.annotationBg)};border:1px solid ${s(labels.annotationBorderColor ?? 'rgba(0,0,0,0.08)')};box-shadow:0 4px 12px rgba(0,0,0,0.15);font-family:${s(labels.bodyFont ?? 'sans-serif')};line-height:1.45}`,\n `.wp-tooltip-title{font-family:${s(labels.headerFont)};font-weight:${s(labels.headerFontWeight ?? 600)};font-size:10px;letter-spacing:0.06em;text-transform:uppercase;color:${s(labels.color)}}`,\n `.wp-tooltip-primary{font-weight:${s(labels.headerFontWeight ?? 600)};font-size:12px;color:${s(labels.color)}}`,\n `.wp-tooltip-secondary{font-size:11px;color:${s(labels.bodyColor)}}`,\n ].join('');\n}\n"],"mappings":"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","names":["d3module","d3tip","defu","formatNumber","getProfileDiamValues","textures","formatNumber","formatNumber","textures","textures","d3","d3","getProfileDiamValues","getProfileDiamValues","d3","d3","getProfileDiamValues","d3","sanitizeHtml","d3","d3module","d3tip","defu","formatNumber","getProfileDiamValues"]}
1
+ {"version":3,"sources":["../src/configs/render.configs.ts","../src/utils/format.utils.ts","../src/Renderer.ts","../src/configs/render.textures.ts","../src/configs/render.classnames.ts","../src/utils/render.utils.ts","../src/utils/construction.geometry.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/utils/key.utils.ts","../src/renderers/centralizers.renderer.ts","../src/utils/layout.utils.ts","../src/renderers/column-headers.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/markers.renderer.ts","../src/renderers/overlap.renderer.ts","../src/renderers/overview.renderer.ts","../src/renderers/pump.renderer.ts","../src/renderers/unit-labels.renderer.ts","../src/utils/render.styles.ts"],"sourcesContent":["import { easeCubic } from 'd3';\nimport {\n RenderConfig,\n RenderLabelPack,\n RenderLocalizedText,\n TooltipLabels,\n WellTheme,\n} from '~/types/render.types';\nimport { resolveRenderLabel } from '~/utils/format.utils';\n\n/**\n * Canonical, paired-locale source for every string `@welldot/render` draws\n * (construction-label prefixes, legend entries, tooltip titles/fields,\n * fracture/cave type words). `pt` values must match the literals historically\n * hardcoded in `tooltips.utils.ts`/`annotation-labels.renderer.ts` exactly —\n * this is the single source of truth `applyRenderLocale()` resolves from.\n */\nexport const RENDER_LABELS: RenderLabelPack = {\n constructionLabels: {\n wellCasePrefix: { pt: 'Revest.', en: 'Casing' },\n wellScreenPrefix: { pt: 'Filtro', en: 'Screen' },\n wellScreenSlotPrefix: { pt: 'Ranhura:', en: 'Slot:' },\n },\n legend: {\n title: { pt: 'LEGENDA', en: 'LEGEND' },\n labels: {\n fractureSingle: { pt: 'Fratura simples', en: 'Single fracture' },\n fractureSwarm: { pt: 'Enxame de fraturas', en: 'Fracture swarm' },\n fractureWater: { pt: \"Entrada d'água\", en: 'Water intake' },\n caveDry: { pt: 'Caverna seca', en: 'Dry cave' },\n caveWet: { pt: 'Caverna c/ água', en: 'Wet cave' },\n boreHole: { pt: 'Perfuração', en: 'Borehole' },\n surfaceCase: { pt: 'Tubo guia', en: 'Surface casing' },\n holeFillGravel: { pt: 'Pré-filtro', en: 'Gravel pack' },\n holeFillSeal: { pt: 'Vedação', en: 'Seal' },\n wellCase: { pt: 'Revestimento', en: 'Casing' },\n wellScreen: { pt: 'Filtro', en: 'Screen' },\n reduction: { pt: 'Redução', en: 'Reduction' },\n centralizer: { pt: 'Centralizador', en: 'Centralizer' },\n pump: { pt: 'Bomba e edutor', en: 'Pump and riser' },\n cementPad: { pt: 'Laje de cimento', en: 'Cement pad' },\n conflict: { pt: 'Conflito', en: 'Conflict' },\n },\n },\n tooltipLabels: {\n common: {\n from: { pt: 'De', en: 'From' },\n to: { pt: 'até', en: 'to' },\n description: { pt: 'Descrição:', en: 'Description:' },\n diameter: { pt: 'Diâmetro:', en: 'Diameter:' },\n type: { pt: 'Tipo:', en: 'Type:' },\n },\n geology: {\n title: { pt: 'Litologia', en: 'Lithology' },\n geologicUnit: { pt: 'Unidade geológica:', en: 'Geologic unit:' },\n aquiferUnit: { pt: 'Unidade aquífera:', en: 'Aquifer unit:' },\n },\n hole: { title: { pt: 'FURO', en: 'BOREHOLE' } },\n surfaceCase: { title: { pt: 'TUBO DE BOCA', en: 'SURFACE CASING' } },\n holeFill: { title: { pt: 'ESP. ANULAR', en: 'ANNULAR SPACE' } },\n wellCase: { title: { pt: 'REVESTIMENTO', en: 'CASING' } },\n wellScreen: {\n title: { pt: 'FILTROS', en: 'SCREENS' },\n slot: { pt: 'Ranhura:', en: 'Slot:' },\n material: { pt: 'Material:', en: 'Material:' },\n slotType: { pt: 'Tipo:', en: 'Type:' },\n },\n reduction: { title: { pt: 'REDUÇÃO', en: 'REDUCTION' } },\n centralizer: {\n title: { pt: 'CENTRALIZADOR', en: 'CENTRALIZER' },\n depth: { pt: 'Profundidade:', en: 'Depth:' },\n spacing: { pt: 'Espaçamento:', en: 'Spacing:' },\n },\n pump: {\n title: { pt: 'BOMBA', en: 'PUMP' },\n intakeDepth: { pt: 'Profundidade do crivo:', en: 'Intake depth:' },\n model: { pt: 'Modelo:', en: 'Model:' },\n power: { pt: 'Potência:', en: 'Power:' },\n riser: { pt: 'Edutor:', en: 'Riser:' },\n type_submersible: { pt: 'Bomba submersa', en: 'Submersible pump' },\n type_vertical_turbine: {\n pt: 'Bomba de eixo vertical',\n en: 'Vertical turbine pump',\n },\n type_jet: { pt: 'Bomba injetora', en: 'Jet pump' },\n type_progressive_cavity: {\n pt: 'Bomba helicoidal',\n en: 'Progressive cavity pump',\n },\n type_hand_pump: { pt: 'Bomba manual', en: 'Hand pump' },\n type_compressor_airlift: {\n pt: 'Compressor (air-lift)',\n en: 'Compressor (air-lift)',\n },\n },\n conflict: { title: { pt: 'CONFLITO', en: 'CONFLICT' } },\n fracture: {\n title: { pt: 'FRATURA', en: 'FRACTURE' },\n titleSwarm: { pt: 'ENXAME DE FRATURAS', en: 'FRACTURE SWARM' },\n depth: { pt: 'Profundidade:', en: 'Depth:' },\n waterIntake: { pt: \"Entrada d'água:\", en: 'Water intake:' },\n dip: { pt: 'Mergulho:', en: 'Dip:' },\n azimuth: { pt: 'Azimute:', en: 'Azimuth:' },\n },\n cementPad: {\n title: { pt: 'LAJE DE PROTEÇÃO', en: 'PROTECTION SLAB' },\n thickness: { pt: 'Espessura:', en: 'Thickness:' },\n width: { pt: 'Largura:', en: 'Width:' },\n length: { pt: 'Comprimento:', en: 'Length:' },\n },\n cave: {\n title: { pt: 'CAVERNA', en: 'CAVE' },\n waterIntake: { pt: \"Entrada d'água\", en: 'Water intake' },\n },\n },\n typeLabels: {\n fracture: { pt: 'fratura', en: 'fracture' },\n fractureWater: { pt: 'fratura aberta', en: 'open fracture' },\n cave: { pt: 'caverna', en: 'cave' },\n caveWater: { pt: 'caverna úmida', en: 'wet cave' },\n },\n columnHeaders: {\n depth: { pt: 'PROF.', en: 'DEPTH' },\n lithology: { pt: 'LIT.', en: 'LITH.' },\n construction: { pt: 'CONSTRUÇÃO', en: 'CONSTRUCTION' },\n description: { pt: 'DESCRIÇÃO GEOLÓGICA', en: 'GEOLOGICAL DESCRIPTION' },\n },\n continuation: { prefix: { pt: 'continuação', en: 'continued' } },\n overlap: {\n label: {\n pt: '{range} repetido da pág. anterior',\n en: '{range} repeated from previous page',\n },\n },\n};\n\n/** Resolves every `RenderLocalizedText` leaf of a flat group to a plain string for `locale`. */\nfunction resolveGroup<G extends Record<string, RenderLocalizedText>>(\n group: G,\n locale: 'en' | 'pt',\n): { [K in keyof G]: string } {\n const result = {} as { [K in keyof G]: string };\n for (const key in group) {\n result[key] = resolveRenderLabel(group[key], locale);\n }\n return result;\n}\n\n/** Resolves `RENDER_LABELS.tooltipLabels` to the plain-string shape `RenderConfig.tooltipLabels` expects. */\nfunction resolveTooltipLabels(locale: 'en' | 'pt'): TooltipLabels {\n const t = RENDER_LABELS.tooltipLabels;\n return {\n common: resolveGroup(t.common, locale),\n geology: resolveGroup(t.geology, locale),\n hole: resolveGroup(t.hole, locale),\n surfaceCase: resolveGroup(t.surfaceCase, locale),\n holeFill: resolveGroup(t.holeFill, locale),\n wellCase: resolveGroup(t.wellCase, locale),\n wellScreen: resolveGroup(t.wellScreen, locale),\n reduction: resolveGroup(t.reduction, locale),\n centralizer: resolveGroup(t.centralizer, locale),\n pump: resolveGroup(t.pump, locale),\n conflict: resolveGroup(t.conflict, locale),\n fracture: resolveGroup(t.fracture, locale),\n cementPad: resolveGroup(t.cementPad, locale),\n cave: resolveGroup(t.cave, locale),\n };\n}\n\n/**\n * Returns a copy of `config` with `constructionLabels.labels`, `legend.labels`,\n * `tooltipLabels`, `labels.typeLabels`, `labels.continuation.prefix`,\n * `columnHeaders.labels` and `overlap.label` resolved from `RENDER_LABELS`\n * for `locale`. Every other field of `config` is preserved unchanged.\n */\nexport function applyRenderLocale(\n config: RenderConfig,\n locale: 'en' | 'pt',\n): RenderConfig {\n return {\n ...config,\n constructionLabels: {\n ...config.constructionLabels,\n labels: resolveGroup(RENDER_LABELS.constructionLabels, locale),\n },\n legend: {\n ...config.legend,\n title: resolveRenderLabel(RENDER_LABELS.legend.title, locale),\n labels: resolveGroup(RENDER_LABELS.legend.labels, locale),\n },\n tooltipLabels: resolveTooltipLabels(locale),\n labels: {\n ...config.labels,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, locale),\n continuation: {\n ...config.labels.continuation,\n prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, locale),\n },\n },\n columnHeaders: {\n ...config.columnHeaders,\n labels: resolveGroup(RENDER_LABELS.columnHeaders, locale),\n },\n overlap: {\n ...config.overlap,\n label: resolveRenderLabel(RENDER_LABELS.overlap.label, locale),\n },\n };\n}\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: 1 },\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: 1.2 },\n wellCase: { fill: '#ffffff', stroke: '#303030', strokeWidth: 2 },\n wellScreen: {\n stroke: '#303030',\n strokeWidth: 2,\n endStrokeWidth: 0.75,\n endDasharray: '3, 2',\n },\n reduction: { fill: '#ffffff', stroke: '#303030', strokeWidth: 2 },\n centralizer: { fill: 'none', stroke: '#303030', strokeWidth: 1.4 },\n pump: {\n fill: '#5b6b7a',\n stroke: '#202020',\n strokeWidth: 1.2,\n riserFill: '#a3adb7',\n riserStroke: '#2f3a44',\n riserStrokeWidth: 1,\n },\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 overview: {\n stroke: '#303030',\n strokeWidth: 0.5,\n emptyFill: '#d9d9d9',\n windowStroke: '#c0392b',\n windowStrokeWidth: 1.2,\n },\n columnHeaders: {\n fontSize: 6.5,\n color: '#303030',\n fontFamily: 'sans-serif',\n fontWeight: 600,\n ruleStroke: '#101010',\n ruleStrokeWidth: 1,\n },\n markers: {\n fill: '#ffffff',\n stroke: '#101010',\n strokeWidth: 0.6,\n color: '#101010',\n fontSize: 6,\n fontFamily: 'sans-serif',\n fontWeight: 600,\n },\n overlap: {\n stroke: '#9a9a9a',\n strokeWidth: 0.6,\n size: 6,\n ruleStroke: '#9a9a9a',\n labelColor: '#555555',\n fontSize: 6.5,\n fontFamily: 'monospace',\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 maxZoomScale: 150,\n minZoomScale: 0,\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: { widthRatio: 1.4, height: 6 },\n casingShoe: { active: true, size: 4 },\n screenEnds: { active: true },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n centralizer: { markerHalfHeight: 4 },\n pump: {\n active: true,\n bodyHeight: 22,\n bodyWidthRatio: 0.6,\n riserWidthRatio: 0.3,\n },\n },\n tooltipLabels: resolveTooltipLabels('pt'),\n labels: {\n active: true,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, 'pt'),\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 continuation: {\n active: false,\n prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, 'pt'),\n },\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 reduction: 'Redução',\n centralizer: 'Centralizador',\n pump: 'Bomba e edutor',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n overview: { active: false, x: 4, width: 8, height: 200 },\n columnHeaders: {\n active: false,\n height: 14,\n labels: resolveGroup(RENDER_LABELS.columnHeaders, 'pt'),\n },\n markers: { lithology: false, fractures: false, radius: 4.5 },\n overlap: {\n label: resolveRenderLabel(RENDER_LABELS.overlap.label, 'pt'),\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n\nexport const INTERACTIVE_RENDER_CONFIG: RenderConfig = {\n zoom: true,\n pan: true,\n zoomLevel: 1,\n maxZoomScale: 150,\n minZoomScale: 0,\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: { widthRatio: 1.4, height: 6 },\n casingShoe: { active: true, size: 4 },\n screenEnds: { active: true },\n surfaceCase: { diameterPaddingRatio: 0.1 },\n centralizer: { markerHalfHeight: 4 },\n pump: {\n active: true,\n bodyHeight: 22,\n bodyWidthRatio: 0.6,\n riserWidthRatio: 0.3,\n },\n },\n tooltipLabels: resolveTooltipLabels('pt'),\n labels: {\n active: false,\n typeLabels: resolveGroup(RENDER_LABELS.typeLabels, 'pt'),\n depthTipHeight: 11,\n depthTipPadX: 2,\n descriptionXOffset: 78,\n descriptionMaxWidth: 226,\n stackingLineHeight: 11,\n stackingGap: 0,\n continuation: {\n active: false,\n prefix: resolveRenderLabel(RENDER_LABELS.continuation.prefix, 'pt'),\n },\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 reduction: 'Redução',\n centralizer: 'Centralizador',\n pump: 'Bomba e edutor',\n cementPad: 'Laje de cimento',\n conflict: 'Conflito',\n },\n },\n overview: { active: false, x: 4, width: 8, height: 200 },\n columnHeaders: {\n active: false,\n height: 14,\n labels: resolveGroup(RENDER_LABELS.columnHeaders, 'pt'),\n },\n markers: { lithology: false, fractures: false, radius: 4.5 },\n overlap: {\n label: resolveRenderLabel(RENDER_LABELS.overlap.label, 'pt'),\n },\n highlights: DEFAULT_HIGHLIGHT_CONFIG,\n};\n","import type { DiameterUnits, LengthUnits } from '@welldot/core';\nimport { resolveLanguageText } from '@welldot/core';\nimport { formatNumber } from '@welldot/utils';\nimport type { RenderLocalizedText } from '~/types/render.types';\n\nconst MM_TO_INCHES = 0.0393701;\nconst M_TO_FT = 3.28084;\n\n/**\n * Formats a depth value in metres to the active length unit string, rounded\n * (never raw floating-point) and using the target locale's decimal separator.\n */\nexport function formatLength(\n m: number,\n units: LengthUnits,\n locale: 'en' | 'pt',\n): string {\n return units === 'ft'\n ? formatNumber(m * M_TO_FT, { maximumFractionDigits: 1, locale })\n : formatNumber(m, { maximumFractionDigits: 2, locale });\n}\n\n/**\n * Formats a diameter value in millimetres to the active diameter unit\n * string, rounded (never raw floating-point) and using the target locale's\n * decimal separator.\n */\nexport function formatDiameter(\n mm: number,\n units: DiameterUnits,\n locale: 'en' | 'pt',\n): string {\n return units === 'inches'\n ? formatNumber(mm * MM_TO_INCHES, { maximumFractionDigits: 2, locale })\n : formatNumber(mm, { maximumFractionDigits: 2, locale });\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/**\n * Returns the display symbol for the active diameter unit. `mm` is\n * locale-invariant; `inches` is `'\"'` unless `locale` is `'en'`, in which\n * case it's `'in.'`. Omitting `locale` preserves the historical `'\"'` default.\n */\nexport function getDiameterUnit(\n units: DiameterUnits,\n locale?: 'en' | 'pt',\n): string {\n if (units !== 'inches') return 'mm';\n return locale === 'en' ? 'in.' : '\"';\n}\n\n/**\n * Resolves a render label to a plain string: core `resolveLanguageText()`\n * with `pt` as the fallback locale. A bare string is returned as-is\n * (locale-invariant).\n */\nexport function resolveRenderLabel(\n value: RenderLocalizedText,\n locale: 'en' | 'pt',\n): string {\n return resolveLanguageText(value, locale, 'pt');\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 = { ...d3module, tip: d3tip };\n\nimport {\n isWellEmpty,\n type Constructive,\n type Lithology,\n type Units,\n type Well,\n} from '@welldot/core';\nimport {\n formatNumber,\n getCurrentPump,\n getProfileLastItemsDepths,\n} from '@welldot/utils';\nimport {\n ComponentsClassNames,\n DeepPartial,\n DrawContext,\n DrawGroups,\n Highlights,\n InstanceState,\n RenderableWell,\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 { drawCentralizers } from './renderers/centralizers.renderer';\nimport { drawColumnHeaders } from './renderers/column-headers.renderer';\nimport { drawConstructionLabels } from './renderers/construction-labels.renderer';\nimport {\n drawCementPad,\n drawConstructive,\n layoutConstruction,\n} from './renderers/construction.renderer';\nimport { drawFractures } from './renderers/fractures.renderer';\nimport { drawHighlights } from './renderers/highlights.renderer';\nimport {\n drawWellLegend,\n drawWellLegendSymbol,\n getWellLegendItems,\n WellLegendItem,\n} from './renderers/legend.renderer';\nimport {\n drawLithology,\n drawLithologySwatch,\n} from './renderers/lithology.renderer';\nimport { drawMarkers } from './renderers/markers.renderer';\nimport { drawOverlap } from './renderers/overlap.renderer';\nimport { drawOverview } from './renderers/overview.renderer';\nimport { drawPump } from './renderers/pump.renderer';\nimport { drawUnitLabels } from './renderers/unit-labels.renderer';\nimport { asSvgElement } from './utils/d3.utils';\nimport { getProfileTopDepth, resolvePanelWindows } from './utils/layout.utils';\nimport { buildSvgStyleBlock } from './utils/render.styles';\nimport {\n filterByDepth,\n fractureDip,\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 private onZoom?: (scale: number) => 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 private locale: 'en' | 'pt' = 'pt';\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.locale - Locale for renderer-drawn text (diameter symbol, and any `RenderConfig` fields resolved via `applyRenderLocale`). Defaults to `'pt'`, matching the package's historical output.\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 * @param options.onZoom - Called with the current zoom scale (`1` = initial/fit) whenever the user zooms or pans, and whenever `zoomBy`/`resetZoom` are called. No-op if `renderConfig.zoom`/`pan` are both disabled.\n */\n constructor(\n svgs: SvgInstance[],\n options: {\n classNames?: DeepPartial<ComponentsClassNames>;\n units?: Units;\n locale?: 'en' | 'pt';\n renderConfig?: DeepPartial<RenderConfig>;\n theme?: DeepPartial<WellTheme>;\n onError?: (err: Error) => void;\n onZoom?: (scale: number) => 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 if (options.onZoom) this.onZoom = options.onZoom;\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.locale) {\n this.locale = options.locale;\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 svg\n .append('g')\n .attr('class', this.classes.overview.group)\n .attr('transform', `translate(0, ${margins.top})`);\n svg.append('g').attr('class', this.classes.columnHeaders.group);\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 poco\n .append('g')\n .attr('class', this.classes.markers.group)\n .attr('transform', `translate(${margins.left}, ${margins.top})`);\n\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.reduction.group);\n construction.append('g').attr('class', this.classes.pump.group);\n construction.append('g').attr('class', this.classes.centralizer.group);\n construction.append('g').attr('class', this.classes.conflict.group);\n construction\n .append('g')\n .attr('class', this.classes.constructionLabels.group);\n construction\n .append('g')\n .attr('class', this.classes.highlights.constructionGroup);\n\n // Last child of the well group, so the band hatches over everything.\n poco\n .append('g')\n .attr('class', this.classes.overlap.group)\n .attr('transform', `translate(${margins.left}, ${margins.top})`);\n\n Object.values(this.textures).forEach(texture => svg.call(texture));\n\n return {\n svg,\n height,\n width,\n margins,\n clipId,\n clipRectId,\n depthRange: inst.depthRange,\n repeatedTo: inst.repeatedTo,\n };\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 /** Lists the legend entries `profile` needs, labeled from `renderConfig.legend.labels`. */\n public getLegendItems(profile: Well): WellLegendItem[] {\n return getWellLegendItems(profile, this.renderConfig.legend.labels);\n }\n\n /**\n * Renders one legend entry's symbol (see {@link getLegendItems}) into its\n * own SVG matched by `selector`, with the textures it needs defined inside.\n */\n public renderLegendSymbol(selector: string, item: WellLegendItem): void {\n drawWellLegendSymbol(selector, item, {\n theme: this.theme,\n classNames: this.classes.legend,\n textures: this.renderConfig.textures,\n });\n }\n\n /**\n * Renders one lithology layer's fill as a `size`×`size` square into its\n * own SVG matched by `selector`, with its texture defined inside (e.g. for\n * a swatch in a PDF table). Call after `prepareSvg()`, which loads the\n * FGDC textures.\n */\n public renderLithologySwatch(\n selector: string,\n layer: Lithology,\n size = 10,\n ): void {\n drawLithologySwatch(selector, layer, { size, theme: this.theme });\n }\n\n /**\n * Multiplies the current zoom scale by `factor` (e.g. `1.25` to zoom in,\n * `1 / 1.25` to zoom out) on every panel. No-op if both `renderConfig.zoom`\n * and `renderConfig.pan` are disabled (no zoom behavior was attached).\n */\n public zoomBy(factor: number): void {\n for (const state of this.instanceStates) {\n if (!state.zoomNode) continue;\n asSvgElement<SVGSVGElement>(state.svg)\n .transition()\n .call(state.zoomNode.scaleBy, factor);\n }\n }\n\n /**\n * Resets zoom/pan on every panel back to `renderConfig.zoomLevel`\n * (defaults to `1`, i.e. the initial fit-to-container view).\n */\n public resetZoom(): void {\n const target = d3.zoomIdentity.scale(this.renderConfig.zoomLevel ?? 1);\n for (const state of this.instanceStates) {\n if (!state.zoomNode) continue;\n asSvgElement<SVGSVGElement>(state.svg)\n .transition()\n .call(state.zoomNode.transform, target);\n }\n }\n\n /**\n * Current zoom scale factor of the first panel (`1` = initial/fit).\n * Returns `1` if zoom/pan is disabled or `prepareSvg()` hasn't run yet.\n */\n public getZoomScale(): number {\n const node = this.instanceStates[0]?.svg.node();\n return node ? d3.zoomTransform(node as Element).k : 1;\n }\n\n /**\n * Removes everything drawn on every panel (layers, labels, axis,\n * highlights) and keeps the structure `prepareSvg()` built, so the next\n * `draw()` needs no new `prepareSvg()`. `draw()` calls it for an empty well.\n */\n public clear(): void {\n const c = this.classes;\n const layerGroups = [\n c.overview.group,\n c.columnHeaders.group,\n c.yAxis,\n c.unitLabels.group,\n c.lithology.group,\n c.caves.group,\n c.labels.lithology.group,\n c.highlights.geologicGroup,\n c.highlights.constructionGroup,\n c.highlights.fracturesGroup,\n c.markers.group,\n c.cementPad.group,\n c.boreHole.group,\n c.surfaceCase.group,\n c.holeFill.group,\n c.wellCase.group,\n c.wellScreen.group,\n c.reduction.group,\n c.pump.group,\n c.centralizer.group,\n c.conflict.group,\n c.constructionLabels.group,\n c.overlap.group,\n ];\n for (const { svg } of this.instanceStates) {\n for (const cls of layerGroups) {\n svg.select(`.${cls}`).selectAll('*').interrupt().remove();\n }\n // The fractures group also holds its highlights subgroup: drop only the items.\n svg\n .select(`.${c.fractures.group}`)\n .selectAll(`g.${c.fractures.item}`)\n .interrupt()\n .remove();\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. Layers the\n * profile no longer has are removed; an empty well (`isWellEmpty`) clears\n * the panels (see {@link clear}).\n * @param profile - The well data to render.\n * @param options.units - Override the instance-level measurement units for this render.\n * @param options.locale - Override the instance-level locale for this render.\n * @param options.highlights - Highlight overlays to display on top of the profile.\n */\n draw(\n profile: RenderableWell,\n options: {\n units?: Units;\n locale?: 'en' | 'pt';\n highlights?: Highlights;\n } = {},\n ) {\n if (isWellEmpty(profile)) {\n this.clear();\n return;\n }\n\n if (profile.version !== 2) {\n console.warn(\n `[WellRenderer] Received a .well file with version ${profile.version ?? 'unknown'}. ` +\n `Only v2 is supported. Normalize with deserializeWell() from @welldot/core before rendering.`,\n );\n }\n\n this.units = { ...this.units, ...options.units };\n if (options.locale) {\n this.locale = options.locale;\n }\n const highlights = options.highlights ?? {};\n\n const maxValues = getProfileLastItemsDepths(profile);\n const maxYValues = d3.max(maxValues) || 0;\n\n // Explicit `depthRange`s when every panel has one; otherwise the depth is\n // split in proportion to the panel heights, back to back.\n const windows = resolvePanelWindows(\n this.instanceStates,\n maxYValues,\n getProfileTopDepth(profile),\n );\n this.instanceStates.forEach((state, i) => {\n const [from, to] = windows[i]!;\n this.drawLogToInstance(state, profile, from, to, maxYValues, highlights);\n });\n }\n\n private drawLogToInstance(\n state: InstanceState,\n profile: RenderableWell,\n depthFrom: number,\n depthTo: number,\n totalDepth: 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 reductionGroup = svg.select(`.${this.classes.reduction.group}`);\n const centralizerGroup = svg.select(`.${this.classes.centralizer.group}`);\n const pumpGroup = svg.select(`.${this.classes.pump.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 const overviewGroup = svg.select(`.${this.classes.overview.group}`);\n const columnHeadersGroup = svg.select(\n `.${this.classes.columnHeaders.group}`,\n );\n const markersGroup = svg.select(`.${this.classes.markers.group}`);\n const overlapGroup = svg.select(`.${this.classes.overlap.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 this.renderConfig.tooltipLabels,\n this.locale,\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 centralizers: profile.centralizers ?? [],\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.axisLeft(yScaleAxis).tickFormat(\n (d: d3module.NumberValue) =>\n `${formatNumber(Number(d), {\n maximumFractionDigits: this.units.length === 'ft' ? 1 : 2,\n locale: this.locale,\n })}${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 reductionGroup,\n centralizerGroup,\n pumpGroup,\n conflictGroup,\n highlightsGeologicGroup,\n highlightsConstructionGroup,\n highlightsFracturesGroup,\n overviewGroup,\n columnHeadersGroup,\n markersGroup,\n overlapGroup,\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 totalDepth,\n repeatedTo: state.repeatedTo,\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 locale: this.locale,\n constructionData,\n groups,\n };\n\n const inDepth = filterByDepth(depthFrom, depthTo);\n const currentPump = getCurrentPump(profile as Well);\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 centralizers: constructionData.centralizers?.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 // Construction outlines, shoes, reductions and the cement pad follow\n // the rescaled y; the pad is paths, so the rect rescale above skips it.\n layoutConstruction(zoomedCtx);\n drawCementPad(zoomedCtx, constructionData.cement_pad);\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 | null };\n const cx = pocoCenterX;\n const cy = transform.applyY(yScaleLocal(f.depth));\n return `translate(0,${cy}) rotate(${fractureDip(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 drawPump(zoomedCtx, currentPump);\n drawCentralizers(zoomedCtx, filteredConstruction);\n drawConstructionLabels(zoomedCtx, {\n well_case: constructionData.well_case.filter(inDepth),\n well_screen: constructionData.well_screen.filter(inDepth),\n });\n drawMarkers(zoomedCtx, {\n lithology: profile.lithology ?? [],\n fractures: profile.fractures ?? [],\n });\n drawOverlap(zoomedCtx);\n drawHighlights(zoomedCtx, highlights);\n this.onZoom?.(transform.k);\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 drawPump(ctx, currentPump);\n drawCentralizers(ctx, filteredConstruction);\n drawConstructionLabels(ctx, {\n well_case: filteredConstruction.well_case,\n well_screen: filteredConstruction.well_screen,\n });\n drawMarkers(ctx, {\n lithology: profile.lithology ?? [],\n fractures: profile.fractures ?? [],\n });\n drawOverview(ctx, profile.lithology ?? []);\n drawColumnHeaders(ctx);\n drawOverlap(ctx);\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 zoomNode.scaleExtent(\n zoomEnabled\n ? [\n this.renderConfig.minZoomScale ?? 0,\n this.renderConfig.maxZoomScale ?? Infinity,\n ]\n : [1, 1],\n );\n if (!panEnabled)\n zoomNode.filter(e => e.type === 'wheel' || e.type === 'dblclick');\n asSvgElement<SVGSVGElement>(svg).call(zoomNode);\n state.zoomNode = 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.paths>;\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\n/** Small dot of radius `r` at (x, y), as a closed path. */\nconst dot = (x: number, y: number, r: number) =>\n `M${x - r},${y}a${r},${r} 0 1,0 ${2 * r},0a${r},${r} 0 1,0 ${-2 * r},0Z`;\n\n/** Concrete aggregate tile of side `s`: two triangles and two dots. */\nexport const concreteAggregate = (s: number): string =>\n `M${s * 0.08},${s * 0.42}l${s * 0.3},0l${-s * 0.12},${-s * 0.26}Z` +\n `M${s * 0.55},${s * 0.92}l${s * 0.26},${-s * 0.06}l${-s * 0.16},${-s * 0.2}Z` +\n `${dot(s * 0.72, s * 0.24, s * 0.06)}${dot(s * 0.22, s * 0.78, s * 0.05)}`;\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 // Concrete: aggregate (small triangles and dots) on a light ground, so it\n // reads apart from the seal's diagonals and the gravel pack's circles.\n pad: textures\n .paths()\n .d(concreteAggregate)\n .size(6)\n .strokeWidth(0.4)\n .stroke(pad.stroke)\n .fill(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 { 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 centralizer: {\n group: 'centralizer',\n item: 'centralizer-marker',\n },\n pump: {\n group: 'pump',\n item: 'pump-item',\n },\n reduction: {\n group: 'reduction',\n item: 'reduction-poly',\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 overview: {\n group: 'wp-overview',\n item: 'wp-overview-item',\n window: 'wp-overview-window',\n },\n columnHeaders: {\n group: 'wp-column-headers',\n text: 'wp-column-header',\n rule: 'wp-column-headers-rule',\n },\n markers: {\n group: 'wp-markers',\n lithology: 'wp-marker-lithology',\n fracture: 'wp-marker-fracture',\n },\n overlap: {\n group: 'wp-overlap',\n band: 'wp-overlap-band',\n label: 'wp-overlap-label',\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 { getCementPadGeometry } from '~/utils/construction.geometry';\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\n/** Fracture rotation in degrees; a missing or non-finite dip renders horizontal (0°). */\nexport const fractureDip = (dip: number | null | undefined): number =>\n typeof dip === 'number' && Number.isFinite(dip) ? dip : 0;\n\n/**\n * Box around the cement pad in construction-group coordinates, resting on the\n * surface line `surfaceY`. Its size is fixed in px (see\n * `getCementPadGeometry`): the pad's real width and thickness are left out,\n * so it never overflows the panel whatever the diameters or depth range.\n * `openingWidth` is the px width of the pipe through the pad, `outerWidth`\n * of the widest item it covers.\n */\nexport function getCementPadRect(\n pocoWidth: number,\n pocoCenter: number,\n surfaceY: number,\n config: { widthRatio: number; height: number },\n openingWidth = 0,\n outerWidth = openingWidth,\n): { x: number; y: number; width: number; height: number } {\n return getCementPadGeometry(\n pocoWidth,\n pocoCenter,\n surfaceY,\n config,\n openingWidth,\n outerWidth,\n ).bbox;\n}\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 textureKey = (d: Lithology) => String(d.texture.code);\n const isFgdc = (d: Lithology) =>\n !d.texture.vocabulary || d.texture.vocabulary === 'fgdc';\n\n const uniqueTextureCodes = [...new Set(data.filter(isFgdc).map(textureKey))];\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 key = textureKey(d);\n const pathData = isFgdc(d) ? texturesLoaded[key] : undefined;\n if (!pathData) return [`${key}.${d.from}`, d.color];\n return [\n `${key}.${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[`${String(d.texture.code)}.${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","/**\n * Pure geometry for the construction column: open pipe walls, casing shoes,\n * borehole shoulders, annulus interfaces and the cement pad. No DOM access;\n * every function takes the scales it needs, so the renderers and the zoom\n * handler share the same shapes.\n */\n\nexport type Interval = { from: number; to: number; diameter: number };\ntype Span = { from: number; to: number };\n\n/** Depth tolerance (m) for joints between intervals. */\nconst JOINT_EPS = 1e-3;\n\n/** Diameter of the first interval covering `depth`, or `undefined`. */\nexport function diameterAt(\n items: Interval[],\n depth: number,\n): number | undefined {\n return items.find(i => depth >= i.from && depth <= i.to)?.diameter;\n}\n\n/** How each end of an interval meets the panel and its neighbours. */\nexport type IntervalEnds = {\n /** The interval goes on above the panel top. */\n cutTop: boolean;\n /** The interval goes on below the panel bottom. */\n cutBottom: boolean;\n /** Another interval of the string ends where this one starts. */\n joinedTop: boolean;\n /** Another interval of the string starts where this one ends. */\n joinedBottom: boolean;\n};\n\n/**\n * Classifies both ends of `item` within the panel `[depthFrom, depthTo]`.\n * `string` holds every interval the item can butt against (the item itself\n * may be included). Only butt joints count: a narrower pipe hung inside a\n * wider one does not hide the wider pipe's end.\n */\nexport function getIntervalEnds(\n item: Span,\n string: Span[],\n depthFrom: number,\n depthTo: number,\n): IntervalEnds {\n return {\n cutTop: item.from < depthFrom - JOINT_EPS,\n cutBottom: item.to > depthTo + JOINT_EPS,\n joinedTop: string.some(\n o => o !== item && Math.abs(o.to - item.from) < JOINT_EPS,\n ),\n joinedBottom: string.some(\n o => o !== item && Math.abs(o.from - item.to) < JOINT_EPS,\n ),\n };\n}\n\n/** The two vertical walls of a pipe, open at both ends. */\nexport function pipeWallsPath(\n xLeft: number,\n xRight: number,\n yTop: number,\n yBottom: number,\n): string {\n return `M${xLeft},${yTop}V${yBottom}M${xRight},${yTop}V${yBottom}`;\n}\n\n/**\n * Casing shoe: a filled right triangle outside each wall, its base on `y`.\n * Always two closed subpaths, so a transition can slide it with the walls.\n */\nexport function shoePath(\n xLeft: number,\n xRight: number,\n y: number,\n size: number,\n): string {\n return (\n `M${xLeft},${y - size}L${xLeft},${y}L${xLeft - size},${y}Z` +\n `M${xRight},${y - size}L${xRight},${y}L${xRight + size},${y}Z`\n );\n}\n\n/**\n * Screen end mark: a line across the pipe at the screen's top or base, from\n * wall to wall. Drawn dashed and thin, it marks the slotted section's limit\n * without reading as a closed pipe end.\n */\nexport function screenEndPath(\n xLeft: number,\n xRight: number,\n y: number,\n): string {\n return `M${xLeft},${y}H${xRight}`;\n}\n\n/** Scales shared by the outline builders. */\nexport type OutlineScales = {\n /** Depth (m) → y (px). */\n y: (depth: number) => number;\n /** Diameter (mm) → left wall x (px). */\n left: (diameter: number) => number;\n /** Diameter (mm) → right wall x (px). */\n right: (diameter: number) => number;\n depthFrom: number;\n depthTo: number;\n};\n\nconst clampDepth = (s: OutlineScales, depth: number) =>\n Math.min(Math.max(depth, s.depthFrom), s.depthTo);\n\nconst inPanel = (s: OutlineScales, depth: number) =>\n depth >= s.depthFrom - JOINT_EPS && depth <= s.depthTo + JOINT_EPS;\n\n/** Horizontal step on both sides, from diameter `a` to diameter `b` at `y`. */\nconst shoulders = (s: OutlineScales, a: number, b: number, y: number) =>\n `M${s.left(a)},${y}H${s.left(b)}M${s.right(a)},${y}H${s.right(b)}`;\n\n/**\n * Borehole outline for one interval: its walls, open at the mouth and at\n * panel cuts. Where the hole narrows below it, a shoulder joins its walls to\n * the narrower ones; where it widens below an older interval, a shoulder\n * joins the narrower walls to its own. Only where no interval goes on below\n * does it close with a bottom line (the total depth).\n */\nexport function boreHoleOutlinePath(\n item: Interval,\n holes: Interval[],\n s: OutlineScales,\n): string {\n const yTop = s.y(clampDepth(s, item.from));\n const yBottom = s.y(clampDepth(s, item.to));\n let d = pipeWallsPath(\n s.left(item.diameter),\n s.right(item.diameter),\n yTop,\n yBottom,\n );\n\n if (item.from > JOINT_EPS && inPanel(s, item.from)) {\n const above = holes.find(\n o => o !== item && o.from < item.from && o.to >= item.from - JOINT_EPS,\n );\n if (above && above.diameter < item.diameter)\n d += shoulders(s, above.diameter, item.diameter, yTop);\n }\n\n if (inPanel(s, item.to)) {\n const below = holes.find(\n o => o !== item && o.from <= item.to + JOINT_EPS && o.to > item.to,\n );\n if (!below) {\n d += `M${s.left(item.diameter)},${yBottom}H${s.right(item.diameter)}`;\n } else if (below.diameter < item.diameter) {\n d += shoulders(s, item.diameter, below.diameter, yBottom);\n }\n }\n return d;\n}\n\n/**\n * Hole fill outline: walls against the borehole plus a line at each\n * interface with another material or with the open hole. Interfaces skip\n * the surface and panel cuts, and stop at the outside of the pipe at that\n * depth, so they never cross the casing.\n */\nexport function holeFillOutlinePath(\n item: Interval,\n pipes: Interval[],\n s: OutlineScales,\n): string {\n const yTop = s.y(clampDepth(s, item.from));\n const yBottom = s.y(clampDepth(s, item.to));\n const xL = s.left(item.diameter);\n const xR = s.right(item.diameter);\n let d = pipeWallsPath(xL, xR, yTop, yBottom);\n\n const interfaces = [item.from, item.to].filter(\n depth => depth > JOINT_EPS && inPanel(s, depth),\n );\n for (const depth of interfaces) {\n const y = s.y(depth);\n const pipe = diameterAt(pipes, depth);\n if (pipe !== undefined && pipe < item.diameter) {\n d += `M${xL},${y}H${s.left(pipe)}M${s.right(pipe)},${y}H${xR}`;\n } else {\n d += `M${xL},${y}H${xR}`;\n }\n }\n return d;\n}\n\n/**\n * Pipes inside `[from, to]` as non-overlapping slices, each with the widest\n * pipe diameter over it. Adjacent slices of equal diameter are merged.\n */\nexport function pipeSlices(\n pipes: Interval[],\n from: number,\n to: number,\n): Interval[] {\n const cuts = [...new Set([from, to, ...pipes.flatMap(p => [p.from, p.to])])]\n .filter(d => d >= from && d <= to)\n .sort((a, b) => a - b);\n\n const slices: Interval[] = [];\n for (let i = 1; i < cuts.length; i++) {\n const a = cuts[i - 1]!;\n const b = cuts[i]!;\n const mid = (a + b) / 2;\n const widest = Math.max(\n 0,\n ...pipes.filter(p => p.from <= mid && p.to >= mid).map(p => p.diameter),\n );\n if (widest === 0) continue;\n const last = slices[slices.length - 1];\n if (last && last.to === a && last.diameter === widest) last.to = b;\n else slices.push({ from: a, to: b, diameter: widest });\n }\n return slices;\n}\n\n/**\n * Hole fill area: the borehole interval with the pipes cut out (fill it with\n * `fill-rule: evenodd`), so the material only covers the annulus and never\n * shows through at the pipe's edges.\n */\nexport function annulusFillPath(\n item: Interval,\n pipes: Interval[],\n s: OutlineScales,\n): string {\n const from = clampDepth(s, item.from);\n const to = clampDepth(s, item.to);\n const box = (dia: number, a: number, b: number) =>\n `M${s.left(dia)},${s.y(a)}H${s.right(dia)}V${s.y(b)}H${s.left(dia)}Z`;\n const inner = pipes.filter(p => p.diameter < item.diameter);\n return (\n box(item.diameter, from, to) +\n pipeSlices(inner, from, to)\n .map(p => box(p.diameter, p.from, p.to))\n .join('')\n );\n}\n\n/**\n * Diameters (mm) that place the cement pad at the surface. `opening` is the\n * pipe the pad is cast around: the casing or screen, else the surface case\n * (with its drawing padding) when it is the only pipe, else the borehole of\n * an uncased well; `0` when nothing reaches 0 m. `outer` is the widest item\n * at 0 m, which the pad covers: surface case, borehole and annulus fill sit\n * under it.\n */\nexport function getPadDiameters(\n data: {\n surface_case: Interval[];\n well_case: Interval[];\n well_screen: Interval[];\n bore_hole: Interval[];\n hole_fill: Interval[];\n },\n surfaceCasePaddingRatio: number,\n): { opening: number; outer: number } {\n const surfaceCase = diameterAt(data.surface_case, 0);\n const paddedSurfaceCase =\n surfaceCase === undefined\n ? undefined\n : surfaceCase * (1 + surfaceCasePaddingRatio);\n const casing = diameterAt([...data.well_case, ...data.well_screen], 0);\n const hole = diameterAt(data.bore_hole, 0);\n const opening = casing ?? paddedSurfaceCase ?? hole ?? 0;\n const outer = Math.max(\n opening,\n paddedSurfaceCase ?? 0,\n hole ?? 0,\n diameterAt(data.hole_fill, 0) ?? 0,\n );\n return { opening, outer };\n}\n\nexport type CementPadGeometry = {\n /** Box around both slabs, used for highlights. */\n bbox: { x: number; y: number; width: number; height: number };\n /** Closed outlines of the left and right slabs (empty when no slab). */\n slabs: [string, string];\n};\n\n/**\n * Cement pad drawn as two slabs resting on the surface line `surfaceY`, one\n * each side of the pipe it is cast around (`openingWidth`), covering\n * everything out to `outerWidth` (surface case, annulus). The pad is not\n * drawn to scale (its real width is metres, the column is millimetres): its\n * width is a `widthRatio` of the column, widened so each slab keeps at least\n * 1.5 × `height` px beside the opening and `height` px past `outerWidth`.\n * The outer ends are break lines, the drafting mark for an element that\n * goes on beyond the drawing.\n *\n * `pocoCenter` and the widths use the construction renderer's convention:\n * x = (pocoCenter − width) / 2.\n */\nexport function getCementPadGeometry(\n pocoWidth: number,\n pocoCenter: number,\n surfaceY: number,\n config: { widthRatio: number; height: number },\n openingWidth = 0,\n outerWidth = openingWidth,\n): CementPadGeometry {\n const h = config.height;\n const opening = Math.max(0, openingWidth);\n const width = Math.max(\n pocoWidth * config.widthRatio,\n opening + 3 * h,\n outerWidth + 2 * h,\n );\n const xLeft = (pocoCenter - width) / 2;\n const xRight = xLeft + width;\n const oLeft = (pocoCenter - opening) / 2;\n const oRight = oLeft + opening;\n const yTop = surfaceY - h;\n const a = h * 0.3;\n\n // Break line (\"Z\") at x from y0 to y1; dir is the side the slab goes on.\n const breakLine = (x: number, y0: number, y1: number, dir: -1 | 1) =>\n `L${x + dir * a},${y0 + (y1 - y0) * 0.4}` +\n `L${x - dir * a},${y0 + (y1 - y0) * 0.6}L${x},${y1}`;\n\n const bbox = { x: xLeft, y: yTop, width, height: h };\n if (opening === 0) {\n return {\n bbox,\n slabs: [\n `M${xLeft},${yTop}H${xRight}${breakLine(xRight, yTop, surfaceY, 1)}` +\n `H${xLeft}${breakLine(xLeft, surfaceY, yTop, -1)}Z`,\n '',\n ],\n };\n }\n return {\n bbox,\n slabs: [\n `M${oLeft},${yTop}H${xLeft}${breakLine(xLeft, yTop, surfaceY, -1)}H${oLeft}Z`,\n `M${oRight},${yTop}H${xRight}${breakLine(xRight, yTop, surfaceY, 1)}H${oRight}Z`,\n ],\n };\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\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 Centralizer,\n Fracture,\n HoleFill,\n Lithology,\n PumpInstallation,\n Reduction,\n SurfaceCase,\n Units,\n WellCase,\n WellScreen,\n} from '@welldot/core';\nimport {\n CEMENT_PAD_TYPES,\n CENTRALIZER_TYPES,\n CONSTRUCTION_MATERIALS,\n SCREEN_SLOT_TYPES,\n getVocabLabel,\n powerFromCanonical,\n} from '@welldot/core';\nimport { formatNumber } from '@welldot/utils';\nimport type {\n ComponentsClassNames,\n SvgSelection,\n TooltipKey,\n TooltipLabels,\n} from '~/types/render.types';\nimport {\n formatDiameter,\n formatLength,\n getDiameterUnit,\n getLengthUnit,\n} from '~/utils/format.utils';\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\ntype CachedTooltips = Record<\n string,\n D3Tip | { show: () => void; hide: () => void }\n>;\n\nconst _tooltipCache = new WeakMap<\n Element,\n { signature: string; tooltips: CachedTooltips }\n>();\n\n/**\n * Initialises d3-tip tooltip instances for each well component, respecting the\n * `tooltipConfig` allow-list. Caches instances per SVG element to prevent\n * duplicate DOM nodes on re-render, but only while `units`/`tooltipConfig`/\n * `labels`/`locale` are unchanged — a redraw after any of those change (e.g.\n * the user switches unit or language) regenerates the tooltip content instead\n * of returning stale HTML from the first render.\n */\nexport const populateTooltips = (\n svg: SvgSelection,\n customClasses: ComponentsClassNames,\n units: Units,\n tooltipConfig: TooltipKey[] | false | undefined,\n labels: TooltipLabels,\n locale: 'en' | 'pt',\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 const signature = JSON.stringify({ units, tooltipConfig, labels, locale });\n const cached = svgEl ? _tooltipCache.get(svgEl) : undefined;\n if (cached && cached.signature === signature) {\n return cached.tooltips;\n }\n\n const material = (value: string) =>\n getVocabLabel(CONSTRUCTION_MATERIALS, value, locale);\n\n const tipsText = {\n geology: (_: unknown, d: Lithology) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.geology.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>\n ${d.geologic_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.geology.geologicUnit}</strong> ${esc(d.geologic_unit)}</span>` : ''}\n ${d.aquifer_unit ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.geology.aquiferUnit}</strong> ${esc(d.aquifer_unit)}</span>` : ''}\n `,\n hole: (_: unknown, d: BoreHole) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.hole.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n `,\n surfaceCase: (_: unknown, d: SurfaceCase) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.surfaceCase.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n `,\n holeFill: (_: unknown, d: HoleFill) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.holeFill.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong>${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.description}</strong> ${esc(d.description)}\n </span>\n `,\n wellCase: (_: unknown, d: WellCase) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.wellCase.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(material(d.type))}</span>\n `,\n wellScreen: (_: unknown, d: WellScreen) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.wellScreen.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.wellScreen.material}</strong> ${esc(material(d.type))}</span>\n ${d.slot_type ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.wellScreen.slotType}</strong> ${esc(getVocabLabel(SCREEN_SLOT_TYPES, d.slot_type, locale))}</span>` : ''}\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.wellScreen.slot}</strong> ${esc(formatNumber(d.screen_slot, { maximumFractionDigits: 2, locale }))} mm\n </span>\n `,\n reduction: (_: unknown, d: Reduction) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.reduction.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diam_from, units.diameter, locale))} → ${esc(formatDiameter(d.diam_to, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(material(d.type))}</span>\n `,\n centralizer: (_: unknown, d: Centralizer & { depth: number }) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.centralizer.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\"><strong>${labels.centralizer.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n ${d.from !== d.to ? `<span class=\"${customClasses.tooltip.secondaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ''}\n ${d.spacing ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.centralizer.spacing}</strong> ${esc(formatLength(d.spacing, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ''}\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.type}</strong> ${esc(getVocabLabel(CENTRALIZER_TYPES, d.type, locale))}</span>\n ${d.diameter ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.diameter}</strong> ${esc(formatDiameter(d.diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}</span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ''}\n `,\n pump: (_: unknown, d: PumpInstallation) => {\n const typeLabel =\n (labels.pump as Record<string, string>)[`type_${d.type}`] ?? d.type;\n const model = [d.manufacturer, d.model].filter(Boolean).join(' ');\n return `\n <span class=\"${customClasses.tooltip.title}\">${labels.pump.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${esc(typeLabel)}</span>\n ${d.intake_depth !== undefined ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.pump.intakeDepth}</strong> ${esc(formatLength(d.intake_depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ''}\n ${model ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.pump.model}</strong> ${esc(model)}</span>` : ''}\n ${d.rated_power !== undefined ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.pump.power}</strong> ${esc(formatNumber(powerFromCanonical(d.rated_power, units.power ?? 'kW'), { maximumFractionDigits: 2, locale }))} ${esc(units.power ?? 'kW')}</span>` : ''}\n ${d.riser_diameter !== undefined ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.pump.riser}</strong> ${esc(formatDiameter(d.riser_diameter, units.diameter, locale))} ${esc(getDiameterUnit(units.diameter, locale))}${d.riser_material ? ` · ${esc(material(d.riser_material))}` : ''}</span>` : ''}\n `;\n },\n conflict: (_: unknown, d: { from: number; to: number }) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.conflict.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n `,\n fracture: (_: unknown, d: Fracture) => {\n const title = d.swarm\n ? labels.fracture.titleSwarm\n : labels.fracture.title;\n return `\n <span class=\"${customClasses.tooltip.title}\">${title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\"><strong>${labels.fracture.depth}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.waterIntake}</strong> ${esc(formatLength(d.depth, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>` : ''}\n ${typeof d.dip === 'number' ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.dip}</strong> ${esc(d.dip)}°</span>` : ''}\n ${typeof d.azimuth === 'number' ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.fracture.azimuth}</strong> ${esc(d.azimuth)}°</span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</strong> ${esc(d.description)}</span>` : ''}\n `;\n },\n cementPad: (_: unknown, d: CementPad) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.cementPad.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${esc(getVocabLabel(CEMENT_PAD_TYPES, d.type, locale))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.cementPad.thickness}</strong>\n ${esc(formatLength(d.thickness, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.cementPad.width}</strong> ${esc(formatLength(d.width, units.length, locale))} ${esc(getLengthUnit(units.length))}\n </span>\n <span class=\"${customClasses.tooltip.secondaryInfo}\">\n <strong>${labels.cementPad.length}</strong> ${esc(formatLength(d.length, units.length, locale))} ${esc(getLengthUnit(units.length))}\n </span>\n `,\n cave: (_: unknown, d: Cave) => `\n <span class=\"${customClasses.tooltip.title}\">${labels.cave.title}</span>\n <span class=\"${customClasses.tooltip.primaryInfo}\">${labels.common.from} ${esc(formatLength(d.from, units.length, locale))} ${esc(getLengthUnit(units.length))} ${labels.common.to} ${esc(formatLength(d.to, units.length, locale))} ${esc(getLengthUnit(units.length))}</span>\n ${d.water_intake ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.cave.waterIntake}</strong></span>` : ''}\n ${d.description ? `<span class=\"${customClasses.tooltip.secondaryInfo}\"><strong>${labels.common.description}</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] = (d3tip as unknown as () => D3Tip)()\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, { signature, tooltips });\n\n return tooltips;\n};\n","import type { Lithology } from '@welldot/core';\nimport type {\n AnnotationData,\n DrawContext,\n LithologyLabelItem,\n} from '~/types/render.types';\nimport { formatLength, getLengthUnit } from '~/utils/format.utils';\nimport { getLithologyFill, 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 /** Bold line under the header (`'units'`). */\n unit?: string;\n /** Italic line after the description (`'units'`). */\n aquifer?: string;\n /** Layer drawn as a swatch before the header (`'swatch'`). */\n swatch?: Lithology;\n /** Rule style above the annotation (`'rules'`). */\n rule?: 'solid' | 'dashed';\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 | LithologyLabelItem[] | undefined,\n): Set<LithologyLabelItem> {\n if (cfg === false) return new Set();\n if (!cfg || cfg === true)\n return new Set(['depth', 'description', 'dividers']);\n return new Set(cfg);\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 = `${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`;\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 const continuation = s.continuation;\n data.lithology\n .filter(d => d.from < ctx.depthTo)\n .forEach(d => {\n const range = `${formatLength(d.from, ctx.units.length, ctx.locale)}–${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)}`;\n const continues = continuation?.active && d.from < ctx.depthFrom;\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: continues ? `↑ ${continuation.prefix} · ${range}` : range,\n description: continues ? '' : d.description || '',\n ...(show.has('units')\n ? {\n unit: d.geologic_unit || undefined,\n aquifer: continues ? undefined : d.aquifer_unit || undefined,\n }\n : {}),\n ...(show.has('swatch') && !continues ? { swatch: d } : {}),\n ...(show.has('rules')\n ? { rule: continues ? 'dashed' : 'solid' }\n : {}),\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\n ? (ctx.renderConfig.labels.typeLabels?.fractureWater ??\n 'fratura aberta')\n : (ctx.renderConfig.labels.typeLabels?.fracture ?? '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: `${formatLength(d.depth, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} · ${typeLabel}`,\n description: d.description || '',\n ...(show.has('rules') ? { rule: 'dashed' as const } : {}),\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\n ? (ctx.renderConfig.labels.typeLabels?.caveWater ?? 'caverna úmida')\n : (ctx.renderConfig.labels.typeLabels?.cave ?? '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: `${formatLength(d.from, ctx.units.length, ctx.locale)}–${formatLength(d.to, ctx.units.length, ctx.locale)}${getLengthUnit(ctx.units.length)} · ${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 // Leave the top line to the overlap label of a repeated band.\n let currY = ctx.repeatedTo != null ? s.stackingLineHeight + 2 : 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 = show.has('units')\n ? item.description\n ? wrapText(item.description, charsPerLine).length\n : 0\n : Math.ceil((item.description.length || 1) / charsPerLine);\n const extraLines = (item.unit ? 1 : 0) + (item.aquifer ? 1 : 0);\n const estH = (1 + descLines + extraLines) * 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 const swatchFill = labelPositions.some(p => p.item.swatch)\n ? getLithologyFill(data.lithology, ctx.svg, ctx.theme.lithologyTexture)\n : null;\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 if (item.rule) {\n labelG\n .append('line')\n .attr('x1', 0)\n .attr('x2', s.descriptionMaxWidth)\n .attr('y1', 0)\n .attr('y2', 0)\n .attr('stroke', ctx.theme.labels.color)\n .attr(\n 'stroke-width',\n item.rule === 'solid' ? 0.8 : ctx.theme.labels.dividerStrokeWidth,\n )\n .attr(\n 'stroke-dasharray',\n item.rule === 'solid'\n ? null\n : ctx.theme.labels.dividerStrokeDasharray,\n );\n }\n\n let headerX = 0;\n if (item.swatch && swatchFill) {\n const size = lineH * 0.75;\n labelG\n .append('rect')\n .attr('x', 0)\n .attr('y', lineH * 0.85 - size + 1)\n .attr('width', size)\n .attr('height', size)\n .attr('fill', swatchFill(item.swatch))\n .attr('stroke', ctx.theme.lithology.stroke)\n .attr('stroke-width', 0.5);\n headerX = size + 3;\n }\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', headerX)\n .attr('y', lineH * 0.85)\n .attr('font-size', st.fontSize)\n .text(item.header);\n\n let lineY = lineH * 0.85 + lineH;\n if (item.unit) {\n labelG\n .append('text')\n .attr('class', 'wp-annotation-unit')\n .attr('fill', ctx.theme.labels.color)\n .attr('font-weight', st.headerFontWeight ?? 600)\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', 0)\n .attr('y', lineY)\n .attr('font-size', st.fontSize)\n .text(item.unit);\n lineY += lineH;\n }\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', lineY)\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 lineY += lines.length * lineH;\n }\n\n if (item.aquifer) {\n labelG\n .append('text')\n .attr('class', 'wp-annotation-aquifer')\n .attr('fill', ctx.theme.labels.bodyColor)\n .attr('font-style', 'italic')\n .attr('font-family', ctx.theme.labels.bodyFont ?? 'sans-serif')\n .attr('x', 0)\n .attr('y', lineY)\n .attr('font-size', st.fontSize)\n .text(item.aquifer);\n }\n });\n }\n}\n","import * as d3 from 'd3';\n\nimport { Cave } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { mergeEnter } from '~/utils/d3.utils';\nimport { makeIntervalKey } from '~/utils/key.utils';\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. An empty `data` removes the\n * caves already drawn.\n */\nexport function drawCaves(ctx: DrawContext, data: Cave[]): void {\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 const rc = renderConfig.caves;\n\n const groups = cavesGroup\n .selectAll(`g.${classes.caves.item}`)\n .data(data, makeIntervalKey('cave'));\n\n groups.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const entered = groups\n .enter()\n .append('g')\n .attr('class', classes.caves.item)\n .style('cursor', 'pointer')\n .on('mouseover', tooltips.cave.show)\n .on('mouseout', tooltips.cave.hide)\n .style('opacity', 0);\n\n const merged = mergeEnter(entered, groups);\n\n merged.each(function (cave) {\n const g = d3.select(this);\n g.selectAll('*').remove();\n\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;\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 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 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 merged.transition(ctx.transition).style('opacity', 1);\n}\n","/**\n * Factory for D3 key functions on interval features (`from`/`to`).\n * Format: `${type}:${from}:${to}:${i}` — type scopes the key,\n * coordinates provide semantic stability, index breaks ties for\n * features sharing identical depth positions.\n *\n * Accepts `unknown` datum so the returned function is compatible with\n * both typed and untyped D3 selections without extra casts at call sites.\n */\nexport const makeIntervalKey =\n (type: string) =>\n (d: unknown, _i: number): string => {\n const { key, from, to } = d as {\n key?: string | number;\n from: number;\n to: number;\n };\n return key ? `${key}` : `${type}:${from}:${to}`;\n };\n\n/**\n * Factory for D3 key functions on point features (`depth`).\n * Format: `${type}:${depth}:${i}`.\n */\nexport const makePointKey =\n (type: string) =>\n (d: unknown, i: number): string => {\n const { key, depth } = d as {\n key?: string | number;\n depth: number;\n };\n return key ? `${key}` : `${type}:${depth}:${i}`;\n };\n","import * as d3 from 'd3';\n\nimport type { Centralizer, Constructive } from '@welldot/core';\nimport { getCentralizerDepths, getProfileDiamValues } from '@welldot/utils';\nimport type { DrawContext } from '~/types/render.types';\nimport { diameterAt, type Interval } from '~/utils/construction.geometry';\n\n/** A single centralizer position, carrying its source entry for tooltips. */\nexport type CentralizerMarker = Centralizer & { depth: number };\n\n/**\n * Renders centralizers as bow-shaped markers on both sides of the casing or\n * screen string, spanning the annulus up to the centralizer's outer diameter\n * (or the borehole wall when `diameter` is absent). Positions are derived by\n * `getCentralizerDepths`. Safe to call on every zoom event — markers are\n * joined by depth and repositioned without transitions.\n */\nexport function drawCentralizers(ctx: DrawContext, data: Constructive): void {\n const group = ctx.groups.centralizerGroup;\n const cls = ctx.classes.centralizer;\n\n const maxXValue = d3.max(getProfileDiamValues(ctx.constructionData)) || 0;\n const xScale = d3\n .scaleLinear()\n .domain([0, maxXValue])\n .range([0, ctx.POCO_WIDTH]);\n\n // Pipe and borehole diameters come from the full profile so a marker near a\n // panel boundary still finds the interval it sits in.\n const pipes: Interval[] = [\n ...ctx.constructionData.well_case,\n ...ctx.constructionData.well_screen,\n ];\n const holes: Interval[] = ctx.constructionData.bore_hole;\n\n const markers: CentralizerMarker[] = (data.centralizers ?? []).flatMap(c =>\n getCentralizerDepths(c)\n // exclusive upper bound: depthTo is the start of the next panel\n .filter(depth => depth >= ctx.depthFrom && depth < ctx.depthTo)\n .map(depth => ({ ...c, depth })),\n );\n\n const halfH = ctx.renderConfig.construction.centralizer.markerHalfHeight;\n\n const bowPoints = (m: CentralizerMarker, side: -1 | 1): string => {\n const outerD = m.diameter ?? diameterAt(holes, m.depth) ?? maxXValue;\n const pipeD = diameterAt(pipes, m.depth) ?? outerD * 0.75;\n const pipeX = (ctx.POCO_CENTER + side * xScale(pipeD)) / 2;\n const outerX = (ctx.POCO_CENTER + side * xScale(outerD)) / 2;\n const y = ctx.yScale(m.depth);\n return `${pipeX},${y - halfH} ${outerX},${y} ${pipeX},${y + halfH}`;\n };\n\n const selection = group\n .selectAll<SVGGElement, CentralizerMarker>(`g.${cls.item}`)\n .data(markers, d => `${d.from}:${d.to}:${d.depth}`);\n\n selection.exit().remove();\n\n const entered = selection\n .enter()\n .append('g')\n .attr('class', cls.item)\n .on('mouseover', ctx.tooltips.centralizer.show)\n .on('mouseout', ctx.tooltips.centralizer.hide);\n\n entered.append('polyline').attr('class', `${cls.item}-left`);\n entered.append('polyline').attr('class', `${cls.item}-right`);\n\n const merged = entered.merge(selection);\n\n merged\n .selectAll<SVGPolylineElement, CentralizerMarker>('polyline')\n .attr('fill', ctx.theme.centralizer.fill)\n .attr('stroke', ctx.theme.centralizer.stroke)\n .attr('stroke-width', ctx.theme.centralizer.strokeWidth)\n .attr('stroke-linejoin', 'round');\n\n merged.each((d, i, nodes) => {\n const g = d3.select(nodes[i]);\n g.select(`.${cls.item}-left`).attr('points', bowPoints(d, -1));\n g.select(`.${cls.item}-right`).attr('points', bowPoints(d, 1));\n });\n}\n","import type { Fracture, Lithology } from '@welldot/core';\n\n/**\n * Topmost depth (m) the profile draws: `0` (the surface), or above it when\n * a casing, screen or surface case starts at a negative depth (pipe\n * stick-up above the ground).\n */\nexport function getProfileTopDepth(profile: {\n surface_case?: { from: number }[];\n well_case?: { from: number }[];\n well_screen?: { from: number }[];\n}): number {\n return Math.min(\n 0,\n ...[\n ...(profile.surface_case ?? []),\n ...(profile.well_case ?? []),\n ...(profile.well_screen ?? []),\n ]\n .map(i => i.from)\n .filter(Number.isFinite),\n );\n}\n\n/**\n * Depth window `[from, to]` of each panel. When every panel has a\n * `depthRange` those are used as they are; otherwise the depth\n * `[topDepth, total]` is split in proportion to the panel heights, back to\n * back. `topDepth` (default `0`) is negative when pipes stick up above the\n * ground (see {@link getProfileTopDepth}).\n */\nexport function resolvePanelWindows(\n panels: { height: number; depthRange?: [number, number] }[],\n totalDepth: number,\n topDepth = 0,\n): [number, number][] {\n if (panels.length > 0 && panels.every(p => p.depthRange)) {\n return panels.map(p => [p.depthRange![0], p.depthRange![1]]);\n }\n if (panels.length === 1) return [[topDepth, totalDepth]];\n\n const totalHeight = panels.reduce((s, p) => s + p.height, 0) || 1;\n const metersPerPx = (totalDepth - topDepth) / totalHeight;\n let current = topDepth;\n return panels.map(p => {\n const from = current;\n current = from + p.height * metersPerPx;\n return [from, current];\n });\n}\n\n/** X positions (SVG coordinates) of the column titles. */\nexport type ColumnHeaderPositions = {\n /** Right edge of the depth title, over the axis tick labels. */\n depth: number;\n /** Center of the lithology column. */\n lithology: number;\n /** Center of the construction column. */\n construction: number;\n /** Left edge of the description column, when annotations are drawn. */\n description?: number;\n};\n\n/**\n * Column title positions from the panel geometry. `geoXLeft`, `geoXRight`\n * and `pocoCenterX` are in geologic-group coordinates (offset by\n * `marginLeft`), like the renderers use them.\n */\nexport function getColumnHeaderPositions(geometry: {\n marginLeft: number;\n geoXLeft: number;\n geoXRight: number;\n pocoCenterX: number;\n descriptionX?: number;\n}): ColumnHeaderPositions {\n const { marginLeft, geoXLeft, geoXRight, pocoCenterX, descriptionX } =\n geometry;\n return {\n depth: marginLeft - 2,\n lithology: marginLeft + (geoXLeft + geoXRight) / 2,\n construction: marginLeft + pocoCenterX,\n ...(descriptionX != null ? { description: marginLeft + descriptionX } : {}),\n };\n}\n\n/** A lithology marker: the layer's 1-based index and its visible depths. */\nexport type LithologyMarker = { index: number; from: number; to: number };\n\n/**\n * One marker per lithology layer visible in `[depthFrom, depthTo]`,\n * numbered by the layer's position in the whole list (so a layer keeps its\n * number on every panel it crosses).\n */\nexport function getLithologyMarkers(\n lithology: Pick<Lithology, 'from' | 'to'>[],\n depthFrom: number,\n depthTo: number,\n): LithologyMarker[] {\n const markers: LithologyMarker[] = [];\n lithology.forEach((layer, i) => {\n const from = Math.max(layer.from, depthFrom);\n const to = Math.min(layer.to, depthTo);\n if (to > from) markers.push({ index: i + 1, from, to });\n });\n return markers;\n}\n\n/**\n * `F{n}` marker for each fracture in `[depthFrom, depthTo)`, numbered by\n * position in the whole list.\n */\nexport function getFractureMarkers(\n fractures: Pick<Fracture, 'depth'>[],\n depthFrom: number,\n depthTo: number,\n): { label: string; depth: number }[] {\n const markers: { label: string; depth: number }[] = [];\n fractures.forEach((f, i) => {\n if (f.depth >= depthFrom && f.depth < depthTo) {\n markers.push({ label: `F${i + 1}`, depth: f.depth });\n }\n });\n return markers;\n}\n\n/**\n * Maps depths onto the overview column: `[0, totalDepth]` → `[0, height]`.\n * `window` is the y/height of the panel's `[depthFrom, depthTo]`.\n */\nexport function getOverviewGeometry(\n totalDepth: number,\n height: number,\n depthFrom: number,\n depthTo: number,\n): { y: (depth: number) => number; window: { y: number; height: number } } {\n const ratio = totalDepth > 0 ? height / totalDepth : 0;\n const y = (depth: number) => Math.min(height, Math.max(0, depth * ratio));\n return {\n y,\n window: { y: y(depthFrom), height: Math.max(1, y(depthTo) - y(depthFrom)) },\n };\n}\n\n/** Replaces `{range}` in an overlap label template. */\nexport function formatOverlapLabel(template: string, range: string): string {\n return template.replace('{range}', range);\n}\n","import type { DrawContext } from '~/types/render.types';\nimport { getColumnHeaderPositions } from '~/utils/layout.utils';\n\n/** Whether lithology description annotations are drawn with this config. */\nexport function hasDescriptionColumn(ctx: DrawContext): boolean {\n const { active, lithology } = ctx.renderConfig.labels;\n if (active === false) return false;\n if (Array.isArray(active) && !active.includes('lithology')) return false;\n if (lithology === false) return false;\n return !Array.isArray(lithology) || lithology.includes('description');\n}\n\n/**\n * Draws the column titles (depth, lithology, construction and, when\n * annotations are drawn, description) in the top margin, over a rule just\n * above the drawing area. No-op unless `renderConfig.columnHeaders.active`.\n */\nexport function drawColumnHeaders(ctx: DrawContext): void {\n const group = ctx.groups.columnHeadersGroup;\n group.selectAll('*').remove();\n\n const cfg = ctx.renderConfig.columnHeaders;\n if (!cfg.active) return;\n\n const theme = ctx.theme.columnHeaders;\n const { margins } = ctx.state;\n const positions = getColumnHeaderPositions({\n marginLeft: margins.left,\n geoXLeft: ctx.geoXLeft,\n geoXRight: ctx.geoXRight,\n pocoCenterX: ctx.pocoCenterX,\n descriptionX: hasDescriptionColumn(ctx)\n ? ctx.geoXRight + ctx.renderConfig.labels.descriptionXOffset\n : undefined,\n });\n\n // Above the cement pad, which sits on the surface line of the first panel.\n const ruleY =\n margins.top - 2 - ctx.renderConfig.construction.cementPad.height;\n const textY = ruleY - 4;\n\n const addText = (x: number, text: string, anchor: string) =>\n group\n .append('text')\n .attr('class', ctx.classes.columnHeaders.text)\n .attr('x', x)\n .attr('y', textY)\n .attr('text-anchor', anchor)\n .attr('font-size', theme.fontSize)\n .attr('font-family', theme.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.fontWeight ?? 600)\n .attr('fill', theme.color)\n .text(text);\n\n addText(positions.depth, cfg.labels.depth, 'end');\n addText(positions.lithology, cfg.labels.lithology, 'middle');\n addText(positions.construction, cfg.labels.construction, 'middle');\n if (positions.description != null) {\n addText(positions.description, cfg.labels.description, 'start');\n }\n\n const overview = ctx.renderConfig.overview;\n group\n .append('line')\n .attr('class', ctx.classes.columnHeaders.rule)\n .attr('x1', overview.active ? overview.x : 0)\n .attr('x2', ctx.svgWidth)\n .attr('y1', ruleY)\n .attr('y2', ruleY)\n .attr('stroke', theme.ruleStroke)\n .attr('stroke-width', theme.ruleStrokeWidth);\n}\n","import * as d3 from 'd3';\n\nimport type { WellCase, WellScreen } from '@welldot/core';\nimport { CONSTRUCTION_MATERIALS, getVocabLabel } 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) =>\n formatDiameter(mm, ctx.units.diameter, ctx.locale);\n const dUnit = getDiameterUnit(ctx.units.diameter, ctx.locale);\n const material = (value: string) =>\n getVocabLabel(CONSTRUCTION_MATERIALS, value, ctx.locale);\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 onRight = clc.side === 'right';\n const continuation = ctx.renderConfig.labels.continuation;\n\n const placeLabel = (d: WellCase | WellScreen, label: 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 text =\n continuation?.active && d.from < ctx.depthFrom ? `↑ ${label}` : label;\n const midY = ctx.yScale((clampedFrom + clampedTo) / 2);\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 // `left`: the box ends xOffset px left of the item's own wall.\n // `right`: every box starts xOffset px right of the construction column.\n const labelRightX = onRight\n ? (ctx.POCO_CENTER + ctx.POCO_WIDTH) / 2 + clc.xOffset + boxW\n : (ctx.POCO_CENTER - xScale(d.diameter)) / 2 - clc.xOffset;\n\n const labelH = lines.length * lineH + vertPad;\n // Right-side labels hang from the item's top, like a column of notes.\n let labelY = onRight ? ctx.yScale(clampedFrom) + 1 : 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', onRight ? labelRightX - boxW + 4 : 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', onRight ? 'start' : 'end')\n .attr('fill', clct.labelColor ?? '#303030');\n\n lines.forEach((line, i) => {\n textEl\n .append('tspan')\n .attr('x', onRight ? labelRightX - boxW + 4 : 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} ${material(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} ${material(d.type)} ${clc.labels.wellScreenSlotPrefix} ${fmtD((d as WellScreen).screen_slot)}${dUnit}`,\n ),\n );\n}\n","import type { BaseType, Selection } from 'd3';\nimport * as d3 from 'd3';\n\nimport type {\n CementPad,\n Constructive,\n HoleFill,\n Reduction,\n} from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { Conflict, DrawContext, SvgSelection } from '~/types/render.types';\nimport {\n annulusFillPath,\n boreHoleOutlinePath,\n diameterAt,\n getCementPadGeometry,\n getIntervalEnds,\n getPadDiameters,\n holeFillOutlinePath,\n type Interval,\n type OutlineScales,\n pipeWallsPath,\n screenEndPath,\n shoePath,\n} from '~/utils/construction.geometry';\nimport { mergeEnter, withTransition } from '~/utils/d3.utils';\nimport { makeIntervalKey } from '~/utils/key.utils';\nimport {\n getConflictAreas,\n getYAxisFunctions,\n mergeConflicts,\n} from '~/utils/render.utils';\n\ntype Tooltip = { show: (...args: never[]) => void; hide: () => void };\n\n/** Items appended by the current draw; their outlines start collapsed. */\nconst entering = new WeakSet<Element>();\n\n/** x-scale (diameter mm → px) shared by every construction layer. */\nfunction constructionXScale(ctx: DrawContext) {\n const max = d3.max(getProfileDiamValues(ctx.constructionData)) || 0;\n return d3.scaleLinear().domain([0, max]).range([0, ctx.POCO_WIDTH]);\n}\n\n/** Outline scales for `ctx`, clamped to the panel's depth window. */\nfunction outlineScales(ctx: DrawContext): OutlineScales {\n const x = constructionXScale(ctx);\n return {\n y: ctx.yScale,\n left: d => (ctx.POCO_CENTER - x(d)) / 2,\n right: d => (ctx.POCO_CENTER + x(d)) / 2,\n depthFrom: ctx.depthFrom,\n depthTo: ctx.depthTo,\n };\n}\n\n/** Surface case diameter as drawn: padded so it shows outside the casing. */\nconst surfaceCaseDiameter = (ctx: DrawContext, diameter: number) =>\n diameter *\n (1 + ctx.renderConfig.construction.surfaceCase.diameterPaddingRatio);\n\n/**\n * Joins one interval layer as `g.<cls>` items, each holding a fill (a rect,\n * or an even-odd path when `pathFill` is set), an open outline path and,\n * when `shoe` is set, a shoe path. Geometry is set by\n * {@link layoutConstruction}; entering items start collapsed at their top\n * so the layout transition grows them.\n */\nfunction joinIntervalLayer<T extends { from: number; to: number }>(\n ctx: DrawContext,\n group: SvgSelection,\n cls: string,\n data: T[],\n key: string,\n tooltip: Tooltip,\n { shoe = false, pathFill = false, ends = false } = {},\n): Selection<SVGGElement, T, BaseType, unknown> {\n const sel = group\n .selectAll<SVGGElement, T>(`g.${cls}`)\n .data(data, makeIntervalKey(key));\n\n sel.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const top = (d: T) => ctx.yScale(Math.max(d.from, ctx.depthFrom));\n const entered = sel\n .enter()\n .append('g')\n .attr('class', cls)\n .each((_d, i, nodes) => entering.add(nodes[i]!))\n .on('mouseover', tooltip.show as never)\n .on('mouseout', tooltip.hide);\n if (pathFill)\n entered\n .append('path')\n .attr('class', `${cls}-fill`)\n .attr('stroke', 'none')\n .attr('fill-rule', 'evenodd')\n .attr('d', '');\n else\n entered\n .append('rect')\n .attr('class', `${cls}-fill`)\n .attr('stroke', 'none')\n .attr('y', top)\n .attr('height', 0);\n entered\n .append('path')\n .attr('class', `${cls}-outline`)\n .attr('fill', 'none')\n .attr('d', '');\n if (shoe)\n entered\n .append('path')\n .attr('class', `${cls}-shoe`)\n .attr('stroke-linejoin', 'round')\n .attr('d', '');\n if (ends)\n entered\n .append('path')\n .attr('class', `${cls}-ends`)\n .attr('fill', 'none')\n .attr('d', '');\n\n return entered.merge(sel);\n}\n\n/**\n * Renders the cement pad as two slabs cast around the casing at the\n * surface, covering the surface case and annulus, with break lines at the outer ends (see\n * `getCementPadGeometry`). Paths only, so the generic rect rescale on zoom\n * never touches it; safe to call on every zoom event.\n */\nexport function drawCementPad(\n ctx: DrawContext,\n pad: CementPad | undefined,\n): void {\n const cls = ctx.classes.cementPad.item;\n // On the panel that holds the surface (it may start above it, at a stick-up).\n const visible = !!pad?.thickness && ctx.depthFrom <= 0 && ctx.depthTo > 0;\n const sel = ctx.groups.cementPadGroup\n .selectAll<SVGGElement, CementPad>(`g.${cls}`)\n .data(visible ? [pad!] : [], () => 'cement_pad');\n\n sel.exit().remove();\n if (!visible) return;\n\n const entered = sel\n .enter()\n .append('g')\n .attr('class', cls)\n .on('mouseover', ctx.tooltips.cementPad.show)\n .on('mouseout', ctx.tooltips.cementPad.hide);\n entered.append('path').attr('class', `${cls}-slab`);\n entered.append('path').attr('class', `${cls}-slab`);\n\n const x = constructionXScale(ctx);\n const { opening, outer } = getPadDiameters(\n ctx.constructionData,\n ctx.renderConfig.construction.surfaceCase.diameterPaddingRatio,\n );\n const { slabs } = getCementPadGeometry(\n ctx.POCO_WIDTH,\n ctx.POCO_CENTER,\n ctx.yScale(0),\n ctx.renderConfig.construction.cementPad,\n x(opening),\n x(outer),\n );\n\n entered\n .merge(sel)\n .selectAll<SVGPathElement, unknown>('path')\n .attr('d', (_d, i) => slabs[i] ?? '')\n .attr('fill', ctx.textures.pad.url())\n .attr('stroke', ctx.theme.cementPad.stroke)\n .attr('stroke-width', ctx.theme.cementPad.strokeWidth)\n .attr('stroke-linejoin', 'round');\n}\n\n/**\n * Sets the geometry of every drawn construction item from `ctx.yScale`:\n * fill rects, open outlines, casing shoes and reductions. `drawConstructive`\n * calls it with `animate` (shared transition; items it just appended grow\n * from their top); the zoom handler calls it with a rescaled `ctx` and no\n * transition.\n */\nexport function layoutConstruction(ctx: DrawContext, animate = false): void {\n const c = ctx.classes;\n const scales = outlineScales(ctx);\n const data = ctx.constructionData;\n\n // Selection and Transition share `.attr`; one cast lets callers ignore which.\n const motion = <GEl extends Element, D>(\n sel: Selection<GEl, D, BaseType, unknown>,\n ) =>\n (animate\n ? withTransition(sel, ctx.transition)\n : sel) as unknown as Selection<GEl, D, BaseType, unknown>;\n\n const yTop = (d: { from: number }) =>\n ctx.yScale(Math.max(d.from, ctx.depthFrom));\n const yBottom = (d: { to: number }) =>\n ctx.yScale(Math.min(d.to, ctx.depthTo));\n\n /** Scales that map every depth to the item's top: the collapsed shape. */\n const collapsed = (d: { from: number }): OutlineScales => ({\n ...scales,\n y: () => yTop(d),\n });\n\n /**\n * Sets `attr` of each item's `part` from `shape`. Parts of items this draw\n * appended first take their collapsed shape, so the transition grows them.\n */\n const shapeParts = <T extends { from: number }>(\n items: Selection<SVGGElement, T, BaseType, unknown>,\n part: string,\n attr: string,\n shape: (d: T, s: OutlineScales) => string,\n ) => {\n const parts = items.select<SVGElement>(part);\n if (animate)\n parts\n .filter(function () {\n return entering.has(this.parentNode as Element);\n })\n .attr(attr, d => shape(d, collapsed(d)));\n motion(parts).attr(attr, d => shape(d, scales));\n };\n\n /**\n * Lays out one `joinIntervalLayer` layer. `fill` shapes a path fill;\n * without it the fill is a rect `diameter` wide.\n */\n const layoutLayer = (\n group: SvgSelection,\n cls: string,\n diameter: (d: Interval) => number,\n outline: (d: Interval, s: OutlineScales) => string,\n {\n shoe,\n ends,\n fill,\n }: {\n shoe?: (d: Interval, s: OutlineScales) => string;\n ends?: (d: Interval, s: OutlineScales) => string;\n fill?: (d: Interval, s: OutlineScales) => string;\n } = {},\n ) => {\n const items = group.selectAll<SVGGElement, Interval>(`g.${cls}`);\n shapeParts(items, `.${cls}-outline`, 'd', outline);\n if (shoe) shapeParts(items, `.${cls}-shoe`, 'd', shoe);\n if (ends) shapeParts(items, `.${cls}-ends`, 'd', ends);\n if (fill) {\n shapeParts(items, `.${cls}-fill`, 'd', fill);\n return;\n }\n motion(\n items\n .select<SVGRectElement>(`.${cls}-fill`)\n .attr('x', d => scales.left(diameter(d)))\n .attr(\n 'width',\n d => scales.right(diameter(d)) - scales.left(diameter(d)),\n ),\n )\n .attr('y', yTop)\n .attr('height', d => Math.max(0, yBottom(d) - yTop(d)));\n };\n\n const walls = (d: Interval, s: OutlineScales, dia = d.diameter) =>\n pipeWallsPath(\n s.left(dia),\n s.right(dia),\n s.y(Math.max(d.from, s.depthFrom)),\n s.y(Math.min(d.to, s.depthTo)),\n );\n\n layoutLayer(\n ctx.groups.holeGroup,\n c.boreHole.rect,\n d => d.diameter,\n (d, s) => boreHoleOutlinePath(d, data.bore_hole, s),\n );\n\n const pipes: Interval[] = [...data.well_case, ...data.well_screen];\n const insideSurface = [...data.bore_hole, ...data.hole_fill, ...pipes];\n const scDiameter = (d: Interval) => surfaceCaseDiameter(ctx, d.diameter);\n layoutLayer(\n ctx.groups.surfaceCaseGroup,\n c.surfaceCase.rect,\n scDiameter,\n (d, s) => walls(d, s, scDiameter(d)),\n // Only the ring outside the hole: the texture never shows under the casing.\n {\n fill: (d, s) =>\n annulusFillPath({ ...d, diameter: scDiameter(d) }, insideSurface, s),\n },\n );\n layoutLayer(\n ctx.groups.holeFillGroup,\n c.holeFill.rect,\n d => d.diameter,\n (d, s) => holeFillOutlinePath(d, pipes, s),\n { fill: (d, s) => annulusFillPath(d, pipes, s) },\n );\n\n // The string a pipe butts against: casing, screens and reductions. Taken\n // from the whole profile, so a joint just past the panel is still a joint.\n const string = [...pipes, ...(data.reduction ?? [])];\n const shoeCfg = ctx.renderConfig.construction.casingShoe;\n const endsCfg = ctx.renderConfig.construction.screenEnds;\n // Room in the annulus beside the pipe at `depth`, so marks stay off the\n // hole wall.\n const room = (d: Interval, depth: number, size: number) => {\n const hole = diameterAt(data.bore_hole, depth);\n const annulus =\n hole !== undefined && hole > d.diameter\n ? scales.left(d.diameter) - scales.left(hole) - 1\n : size;\n return Math.max(2, Math.min(size, annulus));\n };\n const shoe = (d: Interval, s: OutlineScales) => {\n const ends = getIntervalEnds(d, string, ctx.depthFrom, ctx.depthTo);\n if (!shoeCfg.active || ends.cutBottom || ends.joinedBottom) return '';\n return shoePath(\n s.left(d.diameter),\n s.right(d.diameter),\n s.y(Math.min(d.to, s.depthTo)),\n room(d, d.to, shoeCfg.size),\n );\n };\n // Screens also mark their top and base with a dashed line (not at panel\n // cuts, where the screen goes on).\n const screenEnds = (d: Interval, s: OutlineScales) => {\n if (!endsCfg.active) return '';\n const ends = getIntervalEnds(d, string, ctx.depthFrom, ctx.depthTo);\n const mark = (depth: number) =>\n screenEndPath(s.left(d.diameter), s.right(d.diameter), s.y(depth));\n return (\n (ends.cutTop ? '' : mark(d.from)) + (ends.cutBottom ? '' : mark(d.to))\n );\n };\n layoutLayer(\n ctx.groups.wellCaseGroup,\n c.wellCase.rect,\n d => d.diameter,\n walls,\n { shoe },\n );\n layoutLayer(\n ctx.groups.wellScreenGroup,\n c.wellScreen.rect,\n d => d.diameter,\n walls,\n { shoe, ends: screenEnds },\n );\n\n // Reductions: a trapezoid fill and its two slanted walls, open at both ends.\n const reductions = ctx.groups.reductionGroup.selectAll<\n SVGGElement,\n Reduction\n >(`g.${c.reduction.item}`);\n const corners = (d: Reduction, s: OutlineScales) => {\n const t = s.y(Math.max(d.from, s.depthFrom));\n const b = s.y(Math.min(d.to, s.depthTo));\n return {\n tl: `${s.left(d.diam_from)},${t}`,\n tr: `${s.right(d.diam_from)},${t}`,\n bl: `${s.left(d.diam_to)},${b}`,\n br: `${s.right(d.diam_to)},${b}`,\n };\n };\n shapeParts(reductions, `.${c.reduction.item}-fill`, 'points', (d, s) => {\n const p = corners(d, s);\n return `${p.tl} ${p.tr} ${p.br} ${p.bl}`;\n });\n shapeParts(reductions, `.${c.reduction.item}-outline`, 'd', (d, s) => {\n const p = corners(d, s);\n return `M${p.tl}L${p.bl}M${p.tr}L${p.br}`;\n });\n\n if (animate) {\n for (const group of [\n ctx.groups.holeGroup,\n ctx.groups.surfaceCaseGroup,\n ctx.groups.holeFillGroup,\n ctx.groups.wellCaseGroup,\n ctx.groups.wellScreenGroup,\n ctx.groups.reductionGroup,\n ])\n group.selectAll<SVGGElement, unknown>('g').each(function () {\n entering.delete(this);\n });\n }\n}\n\n/**\n * Renders all well construction components in order: cement pad, bore holes,\n * surface casing, hole fill, well casing, well screen, reductions and\n * conflict zones. Pipes and the borehole are drawn open: walls only, closed\n * where they physically end (casing shoe, total depth, diameter shoulders,\n * annulus interfaces), never at panel cuts or joints. The x-scale domain is\n * computed from ctx.constructionData for consistent widths across 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 const c = ctx.classes;\n const theme = ctx.theme;\n\n drawCementPad(ctx, data.cement_pad);\n\n // ── Bore hole ──────────────────────────────────────────────────────────────\n joinIntervalLayer(\n ctx,\n ctx.groups.holeGroup,\n c.boreHole.rect,\n data.bore_hole,\n 'bore_hole',\n ctx.tooltips.hole,\n )\n .attr('opacity', theme.boreHole.opacity)\n .call(g => {\n g.select(`.${c.boreHole.rect}-fill`).attr('fill', theme.boreHole.fill);\n g.select(`.${c.boreHole.rect}-outline`)\n .attr('stroke', theme.boreHole.stroke)\n .attr('stroke-width', theme.boreHole.strokeWidth)\n .attr('stroke-dasharray', theme.boreHole.strokeDasharray);\n });\n\n // ── Surface case ───────────────────────────────────────────────────────────\n joinIntervalLayer(\n ctx,\n ctx.groups.surfaceCaseGroup,\n c.surfaceCase.rect,\n data.surface_case,\n 'surface_case',\n ctx.tooltips.surfaceCase,\n { pathFill: true },\n ).call(g => {\n g.select(`.${c.surfaceCase.rect}-fill`).attr(\n 'fill',\n ctx.textures.surface_case.url(),\n );\n g.select(`.${c.surfaceCase.rect}-outline`)\n .attr('stroke', theme.surfaceCase.stroke)\n .attr('stroke-width', theme.surfaceCase.strokeWidth);\n });\n\n // ── Hole fill ──────────────────────────────────────────────────────────────\n joinIntervalLayer(\n ctx,\n ctx.groups.holeFillGroup,\n c.holeFill.rect,\n data.hole_fill,\n 'hole_fill',\n ctx.tooltips.holeFill,\n { pathFill: true },\n ).call(g => {\n g.select(`.${c.holeFill.rect}-fill`).attr('fill', (d: HoleFill) =>\n ctx.textures[d.type].url(),\n );\n g.select(`.${c.holeFill.rect}-outline`)\n .attr('stroke', theme.holeFill.stroke)\n .attr('stroke-width', theme.holeFill.strokeWidth);\n });\n\n // ── Well case and screen ───────────────────────────────────────────────────\n for (const [group, cls, items, key, tooltip, fill, stroke] of [\n [\n ctx.groups.wellCaseGroup,\n c.wellCase.rect,\n data.well_case,\n 'well_case',\n ctx.tooltips.wellCase,\n theme.wellCase.fill,\n theme.wellCase,\n ],\n [\n ctx.groups.wellScreenGroup,\n c.wellScreen.rect,\n data.well_screen,\n 'well_screen',\n ctx.tooltips.wellScreen,\n ctx.textures.well_screen.url(),\n theme.wellScreen,\n ],\n ] as const) {\n joinIntervalLayer(ctx, group, cls, items, key, tooltip, {\n shoe: true,\n ends: cls === c.wellScreen.rect,\n }).call(g => {\n g.select(`.${cls}-fill`).attr('fill', fill);\n g.select(`.${cls}-outline`)\n .attr('stroke', stroke.stroke)\n .attr('stroke-width', stroke.strokeWidth);\n g.select(`.${cls}-shoe`)\n .attr('fill', stroke.stroke)\n .attr('stroke', stroke.stroke)\n .attr('stroke-width', 0.5);\n g.select(`.${cls}-ends`)\n .attr('stroke', stroke.stroke)\n .attr('stroke-width', theme.wellScreen.endStrokeWidth)\n .attr('stroke-dasharray', theme.wellScreen.endDasharray);\n });\n }\n\n // ── Reduction ──────────────────────────────────────────────────────────────\n const reduction = ctx.groups.reductionGroup\n .selectAll<SVGGElement, Reduction>(`g.${c.reduction.item}`)\n .data(data.reduction ?? [], makeIntervalKey('reduction'));\n\n reduction.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const newReduction = reduction\n .enter()\n .append('g')\n .attr('class', c.reduction.item)\n .each((_d, i, nodes) => entering.add(nodes[i]!))\n .on('mouseover', ctx.tooltips.reduction.show)\n .on('mouseout', ctx.tooltips.reduction.hide);\n newReduction\n .append('polygon')\n .attr('class', `${c.reduction.item}-fill`)\n .attr('stroke', 'none');\n newReduction\n .append('path')\n .attr('class', `${c.reduction.item}-outline`)\n .attr('fill', 'none');\n newReduction.merge(reduction).call(g => {\n g.select(`.${c.reduction.item}-fill`).attr('fill', theme.reduction.fill);\n g.select(`.${c.reduction.item}-outline`)\n .attr('stroke', theme.reduction.stroke)\n .attr('stroke-width', theme.reduction.strokeWidth);\n });\n\n // ── Conflict zones ─────────────────────────────────────────────────────────\n // A deliberate warning: kept as a closed, hatched box.\n const mergedConflicts = mergeConflicts(\n [\n ...getConflictAreas(data.well_case, data.well_screen),\n ...getConflictAreas(data.well_screen, data.well_case),\n ],\n 1,\n );\n\n const xScale = constructionXScale(ctx);\n const yPos = getYPos as (d: unknown) => number;\n const conflict = ctx.groups.conflictGroup\n .selectAll(`.${c.conflict.rect}`)\n .data(mergedConflicts, makeIntervalKey('conflict'));\n\n conflict.exit().transition(ctx.transition).attr('height', 0).remove();\n\n const newConflict = conflict\n .enter()\n .append('rect')\n .attr('class', c.conflict.rect)\n .attr('fill', ctx.textures.conflict.url())\n .attr('stroke', theme.conflict.stroke)\n .attr('stroke-width', theme.conflict.strokeWidth)\n .on('mouseover', ctx.tooltips.conflict.show)\n .on('mouseout', ctx.tooltips.conflict.hide)\n .attr('y', yPos)\n .attr('height', 0);\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', getYPos)\n .attr('height', getHeight);\n\n layoutConstruction(ctx, true);\n}\n","import * as d3 from 'd3';\n\nimport { Fracture } from '@welldot/core';\nimport { DrawContext } from '~/types/render.types';\nimport { mergeEnter } from '~/utils/d3.utils';\nimport { makePointKey } from '~/utils/key.utils';\nimport { fractureDip, 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 * An empty `data` removes the fractures already drawn.\n */\nexport function drawFractures(ctx: DrawContext, data: Fracture[]): void {\n const {\n groups: { fracturesGroup },\n POCO_WIDTH,\n pocoCenterX,\n yScale,\n renderConfig,\n theme,\n classes,\n tooltips,\n } = ctx;\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 const groups = fracturesGroup\n .selectAll(`g.${classes.fractures.item}`)\n .data(data, makePointKey('fracture'));\n\n groups.exit().transition(ctx.transition).style('opacity', 0).remove();\n\n const entered = groups\n .enter()\n .append('g')\n .attr('class', classes.fractures.item)\n .on('mouseover', tooltips.fracture.show)\n .on('mouseout', tooltips.fracture.hide)\n .style('cursor', 'pointer')\n .style('opacity', 0);\n\n const merged = mergeEnter(entered, groups);\n\n merged.attr(\n 'transform',\n fracture =>\n `translate(0,${yScale(fracture.depth)}) rotate(${fractureDip(fracture.dip)},${pocoCenterX},0)`,\n );\n\n merged.each(function (fracture) {\n const g = d3.select(this);\n g.selectAll('*').remove();\n\n const rng = makeSeededPrng(fracture.depth, 7919);\n const hitBuffer = fracture.swarm ? rf.hitBuffer.swarm : rf.hitBuffer.single;\n\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 merged.transition(ctx.transition).style('opacity', 1);\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';\nimport { getPadDiameters } from '~/utils/construction.geometry';\nimport { getCementPadRect } from '~/utils/render.utils';\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.depthTo > 0 &&\n ctx.constructionData.cement_pad?.thickness\n ) {\n const { opening, outer } = getPadDiameters(\n ctx.constructionData,\n constructionConfig.surfaceCase.diameterPaddingRatio,\n );\n const pad = getCementPadRect(\n ctx.POCO_WIDTH,\n ctx.POCO_CENTER,\n ctx.yScale(0),\n constructionConfig.cementPad,\n xScaleConstr(opening),\n xScaleConstr(outer),\n );\n drawHighlightItem(\n ctx,\n ctx.groups.highlightsConstructionGroup as SvgSelection,\n pad.x,\n pad.y,\n pad.width,\n pad.height,\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 drawConstrHighlights(\n hl.reduction,\n ctx.constructionData.reduction.map(d => ({\n from: d.from,\n to: d.to,\n diameter: Math.max(d.diam_from, d.diam_to),\n })),\n stdX,\n stdW,\n );\n}\n","import type { Selection } from 'd3';\nimport * as d3module from 'd3';\nimport { defu } from 'defu';\n\nimport { Well } from '@welldot/core';\nimport { getCurrentPump } from '@welldot/utils';\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 {\n TexturesConfig,\n WellTextures,\n createWellTextures,\n} from '../configs/render.textures';\nimport {\n getCementPadGeometry,\n pipeWallsPath,\n screenEndPath,\n shoePath,\n} from '../utils/construction.geometry';\nimport { getConflictAreas, mergeConflicts } from '../utils/render.utils';\n\nconst d3 = { ...d3module };\n\ntype LegendLabelKey = keyof LegendRenderConfig['labels'];\n\n/**\n * One entry of a well's legend: `key` names the entry (and its label in\n * `LegendRenderConfig['labels']`), the other fields select its symbol.\n */\nexport type WellLegendItem =\n | {\n kind: 'fracture';\n key: 'fractureSingle' | 'fractureSwarm' | 'fractureWater';\n label: string;\n swarm: boolean;\n water_intake: boolean;\n }\n | {\n kind: 'cave';\n key: 'caveDry' | 'caveWet';\n label: string;\n water_intake: boolean;\n }\n | {\n kind: 'construction';\n key: ConstructionSubKind;\n label: string;\n subKind: ConstructionSubKind;\n };\n\ntype ConstructionSubKind = Exclude<\n LegendLabelKey,\n 'fractureSingle' | 'fractureSwarm' | 'fractureWater' | 'caveDry' | 'caveWet'\n>;\n\ntype LegendStyle = {\n theme: WellTheme;\n cls: ComponentsClassNames['legend'];\n textures: WellTextures;\n};\n\n// Symbol box, in px.\nconst SYMBOL_WIDTH = 24;\nconst SYMBOL_HEIGHT = 12;\n// Room around a standalone symbol for strokes and the fracture swarm's offsets.\nconst SYMBOL_MARGIN = 2;\n\n/**\n * Lists the legend entries `profile` needs, in display order, labeled from\n * `labels` (defaults to the built-in Portuguese labels).\n */\nexport function getWellLegendItems(\n profile: Well,\n labels: LegendRenderConfig['labels'] = INTERACTIVE_RENDER_CONFIG.legend\n .labels,\n): WellLegendItem[] {\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 reductions = profile.reduction ?? [];\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 hasReduction = reductions.length > 0;\n const hasCentralizer = (profile.centralizers ?? []).length > 0;\n const hasPump = getCurrentPump(profile)?.intake_depth !== undefined;\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 items: WellLegendItem[] = [];\n if (hasSimple)\n items.push({\n kind: 'fracture',\n key: 'fractureSingle',\n label: labels.fractureSingle,\n swarm: false,\n water_intake: false,\n });\n if (hasSwarm)\n items.push({\n kind: 'fracture',\n key: 'fractureSwarm',\n label: labels.fractureSwarm,\n swarm: true,\n water_intake: false,\n });\n if (hasWaterFx)\n items.push({\n kind: 'fracture',\n key: 'fractureWater',\n label: labels.fractureWater,\n swarm: false,\n water_intake: true,\n });\n if (hasCaveDry)\n items.push({\n kind: 'cave',\n key: 'caveDry',\n label: labels.caveDry,\n water_intake: false,\n });\n if (hasCaveWet)\n items.push({\n kind: 'cave',\n key: 'caveWet',\n label: labels.caveWet,\n water_intake: true,\n });\n\n if (hasCementPad)\n items.push({\n kind: 'construction',\n key: 'cementPad',\n label: labels.cementPad,\n subKind: 'cementPad',\n });\n if (hasBoreHole)\n items.push({\n kind: 'construction',\n key: 'boreHole',\n label: labels.boreHole,\n subKind: 'boreHole',\n });\n if (hasSurfaceCase)\n items.push({\n kind: 'construction',\n key: 'surfaceCase',\n label: labels.surfaceCase,\n subKind: 'surfaceCase',\n });\n if (hasHoleFillGravel)\n items.push({\n kind: 'construction',\n key: 'holeFillGravel',\n label: labels.holeFillGravel,\n subKind: 'holeFillGravel',\n });\n if (hasHoleFillSeal)\n items.push({\n kind: 'construction',\n key: 'holeFillSeal',\n label: labels.holeFillSeal,\n subKind: 'holeFillSeal',\n });\n if (hasWellCase)\n items.push({\n kind: 'construction',\n key: 'wellCase',\n label: labels.wellCase,\n subKind: 'wellCase',\n });\n if (hasWellScreen)\n items.push({\n kind: 'construction',\n key: 'wellScreen',\n label: labels.wellScreen,\n subKind: 'wellScreen',\n });\n if (hasReduction)\n items.push({\n kind: 'construction',\n key: 'reduction',\n label: labels.reduction,\n subKind: 'reduction',\n });\n if (hasCentralizer)\n items.push({\n kind: 'construction',\n key: 'centralizer',\n label: labels.centralizer,\n subKind: 'centralizer',\n });\n if (hasPump)\n items.push({\n kind: 'construction',\n key: 'pump',\n label: labels.pump,\n subKind: 'pump',\n });\n if (hasConflict)\n items.push({\n kind: 'construction',\n key: 'conflict',\n label: labels.conflict,\n subKind: 'conflict',\n });\n\n return items;\n}\n\n/** Draws `item`'s symbol into `symG`, its box starting at `cx` and centered on `rowSymY`. */\nfunction drawLegendSymbol(\n symG: Selection<SVGGElement, unknown, HTMLElement, unknown>,\n item: WellLegendItem,\n cx: number,\n rowSymY: number,\n { theme, cls, textures: legendTextures }: LegendStyle,\n): void {\n const RC = 'round' as const;\n const rw = SYMBOL_WIDTH;\n const rh = SYMBOL_HEIGHT;\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 if (item.subKind === 'centralizer') {\n // Pipe walls with a bow on each side, matching the profile marker.\n const pipeW = rw * 0.4;\n const pipeL = cx + (rw - pipeW) / 2;\n const pipeR = pipeL + pipeW;\n const y1 = rowSymY - rh / 2;\n const y2 = rowSymY + rh / 2;\n const bowH = rh * 0.3;\n for (const x of [pipeL, pipeR]) {\n symG\n .append('line')\n .attr('class', cls.constructionRect)\n .attr('x1', x)\n .attr('x2', x)\n .attr('y1', y1)\n .attr('y2', y2)\n .attr('stroke', theme.wellCase.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n }\n for (const [from, to] of [\n [pipeL, cx],\n [pipeR, cx + rw],\n ] as const) {\n symG\n .append('polyline')\n .attr('class', cls.constructionRect)\n .attr(\n 'points',\n `${from},${rowSymY - bowH} ${to},${rowSymY} ${from},${rowSymY + bowH}`,\n )\n .attr('fill', theme.centralizer.fill)\n .attr('stroke', theme.centralizer.stroke)\n .attr('stroke-width', theme.centralizer.strokeWidth);\n }\n } else if (item.subKind === 'pump') {\n // Riser from the top, pump body at the bottom — matching the profile layer.\n const y1 = rowSymY - rh / 2;\n const y2 = rowSymY + rh / 2;\n const midX = cx + rw / 2;\n const riserHalf = rw * 0.12;\n const bodyHalf = rw * 0.28;\n const bodyTop = y1 + rh * 0.4;\n symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', midX - riserHalf)\n .attr('y', y1)\n .attr('width', 2 * riserHalf)\n .attr('height', bodyTop - y1)\n .attr('fill', theme.pump.riserFill)\n .attr('stroke', 'none');\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr('d', pipeWallsPath(midX - riserHalf, midX + riserHalf, y1, bodyTop))\n .attr('fill', 'none')\n .attr('stroke', theme.pump.riserStroke)\n .attr('stroke-width', theme.pump.riserStrokeWidth);\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr(\n 'd',\n `M${midX - bodyHalf},${bodyTop}H${midX + bodyHalf}V${y2}H${midX - bodyHalf}Z`,\n )\n .attr('fill', theme.pump.fill)\n .attr('stroke', theme.pump.stroke)\n .attr('stroke-width', theme.pump.strokeWidth);\n } else if (item.subKind === 'reduction') {\n // Slanted walls only, open at both ends, like the profile.\n const topW = rw * 0.5;\n const y1 = rowSymY - rh / 2;\n const y2 = rowSymY + rh / 2;\n const midX = cx + rw / 2;\n const tl = `${midX - topW / 2},${y1}`;\n const tr = `${midX + topW / 2},${y1}`;\n symG\n .append('polygon')\n .attr('class', cls.constructionRect)\n .attr('points', `${tl} ${tr} ${cx + rw},${y2} ${cx},${y2}`)\n .attr('fill', theme.reduction.fill)\n .attr('stroke', 'none');\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr('d', `M${tl}L${cx},${y2}M${tr}L${cx + rw},${y2}`)\n .attr('fill', 'none')\n .attr('stroke', theme.reduction.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n } else if (\n item.subKind === 'wellCase' ||\n item.subKind === 'wellScreen' ||\n item.subKind === 'boreHole'\n ) {\n // Open walls like the profile: the casing ends on its shoe, the borehole\n // on its bottom line, the screen shows its top and base marks.\n const y1 = rowSymY - rh / 2;\n const y2 = rowSymY + rh / 2;\n const shoe = 3;\n const xL = cx + shoe;\n const xR = cx + rw - shoe;\n const style = {\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 boreHole: { fill: theme.boreHole.fill, stroke: theme.boreHole.stroke },\n }[item.subKind];\n symG\n .append('rect')\n .attr('class', cls.constructionRect)\n .attr('x', xL)\n .attr('y', y1)\n .attr('width', xR - xL)\n .attr('height', rh)\n .attr('fill', style.fill)\n .attr('stroke', 'none');\n const walls = symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr(\n 'd',\n pipeWallsPath(xL, xR, y1, y2) +\n (item.subKind === 'boreHole' ? `M${xL},${y2}H${xR}` : ''),\n )\n .attr('fill', 'none')\n .attr('stroke', style.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth);\n if (item.subKind === 'boreHole')\n walls.attr('stroke-dasharray', theme.boreHole.strokeDasharray);\n if (item.subKind === 'wellCase')\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr('d', shoePath(xL, xR, y2, shoe))\n .attr('fill', style.stroke)\n .attr('stroke', 'none');\n if (item.subKind === 'wellScreen')\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr(\n 'd',\n screenEndPath(xL, xR, y1 + 0.5) + screenEndPath(xL, xR, y2 - 0.5),\n )\n .attr('fill', 'none')\n .attr('stroke', style.stroke)\n .attr('stroke-width', theme.wellScreen.endStrokeWidth)\n .attr('stroke-dasharray', '2, 1.5');\n } else if (item.subKind === 'cementPad') {\n // Two slabs around a pipe opening, with break lines at the outer ends.\n const h = rh * 0.6;\n const { slabs } = getCementPadGeometry(\n rw,\n 2 * cx + rw,\n rowSymY + h / 2,\n { widthRatio: 1, height: h },\n rw * 0.3,\n );\n for (const d of slabs)\n symG\n .append('path')\n .attr('class', cls.constructionRect)\n .attr('d', d)\n .attr('fill', legendTextures.pad.url())\n .attr('stroke', theme.cementPad.stroke)\n .attr('stroke-width', theme.legend.itemStrokeWidth)\n .attr('stroke-linejoin', RC);\n } else {\n const symMap: Record<\n string,\n { fill: string; stroke: string; dasharray?: string }\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 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\ntype LegendOptions = {\n config?: Partial<LegendRenderConfig>;\n theme?: Partial<WellTheme>;\n classNames?: ComponentsClassNames['legend'];\n textures?: TexturesConfig;\n};\n\nfunction resolveStyle(options: LegendOptions): LegendStyle {\n return {\n theme: defu(options.theme ?? {}, DEFAULT_WELL_THEME) as WellTheme,\n cls: options.classNames\n ? { ...DEFAULT_COMPONENTS_CLASS_NAMES.legend, ...options.classNames }\n : DEFAULT_COMPONENTS_CLASS_NAMES.legend,\n textures: createWellTextures(options.textures),\n };\n}\n\n/**\n * Draws a single legend symbol into its own `<svg>` (matched by `selector`),\n * sized to the symbol plus a small margin, with the textures it needs\n * defined inside — so the markup renders standalone, e.g. in a PDF table.\n */\nexport function drawWellLegendSymbol(\n selector: string,\n item: WellLegendItem,\n options: Omit<LegendOptions, 'config'> = {},\n): void {\n const style = resolveStyle(options);\n const svgEl = d3.select(selector);\n svgEl.selectAll('*').remove();\n svgEl\n .attr('width', SYMBOL_WIDTH + SYMBOL_MARGIN * 2)\n .attr('height', SYMBOL_HEIGHT + SYMBOL_MARGIN * 2);\n Object.values(style.textures).forEach(t => svgEl.call(t));\n\n const symG = svgEl.append('g').attr('class', style.cls.item);\n drawLegendSymbol(\n symG,\n item,\n SYMBOL_MARGIN,\n SYMBOL_MARGIN + SYMBOL_HEIGHT / 2,\n style,\n );\n}\n\nexport function drawWellLegend(\n selector: string,\n profile: Well,\n options: LegendOptions = {},\n): void {\n const cfg = defu(\n options.config ?? {},\n INTERACTIVE_RENDER_CONFIG.legend,\n ) as LegendRenderConfig;\n\n const items = getWellLegendItems(profile, cfg.labels);\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 style = resolveStyle(options);\n const { theme, cls } = style;\n Object.values(style.textures).forEach(t => svgEl.call(t));\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 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 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 drawLegendSymbol(symG, item, cx, rowSymY, style);\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 * as d3 from 'd3';\n\nimport { Lithology } from '@welldot/core';\nimport { DrawContext, SvgSelection, WellTheme } from '~/types/render.types';\nimport { mergeEnter, withTransition } from '~/utils/d3.utils';\nimport { makeIntervalKey } from '~/utils/key.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. An empty `data`\n * removes the layers already drawn.\n */\nexport function drawLithology(ctx: DrawContext, data: Lithology[]): void {\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, makeIntervalKey('lithology'));\n\n rects.exit().transition(transition).attr('height', 0).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 .attr('y', getYPos)\n .attr('height', 0);\n\n const merged = mergeEnter(newLayers, rects);\n withTransition(merged, transition)\n .attr('y', getYPos)\n .attr('height', getHeight)\n .attr('fill', getLithologyFill(data, svg, ctx.theme.lithologyTexture));\n}\n\n/**\n * Draws one lithology layer's fill (texture over its `color`) as a\n * `size`×`size` square into its own `<svg>` matched by `selector`, with the\n * texture pattern defined inside so the markup renders standalone. FGDC\n * textures must already be loaded (`WellRenderer.prepareSvg`).\n */\nexport function drawLithologySwatch(\n selector: string,\n layer: Lithology,\n options: { size: number; theme: WellTheme },\n): void {\n const { size, theme } = options;\n const svg = d3.select(selector) as SvgSelection;\n svg.selectAll('*').remove();\n svg.attr('width', size).attr('height', size);\n\n const fill = getLithologyFill([layer], svg, {\n ...theme.lithologyTexture,\n // Denser pattern so a few strokes show inside the small square.\n size: Math.max(12, size * 3),\n });\n svg\n .append('rect')\n .attr('x', 0.5)\n .attr('y', 0.5)\n .attr('width', size - 1)\n .attr('height', size - 1)\n .attr('fill', fill(layer))\n .attr('stroke', theme.lithology.stroke)\n .attr('stroke-width', 0.5);\n}\n","import type { Fracture, Lithology } from '@welldot/core';\nimport type { DrawContext } from '~/types/render.types';\nimport { getFractureMarkers, getLithologyMarkers } from '~/utils/layout.utils';\n\n/**\n * Draws a circled 1-based index on each lithology layer (at the top of its\n * visible part, so it repeats on every panel the layer crosses) and an\n * `F{n}` tag right of each fracture. Numbers follow the order of the full,\n * unfiltered lists passed in. No-op unless `renderConfig.markers` enables\n * either kind.\n */\nexport function drawMarkers(\n ctx: DrawContext,\n data: { lithology: Lithology[]; fractures: Fracture[] },\n): void {\n const group = ctx.groups.markersGroup;\n group.selectAll('*').remove();\n\n const cfg = ctx.renderConfig.markers;\n const theme = ctx.theme.markers;\n const r = cfg.radius;\n\n if (cfg.lithology) {\n const cx = (ctx.geoXLeft + ctx.geoXRight) / 2;\n getLithologyMarkers(data.lithology, ctx.depthFrom, ctx.depthTo).forEach(\n marker => {\n const top = ctx.yScale(marker.from);\n const bottom = ctx.yScale(marker.to);\n if (bottom - top < r) return;\n const cy = bottom - top >= 2 * r + 4 ? top + r + 2 : (top + bottom) / 2;\n\n const g = group\n .append('g')\n .attr('class', ctx.classes.markers.lithology);\n g.append('circle')\n .attr('cx', cx)\n .attr('cy', cy)\n .attr('r', r)\n .attr('fill', theme.fill)\n .attr('stroke', theme.stroke)\n .attr('stroke-width', theme.strokeWidth);\n g.append('text')\n .attr('x', cx)\n .attr('y', cy)\n .attr('text-anchor', 'middle')\n .attr('dominant-baseline', 'central')\n .attr('font-size', theme.fontSize)\n .attr('font-family', theme.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.fontWeight ?? 600)\n .attr('fill', theme.color)\n .text(String(marker.index));\n },\n );\n }\n\n if (cfg.fractures) {\n const x =\n ctx.pocoCenterX +\n (ctx.POCO_WIDTH * ctx.renderConfig.fractures.widthMultiplier) / 2 +\n 3;\n getFractureMarkers(data.fractures, ctx.depthFrom, ctx.depthTo).forEach(\n marker => {\n group\n .append('text')\n .attr('class', ctx.classes.markers.fracture)\n .attr('x', x)\n .attr('y', ctx.yScale(marker.depth))\n .attr('dominant-baseline', 'central')\n .attr('font-size', theme.fontSize)\n .attr('font-family', theme.fontFamily ?? 'sans-serif')\n .attr('font-weight', theme.fontWeight ?? 600)\n .attr('fill', theme.color)\n .text(marker.label);\n },\n );\n }\n}\n","import textures from 'textures';\n\nimport { formatNumber } from '@welldot/utils';\n\nimport type { DrawContext, SvgSelection } from '~/types/render.types';\nimport { getLengthUnit } from '~/utils/format.utils';\nimport { formatOverlapLabel } from '~/utils/layout.utils';\nimport { hasDescriptionColumn } from './column-headers.renderer';\n\n/**\n * Hatches the band `[depthFrom, repeatedTo]` a panel repeats from the\n * previous one, from the axis to the description column, with a dashed\n * rule at its bottom and `renderConfig.overlap.label` at its top right.\n * No-op when the panel has no `repeatedTo`.\n */\nexport function drawOverlap(ctx: DrawContext): void {\n const group = ctx.groups.overlapGroup;\n group.selectAll('*').remove();\n\n const { repeatedTo, depthFrom } = ctx;\n if (repeatedTo == null || repeatedTo <= depthFrom) return;\n\n const theme = ctx.theme.overlap;\n const { margins } = ctx.state;\n const overview = ctx.renderConfig.overview;\n const showsDescription = hasDescriptionColumn(ctx);\n\n const x0 =\n -margins.left + (overview.active ? overview.x + overview.width + 4 : 0);\n const x1 = showsDescription\n ? ctx.geoXRight + ctx.renderConfig.labels.descriptionXOffset - 4\n : ctx.svgWidth - margins.left;\n const y0 = ctx.yScale(depthFrom);\n const y1 = ctx.yScale(repeatedTo);\n\n const hatch = textures\n .lines()\n .size(theme.size)\n .strokeWidth(theme.strokeWidth)\n .stroke(theme.stroke);\n ctx.svg.call(hatch as unknown as (selection: SvgSelection) => void);\n\n group\n .append('rect')\n .attr('class', ctx.classes.overlap.band)\n .attr('x', x0)\n .attr('y', y0)\n .attr('width', Math.max(0, x1 - x0))\n .attr('height', Math.max(0, y1 - y0))\n .attr('fill', hatch.url())\n .style('pointer-events', 'none');\n\n group\n .append('line')\n .attr('x1', x0)\n .attr('x2', ctx.svgWidth - margins.left)\n .attr('y1', y1)\n .attr('y2', y1)\n .attr('stroke', theme.ruleStroke)\n .attr('stroke-width', 0.6)\n .attr('stroke-dasharray', '3, 2');\n\n // Whole units: the band's edges fall wherever the page ends, so decimals\n // would only add noise.\n const whole = (m: number) =>\n formatNumber(ctx.units.length === 'ft' ? m * 3.28084 : m, {\n maximumFractionDigits: 0,\n locale: ctx.locale,\n });\n const unit = getLengthUnit(ctx.units.length);\n const range = `${whole(depthFrom)}–${whole(repeatedTo)} ${unit}`;\n group\n .append('text')\n .attr('class', ctx.classes.overlap.label)\n .attr('x', ctx.svgWidth - margins.left - 2)\n .attr('y', y0 + theme.fontSize + 1)\n .attr('text-anchor', 'end')\n .attr('font-size', theme.fontSize)\n .attr('font-family', theme.fontFamily ?? 'monospace')\n .attr('fill', theme.labelColor)\n .text(formatOverlapLabel(ctx.renderConfig.overlap.label, range));\n}\n","import type { Lithology } from '@welldot/core';\nimport type { DrawContext } from '~/types/render.types';\nimport { getOverviewGeometry } from '~/utils/layout.utils';\n\n/**\n * Draws the mini-map: the whole well's lithology as a thin column at\n * `overview.x` (in the left margin), colored by each layer's `color`, with\n * a window outlining the panel's `[depthFrom, depthTo]`. `lithology` is the\n * full, unfiltered list. No-op unless `renderConfig.overview.active`.\n */\nexport function drawOverview(ctx: DrawContext, lithology: Lithology[]): void {\n const group = ctx.groups.overviewGroup;\n group.selectAll('*').remove();\n\n const cfg = ctx.renderConfig.overview;\n if (!cfg.active || lithology.length === 0 || ctx.totalDepth <= 0) return;\n\n const theme = ctx.theme.overview;\n const height = Math.min(cfg.height, ctx.state.height);\n const { y, window } = getOverviewGeometry(\n ctx.totalDepth,\n height,\n ctx.depthFrom,\n ctx.depthTo,\n );\n\n lithology.forEach(layer => {\n group\n .append('rect')\n .attr('class', ctx.classes.overview.item)\n .attr('x', cfg.x)\n .attr('y', y(layer.from))\n .attr('width', cfg.width)\n .attr('height', Math.max(0, y(layer.to) - y(layer.from)))\n .attr('fill', layer.color || theme.emptyFill);\n });\n\n group\n .append('rect')\n .attr('x', cfg.x)\n .attr('y', 0)\n .attr('width', cfg.width)\n .attr('height', y(ctx.totalDepth))\n .attr('fill', 'none')\n .attr('stroke', theme.stroke)\n .attr('stroke-width', theme.strokeWidth);\n\n group\n .append('rect')\n .attr('class', ctx.classes.overview.window)\n .attr('x', cfg.x - 2)\n .attr('y', window.y)\n .attr('width', cfg.width + 4)\n .attr('height', window.height)\n .attr('fill', 'none')\n .attr('stroke', theme.windowStroke)\n .attr('stroke-width', theme.windowStrokeWidth);\n}\n","import * as d3 from 'd3';\n\nimport type { PumpInstallation } from '@welldot/core';\nimport { getProfileDiamValues } from '@welldot/utils';\nimport type { DrawContext } from '~/types/render.types';\nimport { diameterAt, type Interval } from '~/utils/construction.geometry';\n\n/** Vertical extent (px) of the pump parts inside one panel. */\nexport type PumpSpans = {\n /** Bottom of the riser, never below the panel. */\n riserBottom: number;\n /** Visible part of the body, or `null` when it is off the panel. */\n body: {\n top: number;\n bottom: number;\n /** Cut by the panel edge (drawn square there, without rounding). */\n cutTop: boolean;\n cutBottom: boolean;\n } | null;\n};\n\n/**\n * Clamps the riser and body to the panel's drawing area `[panelTop,\n * panelBottom]`, so neither runs past a page break. The riser hangs from\n * `panelTop` down to the body top (`intakeY − bodyHeight`).\n */\nexport function getPumpSpans(\n panelTop: number,\n panelBottom: number,\n bodyTop: number,\n intakeY: number,\n): PumpSpans {\n const riserBottom = Math.min(Math.max(panelTop, bodyTop), panelBottom);\n const top = Math.max(bodyTop, panelTop);\n const bottom = Math.min(intakeY, panelBottom);\n return {\n riserBottom,\n body:\n bottom > top\n ? { top, bottom, cutTop: top > bodyTop, cutBottom: bottom < intakeY }\n : null,\n };\n}\n\n/** Height (px) of the riser's break zigzag above and below its line. */\nconst riserBreakAmplitude = (width: number) => Math.min(2, width / 3);\n\n/**\n * Top of the riser bar from `xLeft` to `xRight` at `y`. With `broken` (the\n * wellhead is on the panel) it is a break line, a zigzag across the pipe\n * marking that it goes on to the discharge line: `edge` continues the fill\n * outline from (xLeft, y) to (xRight, y) along it and `breakLine` strokes\n * it. Otherwise (a panel cut) the top is a plain open edge.\n */\nexport function getRiserTop(\n xLeft: number,\n xRight: number,\n y: number,\n broken: boolean,\n): { edge: string; breakLine: string } {\n if (!broken) return { edge: `H${xRight}`, breakLine: '' };\n const a = riserBreakAmplitude(xRight - xLeft);\n const w = xRight - xLeft;\n const zigzag =\n `L${xLeft + w / 3},${y - a}` +\n `L${xLeft + (2 * w) / 3},${y + a}L${xRight},${y}`;\n return { edge: zigzag, breakLine: `M${xLeft},${y}${zigzag}` };\n}\n\n/** Share of the pipe at the intake the body may fill, so a gap shows around it. */\nconst BODY_MAX_FILL = 0.85;\n/** Riser width relative to the room it has, so it stays narrower than the body and clear of the casing. */\nconst RISER_MAX_FILL = 0.7;\n\n/**\n * Drawn diameters (mm) of the riser and pump body. Both always fit the well:\n * the body stays inside the pipe at the intake (`intakeD`), the riser inside\n * the narrowest pipe it hangs through (`narrowestD`) and narrower than the\n * body. A declared `riser_diameter` larger than that room is shrunk to fit.\n */\nexport function getPumpDiameters(\n intakeD: number,\n narrowestD: number,\n riserDiameter: number | undefined,\n cfg: { bodyWidthRatio: number; riserWidthRatio: number },\n): { riser: number; body: number } {\n const maxBody = intakeD * BODY_MAX_FILL;\n const riser = Math.min(\n riserDiameter ?? intakeD * cfg.riserWidthRatio,\n narrowestD * RISER_MAX_FILL,\n maxBody * RISER_MAX_FILL,\n );\n const body = Math.min(\n Math.max(intakeD * cfg.bodyWidthRatio, riser * 1.4),\n maxBody,\n );\n return { riser, body };\n}\n\n/**\n * Renders the current pump (`.well` v2.3 `pump_installations`) as a body\n * ending at `intake_depth`, hung from a riser pipe that runs from the\n * wellhead (casing top above the ground, else the pad top), where a break\n * line marks it going on to the discharge line. The riser uses\n * `riser_diameter` when present, otherwise a fraction\n * of the casing diameter; both are kept inside the well (see\n * `getPumpDiameters`). Pass `undefined` to clear the layer.\n *\n * Paths only (no `rect`), so the generic rect rescale on zoom never touches\n * it; safe to call on every zoom event — geometry is recomputed from\n * `ctx.yScale` without transitions. The body keeps a constant pixel height.\n */\nexport function drawPump(\n ctx: DrawContext,\n pump: PumpInstallation | undefined,\n): void {\n const group = ctx.groups.pumpGroup;\n const cls = ctx.classes.pump;\n const cfg = ctx.renderConfig.construction.pump;\n const theme = ctx.theme.pump;\n\n const intake = pump?.intake_depth;\n const visible =\n !!pump &&\n cfg.active &&\n intake !== undefined &&\n intake > 0 &&\n // the riser crosses this panel when the panel starts above the intake\n ctx.depthFrom < intake;\n\n const data = visible ? [pump] : [];\n\n const selection = group\n .selectAll<SVGGElement, PumpInstallation>(`g.${cls.item}`)\n .data(data, d => d.id);\n\n selection.exit().remove();\n if (!visible) return;\n\n const maxXValue = d3.max(getProfileDiamValues(ctx.constructionData)) || 0;\n const xScale = d3\n .scaleLinear()\n .domain([0, maxXValue])\n .range([0, ctx.POCO_WIDTH]);\n\n const pipes: Interval[] = [\n ...ctx.constructionData.well_case,\n ...ctx.constructionData.well_screen,\n ];\n const casingD =\n diameterAt(pipes, intake) ??\n diameterAt(ctx.constructionData.bore_hole, intake) ??\n maxXValue;\n\n // Narrowest pipe (or open hole) the riser passes through above the intake.\n const narrowestD = Math.min(\n casingD,\n ...[...pipes, ...ctx.constructionData.bore_hole]\n .filter(i => i.from < intake && i.to > 0)\n .map(i => i.diameter),\n );\n const { riser: riserD, body: bodyD } = getPumpDiameters(\n casingD,\n narrowestD,\n pump.riser_diameter,\n cfg,\n );\n\n const riserLeft = (ctx.POCO_CENTER - xScale(riserD)) / 2;\n const riserRight = (ctx.POCO_CENTER + xScale(riserD)) / 2;\n const bodyLeft = (ctx.POCO_CENTER - xScale(bodyD)) / 2;\n const bodyRight = (ctx.POCO_CENTER + xScale(bodyD)) / 2;\n\n const yIntake = ctx.yScale(intake);\n const yBodyTop = yIntake - cfg.bodyHeight;\n // The riser rises to the wellhead: the top of a casing sticking up above\n // the ground, else the top of the cement pad on the surface. There it ends\n // on a break line, the pipe going on to the discharge line. On a panel\n // that starts below the wellhead it runs from the panel top, unbroken.\n const headDepth = Math.min(\n 0,\n ...pipes.filter(p => p.from < 0).map(p => p.from),\n );\n const headInPanel = ctx.depthFrom <= headDepth;\n const padOnHead =\n headDepth === 0 && !!ctx.constructionData.cement_pad?.thickness;\n // On the pad, the break stays within its thickness (column titles sit\n // just above it).\n const yRiserTop = headInPanel\n ? ctx.yScale(headDepth) -\n (padOnHead\n ? ctx.renderConfig.construction.cementPad.height -\n riserBreakAmplitude(xScale(riserD))\n : 0)\n : ctx.yScale(ctx.depthFrom);\n const { riserBottom: yRiserBottom, body } = getPumpSpans(\n yRiserTop,\n ctx.yScale(ctx.depthTo),\n yBodyTop,\n yIntake,\n );\n const r = Math.min(3, (bodyRight - bodyLeft) / 4);\n\n const entered = selection\n .enter()\n .append('g')\n .attr('class', cls.item)\n .on('mouseover', ctx.tooltips.pump.show)\n .on('mouseout', ctx.tooltips.pump.hide);\n\n entered.append('path').attr('class', `${cls.item}-riser-fill`);\n entered.append('path').attr('class', `${cls.item}-riser`);\n entered.append('path').attr('class', `${cls.item}-body`);\n entered.append('path').attr('class', `${cls.item}-intake`);\n\n const merged = entered.merge(selection);\n\n const top = getRiserTop(riserLeft, riserRight, yRiserTop, headInPanel);\n\n // Filled riser: a narrow solid bar, unlike the open white-interior casing.\n merged\n .select(`.${cls.item}-riser-fill`)\n .attr(\n 'd',\n yRiserBottom > yRiserTop\n ? `M${riserLeft},${yRiserTop}${top.edge}V${yRiserBottom}H${riserLeft}Z`\n : '',\n )\n .attr('fill', theme.riserFill)\n .attr('stroke', 'none');\n\n merged\n .select(`.${cls.item}-riser`)\n .attr(\n 'd',\n yRiserBottom > yRiserTop\n ? `M${riserLeft},${yRiserTop}V${yRiserBottom}M${riserRight},${yRiserTop}V${yRiserBottom}${top.breakLine}`\n : '',\n )\n .attr('stroke-linejoin', 'round')\n .attr('fill', 'none')\n .attr('stroke', theme.riserStroke)\n .attr('stroke-width', theme.riserStrokeWidth);\n\n // Rounded corners only where the body is not cut by the panel edge.\n let bodyPath = '';\n if (body) {\n const rt = body.cutTop ? 0 : Math.min(r, (body.bottom - body.top) / 2);\n const rb = body.cutBottom ? 0 : Math.min(r, (body.bottom - body.top) / 2);\n const { top, bottom } = body;\n bodyPath =\n `M${bodyLeft + rt},${top}H${bodyRight - rt}Q${bodyRight},${top} ${bodyRight},${top + rt}` +\n `V${bottom - rb}Q${bodyRight},${bottom} ${bodyRight - rb},${bottom}` +\n `H${bodyLeft + rb}Q${bodyLeft},${bottom} ${bodyLeft},${bottom - rb}` +\n `V${top + rt}Q${bodyLeft},${top} ${bodyLeft + rt},${top}Z`;\n }\n\n merged\n .select(`.${cls.item}-body`)\n .attr('d', bodyPath)\n .attr('fill', theme.fill)\n .attr('stroke', theme.stroke)\n .attr('stroke-width', theme.strokeWidth);\n\n // Intake screen (crivo): short horizontal hatches near the bottom of the\n // body, only where the body is drawn.\n const hatchY = [\n yIntake - cfg.bodyHeight * 0.3,\n yIntake - cfg.bodyHeight * 0.15,\n ].filter(y => body && y > body.top && y < body.bottom);\n merged\n .select(`.${cls.item}-intake`)\n .attr(\n 'd',\n hatchY.map(y => `M${bodyLeft + 1.5},${y}H${bodyRight - 1.5}`).join(''),\n )\n .attr('fill', 'none')\n .attr('stroke', theme.stroke)\n .attr('stroke-width', 0.8);\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. Clears the strip first, then returns early if the feature is\n * disabled via `ctx.renderConfig.unitLabels.active` or if `data` is empty.\n */\nexport function drawUnitLabels(ctx: DrawContext, data: Lithology[]): void {\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 if (!renderConfig.unitLabels.active || !data.length) return;\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 `.wp-tooltip{position:absolute;z-index:1000;display:flex;flex-direction:column;gap:2px;max-width:240px;padding:8px 10px;border-radius:6px;background:${s(labels.annotationBg)};border:1px solid ${s(labels.annotationBorderColor ?? 'rgba(0,0,0,0.08)')};box-shadow:0 4px 12px rgba(0,0,0,0.15);font-family:${s(labels.bodyFont ?? 'sans-serif')};line-height:1.45}`,\n `.wp-tooltip-title{font-family:${s(labels.headerFont)};font-weight:${s(labels.headerFontWeight ?? 600)};font-size:10px;letter-spacing:0.06em;text-transform:uppercase;color:${s(labels.color)}}`,\n `.wp-tooltip-primary{font-weight:${s(labels.headerFontWeight ?? 600)};font-size:12px;color:${s(labels.color)}}`,\n `.wp-tooltip-secondary{font-size:11px;color:${s(labels.bodyColor)}}`,\n ].join('');\n}\n"],"mappings":"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","names":["d3module","d3tip","defu","formatNumber","getCurrentPump","textures","formatNumber","formatNumber","textures","textures","d3","d3","CONSTRUCTION_MATERIALS","getVocabLabel","getProfileDiamValues","getVocabLabel","CONSTRUCTION_MATERIALS","getProfileDiamValues","d3","getProfileDiamValues","max","getProfileDiamValues","shoe","d3","d3","getProfileDiamValues","getProfileDiamValues","d3","d3","textures","formatNumber","textures","formatNumber","d3","getProfileDiamValues","getProfileDiamValues","top","sanitizeHtml","d3","d3module","d3tip","defu","formatNumber","getCurrentPump"]}