Add next 40 backlog calculators (banana dose, bar/barn, awg-swg)

This commit is contained in:
Codex Agent
2026-03-08 02:58:17 +00:00
parent 962b6d090d
commit 25a671535a
3 changed files with 201 additions and 56 deletions

View File

@@ -129,26 +129,47 @@ export function solve(
}
break;
case 'dec-frac':
if (source === 1) {
if (!isNaN(v1)) {
const parts = v1.toString().split('.');
const len = parts[1] ? parts[1].length : 0;
const den = Math.pow(10, len);
const num = v1 * den;
const div = gcd(num, den);
out.val2 = `${num / div}/${den / div}`;
} else { out.val2 = ''; }
} else {
const parts = rawVal2.split('/');
case 'dec-frac': {
// Two calculators share this type:
// - decimal -> fraction
// - fraction -> decimal
// Detect which direction the left field represents via its label.
const fractionFirst = calc.labels.in1.toLowerCase().includes('fraction');
const decimalToFraction = (n: number) => {
if (isNaN(n)) return '';
const parts = n.toString().split('.');
const len = parts[1] ? parts[1].length : 0;
const den = Math.pow(10, len);
const num = n * den;
const div = gcd(num, den);
return `${num / div}/${den / div}`;
};
const fractionToDecimal = (raw: string) => {
const parts = raw.split('/');
if (parts.length === 2 && !isNaN(Number(parts[0])) && !isNaN(Number(parts[1])) && Number(parts[1]) !== 0) {
out.val1 = fmt(Number(parts[0]) / Number(parts[1]));
return fmt(Number(parts[0]) / Number(parts[1]));
}
const f = parseFloat(parts[0]);
return !isNaN(f) ? f.toString() : '';
};
if (fractionFirst) {
if (source === 1) {
out.val2 = fractionToDecimal(rawVal1);
} else {
const f = parseFloat(parts[0]);
out.val1 = !isNaN(f) ? f.toString() : '';
out.val1 = decimalToFraction(v2);
}
} else {
if (source === 1) {
out.val2 = decimalToFraction(v1);
} else {
out.val1 = fractionToDecimal(rawVal2);
}
}
break;
}
case 'db-int':
if (source === 1) {
@@ -232,6 +253,49 @@ export function solve(
break;
}
case 'awg-swg': {
const log92 = Math.log(92);
const awgToDiameterMm = (g: number) => 0.127 * Math.pow(92, (36 - g) / 39);
const diameterMmToAwg = (d: number) => 36 - 39 * Math.log(d / 0.127) / log92;
const swgTable: Record<number, number> = {
0: 8.23, 1: 7.62, 2: 7.01, 3: 6.4, 4: 5.89, 5: 5.385, 6: 4.877,
7: 4.47, 8: 4.064, 9: 3.658, 10: 3.251, 11: 2.946, 12: 2.642, 13: 2.337,
14: 2.032, 15: 1.829, 16: 1.626, 17: 1.422, 18: 1.219, 19: 1.016,
20: 0.914, 21: 0.813, 22: 0.711, 23: 0.61, 24: 0.559, 25: 0.508,
26: 0.457, 27: 0.417, 28: 0.376, 29: 0.345, 30: 0.315, 31: 0.294,
32: 0.274, 33: 0.254, 34: 0.234, 35: 0.213, 36: 0.193,
37: 0.173, 38: 0.152, 39: 0.132, 40: 0.122, 41: 0.112, 42: 0.102,
43: 0.091, 44: 0.081, 45: 0.071, 46: 0.061, 47: 0.051, 48: 0.04,
49: 0.03, 50: 0.025
};
const nearestSwg = (diamMm: number) => {
let bestGauge = 0;
let bestDiff = Number.POSITIVE_INFINITY;
for (const [gStr, d] of Object.entries(swgTable)) {
const diff = Math.abs(diamMm - d);
if (diff < bestDiff) { bestDiff = diff; bestGauge = Number(gStr); }
}
return bestGauge;
};
if (source === 1) {
// AWG -> SWG
if (!isNaN(v1)) {
const diam = awgToDiameterMm(v1);
out.val2 = fmt(nearestSwg(diam));
} else { out.val2 = ''; }
} else {
// SWG -> AWG
if (!isNaN(v2)) {
const diam = swgTable[Math.round(v2)];
if (diam) out.val1 = fmt(diameterMmToAwg(diam));
else out.val1 = '';
} else { out.val1 = ''; }
}
break;
}
case 'ev-lux': {
const isEvFirst = calc.labels.in1.toLowerCase().includes('ev');
const toLux = (ev: number) => 2.5 * Math.pow(2, ev);