const FRACTION_DELIMITER = ' per '; const SYSTEMS = ['imperial', 'metric']; // This table should mirror that of the units.php file and application_inventory_footprint view const UNITS = { // LIQUID (Base is Fluid Oz} 'Fluid Oz' : {'base' : 1.0, 'type' : 'liquid', 'system' : 'imperial', 'display': 'Fl Oz'}, 'Gallons' : {'base' : 128.0, 'type' : 'liquid', 'system' : 'imperial', 'sprayer' : true, 'display': 'Gal'}, 'Pints' : {'base' : 16.0, 'type' : 'liquid', 'system' : 'imperial', 'display': 'Pt'}, 'Quarts' : {'base' : 32.0, 'type' : 'liquid', 'system' : 'imperial', 'display': 'Qt'}, 'Liters' : {'base' : 33.814, 'type' : 'liquid', 'system' : 'metric', 'sprayer' : true, 'display': 'L'}, 'Milliliters' : {'base' : 0.03381402265, 'type' : 'liquid', 'system' : 'metric', 'display': 'mL'}, // SOLID (Base is Oz} 'Oz' : {'base' : 1.0, 'type' : 'solid', 'system' : 'imperial', 'display': 'Oz'}, 'Lbs' : {'base' : 16.0, 'type' : 'solid', 'system' : 'imperial', 'display': 'Lbs'}, 'Grams' : {'base' : 0.03527399072, 'type' : 'solid', 'system' : 'metric', 'display': 'g'}, 'Kilograms' : {'base' : 35.2739907226, 'type' : 'solid', 'system' : 'metric', 'display': 'kg'}, // AREA (Base is Acre} 'Acre' : {'base' : 1.0, 'type' : 'area', 'system' : 'imperial', 'course_area' : true}, '1000 Square Feet' : {'base' : 0.022956841138659, 'type' : 'area', 'system' : 'imperial'}, 'Hectare' : {'base' : 2.47105, 'type' : 'area', 'system' : 'metric', 'course_area' : true}, '100 Square Meters': {'base' : 0.0247105163, 'type' : 'area', 'system' : 'metric'}, 'Square Feet' : {'base' : 0.0000229568, 'type' : 'hidden_area', 'system' : 'imperial', 'course_area' : true}, 'Square Meters' : {'base' : 0.000247105, 'type' : 'hidden_area', 'system' : 'metric', 'course_area' : true}, // TEMPERATURE 'F' : {'base' : temperature_handler, 'type' : 'temperature', 'system' : 'imperial'}, 'C' : {'base' : temperature_handler, 'type' : 'temperature', 'system' : 'metric'}, // SPEED 'MPH' : {'base' : 1.0, 'type' : 'speed', 'system' : 'imperial'}, 'KPH' : {'base' : 0.621371, 'type' : 'speed', 'system' : 'metric'}, // PSI 'Lbs per Square Inch' : {'base' : 1.0, 'type' : 'psi', 'system' : 'imperial'}, 'Bar' : {'base' : 0.0689476, 'type' : 'psi', 'system' : 'metric'}, }; class Unit { static is(unitName, typeOrSys) { if (!UNITS.hasOwnProperty(unitName)) { console.error(`ERROR: ${unitName} not in unit list`); return false } else { return UNITS[unitName].type === typeOrSys || UNITS[unitName].system === typeOrSys } } /* static function get(numeratorOpts = array(), denominatorOpts = FALSE, all = FALSE) { pref = self::preference('pref_general_units'); numerators = array(); foreach (UNITS as numeratorUnit => numeratorMeta) { addUnit = all || in_array(numeratorMeta['system'], pref) || numeratorMeta['system'] == 'both'; foreach (numeratorOpts as field => filter) { if (numeratorMeta[field] !== filter) { addUnit = FALSE; } } if (addUnit) { numerators[] = numeratorUnit; } } if (denominatorOpts !== FALSE) { denominators = self::get(denominatorOpts); fractions = array(); foreach (numerators as numerator) { foreach (denominators as denominator) { // If nominator and denominator are from the same system if (UNITS[numerator]['system'] === UNITS[denominator]['system']) { fractions[] = units::fraction(numerator, denominator); } } } sort(fractions); return fractions; } sort(numerators); return numerators; } */ static convert(from, fromUnit, toUnit) { var to = parseFloat(from); var fromUnit = Unit.fraction(fromUnit); var toUnit = Unit.fraction(toUnit); if (fromUnit['numerator'] !== '1' && toUnit['numerator'] !== '1') { var fromBase = Unit.getBaseConversion(fromUnit['numerator']); var toBase = Unit.getBaseConversion(toUnit['numerator']); if (typeof fromBase === "function") { to = fromBase(from, fromUnit['numerator'], toUnit['numerator']); } else { to = to * fromBase; to = to / toBase; // NUMERATOR } } // ----------------------------------------------------------------------------------- if (fromUnit['denominator'] !== '1' && toUnit['denominator'] !== '1') { // DENOMINATOR var fromBase = Unit.getBaseConversion(fromUnit['denominator']); var toBase = Unit.getBaseConversion(toUnit['denominator']); if (typeof fromBase === "function") { to = to / fromBase(to, fromUnit['denominator'], toUnit['denominator']); } else { to = to / fromBase; to = to * toBase; } } return to; } static fraction(nominatorOrUnit, denominator = false) { if (denominator !== false) { return `${nominatorOrUnit}${FRACTION_DELIMITER}${denominator}`; } var fraction = nominatorOrUnit.split(FRACTION_DELIMITER); var numerator = fraction[0]; var denominator = fraction.length > 1 ? fraction[1] : '1'; return { 'numerator': numerator, 'denominator': denominator, 0: numerator, 1: denominator }; } /** * Converts given quantity to its display form * @param {float} from quantity being converted * @param {string} fromUnit original unit of quantity being converted */ static getDisplayUnits(from, fromUnit) { // Verify we are working with a valid unit if(!UNITS.hasOwnProperty(fromUnit)) { console.error(`${fromUnit} not in units table`); return ''; } var majorUnit, minorUnit; fromUnit = UNITS[fromUnit]; if(fromUnit['system'] == 'imperial' && fromUnit['type'] == 'liquid') { majorUnit = UNITS['Gallons']; minorUnit = UNITS['Fluid Oz']; } else if(fromUnit['system'] == 'metric' && fromUnit['type'] == 'liquid') { majorUnit = UNITS['Liters']; minorUnit = UNITS['Milliliters']; } else if(fromUnit['system'] == 'imperial' && fromUnit['type'] == 'solid') { majorUnit = UNITS['Lbs']; minorUnit = UNITS['Oz']; } else if(fromUnit['system'] == 'metric' && fromUnit['type'] == 'solid') { majorUnit = UNITS['Kilograms']; minorUnit = UNITS['Grams']; } else { console.error("Display format not defined"); return `${from}`; } var fromBase = from * fromUnit['base']; var major = Math.trunc(fromBase / majorUnit['base']); if (minor >= 1) { var minor = Math.round((fromBase - major * majorUnit['base']) / minorUnit['base']); } else { var minor = Math.round(((fromBase - major * majorUnit['base']) / minorUnit['base']) * 100) / 100; } if(minorUnit == UNITS['Fluid Oz']){ if(minor == 128){ minor = 0; major += 1; } } else if(minorUnit == UNITS['Milliliters']){ if(minor == 1000){ minor = 0; major += 1; } } else if(minorUnit == UNITS['Oz']){ if(minor == 16){ minor = 0; major += 1; } } else if(minorUnit == UNITS['Grams']){ if(minor == 1000){ minor = 0; major += 1; } } return major ? `${major} ${majorUnit['display']}, ${minor} ${minorUnit['display']}` : `${minor} ${minorUnit['display']}`; } static getBaseConversion(fromUnit) { return UNITS.hasOwnProperty(fromUnit) ? UNITS[fromUnit].base : 1.0; } } function temperature_handler(from, fromUnit, toUnit) { if (fromUnit == toUnit) { return from; } if (fromUnit == 'C' && toUnit == 'F') { return (from * 9 / 5) + 32; } if (fromUnit == 'F' && toUnit == 'C') { return (from - 32) / (9 / 5); } }