{"version":3,"file":"number.mjs","sources":["../src/number.ts"],"sourcesContent":["import { NanointlPlugin } from './makeIntl';\nimport { ExternalParser } from './parse';\nimport { ExternalSerializer } from './serialize';\nimport type { TopLevelBracketsGroup, OptionalSpacingSymbolSequence } from './typings';\n\nexport type NumberSerializationParams = {\n  native: Intl.NumberFormatOptions;\n  scale: number;\n  offset: number;\n  percent?: boolean;\n  verbose?: boolean;\n};\n\nexport const parseNumber: ExternalParser<NumberSerializationParams> = (template, variableName, verboseInput) => {\n  if (template.trim() === 'verbose') return { native: verboseInput, scale: 1, offset: 0, verbose: true };\n  if (template.trim() === 'integer')\n    return { native: { minimumFractionDigits: 0, maximumFractionDigits: 0 }, scale: 1, offset: 0 };\n  if (!template.trimStart().startsWith('::')) return { native: {}, scale: 1, offset: 0 };\n  const tokens = template.split('::')[1].split(' ').filter(Boolean);\n  const params: NumberSerializationParams = { native: {}, scale: 1, offset: 0 };\n  for (const token of tokens) {\n    if (token === '%' || token === 'percent' || token.startsWith('%x')) {\n      params.native.unitDisplay = params.native.unitDisplay ?? 'short';\n      params.native.style = 'unit';\n      params.native.unit = 'percent';\n      params.native.maximumFractionDigits = params.native.maximumFractionDigits ?? 0;\n      params.scale *= 100;\n      if (token.startsWith('%x')) params.scale *= parseFloat(token.substring('%x'.length));\n    } else if (token.startsWith('.')) {\n      const startChar = token[1];\n      for (let i = 1; i < token.length; i++) {\n        const char = token[i];\n        if (char === '0') {\n          params.native.minimumFractionDigits = i;\n          if (startChar === char) params.native.maximumFractionDigits = i;\n        } else if (char === '#') params.native.maximumFractionDigits = i;\n        else if (char === '*') params.native.maximumFractionDigits = 20;\n        else throw new Error(`Unexpected symbol \"${char}\" in \"${template}\" template of \"${variableName}\" interpolation`);\n      }\n    } else if (token.startsWith('/')) {\n      const startChar = token[1];\n      for (let i = 1; i < token.length; i++) {\n        const char = token[i];\n        if (char === '@') {\n          params.native.minimumSignificantDigits = i;\n          if (startChar === char) params.native.maximumSignificantDigits = i;\n        } else if (char === '#') params.native.maximumSignificantDigits = i;\n        else if (char === '*') params.native.maximumSignificantDigits = 20;\n        else throw new Error(`Unexpected symbol \"${char}\" in \"${template}\" template of \"${variableName}\" interpolation`);\n      }\n    } else if (token.startsWith('integer-width')) {\n      params.native.minimumFractionDigits = 0;\n      params.native.maximumFractionDigits = 0;\n      if (token.startsWith('integer-width/')) {\n        const options = token.substring('integer-width'.length);\n        const startChar = options[1];\n        for (let i = 1; i < options.length; i++) {\n          const char = options[i];\n          if (char === '#' && params.native.minimumIntegerDigits === undefined) {\n            params.native.minimumIntegerDigits = i;\n          }\n          if (char === '0') {\n            if (startChar === '*' || startChar === '0') params.native.minimumIntegerDigits = i;\n            if (startChar === '#' || startChar === '0') params.native.maximumSignificantDigits = i;\n          }\n        }\n      }\n    } else if (token.startsWith('E') || token.startsWith('engineering') || token.startsWith('scientific')) {\n      if (token.startsWith('EE') || token.startsWith('engineering')) {\n        params.native.notation = 'engineering';\n      } else {\n        params.native.notation = 'scientific';\n      }\n      if (token.startsWith('E')) {\n        const rest = token.startsWith('EE') ? token.substring('EE'.length) : token.substring('E'.length);\n        if (rest.startsWith('+!')) params.native.signDisplay = 'always';\n        if (rest.startsWith('+?')) params.native.signDisplay = 'exceptZero';\n        let zeroCharsCount = 0;\n        for (let i = 0; i < rest.length; i++) if (rest[i] === '0') zeroCharsCount++;\n        params.native.minimumIntegerDigits = zeroCharsCount;\n      } else {\n        const parts = token.split('/');\n        for (const part of parts) {\n          if (part === 'sign-always') params.native.signDisplay = 'always';\n          if (part === 'except-zero') params.native.signDisplay = 'exceptZero';\n          if (part.startsWith('*')) params.native.minimumIntegerDigits = part.length - 1;\n        }\n      }\n    } else if (token.startsWith('scale/')) params.scale *= parseFloat(token.substring('scale/'.length));\n    else if (token.startsWith('measure-unit/')) {\n      params.native.style = 'unit';\n      params.native.unit = token.substring('measure-unit/'.length);\n    } else if (token.startsWith('unit/')) {\n      params.native.style = 'unit';\n      params.native.unit = token.substring('unit/'.length);\n    } else if (token.startsWith('currency/')) {\n      params.native.style = 'currency';\n      params.native.currency = token.substring('currency/'.length);\n    } else if (token === 'notation-scientific') params.native.notation = 'scientific';\n    else if (token === 'notation-engineering') params.native.notation = 'engineering';\n    else if (token === 'notation-simple') params.native.notation = 'standard';\n    else if (token === 'unit-width-iso-code') params.native.currencyDisplay = 'symbol';\n    else if (token === 'unit-width-short') {\n      params.native.unitDisplay = 'short';\n      params.native.currencyDisplay = 'code';\n    } else if (token === 'unit-width-full-name') {\n      params.native.unitDisplay = 'long';\n      params.native.currencyDisplay = 'name';\n    } else if (token === 'unit-width-narrow') {\n      params.native.unitDisplay = 'narrow';\n      params.native.currencyDisplay = 'narrowSymbol';\n    } else if (token === 'compact-short' || token === 'K') {\n      params.native.notation = 'compact';\n      params.native.compactDisplay = 'short';\n    } else if (token === 'compact-long' || token === 'KK') {\n      params.native.notation = 'compact';\n      params.native.compactDisplay = 'long';\n    } else if (token === 'sign-auto') params.native.signDisplay = 'auto';\n    else if (token === 'sign-always' || token === '+!') params.native.signDisplay = 'always';\n    else if (token === 'sign-never' || token === '+_') params.native.signDisplay = 'never';\n    else if (token === 'sign-except-zero' || token === '+?') params.native.signDisplay = 'exceptZero';\n    else if (token === 'sign-accounting' || token === '()') {\n      params.native.currencySign = 'accounting';\n    } else if (token === 'sign-accounting' || token === 'sign-accounting-always' || token === '()!') {\n      params.native.signDisplay = 'always';\n      params.native.currencySign = 'accounting';\n    } else if (token === 'sign-accounting-except-zero' || token === '()?') {\n      params.native.signDisplay = 'exceptZero';\n      params.native.currencySign = 'accounting';\n    } else if (token === 'group-always') params.native.useGrouping = 'always' as any;\n    else if (token === 'group-auto') params.native.useGrouping = 'auto' as any;\n    else if (token === 'group-off' || token === ',_') params.native.useGrouping = false;\n    else if (token === 'group-min-2' || token === ',?') params.native.useGrouping = 'min2' as any;\n    else throw new Error(`Unexpected token \"${token}\" in \"${template}\" template of \"${variableName}\" interpolation`);\n  }\n\n  return params;\n};\n\nconst multiply = (a: number | bigint, b: number) => (typeof a === 'number' ? a * b : a * BigInt(b));\nconst subtract = (a: number | bigint, b: number) => (typeof a === 'number' ? a - b : a - BigInt(b));\nexport const serializeNumber: ExternalSerializer<NumberSerializationParams> = (params, variableValue) => {\n  const numberFormat = new Intl.NumberFormat('en-US', params?.native ?? {});\n  let value = ['number', 'bigint'].includes(typeof variableValue)\n    ? (variableValue as number | bigint)\n    : parseFloat(String(variableValue));\n  if (params && typeof params.scale === 'number' && params.scale !== 1) value = multiply(value, params.scale);\n  if (params && typeof params.offset === 'number' && params.offset !== 0) value = subtract(value, params.offset);\n  return numberFormat.format(value);\n};\n\nexport const numberPlugin: NanointlPlugin<NumberSerializationParams> = {\n  name: 'number-plugin',\n  init(options) {\n    options.addParser('number', parseNumber);\n    options.addSerializer('number', serializeNumber);\n  },\n};\n\ntype NumberParser<Template extends string> =\n  TopLevelBracketsGroup<Template> extends `{${infer SelectVariable},${OptionalSpacingSymbolSequence}number}`\n    ? {\n        vars: [{ name: SelectVariable; type: number }];\n      }\n    : // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    TopLevelBracketsGroup<Template> extends `{${infer SelectVariable},${OptionalSpacingSymbolSequence}number,${infer NumberOptions}}`\n    ? {\n        vars: [{ name: SelectVariable; type: number }];\n      }\n    : { vars: [] };\n\ndeclare global {\n  interface NanointlBracketsParsers<Template extends string> {\n    number: NumberParser<Template>;\n  }\n}\n"],"names":["parseNumber","template","variableName","verboseInput","trim","native","scale","offset","verbose","minimumFractionDigits","maximumFractionDigits","trimStart","startsWith","_step","params","split","filter","Boolean","_iterator","done","token","_params$native$unitDi","_params$native$maximu","unitDisplay","style","unit","parseFloat","substring","length","i","char","startChar","Error","minimumSignificantDigits","maximumSignificantDigits","options","undefined","minimumIntegerDigits","notation","rest","signDisplay","zeroCharsCount","parts","part","currency","currencyDisplay","compactDisplay","currencySign","useGrouping","variableValue","_params$native","a","b","NumberFormat","value","includes","String","BigInt","subtract","format","numberPlugin","name","init","addParser","addSerializer","serializeNumber"],"mappings":"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"}