{"version":3,"sources":["../src/constants.ts","../src/utils.ts","../src/formatter.ts"],"names":[],"mappings":";;;AAiBO,IAAM,YAAA,GAA0C;AAAA,EACrD;AAAA,IACE,GAAA,EAAK,GAAA;AAAA,IACL,GAAA,EAAK,GAAA;AAAA,IACL,KAAA,EAAO,GAAA;AAAA,IACP,iBAAA,EAAmB,CAAA;AAAA,IACnB,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ;AAAA;AAAA,GACV;AAAA,EACA;AAAA,IACE,GAAA,EAAK,GAAA;AAAA,IACL,GAAA,EAAK,GAAA;AAAA,IACL,KAAA,EAAO,GAAA;AAAA,IACP,iBAAA,EAAmB,CAAA;AAAA,IACnB,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ;AAAA;AAAA,GACV;AAAA,EACA;AAAA,IACE,GAAA,EAAK,GAAA;AAAA,IACL,GAAA,EAAK,IAAA;AAAA,IACL,KAAA,EAAO,GAAA;AAAA,IACP,iBAAA,EAAmB,CAAA;AAAA,IACnB,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ;AAAA;AAAA,GACV;AAAA,EACA;AAAA,IACE,GAAA,EAAK,IAAA;AAAA,IACL,GAAA,EAAK,QAAA;AAAA,IACL,KAAA,EAAO,IAAA;AAAA,IACP,iBAAA,EAAmB,CAAA;AAAA,IACnB,KAAA,EAAO,CAAA;AAAA,IACP,MAAA,EAAQ;AAAA;AAAA;AAEZ;;;ACzBO,SAAS,aAAA,CAAc,KAAa,KAAA,EAA4B;AACrE,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,KAAA;AAG1B,EAAA,MAAM,cAAc,GAAA,GAAM,MAAA;AAI1B,EAAA,IAAI,CAAC,MAAA,CAAO,aAAA,CAAc,WAAW,CAAA,EAAG;AACtC,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,OAAO,cAAc,KAAA,KAAU,CAAA;AACjC;AAaO,SAAS,eAAe,GAAA,EAAgC;AAC7D,EAAA,KAAA,MAAW,SAAS,YAAA,EAAc;AAChC,IAAA,IAAI,GAAA,IAAO,KAAA,CAAM,GAAA,IAAO,GAAA,GAAM,MAAM,GAAA,EAAK;AACvC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;;;AClDA,SAAS,iBAAiB,OAAA,EAAgC;AACxD,EAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,cAAA,GAAiB,SAAQ,GAAI,OAAA;AAGvD,EAAA,MAAM,iBAAA,GAA8C,WAChD,EAAE,KAAA,EAAO,YAAY,QAAA,EAAS,GAC9B,EAAE,KAAA,EAAO,SAAA,EAAU;AAGvB,EAAA,MAAM,gBAAA,GAAmB,IAAI,IAAA,CAAK,YAAA,CAAa,MAAA,EAAQ;AAAA,IACrD,GAAG;AAAA,GACJ,CAAA;AAGD,EAAA,MAAM,oBAAoB,YAAA,CAAa,GAAA;AAAA,IACrC,CAAC,KAAA,KACC,IAAI,IAAA,CAAK,aAAa,MAAA,EAAQ;AAAA,MAC5B,GAAG,iBAAA;AAAA,MACH,QAAA,EAAU,SAAA;AAAA,MACV,cAAA;AAAA,MACA,uBAAuB,KAAA,CAAM,iBAAA;AAAA,MAC7B,qBAAA,EAAuB;AAAA,KACxB;AAAA,GACL;AAEA,EAAA,OAAO;AAAA,IACL,gBAAA;AAAA,IACA;AAAA,GACF;AACF;AAqBO,SAAS,eAAe,OAAA,EAAyD;AACtF,EAAA,MAAM,EAAE,gBAAA,EAAkB,iBAAA,EAAkB,GAAI,iBAAiB,OAAO,CAAA;AACxE,EAAA,MAAM,EAAE,YAAW,GAAI,OAAA;AAEvB,EAAA,OAAO;AAAA,IACL,OAAO,KAAA,EAAuB;AAC5B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA;AAG1B,MAAA,IAAI,MAAM,GAAA,EAAM;AACd,QAAA,OAAO,aAAa,UAAA,CAAW,KAAK,CAAA,GAAI,gBAAA,CAAiB,OAAO,KAAK,CAAA;AAAA,MACvE;AAGA,MAAA,MAAM,KAAA,GAAQ,eAAe,GAAG,CAAA;AAGhC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,OAAO,aAAa,UAAA,CAAW,KAAK,CAAA,GAAI,gBAAA,CAAiB,OAAO,KAAK,CAAA;AAAA,MACvE;AAGA,MAAA,IAAI,CAAC,aAAA,CAAc,GAAA,EAAK,KAAK,CAAA,EAAG;AAC9B,QAAA,OAAO,aAAa,UAAA,CAAW,KAAK,CAAA,GAAI,gBAAA,CAAiB,OAAO,KAAK,CAAA;AAAA,MACvE;AAGA,MAAA,OAAO,iBAAA,CAAkB,KAAA,CAAM,KAAK,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,IACpD;AAAA,GACF;AACF","file":"index.cjs","sourcesContent":["import type { ScaleLevel } from '../types';\n\n/**\n * Scale levels definition\n *\n * Level 1: Thousands (1K - 999K)\n * - Allows up to 1 decimal place (e.g., 1.5K)\n *\n * Level 2: Millions (1M - 999M)\n * - Allows up to 2 decimal places (e.g., 1.23M)\n *\n * Level 3: Billions (1B - 999B)\n * - Allows up to 2 decimal places (e.g., 1.23B)\n *\n * Level 4: Trillions and above (1T+)\n * - Allows up to 2 decimal places (e.g., 1.23T)\n */\nexport const SCALE_LEVELS: ReadonlyArray<ScaleLevel> = [\n  {\n    min: 1000,\n    max: 1_000_000,\n    scale: 1000,\n    maxFractionDigits: 1,\n    index: 0,\n    factor: 10, // 10^1\n  },\n  {\n    min: 1_000_000,\n    max: 1_000_000_000,\n    scale: 1_000_000,\n    maxFractionDigits: 2,\n    index: 1,\n    factor: 100, // 10^2\n  },\n  {\n    min: 1_000_000_000,\n    max: 1_000_000_000_000,\n    scale: 1_000_000_000,\n    maxFractionDigits: 2,\n    index: 2,\n    factor: 100, // 10^2\n  },\n  {\n    min: 1_000_000_000_000,\n    max: Infinity,\n    scale: 1_000_000_000_000,\n    maxFractionDigits: 2,\n    index: 3,\n    factor: 100, // 10^2\n  },\n] as const;\n","import type { ScaleLevel } from '../types';\nimport { SCALE_LEVELS } from './constants';\n\n/**\n * Check if a number is \"exact\" on the grid for a given scale level\n *\n * A number is considered exact if it can be represented as:\n * abs = (N / 10^d) * scale, where N is an integer\n *\n * This ensures the mantissa has at most maxFractionDigits decimal places\n * without rounding.\n *\n * @param abs - Absolute value of the number\n * @param level - Scale level to check against\n * @returns true if the number is exact on the grid\n *\n * @example\n * // Thousands level (scale=1000, d=1)\n * isExactOnGrid(1000, SCALE_LEVELS[0])  // true: 1000 * 10 = 10000, 10000 % 1000 = 0\n * isExactOnGrid(1150, SCALE_LEVELS[0])  // false: 1150 * 10 = 11500, 11500 % 1000 = 500\n *\n * // Millions level (scale=1000000, d=2)\n * isExactOnGrid(1230000, SCALE_LEVELS[1])  // true: 1230000 * 100 = 123000000, 123000000 % 1000000 = 0\n * isExactOnGrid(1234567, SCALE_LEVELS[1])  // false: 1234567 * 100 = 123456700, 123456700 % 1000000 = 456700\n */\nexport function isExactOnGrid(abs: number, level: ScaleLevel): boolean {\n  const { scale, factor } = level;\n\n  // Calculate the scaled value using pre-computed factor\n  const scaledValue = abs * factor;\n\n  // Check if the scaled value is a safe integer\n  // This prevents floating-point errors for very large numbers\n  if (!Number.isSafeInteger(scaledValue)) {\n    return false;\n  }\n\n  // Check if the scaled value is divisible by scale without remainder\n  // This ensures the mantissa has at most maxFractionDigits decimal places\n  return scaledValue % scale === 0;\n}\n\n/**\n * Find the appropriate scale level for a given absolute value\n *\n * @param abs - Absolute value to check\n * @returns Scale level or null if no level matches\n *\n * @example\n * findScaleLevel(500)       // null (below 1000)\n * findScaleLevel(5000)      // SCALE_LEVELS[0] (thousands)\n * findScaleLevel(5000000)   // SCALE_LEVELS[1] (millions)\n */\nexport function findScaleLevel(abs: number): ScaleLevel | null {\n  for (const level of SCALE_LEVELS) {\n    if (abs >= level.min && abs < level.max) {\n      return level;\n    }\n  }\n  return null;\n}\n","import type { PreciseCompactOptions, PreciseCompactFormatter } from '../types';\nimport { SCALE_LEVELS } from './constants';\nimport { findScaleLevel, isExactOnGrid } from './utils';\n\n/**\n * Create formatters for the given options\n *\n * @param options - Formatter options\n * @returns Object with regular and compact formatters\n */\nfunction createFormatters(options: PreciseCompactOptions) {\n  const { locale, currency, compactDisplay = 'short' } = options;\n\n  // Base format options\n  const baseFormatOptions: Intl.NumberFormatOptions = currency\n    ? { style: 'currency', currency }\n    : { style: 'decimal' };\n\n  // Create regular formatter (no compact notation)\n  const regularFormatter = new Intl.NumberFormat(locale, {\n    ...baseFormatOptions,\n  });\n\n  // Create compact formatters for each scale level\n  const compactFormatters = SCALE_LEVELS.map(\n    (level) =>\n      new Intl.NumberFormat(locale, {\n        ...baseFormatOptions,\n        notation: 'compact',\n        compactDisplay,\n        maximumFractionDigits: level.maxFractionDigits,\n        minimumFractionDigits: 0,\n      }),\n  );\n\n  return {\n    regularFormatter,\n    compactFormatters,\n  };\n}\n\n/**\n * Create a precise compact formatter with the given options\n *\n * This formatter uses compact notation (e.g., \"1K\", \"1.5M\") only for \"exact\" numbers\n * that can be represented without approximation. For all other numbers, it uses\n * regular formatting.\n *\n * @param options - Formatter options\n * @returns PreciseCompactFormatter instance\n *\n * @example\n * const fmt = PreciseCompact({ locale: 'cs-CZ', currency: 'EUR' });\n *\n * fmt.format(1000)      // \"1 tis. EUR\" (compact - exact)\n * fmt.format(1100)      // \"1,1 tis. EUR\" (compact - exact)\n * fmt.format(1150)      // \"1 150,00 €\" (regular - not exact)\n * fmt.format(1000000)   // \"1 mil. EUR\" (compact - exact)\n * fmt.format(1234567)   // \"1 234 567,00 €\" (regular - not exact)\n */\nexport function PreciseCompact(options: PreciseCompactOptions): PreciseCompactFormatter {\n  const { regularFormatter, compactFormatters } = createFormatters(options);\n  const { fallbackFn } = options;\n\n  return {\n    format(value: number): string {\n      const abs = Math.abs(value);\n\n      // For values below 1000, always use regular format\n      if (abs < 1000) {\n        return fallbackFn ? fallbackFn(value) : regularFormatter.format(value);\n      }\n\n      // Find the appropriate scale level\n      const level = findScaleLevel(abs);\n\n      // If no level found, use regular format\n      if (!level) {\n        return fallbackFn ? fallbackFn(value) : regularFormatter.format(value);\n      }\n\n      // Check if the number is \"exact\" on the grid\n      if (!isExactOnGrid(abs, level)) {\n        return fallbackFn ? fallbackFn(value) : regularFormatter.format(value);\n      }\n\n      // Use compact format with pre-computed index\n      return compactFormatters[level.index].format(value);\n    },\n  };\n}\n"]}