{"version":3,"sources":["../src/index.ts","../src/core/errors.ts","../src/core/wall-date.ts","../src/core/calendar.ts"],"sourcesContent":["export {\n  BusinessCalendarParseError,\n  addWallDays,\n  createBusinessCalendar,\n  normalizeWallDate,\n  wallDateDayOfWeek,\n} from \"./core/index.js\";\nexport type {\n  BusinessCalendar,\n  BusinessCalendarOptions,\n  WallDate,\n} from \"./core/index.js\";\n","export class BusinessCalendarParseError extends Error {\n  readonly code = \"BUSINESS_CALENDAR_PARSE_ERROR\" as const;\n\n  constructor(message: string) {\n    super(message);\n    this.name = \"BusinessCalendarParseError\";\n  }\n}\n","import { BusinessCalendarParseError } from \"./errors.js\";\n\n/** Calendar date `YYYY-MM-DD` (no time zone — wall intent). */\nexport type WallDate = string;\n\nconst WALL_DATE_RE = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\nexport function normalizeWallDate(value: string): WallDate {\n  const trimmed = value.trim();\n  const match = WALL_DATE_RE.exec(trimmed);\n  if (!match) {\n    throw new BusinessCalendarParseError(\n      `Invalid wall date \"${value}\" — expected YYYY-MM-DD`,\n    );\n  }\n  const year = Number(match[1]);\n  const month = Number(match[2]);\n  const day = Number(match[3]);\n  const utc = Date.UTC(year, month - 1, day);\n  const check = new Date(utc);\n  if (\n    check.getUTCFullYear() !== year ||\n    check.getUTCMonth() !== month - 1 ||\n    check.getUTCDate() !== day\n  ) {\n    throw new BusinessCalendarParseError(`Invalid calendar date \"${value}\"`);\n  }\n  const mm = String(month).padStart(2, \"0\");\n  const dd = String(day).padStart(2, \"0\");\n  return `${year}-${mm}-${dd}`;\n}\n\nexport function wallDateDayOfWeek(date: WallDate): number {\n  const normalized = normalizeWallDate(date);\n  const [y, m, d] = normalized.split(\"-\").map(Number) as [number, number, number];\n  return new Date(Date.UTC(y, m - 1, d)).getUTCDay();\n}\n\nexport function addWallDays(date: WallDate, days: number): WallDate {\n  const normalized = normalizeWallDate(date);\n  const [y, m, d] = normalized.split(\"-\").map(Number) as [number, number, number];\n  const next = new Date(Date.UTC(y, m - 1, d));\n  next.setUTCDate(next.getUTCDate() + days);\n  const ny = next.getUTCFullYear();\n  const nm = String(next.getUTCMonth() + 1).padStart(2, \"0\");\n  const nd = String(next.getUTCDate()).padStart(2, \"0\");\n  return `${ny}-${nm}-${nd}`;\n}\n","import { BusinessCalendarParseError } from \"./errors.js\";\nimport type { BusinessCalendar, BusinessCalendarOptions } from \"./types.js\";\nimport {\n  addWallDays,\n  normalizeWallDate,\n  wallDateDayOfWeek,\n  type WallDate,\n} from \"./wall-date.js\";\n\nfunction normalizeWeekendDays(days: readonly number[]): ReadonlySet<number> {\n  const set = new Set<number>();\n  for (const day of days) {\n    if (!Number.isInteger(day) || day < 0 || day > 6) {\n      throw new BusinessCalendarParseError(\n        `weekendDays entry ${day} must be an integer 0–6 (Sun–Sat)`,\n      );\n    }\n    set.add(day);\n  }\n  return set;\n}\n\nexport function createBusinessCalendar(\n  options: BusinessCalendarOptions,\n): BusinessCalendar {\n  const weekendDays = normalizeWeekendDays(options.weekendDays);\n  const holidays = new Set(\n    options.holidays.map((h) => normalizeWallDate(h)),\n  );\n\n  function isBusinessDay(date: string): boolean {\n    const wall = normalizeWallDate(date);\n    if (holidays.has(wall)) {\n      return false;\n    }\n    const dow = wallDateDayOfWeek(wall);\n    return !weekendDays.has(dow);\n  }\n\n  function nextBusinessDay(date: string): WallDate {\n    let cursor = normalizeWallDate(date);\n    do {\n      cursor = addWallDays(cursor, 1);\n    } while (!isBusinessDay(cursor));\n    return cursor;\n  }\n\n  function addBusinessDays(date: string, days: number): WallDate {\n    if (!Number.isInteger(days)) {\n      throw new BusinessCalendarParseError(\"days must be an integer\");\n    }\n    let cursor = normalizeWallDate(date);\n    if (days === 0) {\n      return cursor;\n    }\n    const step = days > 0 ? 1 : -1;\n    let remaining = Math.abs(days);\n    while (remaining > 0) {\n      cursor = addWallDays(cursor, step);\n      if (isBusinessDay(cursor)) {\n        remaining -= 1;\n      }\n    }\n    return cursor;\n  }\n\n  return { isBusinessDay, nextBusinessDay, addBusinessDays };\n}\n"],"mappings":"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","names":[]}