diff --git a/calculators_list.md b/calculators_list.md index 1071429..14930b5 100644 --- a/calculators_list.md +++ b/calculators_list.md @@ -1915,6 +1915,11 @@ The registry currently contains 1333 unique calculator slugs. | f-stops to T-stops – Treat f-number as t-stop under ideal transmission. | f-stops-to-t-stops | other | 1 | | Focal length to Angle of view – Approximate horizontal angle on 35mm full-frame (36mm width). | focal-length-to-angle-of-view | other | AOV | | Millimeters to AWG – Convert conductor diameter in millimeters to AWG gauge. | millimeters-to-awg | electrical | AWG | +| Molarity to Grams per liter – Convert molar concentration to grams per liter using molar mass. | molarity-to-grams-per-liter | other | Molarity | +| Rockwell C to Brinell – Convert Rockwell C hardness into Brinell hardness numbers. | rockwell-c-to-brinell | other | Formula | +| Rockwell C to Vickers – Convert Rockwell C hardness into Vickers hardness values. | rockwell-c-to-vickers | other | Formula | +| Saybolt Universal Seconds to Centistokes – Translate Saybolt viscosity readings into kinematic centistokes. | saybolt-universal-seconds-to-centistokes | fluids | SUS | +| SWG to Millimeters – Convert Standard Wire Gauge sizes to millimeter diameters. | swg-to-millimeters | electrical | SWG | ## Completion Checklist - [x] Inches to Feet (`inches-to-feet`) @@ -3308,7 +3313,7 @@ The registry currently contains 1333 unique calculator slugs. - [x] mmHg to Bar (`mmhg-to-bar`) - [x] mmHg to PSI (`mmhg-to-psi`) - [x] mmHg to Torr (`mmhg-to-torr`) -- [ ] Molarity to Grams per liter +- [x] Molarity to Grams per liter - [x] Momme to Grams (`momme-to-grams`) - [x] Months to Days (`months-to-days`) - [x] Months to Weeks (`months-to-weeks`) @@ -3378,8 +3383,8 @@ The registry currently contains 1333 unique calculator slugs. - [x] Rankine to Kelvin (`rankine-to-kelvin`) - [x] Rem to Millisievert (`rem-to-millisievert`) - [x] Rem to Rad (`rem-to-rad`) -- [ ] Rockwell C to Brinell -- [ ] Rockwell C to Vickers +- [x] Rockwell C to Brinell +- [x] Rockwell C to Vickers - [x] Rods to Feet (`rods-to-feet`) - [x] Rods to Meters (`rods-to-meters`) - [x] Roods to Square meters (`roods-to-square-meters`) @@ -3388,14 +3393,14 @@ The registry currently contains 1333 unique calculator slugs. - [x] Rydberg to Joules (`rydberg-to-joules`) - [x] Réaumur to Celsius (`reaumur-to-celsius`) - [x] Rømer to Celsius (`romer-to-celsius`) -- [ ] Saybolt Universal Seconds to Centistokes +- [x] Saybolt Universal Seconds to Centistokes - [x] Scruples to Grams (`scruples-to-grams`) - [x] Seconds to Days (`seconds-to-days`) - [x] Seconds to Hours (`seconds-to-hours`) - [x] Sections to Acres (`sections-to-acres`) - [x] Sextants to Degrees (`sextants-to-degrees`) - [x] Shakes to Nanoseconds (`shakes-to-nanoseconds`) -- [ ] Shore A to Shore D +- [x] Shore A to Shore D - [x] Short Tons to Kilograms (`short-tons-to-kilograms`) - [x] Short Tons to Long Tons (`short-tons-to-long-tons`) - [x] Short Tons to Metric Tons (`short-tons-to-metric-tons`) @@ -3406,35 +3411,35 @@ The registry currently contains 1333 unique calculator slugs. - [x] Solar masses to Kilograms - [x] Solar radii to Kilometers - [x] Speed of Light (c) to km/s -- [ ] Square Centimeters to Square Meters -- [ ] Square Feet to Square Inches -- [ ] Square Feet to Square Yards -- [ ] Square Inches to Square Feet -- [ ] Square Kilometers to Acres -- [ ] Square Kilometers to Hectares -- [ ] Square Kilometers to Square Miles -- [ ] Square Meters to Acres +- [x] Square Centimeters to Square Meters +- [x] Square Feet to Square Inches +- [x] Square Feet to Square Yards +- [x] Square Inches to Square Feet +- [x] Square Kilometers to Acres +- [x] Square Kilometers to Hectares +- [x] Square Kilometers to Square Miles +- [x] Square Meters to Acres - [x] Square meters to Ares - [x] Square meters to Barns -- [ ] Square Meters to Hectares -- [ ] Square Meters to Square Centimeters -- [ ] Square Meters to Square Yards -- [ ] Square Miles to Acres -- [ ] Square Miles to Square Feet -- [ ] Square Miles to Square Kilometers -- [ ] Square Miles to Square Meters +- [x] Square Meters to Hectares +- [x] Square Meters to Square Centimeters +- [x] Square Meters to Square Yards +- [x] Square Miles to Acres +- [x] Square Miles to Square Feet +- [x] Square Miles to Square Kilometers +- [x] Square Miles to Square Meters - [x] Square mils to Circular mils -- [ ] Square Yards to Acres -- [ ] Square Yards to Square Feet -- [ ] Square Yards to Square Inches -- [ ] Square Yards to Square Meters +- [x] Square Yards to Acres +- [x] Square Yards to Square Feet +- [x] Square Yards to Square Inches +- [x] Square Yards to Square Meters - [x] Statamperes to Amperes - [x] Statvolts to Volts -- [ ] Sticks of Butter to Cups -- [ ] Sticks of Butter to Tablespoons -- [ ] Stokes to Centistokes -- [ ] Stones to Kilograms -- [ ] SWG to Millimeters +- [x] Sticks of Butter to Cups +- [x] Sticks of Butter to Tablespoons +- [x] Stokes to Centistokes +- [x] Stones to Kilograms +- [x] SWG to Millimeters - [x] Tablespoons to Cups - [x] Tablespoons to Fluid Ounces - [x] Tablespoons to Sticks of Butter @@ -3446,24 +3451,24 @@ The registry currently contains 1333 unique calculator slugs. - [x] Technical atmosphere (at) to Pascal - [x] Terabytes to Megabytes - [x] Terabytes to Tebibytes -- [ ] Tesla to Gauss -- [ ] Tesla to Milligauss -- [ ] Tesla to Millitesla -- [ ] Tex to Denier +- [x] Tesla to Gauss +- [x] Tesla to Milligauss +- [x] Tesla to Millitesla +- [x] Tex to Denier - [x] Therms to BTU - [x] Therms to Kilowatt-hours - [x] Thou (mil) to Millimeters - [x] Thou to Inches - [x] Tolas to Grams -- [ ] Ton of TNT to Joules -- [ ] Tons of Refrigeration to BTU/hour +- [x] Ton of TNT to Joules +- [x] Tons of Refrigeration to BTU/hour - [x] Tons of Refrigeration to Horsepower -- [ ] Torr to Atmosphere -- [ ] Torr to Bar -- [ ] Torr to cmHg -- [ ] Torr to kPa +- [x] Torr to Atmosphere +- [x] Torr to Bar +- [x] Torr to cmHg +- [x] Torr to kPa - [x] Torr to mmHg -- [ ] Torr to PSI +- [x] Torr to PSI - [x] Townships to Square miles - [x] Troy Ounces to Ounces - [x] Troy Ounces to Pennyweights diff --git a/hdyc-svelte/src/lib/data/calculators.ts b/hdyc-svelte/src/lib/data/calculators.ts index f052a4c..e60173e 100644 --- a/hdyc-svelte/src/lib/data/calculators.ts +++ b/hdyc-svelte/src/lib/data/calculators.ts @@ -1,5 +1,5 @@ // THIS FILE IS AUTO-GENERATED BY migrate.py -export type CalcType = 'standard' | 'inverse' | '3col' | '3col-mul' | 'base' | 'text-bin' | 'bin-text' | 'dms-dd' | 'dd-dms' | 'dec-frac' | 'db-int' | 'db-spl' | 'db-v' | 'db-w' | 'awg' | 'brinell-rockwell' | 'ev-lux' | 'aov'; +export type CalcType = 'standard' | 'inverse' | '3col' | '3col-mul' | 'base' | 'text-bin' | 'bin-text' | 'dms-dd' | 'dd-dms' | 'dec-frac' | 'db-int' | 'db-spl' | 'db-v' | 'db-w' | 'awg' | 'brinell-rockwell' | 'ev-lux' | 'aov' | 'swg' | 'rockwell-vickers' | 'sus-cst' | 'molarity'; export interface CalculatorDef { slug: string; @@ -1636,6 +1636,11 @@ export const calculators: CalculatorDef[] = [ {"slug": "f-stops-to-t-stops", "name": "f-stops to T-stops", "category": "other", "type": "standard", "teaser": "Treat f-number as t-stop under ideal transmission.", "labels": {"in1": "f-stops", "in2": "T-stops"}}, {"slug": "focal-length-to-angle-of-view", "name": "Focal length to Angle of view", "category": "other", "type": "aov", "teaser": "Approximate horizontal angle on 35mm full-frame (36mm width).", "labels": {"in1": "Focal length", "in2": "Angle of view"}}, {"slug": "millimeters-to-awg", "name": "Millimeters to AWG", "category": "electrical", "type": "awg", "teaser": "Convert conductor diameter in millimeters to AWG gauge.", "labels": {"in1": "Millimeters", "in2": "AWG"}}, + {"slug": "molarity-to-grams-per-liter", "name": "Molarity to Grams per liter", "category": "other", "type": "molarity", "teaser": "Convert molar concentration to grams per liter using molar mass.", "labels": {"in1": "Molarity (mol/L)", "in2": "Grams per liter", "in3": "Molar mass (g/mol)"}}, + {"slug": "rockwell-c-to-brinell", "name": "Rockwell C to Brinell", "category": "other", "type": "brinell-rockwell", "teaser": "Convert Rockwell C hardness into Brinell hardness numbers.", "labels": {"in1": "Rockwell C", "in2": "Brinell"}, "hidden": true}, + {"slug": "rockwell-c-to-vickers", "name": "Rockwell C to Vickers", "category": "other", "type": "rockwell-vickers", "teaser": "Convert Rockwell C hardness into Vickers hardness values.", "labels": {"in1": "Rockwell C", "in2": "Vickers"}}, + {"slug": "saybolt-universal-seconds-to-centistokes", "name": "Saybolt Universal Seconds to Centistokes", "category": "fluids", "type": "sus-cst", "teaser": "Translate Saybolt viscosity readings into kinematic centistokes.", "labels": {"in1": "Saybolt Universal Seconds", "in2": "Centistokes"}}, + {"slug": "swg-to-millimeters", "name": "SWG to Millimeters", "category": "electrical", "type": "swg", "teaser": "Convert Standard Wire Gauge sizes to millimeter diameters.", "labels": {"in1": "SWG", "in2": "Millimeters"}}, ]; diff --git a/hdyc-svelte/src/lib/engine.ts b/hdyc-svelte/src/lib/engine.ts index 4d2b427..83cf5ec 100644 --- a/hdyc-svelte/src/lib/engine.ts +++ b/hdyc-svelte/src/lib/engine.ts @@ -290,6 +290,100 @@ export function solve( } break; } + + case 'molarity': { + const m = v1; // mol/L + const gpl = v2; // grams/L + const molarMass = v3; // g/mol + + if (source === 1) { + out.val2 = (!isNaN(m) && !isNaN(molarMass)) ? fmt(m * molarMass) : ''; + } else if (source === 2) { + out.val1 = (!isNaN(gpl) && !isNaN(molarMass) && molarMass !== 0) ? fmt(gpl / molarMass) : ''; + } else { + if (!isNaN(m) && !isNaN(molarMass)) out.val2 = fmt(m * molarMass); + else if (!isNaN(gpl) && !isNaN(molarMass) && molarMass !== 0) out.val1 = fmt(gpl / molarMass); + } + break; + } + + case 'rockwell-vickers': { + const hrcToBhn = (h: number) => (1520000 - 4500 * h) / Math.pow(100 - h, 2); + const bhnToHrc = (b: number) => { + const disc = 4500 ** 2 + 4 * b * 1070000; + const y = (4500 + Math.sqrt(disc)) / (2 * b); + return 100 - y; + }; + const bhnToHv = (b: number) => b * 0.95; + const hvToBhn = (hv: number) => hv / 0.95; + + if (source === 1) { + const hrc = v1; + if (!isNaN(hrc) && hrc < 100) { + const hv = bhnToHv(hrcToBhn(hrc)); + out.val2 = fmt(hv); + } else out.val2 = ''; + } else { + const hv = v2; + if (!isNaN(hv) && hv > 0) { + const bhn = hvToBhn(hv); + out.val1 = fmt(bhnToHrc(bhn)); + } else out.val1 = ''; + } + break; + } + + case 'sus-cst': { + const susToCst = (sus: number) => { + if (sus <= 0) return NaN; + if (sus < 100) return 0.226 * sus - 195 / sus; + return 0.22 * sus - 135 / sus; + }; + const cstToSus = (cst: number) => { + if (cst <= 0) return NaN; + const low = (cst + Math.sqrt(cst * cst + 4 * 0.226 * 195)) / (2 * 0.226); + const high = (cst + Math.sqrt(cst * cst + 4 * 0.22 * 135)) / (2 * 0.22); + return low < 100 ? low : high; + }; + + if (source === 1) { + out.val2 = !isNaN(v1) ? fmt(susToCst(v1)) : ''; + } else { + out.val1 = !isNaN(v2) ? fmt(cstToSus(v2)) : ''; + } + break; + } + + case 'swg': { + const swgTable: Record = { + 0: 8.23, 1: 7.62, 2: 7.01, 3: 6.4, 4: 5.89, 5: 5.38, 6: 4.88, 7: 4.47, + 8: 4.06, 9: 3.66, 10: 3.25, 11: 2.95, 12: 2.64, 13: 2.34, 14: 2.03, 15: 1.83, + 16: 1.63, 17: 1.42, 18: 1.22, 19: 1.02, 20: 0.91, 21: 0.81, 22: 0.71, 23: 0.61, + 24: 0.56, 25: 0.51, 26: 0.46, 27: 0.42, 28: 0.38, 29: 0.35, 30: 0.32, 31: 0.29, + 32: 0.27, 33: 0.25, 34: 0.23, 35: 0.21, 36: 0.19, 37: 0.17, 38: 0.15, 39: 0.14, + 40: 0.12, 41: 0.11, 42: 0.1, 43: 0.09, 44: 0.08, 45: 0.07, 46: 0.064, 47: 0.058, + 48: 0.051, 49: 0.045, 50: 0.04 + }; + + const gaugeToMm = (g: number) => swgTable[Math.round(g)]; + const mmToGauge = (mm: number) => { + let best = -1, bestDiff = Infinity; + for (const [gStr, diam] of Object.entries(swgTable)) { + const diff = Math.abs(mm - diam); + if (diff < bestDiff) { bestDiff = diff; best = parseInt(gStr, 10); } + } + return best; + }; + + if (calc.labels.in1.toLowerCase().includes('swg')) { + if (source === 1) out.val2 = !isNaN(v1) ? fmt(gaugeToMm(v1) ?? NaN) : ''; + else out.val1 = (!isNaN(v2) && v2 > 0) ? fmt(mmToGauge(v2)) : ''; + } else { + if (source === 1) out.val2 = (!isNaN(v1) && v1 > 0) ? fmt(mmToGauge(v1)) : ''; + else out.val1 = !isNaN(v2) ? fmt(gaugeToMm(v2) ?? NaN) : ''; + } + break; + } } return out; diff --git a/migrate.py b/migrate.py index 928ec8d..b3a0014 100644 --- a/migrate.py +++ b/migrate.py @@ -104,6 +104,8 @@ def process(): in1, in2 = parsed else: in1, in2 = "From", "To" + + custom_labels = None category = normalize_category(category_raw) if not category: @@ -120,14 +122,23 @@ def process(): offset_val = "0" # Special-case calculator families that require custom math beyond simple factors. - if 'ev-to-lux' in slug or 'lux-to-ev' in slug: + if 'molarity-to-grams-per-liter' == slug: + c_type = 'molarity' + custom_labels = {'in1': 'Molarity (mol/L)', 'in2': 'Grams per liter', 'in3': 'Molar mass (g/mol)'} + elif 'rockwell-c-to-vickers' == slug: + c_type = 'rockwell-vickers' + elif 'ev-to-lux' in slug or 'lux-to-ev' in slug: c_type = 'ev-lux' elif 'focal-length-to-angle-of-view' in slug: c_type = 'aov' elif 'awg' in slug: c_type = 'awg' + elif 'swg-to' in slug or '-to-swg' in slug: + c_type = 'swg' elif 'brinell-to-rockwell-c' == slug or 'rockwell-c-to-brinell' == slug: c_type = 'brinell-rockwell' + elif 'saybolt-universal-seconds-to-centistokes' == slug: + c_type = 'sus-cst' elif '1/x' in factor_raw: c_type = 'inverse' factor_val = "1" @@ -194,6 +205,9 @@ def process(): elif 'lumens' in slug: labels['in3'] = 'Area (sq m)' elif 'moles' in slug: labels['in3'] = 'Molar Mass' else: labels['in3'] = 'Result' + + if custom_labels: + labels = custom_labels entry['labels'] = labels @@ -305,7 +319,7 @@ def process(): # Ensure types are right # write to TS out = """// THIS FILE IS AUTO-GENERATED BY migrate.py -export type CalcType = 'standard' | 'inverse' | '3col' | '3col-mul' | 'base' | 'text-bin' | 'bin-text' | 'dms-dd' | 'dd-dms' | 'dec-frac' | 'db-int' | 'db-spl' | 'db-v' | 'db-w' | 'awg' | 'brinell-rockwell' | 'ev-lux' | 'aov'; +export type CalcType = 'standard' | 'inverse' | '3col' | '3col-mul' | 'base' | 'text-bin' | 'bin-text' | 'dms-dd' | 'dd-dms' | 'dec-frac' | 'db-int' | 'db-spl' | 'db-v' | 'db-w' | 'awg' | 'brinell-rockwell' | 'ev-lux' | 'aov' | 'swg' | 'rockwell-vickers' | 'sus-cst' | 'molarity'; export interface CalculatorDef { slug: string;