{
  "name": "time",
  "type": "registry:lib",
  "files": [
    {
      "path": "./items/lib/time/time.ts",
      "type": "registry:lib",
      "target": "./lib/time.ts",
      "content": "export const MINUTE_STEP = 5;\n\nexport const HOUR_OPTIONS: string[] = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0'));\n\nexport const MINUTE_OPTIONS: string[] = Array.from({ length: 60 / MINUTE_STEP }, (_, i) =>\n  String(i * MINUTE_STEP).padStart(2, '0'),\n);\n\nexport type TimeRangeValue = { start: string; end: string };\n\nexport function splitTime(time: string): { hour: string; minute: string } {\n  const [hour = '', minute = ''] = time.split(':');\n  return { hour, minute };\n}\n\nexport function joinTime(hour: string, minute: string): string {\n  if (!hour && !minute) return '';\n  return `${hour || '00'}:${minute || '00'}`;\n}\n\nexport function toMinutes(time: string): number | null {\n  const { hour, minute } = splitTime(time);\n  if (!hour || !minute) return null;\n  const h = Number(hour);\n  const m = Number(minute);\n  if (Number.isNaN(h) || Number.isNaN(m)) return null;\n  return h * 60 + m;\n}\n\nexport function fromMinutes(total: number): string {\n  const clamped = Math.max(0, Math.min(total, 24 * 60 - MINUTE_STEP));\n  const h = Math.floor(clamped / 60);\n  const m = clamped % 60;\n  return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\nexport function addOneHour(time: string): string {\n  const minutes = toMinutes(time);\n  if (minutes === null) return time;\n  return fromMinutes(minutes + 60);\n}\n\nexport function nextSlot(time: string): string {\n  const minutes = toMinutes(time);\n  if (minutes === null) return time;\n  return fromMinutes(minutes + MINUTE_STEP);\n}\n\nexport function isHourDisabled(hour: string, bounds?: { min?: string; max?: string }): boolean {\n  if (!hour) return false;\n  const h = Number(hour);\n  if (Number.isNaN(h)) return false;\n  const hourStart = h * 60;\n  const hourEnd = h * 60 + 55;\n  const min = bounds?.min ? toMinutes(bounds.min) : null;\n  const max = bounds?.max ? toMinutes(bounds.max) : null;\n  if (min !== null && hourEnd < min) return true;\n  if (max !== null && hourStart > max) return true;\n  return false;\n}\n\nexport function isMinuteDisabled(minute: string, hour: string, bounds?: { min?: string; max?: string }): boolean {\n  if (!hour || !minute) return false;\n  const t = toMinutes(joinTime(hour, minute));\n  if (t === null) return false;\n  const min = bounds?.min ? toMinutes(bounds.min) : null;\n  const max = bounds?.max ? toMinutes(bounds.max) : null;\n  if (min !== null && t < min) return true;\n  if (max !== null && t > max) return true;\n  return false;\n}\n"
    }
  ],
  "$schema": "https://ui.shadcn.com/schema/registry-item.json"
}
