{"version":3,"sources":["../../src/vin/constants.ts","../../src/vin/validate.ts","../../src/vin/errors.ts","../../src/vin/parse.ts","../../src/vin/mask.ts","../../src/vin/clean.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The standard length of a VIN (ISO 3779).\n */\nexport const VIN_LENGTH = 17;\n\n/**\n * The 0-based index of the check digit in the VIN (Position 9).\n */\nexport const VIN_CHECK_DIGIT_INDEX = 8;\n\n/**\n * The modulus used in the VIN checksum calculation.\n */\nexport const VIN_MODULUS = 11;\n\n/**\n * The character representing a checksum value of 10.\n */\nexport const VIN_CHECK_DIGIT_X = 'X';\n\n/**\n * Weights used in the VIN checksum calculation.\n * Each position (1-17) is multiplied by its corresponding weight.\n * Position 9 is the check digit itself (weight 0).\n */\nexport const VIN_WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];\n\n/**\n * Values assigned to each valid character for VIN calculation.\n * Invalid characters: I, O, Q are not allowed in VIN.\n */\nexport const VIN_CHAR_VALUES: Record<string, number> = {\n  '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,\n  'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8,\n  'J': 1, 'K': 2, 'L': 3, 'M': 4, 'N': 5, 'P': 7, 'R': 9,\n  'S': 2, 'T': 3, 'U': 4, 'V': 5, 'W': 6, 'X': 7, 'Y': 8, 'Z': 9,\n};\n\n/**\n * Characters excluded from VIN (I, O, Q).\n */\nexport const EXCLUDED_VIN_CHARS = ['I', 'O', 'Q'];\n\n/**\n * Version of the VIN utility module.\n */\nexport const VIN_VERSION = '1.0.0';\n\n","import {\n  VIN_WEIGHTS,\n  VIN_CHAR_VALUES,\n  EXCLUDED_VIN_CHARS,\n  VIN_LENGTH,\n  VIN_CHECK_DIGIT_INDEX,\n  VIN_MODULUS,\n  VIN_CHECK_DIGIT_X,\n} from './constants';\n\n/**\n * Validates a Vehicle Identification Number (VIN) based on ISO 3779.\n *\n * Checks for:\n * - Exactly 17 characters length.\n * - Exclusion of characters I, O, and Q.\n * - Checksum validation using the check digit at position 9.\n *\n * @param vin - The VIN string to validate\n * @returns boolean indicating if the VIN is valid\n *\n * @example\n * ```typescript\n * import { validateVIN } from '@indodev/toolkit/vin';\n *\n * validateVIN('1HBHA82L7ZB000001'); // true\n * validateVIN('1HBHA82I7ZB000001'); // false (contains 'I')\n * ```\n */\nexport function validateVIN(vin: string): boolean {\n  if (!vin || vin.length !== VIN_LENGTH) {\n    return false;\n  }\n\n  const normalizedVIN = vin.toUpperCase();\n\n  // 1. Check for excluded characters (I, O, Q)\n  for (const char of EXCLUDED_VIN_CHARS) {\n    if (normalizedVIN.includes(char)) {\n      return false;\n    }\n  }\n\n  // 2. Checksum validation (Position 9)\n  let sum = 0;\n  for (let i = 0; i < VIN_LENGTH; i++) {\n    const char = normalizedVIN[i];\n    const weight = VIN_WEIGHTS[i];\n    const val = VIN_CHAR_VALUES[char];\n\n    if (val === undefined) {\n      return false; // Invalid character found\n    }\n\n    sum += val * weight;\n  }\n\n  const checkDigitValue = sum % VIN_MODULUS;\n  const expectedCheckDigit =\n    checkDigitValue === 10 ? VIN_CHECK_DIGIT_X : checkDigitValue.toString();\n  const actualCheckDigit = normalizedVIN[VIN_CHECK_DIGIT_INDEX];\n\n  return actualCheckDigit === expectedCheckDigit;\n}\n","/**\n * Error thrown when an invalid VIN is provided to a function.\n * Extends native Error with a `code` property for programmatic error handling.\n *\n * @example\n * ```typescript\n * try {\n *   requireVIN('invalid');\n * } catch (error) {\n *   if (error instanceof InvalidVINError) {\n *     console.log(error.code); // 'INVALID_VIN'\n *   }\n * }\n * ```\n *\n * @public\n */\nexport class InvalidVINError extends Error {\n  readonly code = 'INVALID_VIN' as const;\n\n  constructor(message: string = 'Invalid VIN provided') {\n    super(message);\n    this.name = 'InvalidVINError';\n  }\n}\n","import {\n  VIN_LENGTH,\n  VIN_CHAR_VALUES,\n  EXCLUDED_VIN_CHARS,\n  VIN_WEIGHTS,\n  VIN_CHECK_DIGIT_INDEX,\n  VIN_MODULUS,\n  VIN_CHECK_DIGIT_X,\n} from './constants';\nimport type { VINInfo } from './types';\n\n/**\n * Parses a Vehicle Identification Number (VIN) into its component parts.\n *\n * Extracts the WMI (World Manufacturer Identifier), VDS (Vehicle Descriptor Section),\n * check digit, model year code, plant code, and serial number from a VIN.\n *\n * @param vin - The VIN string to parse\n * @returns VINInfo object with extracted components, or null if invalid\n *\n * @example\n * Valid VIN:\n * ```typescript\n * parseVIN('1HBHA82L7ZB000001');\n * // {\n * //   wmi: '1HB',\n * //   vds: 'HA82L7',\n * //   checkDigit: '7',\n * //   modelYearCode: 'Z',\n * //   plantCode: 'B',\n * //   serialNumber: '0000001',\n * //   isValid: true\n * // }\n * ```\n *\n * @example\n * Invalid VIN returns null:\n * ```typescript\n * parseVIN('invalid');\n * // null\n * ```\n *\n * @public\n */\nexport function parseVIN(vin: string): VINInfo | null {\n  if (!vin || typeof vin !== 'string') {\n    return null;\n  }\n\n  const normalizedVIN = vin.toUpperCase();\n\n  if (normalizedVIN.length !== VIN_LENGTH) {\n    return null;\n  }\n\n  for (const char of EXCLUDED_VIN_CHARS) {\n    if (normalizedVIN.includes(char)) {\n      return null;\n    }\n  }\n\n  for (const char of normalizedVIN) {\n    if (VIN_CHAR_VALUES[char] === undefined) {\n      return null;\n    }\n  }\n\n  const isValid = validateCheckDigit(normalizedVIN);\n\n  const wmi = normalizedVIN.substring(0, 3);\n  const vds = normalizedVIN.substring(3, 9);\n  const checkDigit = normalizedVIN[VIN_CHECK_DIGIT_INDEX];\n  const modelYearCode = normalizedVIN[9];\n  const plantCode = normalizedVIN[10];\n  const serialNumber = normalizedVIN.substring(11, 17);\n\n  return {\n    wmi,\n    vds,\n    checkDigit,\n    modelYearCode,\n    plantCode,\n    serialNumber,\n    isValid,\n  };\n}\n\n/**\n * Validates the check digit of a VIN.\n *\n * @internal\n */\nfunction validateCheckDigit(vin: string): boolean {\n  let sum = 0;\n  for (let i = 0; i < VIN_LENGTH; i++) {\n    const char = vin[i];\n    const weight = VIN_WEIGHTS[i];\n    const val = VIN_CHAR_VALUES[char];\n\n    if (val === undefined) {\n      return false;\n    }\n\n    sum += val * weight;\n  }\n\n  const checkDigitValue = sum % VIN_MODULUS;\n  const expectedCheckDigit =\n    checkDigitValue === 10 ? VIN_CHECK_DIGIT_X : checkDigitValue.toString();\n  const actualCheckDigit = vin[VIN_CHECK_DIGIT_INDEX];\n\n  return actualCheckDigit === expectedCheckDigit;\n}\n","import { validateVIN } from './validate';\nimport type { VINMaskOptions } from './types';\n\n/**\n * Masks a Vehicle Identification Number (VIN) for privacy.\n *\n * By default, masks the serial number section (positions 12-17).\n * VIN must pass validation to be masked.\n *\n * @param vin - The VIN to mask\n * @param options - Mask options (visibleStart, visibleEnd, maskChar)\n * @returns Masked VIN string, or empty string if invalid\n *\n * @example\n * Default masking (masks serial section):\n * ```typescript\n * maskVIN('1HGBH41JXMN109186'); // '1HGBH41JXMN******'\n * ```\n *\n * @example\n * Custom visibility:\n * ```typescript\n * maskVIN('1HGBH41JXMN109186', { visibleEnd: 2 }); // '1HGBH41JXMN109***'\n * maskVIN('1HGBH41JXMN109186', { visibleEnd: 6 }); // '1HGBH41JXMN******'\n * ```\n *\n * @example\n * Custom mask character:\n * ```typescript\n * maskVIN('1HGBH41JXMN109186', { maskChar: '#' }); // '1HGBH41JXMN######'\n * ```\n *\n * @example\n * Invalid VIN returns empty string:\n * ```typescript\n * maskVIN('invalid');   // ''\n * maskVIN('');          // ''\n * ```\n *\n * @public\n */\nexport function maskVIN(vin: string, options: VINMaskOptions = {}): string {\n  if (!vin || typeof vin !== 'string') {\n    return '';\n  }\n\n  if (!validateVIN(vin)) {\n    return '';\n  }\n\n  const { visibleStart = 11, visibleEnd = 0, maskChar = '*' } = options;\n\n  if (visibleStart < 0 || visibleEnd < 0) {\n    return '';\n  }\n\n  const normalized = vin.toUpperCase();\n  const totalLength = normalized.length;\n\n  if (visibleStart + visibleEnd >= totalLength) {\n    return normalized;\n  }\n\n  const maskLength = totalLength - visibleStart - visibleEnd;\n  const mask = maskChar.repeat(maskLength);\n\n  return (\n    normalized.substring(0, visibleStart) +\n    mask +\n    normalized.substring(visibleStart + maskLength)\n  );\n}\n","/**\n * Cleans a VIN by removing all non-alphanumeric characters\n * and converting to uppercase.\n *\n * @param vin - The VIN to clean\n * @returns Cleaned VIN string (alphanumeric only, uppercase), or empty string if empty input\n *\n * @example\n * ```typescript\n * cleanVIN('1HGBH-41JXMN-109186'); // '1HGBH41JXMN109186'\n * cleanVIN(' 1hgbh41jxmn109186 '); // '1HGBH41JXMN109186'\n * cleanVIN(''); // ''\n * ```\n *\n * @public\n */\nexport function cleanVIN(vin: string): string {\n  if (typeof vin !== 'string') {\n    return '';\n  }\n\n  const cleaned = vin.replace(/[^a-zA-Z0-9]/g, '').toUpperCase();\n\n  return cleaned;\n}\n"]}