From 2538351ad4addeb1882c0a678576d2a4e6436bcd Mon Sep 17 00:00:00 2001 From: lowercasedonkey <lowercasedonkey@gmail.com> Date: Wed, 23 Dec 2020 16:28:47 -0500 Subject: [PATCH] unit related functions to new file --- src/js/utilsFC.js | 506 ------------------------------------------- src/js/utilsUnits.js | 505 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 505 insertions(+), 506 deletions(-) create mode 100644 src/js/utilsUnits.js diff --git a/src/js/utilsFC.js b/src/js/utilsFC.js index 14f26e503cc..dc02af8842c 100644 --- a/src/js/utilsFC.js +++ b/src/js/utilsFC.js @@ -948,380 +948,6 @@ globalThis.Categorizer = class { } }; -/** - * Returns numbers as text, e.g. 10 as "ten", according to the player's settings - * @param {number} x - * @param {boolean} [printText=false] (optional) - * @returns {string} - */ -globalThis.num = function(x, printText = false) { - const max = V.showNumbersMax; - - const ONE_TO_NINETEEN = [ - "one", "two", "three", "four", "five", - "six", "seven", "eight", "nine", "ten", - "eleven", "twelve", "thirteen", "fourteen", "fifteen", - "sixteen", "seventeen", "eighteen", "nineteen", - ]; - - const TENS = [ - "ten", "twenty", "thirty", "forty", "fifty", - "sixty", "seventy", "eighty", "ninety", - ]; - - const SCALES = ["thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion"]; - - /** - * helper function for use with Array.filter - * @param {any} item - * @returns {boolean} - */ - function isTruthy(item) { - return !!item; - } - - /** - * convert a number into "chunks" of 0-999 - * @param {number} number - * @returns {number[]} - */ - function chunk(number) { - const thousands = []; - - while (number > 0) { - thousands.push(number % 1000); - number = Math.floor(number / 1000); - } - - return thousands; - } - - /** - * translate a number from 1-999 into English - * @param {number} number - * @returns {string} - */ - function inEnglish(number) { - let hundreds; - let tens; - let ones; - const words = []; - - if (number === 0) { - return "zero"; - } - - if (number < 20) { - return ONE_TO_NINETEEN[number - 1]; // may be undefined - } - - if (number < 100) { - ones = number % 10; - tens = number / 10 | 0; // equivalent to Math.floor(number / 10) - - words.push(TENS[tens - 1]); - words.push(inEnglish(ones)); - - return words.filter(isTruthy).join("-"); - } - - hundreds = number / 100 | 0; - words.push(inEnglish(hundreds)); - words.push("hundred"); - words.push(inEnglish(number % 100)); - - return words.filter(isTruthy).join(" "); - } - - if (printText) { - return inEnglish(x); - } - - /** - * append the word for a scale. Made for use with Array.map - * @param {string} chunk - * @param {number} exp - * @returns {string} - */ - function appendScale(chunk, exp) { - let scale; - if (!chunk) { - return null; - } - scale = SCALES[exp - 1]; - return [chunk, scale].filter(isTruthy).join(" "); - } - - if (V.showNumbers === 2) { - return commaNum(x); - } else { - if (x === 0) { - return "zero"; - } - - if (V.showNumbers === 1 && Math.abs(x) > max) { - return commaNum(x); - } - - let numberAsString = chunk(Math.abs(x)) - .map(inEnglish) - .map(appendScale) - .filter(isTruthy) - .reverse() - .join(" "); - - if (x > 0) { - return numberAsString; - } else { - return `negative ${numberAsString}`; - } - } -}; - -globalThis.asPlural = function(single, plural) { - if (typeof single !== 'string') { - let asObj = single; - single = asObj.single; - plural = asObj.plural; - } - if (plural == null) { - plural = single + "s"; - } - return plural; -}; -globalThis.asSingular = function(single) { - if (typeof single !== 'string') { - let asObj = single; - single = asObj.single; - } - return single; -}; -// When 1, shows "a (slave)" -globalThis.numberWithPlural = function(number, single, plural) { - if (number === 0) { - return "no " + asPlural(single, plural); - } else if (number === 1) { - return addA(asSingular(single)); - } else if (number > 0 && number < 1) { - return "less than one " + asSingular(single); - } else { - return number + " " + asPlural(single, plural); - } -}; - -// when 1, shows "one (slave)" -globalThis.numberWithPluralOne = function(number, single, plural) { - if (number === 0) { - return "no " + asPlural(single, plural); - } else if (number === 1) { - return "one " + asSingular(single); - } else if (number > 0 && number < 1) { - return "less than one " + asSingular(single); - } else { - return number + " " + asPlural(single, plural); - } -}; -// shows "less than one (slave)" instead of "no (slaves)" when number is 0. -globalThis.numberWithPluralNonZero = function(number, single, plural) { - if (number === 0) { - number = 0.1; - } - return numberWithPlural(number, single, plural); -}; -globalThis.onlyPlural = function(number, single, plural) { - if (number > 0 && number <= 1) { - return asSingular(single); - } - return asPlural(single, plural); -}; -globalThis.Separator = function(SeparatorObject) { - if (SeparatorObject.need) { - return SeparatorObject.text; - } - SeparatorObject.need = true; - return ""; -}; -/** - * Returns numbers with comma, e.g. 10000 as "10,000", according to the player's settings - * @param {number} s - * @returns {string} - */ -globalThis.commaNum = function(s) { - // Separated from num because some places in code (like long lists, tables) should never have numbers spelled out, but still benefit from commas - if (!s) { - return "0"; - } - if (V.formatNumbers !== 1) { - return s.toString(); - } else { - return s.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); - } -}; - -/** - * Returns the number of weeks in a years / months / weeks format - * @param {number} weeks - * @returns {string} - */ -globalThis.years = function(weeks) { - let years = 0; - let quarters = 0; // needed for calc, not user facing - let months = 0; - let array = []; - - // A year is always 52 weeks - // that could be 13 months, but lets say 4 quarters each getting an extra week (13 weeks) - - // Find years - years = Math.trunc(weeks / 52); - - if (years >= 1) { // Is there at least 1 year - weeks = weeks - (years * 52); // Find leftover weeks - } - if (weeks && weeks / 13 >= 1) { // Is there at least 1 quarter - quarters = Math.trunc(weeks / 13); // How many quarters? - weeks = weeks - (quarters * 13); // A quarter contains 13 weeks, how many extra weeks do we have? - } - if (weeks && weeks / 4 >= 1) { // Is there at least 1 month - months = Math.trunc(weeks / 4); // How many months? - if (months === 3) { // Almost a quarter of a year - months--; // Quarters have 13 weeks though, so let's be sure the extra is in weeks. Otherwise 51 will return "12 months" instead of "11 months and 4 weeks." - } - weeks = weeks - (months * 4); // A month contains 4 weeks, how many extra weeks do we have? - } - - // So we have years, quarters, months, and weeks. - - // Quarters are useless so: - - months += quarters * 3; // Each quarter has three months. - - if (years) { - array.push(`${num(years)} year${years !== 1 ? `s` : ``}`); - } - - if (months) { - array.push(`${num(months)} month${months !== 1 ? `s` : ``}`); - } - - if (weeks) { - array.push(`${num(weeks)} week${weeks !== 1 ? `s` : ``}`); - } - - return array.toStringExt(); -}; -/** - * @param {number} [weeks] - * @param {number} [bonusDay] - * @returns {Date} - */ -globalThis.asDate = function(weeks = null, bonusDay = 0) { - if (weeks == null) { - weeks = V.week; - } - let d = new Date(2037, 0, 12); - d.setDate(d.getDate() + weeks * 7 + bonusDay); - return d; -}; -/** - * @param {number} [weeks] - * @param {number} [bonusDay] - * @returns {string} - */ -globalThis.asDateString = function(weeks = null, bonusDay = 0) { - return asDate(weeks, bonusDay).toLocaleString(undefined, {year: 'numeric', month: 'long', day: 'numeric'}); -}; - -/** - * @param {number} s - * @returns {string} - */ -globalThis.cashFormat = function(s) { - if (s < 0) { - return `-¤${commaNum(Math.abs(s))}`; - } - return `¤${commaNum(s)}`; -}; -globalThis.cashFormatColor = function(s, invert = false) { - if (invert) { - s = -1 * s; - } - // Display red if the value is negative, unless invert is true - if (s < 0) { - return `<span class='red'>${cashFormat(s)}</span>`; - // White for exactly zero - } else if (s === 0) { - return `<span>${cashFormat(s)}</span>`; - // Yellow for positive - } else { - return `<span class='yellowgreen'>${cashFormat(s)}</span>`; - } -}; - -/** - * @param {number} s - * @returns {string} - */ -globalThis.repFormat = function(s) { - /* if (!s) { s = 0; }*/ - if (V.cheatMode === 1 || V.debugMode === 1) { - if (s > 0) { - return `<span class="green">${commaNum(Math.round(s * 100) / 100)} rep</span>`; - } else if (s < 0) { - return `<span class="red">${commaNum(Math.round(s * 100) / 100)} rep</span>`; - } else { - return `${commaNum(Math.round(s * 100) / 100)} rep`; - } - } else { - /* In order to calculate just how much any one category matters so we can show a "fuzzy" symbolic value to the player, we need to know how "busy" reputation was this week. To calculate this, I ADD income to expenses. Why? 100 - 100 and 10000 - 10000 BOTH are 0, but a +50 event matters a lot more in the first case than the second. I exclude overflow from the calculation because it's not a "real" expense for our purposes, and divide by half just to make percentages a bit easier. */ - let weight = s / (((V.lastWeeksRepIncome.Total - V.lastWeeksRepExpenses.Total) + V.lastWeeksRepExpenses.overflow) / 2); - if (weight > 0.60) { - return `<span class="green">+++++ rep</span>`; - } else if (weight > 0.45) { - return `<span class="green">++++ rep</span>`; - } else if (weight > 0.30) { - return `<span class="green">+++ rep</span>`; - } else if (weight > 0.15) { - return `<span class="green">++ rep</span>`; - } else if (weight > 0.0) { - return `<span class="green">+ rep</span>`; - } else if (weight === 0) { - return "0 rep"; - } else if (weight < -0.60) { - return `<span class="red">−−−−− rep</span>`; - } else if (weight < -0.45) { - return `<span class="red">−−−− rep</span>`; - } else if (weight < -0.30) { - return `<span class="red">−−− rep</span>`; - } else if (weight < -0.15) { - return `<span class="red">−− rep</span>`; - } else if (weight < 0) { - return `<span class="red">− rep</span>`; - } - /* return weight;*/ - } -}; - -/** - * @param {number} s - * @returns {string} - */ -globalThis.massFormat = function(s) { - if (!s) { - s = 0; - } - if (Math.abs(s) >= 1000) { - s = Math.trunc(s / 1000); - if (s !== 1) { - return `${num(s)} tons`; - } else { - return `${num(s)} ton`; - } - } else { - return `${num(s)} kg`; - } -}; - /** * @param {string} category * @param {string} title @@ -1441,138 +1067,6 @@ globalThis.getSlaveTrustClass = function(slave) { } }; -/** - * Takes an integer e.g. slave.hLength, returns a string in the format 10 inches - * @param {number} cm - * @returns {string} - */ -globalThis.cmToInchString = function(cm) { - let inches = cm / 2.54; - if (inches > 0 && inches < 1) { - return "less than an inch"; - } - inches = Math.round(inches); - if (inches === 1) { - return "1 inch"; - } - return `${inches} inches`; -}; - -/** - * takes an integer e.g. slave.height, returns a string in the format 6'5" - * @param {number} cm - * @returns {string} - */ -globalThis.cmToFootInchString = function(cm) { - if (Math.round(cm / 2.54) < 12) { - return cmToInchString(cm); - } - return `${Math.trunc(Math.round(cm / 2.54) / 12)}'${Math.round(cm / 2.54) % 12}"`; -}; - -/** - * takes a dick value e.g. slave.dick, returns a string in the format 6 inches - * @param {number} dick - * @returns {string} - */ -globalThis.dickToInchString = function(dick) { - return cmToInchString(dickToCM(dick)); -}; - -/** - * takes a dick value e.g. slave.dick, returns an int of the dick length in cm - * @param {number} dick - * @returns {number} - */ -globalThis.dickToCM = function(dick) { - if (dick < 9) { - return dick * 5; - } else if (dick === 9) { - return 50; - } - return dick * 6; -}; -/** - * takes a ball value e.g. slave.balls, returns a string in the format 3 inches - * @param {number} balls - * @returns {string} - */ -globalThis.ballsToInchString = function(balls) { - return cmToInchString(ballsToCM(balls)); -}; - -/** - * takes a ball value e.g. slave.balls, returns an int of the ball size in cm - * @param {number} balls - * @returns {number} - */ -globalThis.ballsToCM = function(balls) { - if (balls < 2) { - return 0; - } - return (balls < 10 ? (balls - 1) * 2 : balls * 2); -}; - -/** - * takes a dick value e.g. slave.dick, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` - * @param {number} dick - * @returns {string} - */ -globalThis.dickToEitherUnit = function(dick) { - if (V.showInches === 1) { - return `${dickToCM(dick)}cm (${dickToInchString(dick)})`; - } - if (V.showInches === 2) { - return dickToInchString(dick); - } - return `${dickToCM(dick)}cm`; -}; - -/** - * takes a ball value e.g. slave.balls, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` - * @param {number} balls - * @returns {string} - */ -globalThis.ballsToEitherUnit = function(balls) { - if (V.showInches === 1) { - return `${ballsToCM(balls)}cm (${ballsToInchString(balls)})`; - } - if (V.showInches === 2) { - return ballsToInchString(balls); - } - return `${ballsToCM(balls)}cm`; -}; - -/** - * takes an int in centimeters e.g. slave.height, returns a string in the format of either `200cm (6'7")`, `6'7"`, or `200cm` - * @param {number} height - * @returns {string} - */ -globalThis.heightToEitherUnit = function(height) { - if (V.showInches === 1) { - return `${height}cm (${cmToFootInchString(height)})`; - } - if (V.showInches === 2) { - return cmToFootInchString(height); - } - return `${height}cm`; -}; - -/** - * takes an int in centimeters e.g. slave.hLength, returns a string in the format of either `30cm (12 inches)`, `12 inches`, or `30cm` - * @param {number} length - * @returns {string} - */ -globalThis.lengthToEitherUnit = function(length) { - if (V.showInches === 1) { - return `${length}cm (${cmToInchString(length)})`; - } - if (V.showInches === 2) { - return cmToInchString(length); - } - return `${length}cm`; -}; - /** * @param {App.Entity.SlaveState} slave * @param {number} [induce] diff --git a/src/js/utilsUnits.js b/src/js/utilsUnits.js new file mode 100644 index 00000000000..bb2ca3278f4 --- /dev/null +++ b/src/js/utilsUnits.js @@ -0,0 +1,505 @@ +/** + * Returns numbers as text, e.g. 10 as "ten", according to the player's settings + * @param {number} x + * @param {boolean} [printText=false] (optional) + * @returns {string} + */ +globalThis.num = function(x, printText = false) { + const max = V.showNumbersMax; + + const ONE_TO_NINETEEN = [ + "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", + "eleven", "twelve", "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eighteen", "nineteen", + ]; + + const TENS = [ + "ten", "twenty", "thirty", "forty", "fifty", + "sixty", "seventy", "eighty", "ninety", + ]; + + const SCALES = ["thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion"]; + + /** + * helper function for use with Array.filter + * @param {any} item + * @returns {boolean} + */ + function isTruthy(item) { + return !!item; + } + + /** + * convert a number into "chunks" of 0-999 + * @param {number} number + * @returns {number[]} + */ + function chunk(number) { + const thousands = []; + + while (number > 0) { + thousands.push(number % 1000); + number = Math.floor(number / 1000); + } + + return thousands; + } + + /** + * translate a number from 1-999 into English + * @param {number} number + * @returns {string} + */ + function inEnglish(number) { + let hundreds; + let tens; + let ones; + const words = []; + + if (number === 0) { + return "zero"; + } + + if (number < 20) { + return ONE_TO_NINETEEN[number - 1]; // may be undefined + } + + if (number < 100) { + ones = number % 10; + tens = number / 10 | 0; // equivalent to Math.floor(number / 10) + + words.push(TENS[tens - 1]); + words.push(inEnglish(ones)); + + return words.filter(isTruthy).join("-"); + } + + hundreds = number / 100 | 0; + words.push(inEnglish(hundreds)); + words.push("hundred"); + words.push(inEnglish(number % 100)); + + return words.filter(isTruthy).join(" "); + } + + if (printText) { + return inEnglish(x); + } + + /** + * append the word for a scale. Made for use with Array.map + * @param {string} chunk + * @param {number} exp + * @returns {string} + */ + function appendScale(chunk, exp) { + let scale; + if (!chunk) { + return null; + } + scale = SCALES[exp - 1]; + return [chunk, scale].filter(isTruthy).join(" "); + } + + if (V.showNumbers === 2) { + return commaNum(x); + } else { + if (x === 0) { + return "zero"; + } + + if (V.showNumbers === 1 && Math.abs(x) > max) { + return commaNum(x); + } + + let numberAsString = chunk(Math.abs(x)) + .map(inEnglish) + .map(appendScale) + .filter(isTruthy) + .reverse() + .join(" "); + + if (x > 0) { + return numberAsString; + } else { + return `negative ${numberAsString}`; + } + } +}; + +globalThis.asPlural = function(single, plural) { + if (typeof single !== 'string') { + let asObj = single; + single = asObj.single; + plural = asObj.plural; + } + if (plural == null) { + plural = single + "s"; + } + return plural; +}; +globalThis.asSingular = function(single) { + if (typeof single !== 'string') { + let asObj = single; + single = asObj.single; + } + return single; +}; +// When 1, shows "a (slave)" +globalThis.numberWithPlural = function(number, single, plural) { + if (number === 0) { + return "no " + asPlural(single, plural); + } else if (number === 1) { + return addA(asSingular(single)); + } else if (number > 0 && number < 1) { + return "less than one " + asSingular(single); + } else { + return number + " " + asPlural(single, plural); + } +}; + +// when 1, shows "one (slave)" +globalThis.numberWithPluralOne = function(number, single, plural) { + if (number === 0) { + return "no " + asPlural(single, plural); + } else if (number === 1) { + return "one " + asSingular(single); + } else if (number > 0 && number < 1) { + return "less than one " + asSingular(single); + } else { + return number + " " + asPlural(single, plural); + } +}; +// shows "less than one (slave)" instead of "no (slaves)" when number is 0. +globalThis.numberWithPluralNonZero = function(number, single, plural) { + if (number === 0) { + number = 0.1; + } + return numberWithPlural(number, single, plural); +}; +globalThis.onlyPlural = function(number, single, plural) { + if (number > 0 && number <= 1) { + return asSingular(single); + } + return asPlural(single, plural); +}; +globalThis.Separator = function(SeparatorObject) { + if (SeparatorObject.need) { + return SeparatorObject.text; + } + SeparatorObject.need = true; + return ""; +}; +/** + * Returns numbers with comma, e.g. 10000 as "10,000", according to the player's settings + * @param {number} s + * @returns {string} + */ +globalThis.commaNum = function(s) { + // Separated from num because some places in code (like long lists, tables) should never have numbers spelled out, but still benefit from commas + if (!s) { + return "0"; + } + if (V.formatNumbers !== 1) { + return s.toString(); + } else { + return s.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); + } +}; + +/** + * Returns the number of weeks in a years / months / weeks format + * @param {number} weeks + * @returns {string} + */ +globalThis.years = function(weeks) { + let years = 0; + let quarters = 0; // needed for calc, not user facing + let months = 0; + let array = []; + + // A year is always 52 weeks + // that could be 13 months, but lets say 4 quarters each getting an extra week (13 weeks) + + // Find years + years = Math.trunc(weeks / 52); + + if (years >= 1) { // Is there at least 1 year + weeks = weeks - (years * 52); // Find leftover weeks + } + if (weeks && weeks / 13 >= 1) { // Is there at least 1 quarter + quarters = Math.trunc(weeks / 13); // How many quarters? + weeks = weeks - (quarters * 13); // A quarter contains 13 weeks, how many extra weeks do we have? + } + if (weeks && weeks / 4 >= 1) { // Is there at least 1 month + months = Math.trunc(weeks / 4); // How many months? + if (months === 3) { // Almost a quarter of a year + months--; // Quarters have 13 weeks though, so let's be sure the extra is in weeks. Otherwise 51 will return "12 months" instead of "11 months and 4 weeks." + } + weeks = weeks - (months * 4); // A month contains 4 weeks, how many extra weeks do we have? + } + + // So we have years, quarters, months, and weeks. + + // Quarters are useless so: + + months += quarters * 3; // Each quarter has three months. + + if (years) { + array.push(`${num(years)} year${years !== 1 ? `s` : ``}`); + } + + if (months) { + array.push(`${num(months)} month${months !== 1 ? `s` : ``}`); + } + + if (weeks) { + array.push(`${num(weeks)} week${weeks !== 1 ? `s` : ``}`); + } + + return array.toStringExt(); +}; +/** + * @param {number} [weeks] + * @param {number} [bonusDay] + * @returns {Date} + */ +globalThis.asDate = function(weeks = null, bonusDay = 0) { + if (weeks == null) { + weeks = V.week; + } + let d = new Date(2037, 0, 12); + d.setDate(d.getDate() + weeks * 7 + bonusDay); + return d; +}; +/** + * @param {number} [weeks] + * @param {number} [bonusDay] + * @returns {string} + */ +globalThis.asDateString = function(weeks = null, bonusDay = 0) { + return asDate(weeks, bonusDay).toLocaleString(undefined, {year: 'numeric', month: 'long', day: 'numeric'}); +}; + +/** + * @param {number} s + * @returns {string} + */ +globalThis.cashFormat = function(s) { + if (s < 0) { + return `-¤${commaNum(Math.abs(s))}`; + } + return `¤${commaNum(s)}`; +}; +globalThis.cashFormatColor = function(s, invert = false) { + if (invert) { + s = -1 * s; + } + // Display red if the value is negative, unless invert is true + if (s < 0) { + return `<span class='red'>${cashFormat(s)}</span>`; + // White for exactly zero + } else if (s === 0) { + return `<span>${cashFormat(s)}</span>`; + // Yellow for positive + } else { + return `<span class='yellowgreen'>${cashFormat(s)}</span>`; + } +}; + +/** + * @param {number} s + * @returns {string} + */ +globalThis.repFormat = function(s) { + /* if (!s) { s = 0; }*/ + if (V.cheatMode === 1 || V.debugMode === 1) { + if (s > 0) { + return `<span class="green">${commaNum(Math.round(s * 100) / 100)} rep</span>`; + } else if (s < 0) { + return `<span class="red">${commaNum(Math.round(s * 100) / 100)} rep</span>`; + } else { + return `${commaNum(Math.round(s * 100) / 100)} rep`; + } + } else { + /* In order to calculate just how much any one category matters so we can show a "fuzzy" symbolic value to the player, we need to know how "busy" reputation was this week. To calculate this, I ADD income to expenses. Why? 100 - 100 and 10000 - 10000 BOTH are 0, but a +50 event matters a lot more in the first case than the second. I exclude overflow from the calculation because it's not a "real" expense for our purposes, and divide by half just to make percentages a bit easier. */ + let weight = s / (((V.lastWeeksRepIncome.Total - V.lastWeeksRepExpenses.Total) + V.lastWeeksRepExpenses.overflow) / 2); + if (weight > 0.60) { + return `<span class="green">+++++ rep</span>`; + } else if (weight > 0.45) { + return `<span class="green">++++ rep</span>`; + } else if (weight > 0.30) { + return `<span class="green">+++ rep</span>`; + } else if (weight > 0.15) { + return `<span class="green">++ rep</span>`; + } else if (weight > 0.0) { + return `<span class="green">+ rep</span>`; + } else if (weight === 0) { + return "0 rep"; + } else if (weight < -0.60) { + return `<span class="red">−−−−− rep</span>`; + } else if (weight < -0.45) { + return `<span class="red">−−−− rep</span>`; + } else if (weight < -0.30) { + return `<span class="red">−−− rep</span>`; + } else if (weight < -0.15) { + return `<span class="red">−− rep</span>`; + } else if (weight < 0) { + return `<span class="red">− rep</span>`; + } + /* return weight;*/ + } +}; + +/** + * @param {number} s + * @returns {string} + */ +globalThis.massFormat = function(s) { + if (!s) { + s = 0; + } + if (Math.abs(s) >= 1000) { + s = Math.trunc(s / 1000); + if (s !== 1) { + return `${num(s)} tons`; + } else { + return `${num(s)} ton`; + } + } else { + return `${num(s)} kg`; + } +}; + +/** + * Takes an integer e.g. slave.hLength, returns a string in the format 10 inches + * @param {number} cm + * @returns {string} + */ +globalThis.cmToInchString = function(cm) { + let inches = cm / 2.54; + if (inches > 0 && inches < 1) { + return "less than an inch"; + } + inches = Math.round(inches); + if (inches === 1) { + return "1 inch"; + } + return `${inches} inches`; +}; + +/** + * takes an integer e.g. slave.height, returns a string in the format 6'5" + * @param {number} cm + * @returns {string} + */ +globalThis.cmToFootInchString = function(cm) { + if (Math.round(cm / 2.54) < 12) { + return cmToInchString(cm); + } + return `${Math.trunc(Math.round(cm / 2.54) / 12)}'${Math.round(cm / 2.54) % 12}"`; +}; + +/** + * takes a dick value e.g. slave.dick, returns a string in the format 6 inches + * @param {number} dick + * @returns {string} + */ +globalThis.dickToInchString = function(dick) { + return cmToInchString(dickToCM(dick)); +}; + +/** + * takes a dick value e.g. slave.dick, returns an int of the dick length in cm + * @param {number} dick + * @returns {number} + */ +globalThis.dickToCM = function(dick) { + if (dick < 9) { + return dick * 5; + } else if (dick === 9) { + return 50; + } + return dick * 6; +}; +/** + * takes a ball value e.g. slave.balls, returns a string in the format 3 inches + * @param {number} balls + * @returns {string} + */ +globalThis.ballsToInchString = function(balls) { + return cmToInchString(ballsToCM(balls)); +}; + +/** + * takes a ball value e.g. slave.balls, returns an int of the ball size in cm + * @param {number} balls + * @returns {number} + */ +globalThis.ballsToCM = function(balls) { + if (balls < 2) { + return 0; + } + return (balls < 10 ? (balls - 1) * 2 : balls * 2); +}; + +/** + * takes a dick value e.g. slave.dick, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` + * @param {number} dick + * @returns {string} + */ +globalThis.dickToEitherUnit = function(dick) { + if (V.showInches === 1) { + return `${dickToCM(dick)}cm (${dickToInchString(dick)})`; + } + if (V.showInches === 2) { + return dickToInchString(dick); + } + return `${dickToCM(dick)}cm`; +}; + +/** + * takes a ball value e.g. slave.balls, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm` + * @param {number} balls + * @returns {string} + */ +globalThis.ballsToEitherUnit = function(balls) { + if (V.showInches === 1) { + return `${ballsToCM(balls)}cm (${ballsToInchString(balls)})`; + } + if (V.showInches === 2) { + return ballsToInchString(balls); + } + return `${ballsToCM(balls)}cm`; +}; + +/** + * takes an int in centimeters e.g. slave.height, returns a string in the format of either `200cm (6'7")`, `6'7"`, or `200cm` + * @param {number} height + * @returns {string} + */ +globalThis.heightToEitherUnit = function(height) { + if (V.showInches === 1) { + return `${height}cm (${cmToFootInchString(height)})`; + } + if (V.showInches === 2) { + return cmToFootInchString(height); + } + return `${height}cm`; +}; + +/** + * takes an int in centimeters e.g. slave.hLength, returns a string in the format of either `30cm (12 inches)`, `12 inches`, or `30cm` + * @param {number} length + * @returns {string} + */ +globalThis.lengthToEitherUnit = function(length) { + if (V.showInches === 1) { + return `${length}cm (${cmToInchString(length)})`; + } + if (V.showInches === 2) { + return cmToInchString(length); + } + return `${length}cm`; +}; -- GitLab