if type (Require) ~= 'function' then loadstring(exports['nc_libraries']:extend('Extend'), 'Require')() end if type (CreateThread) ~= 'function' then require 'Thread' end require 'Math'; require 'String'; local Format = {} Format.Cache = {} local function currency(value) local s = (type(value) == 'number') and string.format('%.2f', value) or tostring(value) local sign, integerPart, decimalPart = s:match('^([%-]?)(%d+)[%.,](%d+)$') if (not integerPart) then sign, integerPart = s:match('^([%-]?)(%d+)$') decimalPart = '00' end local rev = integerPart:reverse():gsub('(%d%d%d)', '%1.'):reverse():gsub('^%.', '') local formattedValue = (sign or '')..rev..','..(decimalPart or '00') return formattedValue end function Format:Currency(index, value) if (index and not value) then return currency(index) elseif (not index and not value) then return 0 end if (not Format.Cache.CurrencyFormatted) then Format.Cache.CurrencyFormatted = {} end local cache = Format.Cache.CurrencyFormatted local cached = cache[index] if (cached and value == cached.stock) then return cached.formatted end local formattedValue = currency(value) cache[index] = { stock = value, formatted = formattedValue, } if type(outputDevLog) == 'function' then outputDevLog(index..' formatted: from: '..value..' to: '..formattedValue, 'Format', 'debug') end return formattedValue end local function number(value, separator) local s = string.format("%.0f", value) repeat s, c = s:gsub("^(-?%d+)(%d%d%d)", "%1"..(separator or '.').."%2") until c == 0 return s end function Format:Number(index, value, separator) if (index and not value) then return number(index) elseif (not index and not value) then return 0 end if (not Format.Cache.NumberFormatted) then Format.Cache.NumberFormatted = {} end local cache = Format.Cache.NumberFormatted local cached = cache[index] if (cached and value == cached.stock) then return cached.formatted end local formattedValue = number(value, separator) cache[index] = { stock = value, formatted = formattedValue, } if type(outputDevLog) == 'function' then outputDevLog(index..' formatted: from: '..value..' to: '..formattedValue, 'Format', 'debug') end return formattedValue end local steps = { {div = 1e9, suffix = 'B'}, {div = 1e6, suffix = 'M'}, {div = 1e3, suffix = 'K'}, {div = 1, suffix = ''}, } local function reduced(value) local abs = math.abs(value) local reduced, suffix = 0, '' for i = 1, #steps do if abs >= steps[i].div then reduced = value / steps[i].div suffix = steps[i].suffix break end end if (not reduced) then reduced = value end local formattedValue if suffix ~= '' then if math.floor(reduced) == reduced then formattedValue = string.format("%.0f%s", reduced, suffix) else formattedValue = string.format("%.1f%s", reduced, suffix) formattedValue = formattedValue:gsub('%.0([bmk])$', '%1') end else formattedValue = tostring(reduced) end return formattedValue end function Format:ReducedNumber(index, value) if (index and not value) then return reduced(index) elseif (not index and not value) then return 0 end if (not Format.Cache.ReducedNumberFormatted) then Format.Cache.ReducedNumberFormatted = {} end local cache = Format.Cache.ReducedNumberFormatted local cached = cache[index] if (cached and value == cached.stock) then return cached.formatted end local formattedValue = reduced(value) cache[index] = { stock = value, formatted = formattedValue, } if type(outputDevLog) == 'function' then outputDevLog(index..' reduced formatted: from: '..value..' to: '..formattedValue, 'Format', 'debug') end return formattedValue end function Format:Clear() if (next(Format.Cache)) then Format.Cache = {} if type(outputDevLog) == 'function' then outputDevLog('Cache cleared ('..(isClient and 'client' or 'server')..')', 'Format', 'info') end return true end return false end CreateThread(function() while (true) do WaitSeconds(60 * 1) Format:Clear() end end) _G.Format = Format return Format