UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

820 lines (819 loc) 27.3 kB
"use strict"; "use client"; Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanNumber = cleanNumber; exports.copyWithEffect = copyWithEffect; exports.formatPhone = exports.formatORG = exports.formatNumber = exports.formatNIN = exports.formatDecimals = exports.formatBAN = exports.format = exports.countDecimals = void 0; exports.getCurrencySymbol = getCurrencySymbol; exports.getDecimalSeparator = getDecimalSeparator; exports.getFallbackCurrencyDisplay = getFallbackCurrencyDisplay; exports.getThousandsSeparator = getThousandsSeparator; exports.roundHalfEven = roundHalfEven; exports.runIOSSelectionFix = runIOSSelectionFix; exports.showSelectionNotice = showSelectionNotice; exports.useCopyWithNotice = useCopyWithNotice; require("core-js/modules/es.string.replace.js"); var _react = _interopRequireDefault(require("react")); var _Context = _interopRequireDefault(require("../../shared/Context")); var _defaults = require("../../shared/defaults"); var _componentHelper = require("../../shared/component-helper"); var _helpers = require("../../shared/helpers"); var _locales = _interopRequireDefault(require("../../shared/locales")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } const NUMBER_CHARS = '\\-0-9,.'; const format = function (value) { let { locale = null, clean = false, compact = null, phone = null, org = null, ban = null, nin = null, percent = null, currency = null, currency_display = null, currency_position = null, omit_currency_sign = null, clean_copy_value = null, decimals = null, omit_rounding = null, rounding = null, options = null, returnAria = false, invalidAriaText = null } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; let display = value; let aria = null; let type = 'number'; if (!locale) { locale = _defaults.LOCALE; } else if (locale === 'auto') { try { locale = window.navigator.language; } catch (e) { (0, _componentHelper.warn)(e); } } if ((0, _componentHelper.isTrue)(clean)) { value = cleanNumber(value); } const opts = (typeof options === 'string' && options[0] === '{' ? JSON.parse(options) : options) || {}; if (parseFloat(decimals) >= 0) { value = formatDecimals(value, decimals, rounding !== null && rounding !== void 0 ? rounding : omit_rounding, opts); } else if (typeof opts.maximumFractionDigits === 'undefined' && !(0, _componentHelper.isTrue)(percent) && !(0, _componentHelper.isTrue)(currency)) { opts.maximumFractionDigits = 20; } if ((0, _componentHelper.isTrue)(phone)) { type = 'phone'; const { number: _number, aria: _aria } = formatPhone(value, locale); if (clean === null) { value = cleanNumber(value); } display = _number; aria = _aria; } else if ((0, _componentHelper.isTrue)(ban)) { type = 'ban'; const { number: _number, aria: _aria } = formatBAN(value, locale); display = _number; aria = _aria; } else if ((0, _componentHelper.isTrue)(nin)) { type = 'nin'; const { number: _number, aria: _aria } = formatNIN(value, locale); display = _number; aria = _aria; } else if ((0, _componentHelper.isTrue)(org)) { type = 'org'; const { number: _number, aria: _aria } = formatORG(value, locale); display = _number; aria = _aria; } else if ((0, _componentHelper.isTrue)(percent)) { if (decimals === null) { if (typeof opts.maximumFractionDigits === 'undefined') { decimals = countDecimals(value); } value = formatDecimals(value, decimals, rounding !== null && rounding !== void 0 ? rounding : omit_rounding, opts); } if (!opts.style) { opts.style = 'percent'; } display = formatNumber(value / 100, locale, opts); } else if ((0, _componentHelper.isTrue)(currency) || typeof currency === 'string') { type = 'currency'; opts.currency = opts.currency || ((0, _componentHelper.isTrue)(currency) ? _defaults.CURRENCY : currency); handleCompactBeforeDisplay({ value, locale, compact, decimals, opts }); if (decimals === null) { decimals = 2; value = formatDecimals(value, decimals, rounding !== null && rounding !== void 0 ? rounding : omit_rounding, opts); } let cleanedNumber = decimals >= 0 ? value : clean ? cleanNumber(value) : value; if (currency_display === false || currency_display === '') { omit_currency_sign = true; } opts.style = 'currency'; opts.currencyDisplay = getFallbackCurrencyDisplay(locale, opts.currencyDisplay || currency_display); if (typeof opts.minimumFractionDigits === 'undefined' && String(value).indexOf('.') === -1 && cleanedNumber % 1 === 0) { opts.minimumFractionDigits = 0; } let formatter = undefined; if ((0, _componentHelper.isTrue)(omit_currency_sign)) { formatter = item => { switch (item.type) { case 'literal': item.value = item.value === ' ' ? '' : item.value; return item; case 'currency': item.value = ''; return item; default: return item; } }; } if (!currency_position && locale && /(no|nb|nn)$/i.test(locale)) { currency_position = 'after'; } let currencySuffix = null; if (currency_position) { formatter = currencyPositionFormatter(formatter, _ref => { let { value } = _ref; return currencySuffix = alignCurrencySymbol(value.trim(), currency_display); }, currency_position); } display = formatNumber(cleanedNumber, locale, opts, formatter); display = prepareMinus(display, locale); if (currency_position && currencySuffix) { if (currency_position === 'after') { display = `${display.trim()} ${currencySuffix}`; } else if (currency_position === 'before') { display = `${currencySuffix} ${display.trim()}`; } } handleCompactBeforeAria({ value, compact, opts }); aria = formatNumber(cleanedNumber, locale, _objectSpread(_objectSpread({ minimumFractionDigits: 0, maximumFractionDigits: 2 }, opts), {}, { currencyDisplay: 'name' })); aria = enhanceSR(cleanedNumber, aria, locale); } else { handleCompactBeforeDisplay({ value, locale, compact, decimals, opts }); display = formatNumber(value, locale, opts); display = prepareMinus(display, locale); handleCompactBeforeAria({ value, compact, opts }); aria = formatNumber(value, locale, opts); aria = enhanceSR(value, aria, locale); } if (aria === null) { aria = display; } if (returnAria) { let cleanedValue; if (clean_copy_value) { cleanedValue = formatNumber(opts.style === 'percent' ? value / 100 : value, locale, opts, item => { switch (item.type) { case 'group': case 'literal': case 'currency': case 'percentSign': item.value = ''; return item; default: return item; } }); } else { const thousandsSeparator = getThousandsSeparator(locale); cleanedValue = String(display).replace(new RegExp(`${thousandsSeparator}(?=\\d{3})`, 'g'), ''); } if (value === 'invalid') { var _locales$locale; aria = invalidAriaText || ((_locales$locale = _locales.default[locale]) === null || _locales$locale === void 0 ? void 0 : _locales$locale.NumberFormat.not_available) || 'N/A'; } return { value, cleanedValue, number: display, aria, locale, type }; } return display; }; exports.format = format; const formatDecimals = function (value, decimals, rounding) { let opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; decimals = parseFloat(decimals); if (decimals >= 0) { opts.minimumFractionDigits = decimals; opts.maximumFractionDigits = decimals; } if (String(value).includes('.')) { const decimalPlaces = decimals || opts.maximumFractionDigits; if (rounding === 'omit' || rounding === true) { const factor = Math.pow(10, decimalPlaces); value = Math.trunc(value * factor) / factor; } else { switch (rounding) { case 'half-even': { value = roundHalfEven(value, decimalPlaces); break; } } } } return value; }; exports.formatDecimals = formatDecimals; const countDecimals = function (value) { var _String$split$; let decimalSeparator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '.'; if (typeof value === 'number' && Math.floor(value.valueOf()) === value.valueOf()) { return 0; } return ((_String$split$ = String(value).split(decimalSeparator)[1]) === null || _String$split$ === void 0 ? void 0 : _String$split$.length) || 0; }; exports.countDecimals = countDecimals; const currencyPositionFormatter = function (existingFormatter, callback) { let position = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; let count = 0; let countCurrency = -1; return item => { if (typeof existingFormatter === 'function') { item = existingFormatter(item); } count++; switch (item.type) { case 'currency': { if (position === 'after' || position === 'before' && count > 2) { countCurrency = count; callback(item); item.value = ''; } return item; } case 'literal': { if (count === countCurrency + 1) { item.value = ''; } return item; } default: return item; } }; }; const prepareMinus = (display, locale) => { if (!(locale && /(no|nb|nn)$/i.test(locale))) { return display; } const first = display[0]; const second = display[1]; if (first === '-' && second === '-') { return display; } const reg = '^(-|−|‐|‒|–|—|―)'; if (new RegExp(reg).test(first)) { if (parseFloat(second) > 0) { display = display.replace(new RegExp(reg + '(.*)'), '-$2'); } else { display = display.replace(new RegExp(reg + '([^0-9]+)(.*)'), '$2-$3'); } } return display; }; function alignCurrencySymbol(output, currencyDisplay) { if (typeof output === 'string' && currencyDisplay === 'name') { output = output.replace(/(nor[^\s]+?)\s(\w+)/i, '$2'); } return output; } const enhanceSR = (value, aria, locale) => { if (_helpers.IS_MAC && Math.abs(parseFloat(value)) <= 99999) { aria = String(aria).replace(/\s([0-9])/g, '$1'); } aria = prepareMinus(aria, locale); return aria; }; const formatNumber = function (number, locale) { let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; let formatter = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; try { if (options.currencyDisplay) { options.currencyDisplay = getFallbackCurrencyDisplay(locale, options.currencyDisplay); } delete options.decimals; if (locale && /(en|gb)$/i.test(locale)) { formatter = getGroupFormatter(locale, null, formatter); } if (formatter) { number = formatToParts({ number, locale, options }).map(formatter).reduce((acc, _ref2) => { let { value } = _ref2; return acc + value; }, ''); } else if (typeof Number !== 'undefined' && typeof Number.toLocaleString === 'function') { number = parseFloat(number).toLocaleString(locale, options); } if (String(number).startsWith('−0')) { number = number.replace('−0', '0'); } } catch (e) { (0, _componentHelper.warn)(`Number could not be formatted: ${JSON.stringify([number, locale, options])}`, e); } return replaceNaNWithDash(alignCurrencySymbol(number, options.currencyDisplay)); }; exports.formatNumber = formatNumber; function replaceNaNWithDash(number) { return String(number).replace(/NaN/, '–'); } const formatPhone = function (number) { let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; let display = number; let aria = null; switch (locale) { default: { let code = ''; number = String(number).replace(/^(00|\+|)47([^\s])/, '+47 $2').replace(/^00/, '+'); if (number.substring(0, 1) === '+') { const codeAndNumber = number.match(/^\+([\d-]{1,8})\s{0,2}([\d\s-]{1,20})$/); if (codeAndNumber) { code = `+${codeAndNumber[1]} `; number = codeAndNumber[2]; } } number = number.replace(/[^+\d]/g, ''); const length = number.length; if (length === 8 && number.substring(0, 1) === '8') { display = code + number.split(/([\d]{3})([\d]{2})/).filter(s => s).join(' '); } else { if (length < 6) { display = code + number; } else { if (code.includes('-')) { code = code.replace(/(\+[\d]{1,2})-([\d]{1,6})/, '$1 ($2)'); } display = code + number.split(length === 6 ? /^(\+[\d]{2})|([\d]{3})/ : /^(\+[\d]{2})|([\d]{2})/).filter(s => s).join(' '); } } aria = code + number.split(/([\d]{2})/).filter(s => s).join(' '); } } if (aria === null) { aria = display; } return { number: display, aria }; }; exports.formatPhone = formatPhone; const formatBAN = function (number) { let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; number = String(number).replace(/[^0-9]/g, ''); let display = number; let aria = null; switch (locale) { default: { display = number.split(/([0-9]{4})([0-9]{2})([0-9]{1,})/).filter(s => s).join(' '); aria = number.split(/([0-9]{2})/).filter(s => s).join(' '); } } if (aria === null) { aria = display; } return { number: display, aria }; }; exports.formatBAN = formatBAN; const formatORG = function (number) { let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; number = String(number).replace(/[^0-9]/g, ''); let display = number; let aria = null; switch (locale) { default: { display = number.split(/([0-9]{3})/).filter(s => s).join(' '); aria = number.split(/([0-9]{1})/).filter(s => s).join(' '); } } if (aria === null) { aria = display; } return { number: display, aria }; }; exports.formatORG = formatORG; const formatNIN = function (number) { let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; number = String(number).replace(/[^0-9]/g, ''); let display = number; let aria = null; switch (locale) { default: { display = number.split(/([0-9]{6})/).filter(s => s).join(' '); aria = display.split(/([0-9]{2})([0-9]{2})([0-9]{2}) ([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})/).filter(s => s).join(_helpers.IS_WIN ? '. ' : ' '); } } if (aria === null) { aria = display; } return { number: display, aria }; }; exports.formatNIN = formatNIN; function cleanNumber(num) { let { decimalSeparator = null, thousandsSeparator = null, prefix = null, suffix = null } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (typeof num === 'number') { return num; } num = String(num).trim(); if (typeof prefix === 'string' && num.startsWith(prefix)) { num = num.substring(prefix.length, num.length); } if (typeof suffix === 'string' && num.endsWith(suffix)) { num = num.substring(0, num.length - suffix.length); } if (/^[^0-9-]/.test(num)) { num = num.replace(/^(^[^0-9-]+)/, ''); } let decimal = decimalSeparator; let thousands = thousandsSeparator; if (/(\s)([0-9]{3})/.test(num)) { thousands = thousands || '\\s'; decimal = decimal || ','; } else if (/(\.)([0-9]{3})/.test(num) && !/([,'][0-9]{3})(\.)([0-9]{3})/.test(num)) { thousands = thousands || '\\.'; decimal = decimal || ",|·|'"; } else if (/(,)([0-9]{3})/.test(num)) { thousands = thousands || ','; decimal = decimal || '\\.|·'; } else if (/(')([0-9]{3})/.test(num)) { thousands = thousands || "'"; decimal = decimal || '\\.|,'; } else { thousands = ','; decimal = '\\.'; } const thousandReg = thousandsSeparator ? new RegExp(`([0-9]|)(${(0, _componentHelper.escapeRegexChars)(thousandsSeparator)})([0-9]{3})`, 'g') : new RegExp(`([0-9]|)(${thousands})([0-9]{3})`, 'g'); if (thousandReg.test(num)) { num = num.replace(thousandReg, '$1$3'); } const decimalReg = decimalSeparator ? new RegExp(`(${(0, _componentHelper.escapeRegexChars)(decimalSeparator)})([0-9]{0,})`, 'g') : new RegExp(`(${decimal})([0-9]{1,2})`, 'g'); if (decimalReg.test(num)) { num = num.replace(decimalReg, '.$2'); } if (!decimalSeparator) { const decimalBackup = new RegExp(`(${decimal})([0-9]{3,})`, 'g'); if (decimalBackup.test(num)) { num = num.replace(decimalBackup, '.$2'); } } return num.replace(new RegExp(`([^${NUMBER_CHARS}])`, 'g'), ''); } function runIOSSelectionFix() { try { const selection = window.getSelection(); const range = document.createRange(); selection.removeAllRanges(); selection.addRange(range); } catch (e) {} } async function copyWithEffect(value, label) { let positionElement = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; let success = null; if (value) { try { const fx = showSelectionNotice({ value, label }); success = await (0, _helpers.copyToClipboard)(value); if (success === true) { fx.run(positionElement); } } catch (e) { (0, _componentHelper.warn)(e); success = e; } } return success; } function showSelectionNotice(_ref3) { let { value, label, timeout = 3e3 } = _ref3; const id = 'id-' + (0, _componentHelper.slugify)(value); if (typeof document !== 'undefined' && document.getElementById(id)) { return { run: () => {} }; } let elem, content, root; try { root = document.querySelector('.dnb-tooltip__portal, body'); elem = document.createElement('span'); elem.setAttribute('id', id); elem.setAttribute('class', 'dnb-tooltip'); elem.setAttribute('role', 'tooltip'); const arrow = document.createElement('span'); arrow.setAttribute('class', 'dnb-tooltip__arrow dnb-tooltip__arrow__position--top'); content = document.createElement('span'); content.setAttribute('class', 'dnb-tooltip__content'); content.setAttribute('aria-live', 'assertive'); elem.appendChild(arrow); elem.appendChild(content); } catch (e) { (0, _componentHelper.warn)(e); } return new class SelectionFx { remove() { try { root.removeChild(elem); elem = null; content = null; } catch (e) {} } hide() { try { elem.classList.add('dnb-tooltip--hide'); } catch (e) {} } run() { let pE = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : (0, _helpers.getSelectedElement)(); try { root.appendChild(elem); const top = (0, _helpers.getOffsetTop)(pE); const left = (0, _helpers.getOffsetLeft)(pE); content.innerHTML = String(label) + (pE instanceof HTMLElement ? `<span class="dnb-sr-only">: ${(pE && pE.querySelector('.dnb-number-format__selection') || pE).innerHTML}</span>` : ''); const width = (pE && pE.querySelector('.dnb-number-format__visible') || pE || {}).offsetWidth || 0; elem.style.top = `${top - elem.offsetHeight}px`; elem.style.left = `${left + width / 2 - elem.offsetWidth / 2}px`; elem.classList.add('dnb-tooltip--active'); setTimeout(this.hide, timeout); setTimeout(this.remove, timeout + 600); } catch (e) { (0, _componentHelper.warn)(e); } } }(); } function useCopyWithNotice() { const { translation: { NumberFormat: { clipboard_copy } } } = _react.default.useContext(_Context.default); const copy = (value, positionElement) => { copyWithEffect(value, clipboard_copy, positionElement); }; return { copy }; } function getFallbackCurrencyDisplay() { let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; let currencyDisplay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; if (!currencyDisplay && (!locale || /(no|nb|nn)$/i.test(locale))) { currencyDisplay = 'narrowSymbol'; } return currencyDisplay || _defaults.CURRENCY_DISPLAY; } function getDecimalSeparator() { var _formatToParts$find; let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; const separator = ((_formatToParts$find = formatToParts({ number: 1.1, locale }).find(_ref4 => { let { type } = _ref4; return type === 'decimal'; })) === null || _formatToParts$find === void 0 ? void 0 : _formatToParts$find.value) || ','; return separator; } function getThousandsSeparator() { var _formatToParts$map$fi; let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; const formatter = getGroupFormatter(locale); return ((_formatToParts$map$fi = formatToParts({ number: 1000, locale }).map(formatter).find(_ref5 => { let { type } = _ref5; return type === 'group'; })) === null || _formatToParts$map$fi === void 0 ? void 0 : _formatToParts$map$fi.value) || ' '; } function getCurrencySymbol() { var _formatToParts$find2; let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; let currency = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; let display = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; let number = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 2; if (!currency) { currency = _defaults.CURRENCY; } const currencyDisplay = getFallbackCurrencyDisplay(locale, display); return alignCurrencySymbol(((_formatToParts$find2 = formatToParts({ number, locale, options: { style: 'currency', currency, currencyDisplay } }).find(_ref6 => { let { type } = _ref6; return type === 'currency'; })) === null || _formatToParts$find2 === void 0 ? void 0 : _formatToParts$find2.value) || currency, currencyDisplay); } function getGroupFormatter() { let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; let separatorSymbol = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; let existingFormatter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; if (locale && /(en|gb)$/i.test(locale)) { separatorSymbol = ' '; } return item => { if (typeof existingFormatter === 'function') { item = existingFormatter(item); } if (item.type === 'group') { item.value = separatorSymbol || item.value; } return item; }; } function formatToParts(_ref7) { let { number, locale = null, options = null } = _ref7; if (typeof Intl !== 'undefined' && typeof Intl.NumberFormat === 'function') { try { const inst = Intl.NumberFormat(locale || _defaults.LOCALE, options || {}); if (typeof inst.formatToParts === 'function') { return inst.formatToParts(number); } else { return [{ value: inst.format(number) }]; } } catch (e) { (0, _componentHelper.warn)(e); } } return [{ value: number }]; } function handleCompactBeforeDisplay() { let { value, locale, compact, decimals = 0, opts } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (!canHandleCompact({ value, compact })) { return; } value = parseInt(Math.abs(value)); opts.notation = 'compact'; if ((0, _componentHelper.isTrue)(compact) && locale && /(no|nb|nn)$/i.test(locale)) { opts.compactDisplay = Math.abs(value) < 1000000 ? 'long' : 'short'; } else { opts.compactDisplay = !(0, _componentHelper.isTrue)(compact) ? compact : 'short'; } if (typeof opts.maximumSignificantDigits === 'undefined') { if (isNaN(parseFloat(decimals))) { decimals = 0; } else { decimals = parseFloat(decimals); } const ref = String(value).length % 3; if (ref === 2) { decimals += 1; } else if (ref === 0) { decimals += 2; } opts.maximumSignificantDigits = decimals + 1; } } function handleCompactBeforeAria(_ref8) { let { value, compact, opts } = _ref8; if (!canHandleCompact({ value, compact })) { return; } opts.compactDisplay = 'long'; } function canHandleCompact(_ref9) { let { value, compact } = _ref9; if (compact && Math.abs(value) >= 1000) { return true; } return false; } function roundHalfEven(num) { let decimalPlaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; const multiplier = Math.pow(10, decimalPlaces); const adjustedNum = num * multiplier; const floored = Math.floor(adjustedNum); const diff = adjustedNum - floored; if (diff > 0.5) { return Math.ceil(adjustedNum) / multiplier; } else if (diff < 0.5) { return Math.floor(adjustedNum) / multiplier; } return floored % 2 === 0 ? floored / multiplier : Math.ceil(adjustedNum) / multiplier; } //# sourceMappingURL=NumberUtils.js.map