/* Neonatal jaundice treatment threshold calculator Copyright (C) 2024-2025 Lee Yingtong Li This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ // Import bilirubin_lib.js const fs = require('fs'); eval(fs.readFileSync('src/bilirubin_lib.js').toString()); const assert = require('node:assert'); const { suite, test } = require('node:test'); function unitsEqual(a, b) { return Math.round(a) === b; } function tenthsEqual(a, b) { return Math.round(a * 10) === b * 10; } suite('RWH phototherapy thresholds', () => { test('Phototherapy thresholds at >= 38 weeks', () => { for (let gestation = 42; gestation >= 38; gestation--) { // Test cases assert(unitsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false, false, false, false, false), 135)); assert(unitsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 143)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 233)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 280)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 325)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 327)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 354)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 360)); } }); test('Phototherapy thresholds at >= 38 weeks with risk factors', () => { // Check that any combination of risk factors invokes the 35-37 week chart for (let gestation = 42; gestation >= 38; gestation--) { for (let i = 1; i <= 0b1111; i++) { let flag1 = (i & 1) === 1; let flag2 = ((i >> 1) & 1) === 1; let flag3 = ((i >> 2) & 1) === 1; let flag4 = ((i >> 3) & 1) === 1; // Test cases assert(unitsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, flag1, flag2, false /* bw_lt1000 */, flag3, flag4), 108)); assert(unitsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, flag1, flag2, false, flag3, flag4), 115)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, flag1, flag2, false, flag3, flag4), 198)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, flag1, flag2, false, flag3, flag4), 234)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, flag1, flag2, false, flag3, flag4), 275)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, flag1, flag2, false, flag3, flag4), 277)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, flag1, flag2, false, flag3, flag4), 290)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, flag1, flag2, false, flag3, flag4), 290)); } } }); test('Phototherapy thresholds at 35-37 weeks', () => { for (let gestation = 37; gestation >= 35; gestation--) { // Test cases assert(unitsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false, false, false, false, false), 108)); assert(unitsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 115)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 198)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 234)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 275)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 277)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 290)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 290)); } }); test('Phototherapy thresholds at 33-34 weeks', () => { for (let gestation = 34; gestation >= 33; gestation--) { // Test cases (DAT positive) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, true /* dat */, false, false, false, false), 95.3)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, true, false, false, false, false), 99.9)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, true, false, false, false, false), 168)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, true, false, false, false, false), 199)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, true, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, true, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, true, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, true, false, false, false, false), 220)); // Test cases (DAT negative) assert(unitsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false /* dat */, false, false, false, false), 115)); assert(unitsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 120)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 188)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 219)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 240)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 240)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 240)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 240)); } }); test('Phototherapy thresholds at 31-32 weeks', () => { for (let gestation = 32; gestation >= 31; gestation--) { // Test cases (DAT positive) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, true /* dat */, false, false, false, false), 85.3)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, true, false, false, false, false), 89.9)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, true, false, false, false, false), 154)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, true, false, false, false, false), 184)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, true, false, false, false, false), 200)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, true, false, false, false, false), 200)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, true, false, false, false, false), 200)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, true, false, false, false, false), 200)); // Test cases (DAT negative) assert(unitsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false /* dat */, false, false, false, false), 105)); assert(unitsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 110)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 174)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 204)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 220)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 220)); } }); test('Phototherapy thresholds at 27-30 weeks', () => { for (let gestation = 30; gestation >= 27; gestation--) { // Test cases (DAT positive) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, true /* dat */, false, false, false, false), 75.3)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, true, false, false, false, false), 79.9)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, true, false, false, false, false), 139)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, true, false, false, false, false), 161)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, true, false, false, false, false), 170)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, true, false, false, false, false), 170)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, true, false, false, false, false), 170)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, true, false, false, false, false), 170)); // Test cases (DAT negative) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false /* dat */, false, false, false, false), 95.3)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 99.9)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 159)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 181)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 190)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 190)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 190)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 190)); } }); test('Phototherapy thresholds at < 27 weeks', () => { for (let gestation = 26; gestation >= 0; gestation--) { // Test cases (DAT positive) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, true /* dat */, false, false, false, false), 65.1)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, true, false, false, false, false), 66.6)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, true, false, false, false, false), 104)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, true, false, false, false, false), 123)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, true, false, false, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, true, false, false, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, true, false, false, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, true, false, false, false, false), 130)); // Test cases (DAT negative) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false /* dat */, false, false, false, false), 85.1)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, false, false, false), 86.6)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, false, false, false), 124)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, false, false, false), 143)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, false, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, false, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, false, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, false, false, false), 150)); } }); test('Phototherapy thresholds at < 35 weeks with birth weight < 1000 g', () => { for (let gestation = 34; gestation >= 0; gestation--) { // Test cases (DAT positive) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, true /* dat */, false, true /* bw_lt1000 */, false, false), 65.1)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, true, false, true, false, false), 66.6)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, true, false, true, false, false), 104)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, true, false, true, false, false), 123)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, true, false, true, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, true, false, true, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, true, false, true, false, false), 130)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, true, false, true, false, false), 130)); // Test cases (DAT negative) assert(tenthsEqual(rwh_phototherapy_thresh((6+6/60)/24, gestation, false /* dat */, false, true, false, false), 85.1)); assert(tenthsEqual(rwh_phototherapy_thresh((7+58/60)/24, gestation, false, false, true, false, false), 86.6)); assert(unitsEqual(rwh_phototherapy_thresh((35+11/60)/24, gestation, false, false, true, false, false), 124)); assert(unitsEqual(rwh_phototherapy_thresh((55+21/60)/24, gestation, false, false, true, false, false), 143)); assert(unitsEqual(rwh_phototherapy_thresh((84+11/60)/24, gestation, false, false, true, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((85+29/60)/24, gestation, false, false, true, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((113+11/60)/24, gestation, false, false, true, false, false), 150)); assert(unitsEqual(rwh_phototherapy_thresh((137+31/60)/24, gestation, false, false, true, false, false), 150)); } }); test('Phototherapy thresholds at < 35 weeks are parallel', () => { // Check that DAT-positive and DAT-negative phototherapy thresholds are parallel for (let chartName of ['33-34', '31-32', '27-30', 'lt27']) { let chart = RWH_CURVE_DATA[chartName]; assert(chart['phototherapy_datneg'].length === chart['phototherapy_datpos'].length); for (let i = 0; i < chart['phototherapy_datneg'].length; i++) { assert(chart['phototherapy_datneg'][i][0] === chart['phototherapy_datpos'][i][0]); assert(chart['phototherapy_datneg'][i][1] === chart['phototherapy_datpos'][i][1] + 20); } } }); }); suite('RWH exchange transfusion thresholds', () => { test('Exchange transfusion thresholds at >= 38 weeks', () => { for (let gestation = 42; gestation >= 38; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 283)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 287)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 348)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 384)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 420)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 421)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 432)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 435)); } }); test('Exchange transfusion thresholds at 35-37 weeks', () => { for (let gestation = 37; gestation >= 35; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 248)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 252)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 299)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 334)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 375)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 376)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 385)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 385)); } }); test('Exchange transfusion thresholds at 33-34 weeks', () => { for (let gestation = 34; gestation >= 33; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 225)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 230)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 293)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 324)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 340)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 340)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 340)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 340)); } }); test('Exchange transfusion thresholds at 31-32 weeks', () => { for (let gestation = 32; gestation >= 31; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 208)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 213)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 274)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 304)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 320)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 320)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 320)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 320)); } }); test('Exchange transfusion thresholds at 27-30 weeks', () => { for (let gestation = 30; gestation >= 27; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 185)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 190)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 249)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 276)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 290)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 290)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 290)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 290)); } }); test('Exchange transfusion thresholds at < 27 weeks', () => { for (let gestation = 26; gestation >= 0; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, false, false, false), 165)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, false, false, false), 170)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, false, false, false), 219)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, false, false, false), 241)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, false, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, false, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, false, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, false, false, false), 250)); } }); test('Exchange transfusion thresholds at < 35 weeks with birth weight < 1000 g', () => { for (let gestation = 34; gestation >= 0; gestation--) { // Test cases assert(unitsEqual(rwh_exchange_thresh((6+6/60)/24, gestation, false, false, true /* bw_lt1000 */, false, false), 165)); assert(unitsEqual(rwh_exchange_thresh((7+58/60)/24, gestation, false, false, true, false, false), 170)); assert(unitsEqual(rwh_exchange_thresh((35+11/60)/24, gestation, false, false, true, false, false), 219)); assert(unitsEqual(rwh_exchange_thresh((55+21/60)/24, gestation, false, false, true, false, false), 241)); assert(unitsEqual(rwh_exchange_thresh((84+11/60)/24, gestation, false, false, true, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((85+29/60)/24, gestation, false, false, true, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((113+11/60)/24, gestation, false, false, true, false, false), 250)); assert(unitsEqual(rwh_exchange_thresh((137+31/60)/24, gestation, false, false, true, false, false), 250)); } }); });