--- import { getMessages } from '../../i18n/messages.ts'; interface Props { locale: string; /** Unique per diagram on the page; prefixes ids inside the SVG. */ uid: string; } const { locale, uid } = Astro.props; const t = getMessages(locale); const arrowV = `${uid}-cctga-arrow-v`; const arrowA = `${uid}-cctga-arrow-a`; // Long labels do not fit their free space on one line: split them in two at a word boundary. function twoLines(label: string): [string, string] { const words = label.split(' '); const split = Math.ceil(words.length / 2); return [words.slice(0, split).join(' '), words.slice(split).join(' ')]; } const lvPumpsLines = twoLines(t['diagram.label.lv-pumps-to-aorta']); const rvPumpsLines = twoLines(t['diagram.label.rv-pumps-to-aorta']); const swappedLines = twoLines(t['diagram.label.ventricles-swapped']); // A circulation scheme like the transposition diagram: lungs on top, the body below, the right // atrium on the viewer's left and the left atrium on the right, as seen from the front. The route // of the blood is the same in both states: the ventricle under the right atrium sends venous blood // to the lungs, the one under the left atrium sends arterial blood into the aorta. What changes is // which ventricle sits where: in congenitally corrected transposition the two ventricles swap // places together with their atrioventricular valves. const path = { venaCava: 'M220,350 H40 V132 H178', raToVentricle: 'M220,160 V182', laToVentricle: 'M340,160 V182', pulmonaryArtery: 'M260,222 H280 V53', pulmonaryVeins: 'M340,30 H470 V132 H382', aorta: 'M380,232 H520 V350 H343', // Disease: blood leaking back through the tricuspid valve into the left atrium. backflow: 'M362,202 V146', }; // Ventricle art: a muscle wall around a cavity filled with blood. The wall follows the load, not // the morphology: the ventricle that pumps into the aorta (arterial blood) has the thick wall, the // one that pumps into the lungs a thin wall. So in the disease state the systemic morphologic right // ventricle is not drawn thinner than the subpulmonary left ventricle. The morphologic right // ventricle is marked by its coarse trabeculae, the sign by which echocardiography tells the two // apart; the morphologic left ventricle has a smooth cavity. type Ventricle = { x: number; morph: 'lv' | 'rv'; blood: 'venous' | 'arterial' }; const top = 185; const width = 80; const height = 75; function inset(v: Ventricle) { return v.blood === 'arterial' ? 10 : 4; } function cavity(v: Ventricle) { const i = inset(v); return { x: v.x + i, y: top + i, width: width - 2 * i, height: height - 2 * i, }; } function trabeculae(v: Ventricle) { if (v.morph !== 'rv') return []; const bottom = top + height - inset(v); return [18, 30, 50, 62].map( (dx, i) => `M${v.x + dx},${bottom} L${v.x + dx + (i < 2 ? 3 : -3)},${bottom - 12}`, ); } const normalVentricles: Ventricle[] = [ { x: 180, morph: 'rv', blood: 'venous' }, { x: 300, morph: 'lv', blood: 'arterial' }, ]; const diseaseVentricles: Ventricle[] = [ { x: 180, morph: 'lv', blood: 'venous' }, { x: 300, morph: 'rv', blood: 'arterial' }, ]; const states = [ { cls: 'normal-only', ventricles: normalVentricles }, { cls: 'disease-only', ventricles: diseaseVentricles }, ]; --- {t['diagram.label.lungs']} {t['diagram.label.body']} {t['diagram.label.ra']} {t['diagram.label.la']} {states.map(({ cls, ventricles }) => ( {ventricles.map((v) => { const c = cavity(v); return ( {trabeculae(v).map((d) => ( ))} {t[v.morph === 'lv' ? 'diagram.label.lv' : 'diagram.label.rv']} ); })} ))} {t['diagram.label.tricuspid']} {t['diagram.label.mitral']} {t['diagram.label.mitral']} {t['diagram.label.tricuspid']} {lvPumpsLines[0]} {lvPumpsLines[1]} {rvPumpsLines[0]} {rvPumpsLines[1]} {swappedLines[0]} {swappedLines[1]} {t['diagram.label.backflow-often']} {t['diagram.label.venaCava']} {t['diagram.label.pulmonaryArtery']} {t['diagram.label.pulmonaryVeins']} {t['diagram.label.aorta']} {t['diagram.label.aorta-anterior-left']}