{"version":3,"file":"use-mask.cjs","names":[],"sources":["../../src/use-mask/use-mask.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nconst DEFAULT_TOKENS: Record<string, RegExp> = {\n  '9': /[0-9]/,\n  a: /[A-Za-z]/,\n  A: /[A-Z]/,\n  '*': /[A-Za-z0-9]/,\n  '#': /[-+0-9]/,\n};\n\nexport interface UseMaskOptions {\n  /** Mask pattern string or array of string literals and RegExp objects */\n  mask: string | Array<string | RegExp>;\n\n  /** Override or extend the default token map */\n  tokens?: Record<string, RegExp>;\n\n  /** Called before masking on each keystroke, can return overrides for mask options */\n  modify?: (\n    value: string\n  ) => Partial<Pick<UseMaskOptions, 'mask' | 'tokens' | 'slotChar' | 'separate'>> | undefined;\n\n  /** When true, raw and display values are decoupled */\n  separate?: boolean;\n\n  /** Character displayed in unfilled slots, `\"_\"` by default */\n  slotChar?: string | null;\n\n  /** Show mask pattern even when field is empty and unfocused */\n  alwaysShowMask?: boolean;\n\n  /** Show mask placeholder on focus, `true` by default */\n  showMaskOnFocus?: boolean;\n\n  /** Transform each character before validation and insertion */\n  transform?: (char: string) => string;\n\n  /** Clear value on blur when mask is incomplete, `false` by default */\n  autoClear?: boolean;\n\n  /** Sets aria-invalid on the input */\n  invalid?: boolean;\n\n  /** Called on every change with raw and masked values */\n  onChangeRaw?: (rawValue: string, maskedValue: string) => void;\n\n  /** Called when all required mask slots are filled */\n  onComplete?: (maskedValue: string, rawValue: string) => void;\n\n  /** Escape hatch for advanced cursor/value manipulation */\n  beforeMaskedStateChange?: (states: {\n    previousState: MaskState;\n    currentState: MaskState;\n    nextState: MaskState;\n  }) => MaskState;\n}\n\nexport interface MaskState {\n  value: string;\n  selection: { start: number; end: number } | null;\n}\n\nexport interface UseMaskReturnValue {\n  /** Ref to attach to the input element */\n  ref: React.RefCallback<HTMLInputElement>;\n\n  /** Current masked display value */\n  value: string;\n\n  /** Current raw unmasked value */\n  rawValue: string;\n\n  /** Whether all required mask slots are filled */\n  isComplete: boolean;\n\n  /** Clear the input value and reset state */\n  reset: () => void;\n}\n\ninterface MaskSlot {\n  type: 'token' | 'literal';\n  char: string;\n  pattern?: RegExp;\n  optional?: boolean;\n}\n\ninterface UndoState {\n  rawValue: string;\n  selectionStart: number;\n}\n\nconst MAX_UNDO_HISTORY = 100;\n\nfunction parseMask(\n  mask: string | Array<string | RegExp>,\n  tokens: Record<string, RegExp>\n): MaskSlot[] {\n  if (Array.isArray(mask)) {\n    return mask.map((item) => {\n      if (item instanceof RegExp) {\n        return { type: 'token', char: '_', pattern: item };\n      }\n      return { type: 'literal', char: item };\n    });\n  }\n\n  const slots: MaskSlot[] = [];\n  let optional = false;\n\n  for (let i = 0; i < mask.length; i++) {\n    const char = mask[i];\n\n    if (char === '\\\\' && i + 1 < mask.length) {\n      i++;\n      slots.push({ type: 'literal', char: mask[i] });\n      continue;\n    }\n\n    if (char === '?') {\n      optional = true;\n      continue;\n    }\n\n    if (tokens[char]) {\n      slots.push({ type: 'token', char, pattern: tokens[char], optional });\n    } else {\n      slots.push({ type: 'literal', char, optional });\n    }\n  }\n\n  return slots;\n}\n\nfunction getSlotChar(slotCharOption: string | null | undefined, index: number): string {\n  if (slotCharOption === null || slotCharOption === '' || slotCharOption === undefined) {\n    return '';\n  }\n  if (slotCharOption.length > 1) {\n    return slotCharOption[index] || '_';\n  }\n  return slotCharOption;\n}\n\nfunction applyMaskToRaw(\n  raw: string,\n  slots: MaskSlot[],\n  _slotCharOption: string | null | undefined,\n  transform?: (char: string) => string\n): string {\n  let result = '';\n  let rawIndex = 0;\n  let slotIndex = 0;\n\n  for (slotIndex = 0; slotIndex < slots.length; slotIndex++) {\n    const slot = slots[slotIndex];\n    if (slot.type === 'literal') {\n      result += slot.char;\n    } else if (rawIndex < raw.length) {\n      const ch = transform ? transform(raw[rawIndex]) : raw[rawIndex];\n      if (slot.pattern && slot.pattern.test(ch)) {\n        result += ch;\n        rawIndex++;\n      } else {\n        rawIndex++;\n        slotIndex--;\n      }\n    } else {\n      break;\n    }\n  }\n\n  return result;\n}\n\nfunction buildDisplayValue(\n  value: string,\n  slots: MaskSlot[],\n  slotCharOption: string | null | undefined,\n  showSlots: boolean\n): string {\n  if (!showSlots) {\n    return value;\n  }\n\n  let display = value;\n\n  for (let i = value.length; i < slots.length; i++) {\n    const slot = slots[i];\n    if (slot.type === 'literal') {\n      display += slot.char;\n    } else {\n      const sc = getSlotChar(slotCharOption, i);\n      if (!sc) {\n        break;\n      }\n      display += sc;\n    }\n  }\n\n  return display;\n}\n\nfunction extractRaw(masked: string, slots: MaskSlot[]): string {\n  let raw = '';\n  for (let i = 0; i < masked.length && i < slots.length; i++) {\n    if (slots[i].type === 'token') {\n      raw += masked[i];\n    }\n  }\n  return raw;\n}\n\nfunction checkComplete(masked: string, slots: MaskSlot[]): boolean {\n  for (let i = 0; i < slots.length; i++) {\n    if (slots[i].type === 'token' && !slots[i].optional) {\n      if (i >= masked.length) {\n        return false;\n      }\n      if (!slots[i].pattern!.test(masked[i])) {\n        return false;\n      }\n    }\n  }\n  return true;\n}\n\nfunction findNextTokenIndex(slots: MaskSlot[], from: number): number {\n  for (let i = from; i < slots.length; i++) {\n    if (slots[i].type === 'token') {\n      return i;\n    }\n  }\n  return slots.length;\n}\n\nfunction findPrevTokenIndex(slots: MaskSlot[], from: number): number {\n  for (let i = from; i >= 0; i--) {\n    if (slots[i].type === 'token') {\n      return i;\n    }\n  }\n  return -1;\n}\n\nfunction processInput(\n  inputValue: string,\n  slots: MaskSlot[],\n  _slotCharOption: string | null | undefined\n): string {\n  let result = '';\n  let inputIndex = 0;\n\n  for (\n    let slotIndex = 0;\n    slotIndex < slots.length && inputIndex <= inputValue.length;\n    slotIndex++\n  ) {\n    const slot = slots[slotIndex];\n\n    if (slot.type === 'literal') {\n      result += slot.char;\n      if (inputIndex < inputValue.length && inputValue[inputIndex] === slot.char) {\n        inputIndex++;\n      }\n      continue;\n    }\n\n    if (inputIndex >= inputValue.length) {\n      break;\n    }\n\n    while (inputIndex < inputValue.length) {\n      const ch = inputValue[inputIndex];\n      inputIndex++;\n\n      if (slot.pattern!.test(ch)) {\n        result += ch;\n        break;\n      }\n    }\n\n    if (result.length <= slotIndex) {\n      break;\n    }\n  }\n\n  return result;\n}\n\nfunction getResolvedOptions(options: UseMaskOptions, rawValue: string) {\n  const tokens = { ...DEFAULT_TOKENS, ...options.tokens };\n  let mask = options.mask;\n  let slotChar: string | null | undefined = options.slotChar === undefined ? '_' : options.slotChar;\n  let separate = options.separate ?? false;\n\n  if (options.modify) {\n    const overrides = options.modify(rawValue);\n    if (overrides) {\n      if (overrides.mask !== undefined) {\n        mask = overrides.mask;\n      }\n      if (overrides.tokens !== undefined) {\n        Object.assign(tokens, overrides.tokens);\n      }\n      if (overrides.slotChar !== undefined) {\n        slotChar = overrides.slotChar;\n      }\n      if (overrides.separate !== undefined) {\n        separate = overrides.separate;\n      }\n    }\n  }\n\n  const slots = parseMask(mask, tokens);\n  return { slots, slotChar, separate, tokens, transform: options.transform };\n}\n\nexport function formatMask(raw: string, options: UseMaskOptions): string {\n  const { slots, slotChar, transform } = getResolvedOptions(options, raw);\n  return applyMaskToRaw(raw, slots, slotChar, transform);\n}\n\nexport function unformatMask(masked: string, options: UseMaskOptions): string {\n  const { slots } = getResolvedOptions(options, '');\n  return extractRaw(masked, slots);\n}\n\nexport function isMaskComplete(masked: string, options: UseMaskOptions): boolean {\n  const { slots } = getResolvedOptions(options, '');\n  return checkComplete(masked, slots);\n}\n\nexport function generatePattern(mode: 'full' | 'full-inexact', options: UseMaskOptions): string {\n  const { slots } = getResolvedOptions(options, '');\n  let pattern = '';\n\n  for (const slot of slots) {\n    if (slot.type === 'literal') {\n      pattern += slot.char.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n    } else {\n      const src = slot.pattern!.source;\n      if (mode === 'full-inexact') {\n        pattern += slot.optional ? `${src}?` : src;\n      } else {\n        pattern += slot.optional ? `(${src})?` : `(${src})`;\n      }\n    }\n  }\n\n  return pattern;\n}\n\nexport function useMask(options: UseMaskOptions): UseMaskReturnValue {\n  const optionsRef = useRef(options);\n  optionsRef.current = options;\n\n  const inputRef = useRef<HTMLInputElement | null>(null);\n  const [maskedValue, setMaskedValue] = useState('');\n  const [rawValue, setRawValue] = useState('');\n  const processedRef = useRef('');\n  const displayValueRef = useRef('');\n  const rawValueRef = useRef('');\n  const wasCompleteRef = useRef(false);\n  const isFocusedRef = useRef(false);\n  const undoStackRef = useRef<UndoState[]>([]);\n  const redoStackRef = useRef<UndoState[]>([]);\n\n  const getOptions = useCallback(() => {\n    const opts = optionsRef.current;\n    return getResolvedOptions(opts, rawValue);\n  }, [rawValue]);\n\n  const updateValue = useCallback(\n    (newMasked: string, cursorPos?: number) => {\n      const opts = optionsRef.current;\n      const { slots } = getResolvedOptions(\n        opts,\n        extractRaw(newMasked, getResolvedOptions(opts, '').slots)\n      );\n      const raw = extractRaw(newMasked, slots);\n\n      const { slots: resolvedSlots, slotChar } = getResolvedOptions(opts, raw);\n\n      const reprocessed = processInput(newMasked, resolvedSlots, slotChar);\n      const newRaw = extractRaw(reprocessed, resolvedSlots);\n\n      const showSlots = opts.alwaysShowMask || isFocusedRef.current;\n      const showOnFocus = opts.showMaskOnFocus !== false;\n      const shouldShowSlots = showSlots && (showOnFocus || reprocessed.length > 0);\n\n      const displayValue = buildDisplayValue(reprocessed, resolvedSlots, slotChar, shouldShowSlots);\n\n      processedRef.current = reprocessed;\n      displayValueRef.current = displayValue;\n      rawValueRef.current = newRaw;\n      setMaskedValue(displayValue);\n      setRawValue(newRaw);\n\n      if (inputRef.current) {\n        inputRef.current.value = displayValue;\n        if (cursorPos !== undefined && document.activeElement === inputRef.current) {\n          const pos = Math.min(cursorPos, reprocessed.length);\n          inputRef.current.setSelectionRange(pos, pos);\n        }\n      }\n\n      if (opts.onChangeRaw) {\n        opts.onChangeRaw(newRaw, displayValue);\n      }\n\n      const complete = checkComplete(reprocessed, resolvedSlots);\n      if (complete && !wasCompleteRef.current && opts.onComplete) {\n        opts.onComplete(displayValue, newRaw);\n      }\n      wasCompleteRef.current = complete;\n\n      return { displayValue, newRaw, reprocessed, resolvedSlots };\n    },\n    [getOptions]\n  );\n\n  const pushUndoState = useCallback(() => {\n    const input = inputRef.current;\n    const selectionStart = input?.selectionStart ?? rawValueRef.current.length;\n    const state: UndoState = {\n      rawValue: rawValueRef.current,\n      selectionStart,\n    };\n    const stack = undoStackRef.current;\n    const top = stack[stack.length - 1];\n    if (top && top.rawValue === state.rawValue && top.selectionStart === state.selectionStart) {\n      return;\n    }\n    stack.push(state);\n    if (stack.length > MAX_UNDO_HISTORY) {\n      stack.shift();\n    }\n    redoStackRef.current = [];\n  }, []);\n\n  const applyHistoryState = useCallback(\n    (target: UndoState) => {\n      const opts = optionsRef.current;\n      const { slots, slotChar, transform } = getResolvedOptions(opts, target.rawValue);\n      const newMasked = applyMaskToRaw(target.rawValue, slots, slotChar, transform);\n      updateValue(newMasked, target.selectionStart);\n    },\n    [updateValue]\n  );\n\n  const handleInput = useCallback(\n    (e: Event) => {\n      const input = e.target as HTMLInputElement;\n      const opts = optionsRef.current;\n\n      const { slots: resolvedSlots, slotChar, transform } = getResolvedOptions(opts, '');\n      const prev = displayValueRef.current;\n      const curr = input.value;\n\n      let prefixLen = 0;\n      const maxPrefix = Math.min(prev.length, curr.length);\n      while (prefixLen < maxPrefix && prev[prefixLen] === curr[prefixLen]) {\n        prefixLen++;\n      }\n\n      let suffixLen = 0;\n      const maxSuffix = Math.min(prev.length - prefixLen, curr.length - prefixLen);\n      while (\n        suffixLen < maxSuffix &&\n        prev[prev.length - 1 - suffixLen] === curr[curr.length - 1 - suffixLen]\n      ) {\n        suffixLen++;\n      }\n\n      const insertedText = curr.slice(prefixLen, curr.length - suffixLen);\n      const removedEnd = prev.length - suffixLen;\n\n      const beforeRaw = extractRaw(prev.slice(0, prefixLen), resolvedSlots.slice(0, prefixLen));\n      const afterRaw = extractRaw(prev.slice(removedEnd), resolvedSlots.slice(removedEnd));\n      const reformatted = applyMaskToRaw(\n        beforeRaw + insertedText + afterRaw,\n        resolvedSlots,\n        slotChar,\n        transform\n      );\n      const maskedPrefix = applyMaskToRaw(\n        beforeRaw + insertedText,\n        resolvedSlots,\n        slotChar,\n        transform\n      );\n\n      if (reformatted !== prev) {\n        pushUndoState();\n      }\n      updateValue(reformatted, maskedPrefix.length);\n    },\n    [pushUndoState, updateValue]\n  );\n\n  const clampCursorToProcessed = useCallback((input: HTMLInputElement) => {\n    const start = input.selectionStart ?? 0;\n    const end = input.selectionEnd ?? 0;\n    if (start !== end) {\n      return;\n    }\n\n    const opts = optionsRef.current;\n    const { slots } = getResolvedOptions(opts, '');\n    const processed = processedRef.current;\n    const endPos =\n      processed.length > 0\n        ? findNextEditablePosition(processed.length, slots, processed)\n        : findNextTokenIndex(slots, 0);\n    const startPos = findNextTokenIndex(slots, 0);\n\n    if (start > endPos || start < startPos) {\n      input.setSelectionRange(endPos, endPos);\n    }\n  }, []);\n\n  const handleFocus = useCallback(() => {\n    isFocusedRef.current = true;\n    const opts = optionsRef.current;\n    const input = inputRef.current;\n\n    if (!input) {\n      return;\n    }\n\n    const { slots, slotChar } = getResolvedOptions(opts, '');\n    const showOnFocus = opts.showMaskOnFocus !== false;\n    const processed = processedRef.current;\n\n    if (showOnFocus || opts.alwaysShowMask) {\n      const display = buildDisplayValue(processed, slots, slotChar, true);\n      input.value = display;\n      displayValueRef.current = display;\n      setMaskedValue(display);\n    }\n\n    requestAnimationFrame(() => {\n      if (input === document.activeElement) {\n        clampCursorToProcessed(input);\n      }\n    });\n  }, [clampCursorToProcessed]);\n\n  const handleMouseUp = useCallback(() => {\n    const input = inputRef.current;\n    if (!input || input !== document.activeElement) {\n      return;\n    }\n\n    clampCursorToProcessed(input);\n  }, [clampCursorToProcessed]);\n\n  const handleMouseDown = useCallback(() => {\n    const input = inputRef.current;\n    if (!input) {\n      return;\n    }\n\n    requestAnimationFrame(() => {\n      if (input !== document.activeElement) {\n        return;\n      }\n\n      const start = input.selectionStart ?? 0;\n      const end = input.selectionEnd ?? 0;\n      if (start !== end) {\n        return;\n      }\n\n      const opts = optionsRef.current;\n      const { slots } = getResolvedOptions(opts, '');\n      const processed = processedRef.current;\n      const endPos =\n        processed.length > 0\n          ? findNextEditablePosition(processed.length, slots, processed)\n          : findNextTokenIndex(slots, 0);\n\n      if (start > endPos) {\n        input.setSelectionRange(endPos, endPos);\n      }\n    });\n  }, []);\n\n  const handleBlur = useCallback(() => {\n    isFocusedRef.current = false;\n    const opts = optionsRef.current;\n    const input = inputRef.current;\n\n    if (!input) {\n      return;\n    }\n\n    const { slots, slotChar } = getResolvedOptions(opts, rawValue);\n    const expectedFocusDisplay = buildDisplayValue(processedRef.current, slots, slotChar, true);\n    const processed =\n      input.value === expectedFocusDisplay\n        ? processedRef.current\n        : processInput(input.value, slots, slotChar);\n    const complete = checkComplete(processed, slots);\n\n    if (opts.autoClear && !complete && processed.length > 0) {\n      input.value = '';\n      processedRef.current = '';\n      displayValueRef.current = '';\n      rawValueRef.current = '';\n      setMaskedValue('');\n      setRawValue('');\n      wasCompleteRef.current = false;\n\n      if (opts.onChangeRaw) {\n        opts.onChangeRaw('', '');\n      }\n\n      if (opts.alwaysShowMask) {\n        const emptyDisplay = buildDisplayValue('', slots, slotChar, true);\n        input.value = emptyDisplay;\n        displayValueRef.current = emptyDisplay;\n        setMaskedValue(emptyDisplay);\n      }\n      return;\n    }\n\n    if (!opts.alwaysShowMask && !complete) {\n      if (extractRaw(processed, slots).length === 0) {\n        input.value = '';\n        processedRef.current = '';\n        displayValueRef.current = '';\n        rawValueRef.current = '';\n        setMaskedValue('');\n        setRawValue('');\n        wasCompleteRef.current = false;\n\n        if (opts.onChangeRaw) {\n          opts.onChangeRaw('', '');\n        }\n        return;\n      }\n\n      const display = buildDisplayValue(processed, slots, slotChar, false);\n      input.value = display;\n      displayValueRef.current = display;\n      setMaskedValue(display);\n    }\n  }, [rawValue]);\n\n  const handleKeyDown = useCallback(\n    (e: KeyboardEvent) => {\n      const input = e.target as HTMLInputElement;\n      const opts = optionsRef.current;\n\n      const { slots, slotChar, transform } = getResolvedOptions(opts, rawValue);\n      const start = input.selectionStart ?? 0;\n      const end = input.selectionEnd ?? 0;\n      const processed = processedRef.current;\n\n      const modifier = e.metaKey || (e.ctrlKey && !e.altKey);\n      const key = e.key.toLowerCase();\n\n      if (modifier && key === 'z' && !e.shiftKey) {\n        e.preventDefault();\n        const prev = undoStackRef.current.pop();\n        if (!prev) {\n          return;\n        }\n        redoStackRef.current.push({\n          rawValue: rawValueRef.current,\n          selectionStart: input.selectionStart ?? 0,\n        });\n        applyHistoryState(prev);\n        return;\n      }\n\n      if (modifier && ((key === 'z' && e.shiftKey) || (key === 'y' && !e.shiftKey))) {\n        e.preventDefault();\n        const next = redoStackRef.current.pop();\n        if (!next) {\n          return;\n        }\n        undoStackRef.current.push({\n          rawValue: rawValueRef.current,\n          selectionStart: input.selectionStart ?? 0,\n        });\n        applyHistoryState(next);\n        return;\n      }\n\n      if (e.key === 'Backspace') {\n        e.preventDefault();\n\n        if (e.metaKey || (e.ctrlKey && !e.altKey)) {\n          const clampedStart = Math.min(start, processed.length);\n          const afterRaw = extractRaw(processed.slice(clampedStart), slots.slice(clampedStart));\n          const newValue = applyMaskToRaw(afterRaw, slots, slotChar, transform);\n          pushUndoState();\n          updateValue(newValue, 0);\n          return;\n        }\n\n        if (start !== end) {\n          const clampedEnd = Math.min(end, processed.length);\n          const before = processed.slice(0, start);\n          const afterRaw = extractRaw(processed.slice(clampedEnd), slots.slice(clampedEnd));\n          const newValue = applyMaskToRaw(\n            extractRaw(before, slots) + afterRaw,\n            slots,\n            slotChar,\n            transform\n          );\n          pushUndoState();\n          updateValue(newValue, start);\n          return;\n        }\n\n        if (start === 0) {\n          return;\n        }\n\n        let deletePos = start - 1;\n        while (deletePos >= 0 && slots[deletePos] && slots[deletePos].type === 'literal') {\n          deletePos--;\n        }\n\n        if (deletePos < 0) {\n          return;\n        }\n\n        const beforeRaw = extractRaw(processed.slice(0, deletePos), slots.slice(0, deletePos));\n        const afterRaw = extractRaw(processed.slice(deletePos + 1), slots.slice(deletePos + 1));\n        const newValue = applyMaskToRaw(beforeRaw + afterRaw, slots, slotChar, transform);\n        pushUndoState();\n        updateValue(newValue, deletePos);\n      } else if (e.key === 'Delete') {\n        e.preventDefault();\n\n        if (start !== end) {\n          const clampedEnd = Math.min(end, processed.length);\n          const before = processed.slice(0, start);\n          const afterRaw = extractRaw(processed.slice(clampedEnd), slots.slice(clampedEnd));\n          const newValue = applyMaskToRaw(\n            extractRaw(before, slots) + afterRaw,\n            slots,\n            slotChar,\n            transform\n          );\n          pushUndoState();\n          updateValue(newValue, start);\n          return;\n        }\n\n        let deletePos = start;\n        while (\n          deletePos < slots.length &&\n          slots[deletePos] &&\n          slots[deletePos].type === 'literal'\n        ) {\n          deletePos++;\n        }\n\n        if (deletePos >= processed.length) {\n          return;\n        }\n\n        const beforeRaw = extractRaw(processed.slice(0, start), slots.slice(0, start));\n        const afterRaw = extractRaw(processed.slice(deletePos + 1), slots.slice(deletePos + 1));\n        const newValue = applyMaskToRaw(beforeRaw + afterRaw, slots, slotChar, transform);\n        pushUndoState();\n        updateValue(newValue, start);\n      } else if (e.key === 'ArrowRight' && !e.shiftKey) {\n        const nextPos = findNextEditablePosition(start + 1, slots, input.value);\n        if (nextPos !== start + 1) {\n          e.preventDefault();\n          input.setSelectionRange(nextPos, nextPos);\n        }\n      } else if (e.key === 'ArrowLeft' && !e.shiftKey) {\n        if (start > 0) {\n          const prevToken = findPrevTokenIndex(slots, start - 1);\n          if (prevToken >= 0 && prevToken !== start - 1) {\n            e.preventDefault();\n            input.setSelectionRange(prevToken + 1, prevToken + 1);\n          }\n        }\n      } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n        e.preventDefault();\n\n        let insertPos = Math.min(start, processed.length);\n        while (\n          insertPos < slots.length &&\n          slots[insertPos] &&\n          slots[insertPos].type === 'literal'\n        ) {\n          insertPos++;\n        }\n\n        if (insertPos >= slots.length) {\n          return;\n        }\n\n        const slot = slots[insertPos];\n        const ch = transform ? transform(e.key) : e.key;\n        if (!slot.pattern!.test(ch)) {\n          return;\n        }\n\n        const beforeRaw = extractRaw(processed.slice(0, insertPos), slots.slice(0, insertPos));\n        const afterRaw =\n          start < end\n            ? extractRaw(\n                processed.slice(Math.min(end, processed.length)),\n                slots.slice(Math.min(end, processed.length))\n              )\n            : extractRaw(processed.slice(insertPos), slots.slice(insertPos));\n        const newValue = applyMaskToRaw(beforeRaw + ch + afterRaw, slots, slotChar, transform);\n        const newCursorPos = findNextEditablePosition(insertPos + 1, slots, newValue);\n        pushUndoState();\n        updateValue(newValue, newCursorPos);\n      }\n    },\n    [applyHistoryState, pushUndoState, rawValue, updateValue]\n  );\n\n  const handlePaste = useCallback(\n    (e: ClipboardEvent) => {\n      e.preventDefault();\n      const input = e.target as HTMLInputElement;\n      const opts = optionsRef.current;\n\n      const pastedText = e.clipboardData?.getData('text') ?? '';\n      const start = input.selectionStart ?? 0;\n      const end = input.selectionEnd ?? 0;\n      const processed = processedRef.current;\n\n      const { slots, slotChar, transform } = getResolvedOptions(opts, '');\n      const clampedStart = Math.min(start, processed.length);\n      const clampedEnd = Math.min(end, processed.length);\n      const beforeRaw = extractRaw(processed.slice(0, clampedStart), slots.slice(0, clampedStart));\n      const afterRaw = extractRaw(processed.slice(clampedEnd), slots.slice(clampedEnd));\n      const newValue = applyMaskToRaw(\n        beforeRaw + pastedText + afterRaw,\n        slots,\n        slotChar,\n        transform\n      );\n\n      pushUndoState();\n      updateValue(newValue);\n\n      const maskedPrefix = applyMaskToRaw(beforeRaw + pastedText, slots, slotChar, transform);\n      const pasteEndPos = Math.min(maskedPrefix.length, slots.length);\n      if (input === document.activeElement) {\n        input.setSelectionRange(pasteEndPos, pasteEndPos);\n      }\n    },\n    [pushUndoState, updateValue]\n  );\n\n  const setAriaAttributes = useCallback((input: HTMLInputElement) => {\n    const opts = optionsRef.current;\n\n    if (opts.invalid) {\n      input.setAttribute('aria-invalid', 'true');\n    } else {\n      input.removeAttribute('aria-invalid');\n    }\n  }, []);\n\n  const refCallback = useCallback(\n    (node: HTMLInputElement | null) => {\n      const prevInput = inputRef.current;\n\n      if (prevInput) {\n        prevInput.removeEventListener('input', handleInput);\n        prevInput.removeEventListener('focus', handleFocus);\n        prevInput.removeEventListener('blur', handleBlur);\n        prevInput.removeEventListener('mousedown', handleMouseDown);\n        prevInput.removeEventListener('mouseup', handleMouseUp);\n        prevInput.removeEventListener('keydown', handleKeyDown as EventListener);\n        prevInput.removeEventListener('paste', handlePaste as EventListener);\n      }\n\n      inputRef.current = node;\n\n      if (node) {\n        node.addEventListener('input', handleInput);\n        node.addEventListener('focus', handleFocus);\n        node.addEventListener('blur', handleBlur);\n        node.addEventListener('mousedown', handleMouseDown);\n        node.addEventListener('mouseup', handleMouseUp);\n        node.addEventListener('keydown', handleKeyDown as EventListener);\n        node.addEventListener('paste', handlePaste as EventListener);\n\n        setAriaAttributes(node);\n\n        if (options.alwaysShowMask && !node.value) {\n          const { slots, slotChar } = getResolvedOptions(options, '');\n          const display = buildDisplayValue('', slots, slotChar, true);\n          node.value = display;\n          displayValueRef.current = display;\n          setMaskedValue(display);\n        }\n      }\n    },\n    [\n      handleInput,\n      handleFocus,\n      handleBlur,\n      handleMouseDown,\n      handleMouseUp,\n      handleKeyDown,\n      handlePaste,\n      setAriaAttributes,\n      options,\n    ]\n  );\n\n  useEffect(() => {\n    const input = inputRef.current;\n    if (!input) {\n      return;\n    }\n\n    setAriaAttributes(input);\n  }, [options.invalid, setAriaAttributes]);\n\n  const isComplete = (() => {\n    const { slots } = getOptions();\n    return checkComplete(processedRef.current, slots);\n  })();\n\n  const reset = useCallback(() => {\n    const opts = optionsRef.current;\n    const input = inputRef.current;\n\n    processedRef.current = '';\n    displayValueRef.current = '';\n    rawValueRef.current = '';\n    undoStackRef.current = [];\n    redoStackRef.current = [];\n    setMaskedValue('');\n    setRawValue('');\n    wasCompleteRef.current = false;\n\n    if (input) {\n      if (opts.alwaysShowMask) {\n        const { slots, slotChar } = getResolvedOptions(opts, '');\n        const display = buildDisplayValue('', slots, slotChar, true);\n        input.value = display;\n        displayValueRef.current = display;\n        setMaskedValue(display);\n      } else {\n        input.value = '';\n      }\n    }\n\n    if (opts.onChangeRaw) {\n      opts.onChangeRaw('', '');\n    }\n  }, []);\n\n  return {\n    ref: refCallback,\n    value: maskedValue,\n    rawValue,\n    isComplete,\n    reset,\n  };\n}\n\nfunction findNextEditablePosition(from: number, slots: MaskSlot[], value: string): number {\n  let pos = from;\n  while (pos < slots.length && pos < value.length && slots[pos] && slots[pos].type === 'literal') {\n    pos++;\n  }\n  return pos;\n}\n\nexport namespace useMask {\n  export type Options = UseMaskOptions;\n  export type ReturnValue = UseMaskReturnValue;\n}\n"],"mappings":"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"}