/** * Visual family for heat exchangers — drives glyph + node badge so DX / * flooded / plate / coil / MCHX are distinguishable at a glance. */ export type HxFamilyId = | "dx" | "flooded" | "plate" | "coil" | "mchx" | "shell" | "generic"; export interface HxFamily { id: HxFamilyId; /** Short French badge on the canvas */ badge: string; /** Palette / tooltip line */ label: string; accent: string; } const FAMILIES: Record = { dx: { id: "dx", badge: "DX", label: "Détente directe", accent: "#1565c0", }, flooded: { id: "flooded", badge: "Noyé", label: "Calandre noyée", accent: "#0d7377", }, plate: { id: "plate", badge: "Plaques", label: "Échangeur à plaques", accent: "#1a56a8", }, coil: { id: "coil", badge: "Coil", label: "Batterie à ailettes", accent: "#c27803", }, mchx: { id: "mchx", badge: "MCHX", label: "Microcanaux", accent: "#d97706", }, shell: { id: "shell", badge: "Tubes", label: "Calandre / tubes", accent: "#c0392b", }, generic: { id: "generic", badge: "HX", label: "Échangeur", accent: "#475569", }, }; /** Returns a visual family for heat-exchanger types; null for non-HX. */ export function hxFamily(type: string): HxFamily | null { if (type.startsWith("Bphx") || type.includes("Bphx")) return FAMILIES.plate; if (type.includes("Flooded")) return FAMILIES.flooded; if (type.includes("Mchx")) return FAMILIES.mchx; if ( type.includes("FinCoil") || type.includes("AirCooled") || type === "CondenserCoil" || type === "EvaporatorCoil" ) { return FAMILIES.coil; } if (type === "Evaporator") return FAMILIES.dx; if (type === "Condenser") return FAMILIES.shell; if (type === "HeatExchanger") return FAMILIES.generic; if (type.includes("Condenser") || type.includes("Evaporator")) return FAMILIES.shell; return null; } /** Glyph key used by ComponentIcon — finer than the old include-based map. */ export function hxGlyphKey(type: string): string | null { const f = hxFamily(type); if (!f) return null; switch (f.id) { case "plate": return "hx_plate"; case "flooded": return "hx_flooded"; case "coil": return "hx_coil"; case "mchx": return "hx_mchx"; case "dx": return "hx_dx"; case "shell": return type.includes("Evaporator") ? "hx_shell_evap" : "hx_shell_cond"; default: return "hx"; } }