var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/mask/builds/module.js
var module_exports = {};
__export(module_exports, {
  default: () => module_default,
  mask: () => src_default,
  stripDown: () => stripDown
});
module.exports = __toCommonJS(module_exports);

// packages/mask/src/index.js
function src_default(Alpine) {
  Alpine.directive("mask", (el, { value, expression }, { effect, evaluateLater, cleanup }) => {
    let templateFn = () => expression;
    let lastInputValue = "";
    queueMicrotask(() => {
      if (["function", "dynamic"].includes(value)) {
        let evaluator = evaluateLater(expression);
        effect(() => {
          templateFn = (input) => {
            let result;
            Alpine.dontAutoEvaluateFunctions(() => {
              evaluator((value2) => {
                result = typeof value2 === "function" ? value2(input) : value2;
              }, { scope: {
                // These are "magics" we'll make available to the x-mask:function:
                "$input": input,
                "$money": formatMoney.bind({ el })
              } });
            });
            return result;
          };
          processInputValue(el, false);
        });
      } else {
        processInputValue(el, false);
      }
      if (el._x_model)
        el._x_model.set(el.value);
    });
    const controller = new AbortController();
    cleanup(() => {
      controller.abort();
    });
    el.addEventListener("input", () => processInputValue(el), {
      signal: controller.signal,
      // Setting this as a capture phase listener to ensure it runs
      // before wire:model or x-model added as a latent binding...
      capture: true
    });
    el.addEventListener("blur", () => processInputValue(el, false), { signal: controller.signal });
    function processInputValue(el2, shouldRestoreCursor = true) {
      let input = el2.value;
      let template = templateFn(input);
      if (!template || template === "false")
        return false;
      if (lastInputValue.length - el2.value.length === 1) {
        return lastInputValue = el2.value;
      }
      let setInput = () => {
        lastInputValue = el2.value = formatInput(input, template);
      };
      if (shouldRestoreCursor) {
        restoreCursorPosition(el2, template, () => {
          setInput();
        });
      } else {
        setInput();
      }
    }
    function formatInput(input, template) {
      if (input === "")
        return "";
      let strippedDownInput = stripDown(template, input);
      let rebuiltInput = buildUp(template, strippedDownInput);
      return rebuiltInput;
    }
  }).before("model");
}
function restoreCursorPosition(el, template, callback) {
  let cursorPosition = el.selectionStart;
  let unformattedValue = el.value;
  callback();
  let beforeLeftOfCursorBeforeFormatting = unformattedValue.slice(0, cursorPosition);
  let newPosition = buildUp(
    template,
    stripDown(
      template,
      beforeLeftOfCursorBeforeFormatting
    )
  ).length;
  el.setSelectionRange(newPosition, newPosition);
}
function stripDown(template, input) {
  let inputToBeStripped = input;
  let output = "";
  let regexes = {
    "9": /[0-9]/,
    "a": /[a-zA-Z]/,
    "*": /[a-zA-Z0-9]/
  };
  let wildcardTemplate = "";
  for (let i = 0; i < template.length; i++) {
    if (["9", "a", "*"].includes(template[i])) {
      wildcardTemplate += template[i];
      continue;
    }
    for (let j = 0; j < inputToBeStripped.length; j++) {
      if (inputToBeStripped[j] === template[i]) {
        inputToBeStripped = inputToBeStripped.slice(0, j) + inputToBeStripped.slice(j + 1);
        break;
      }
    }
  }
  for (let i = 0; i < wildcardTemplate.length; i++) {
    let found = false;
    for (let j = 0; j < inputToBeStripped.length; j++) {
      if (regexes[wildcardTemplate[i]].test(inputToBeStripped[j])) {
        output += inputToBeStripped[j];
        inputToBeStripped = inputToBeStripped.slice(0, j) + inputToBeStripped.slice(j + 1);
        found = true;
        break;
      }
    }
    if (!found)
      break;
  }
  return output;
}
function buildUp(template, input) {
  let clean = Array.from(input);
  let output = "";
  for (let i = 0; i < template.length; i++) {
    if (!["9", "a", "*"].includes(template[i])) {
      output += template[i];
      continue;
    }
    if (clean.length === 0)
      break;
    output += clean.shift();
  }
  return output;
}
function formatMoney(input, delimiter = ".", thousands, precision = 2) {
  if (input === "-")
    return "-";
  if (/^\D+$/.test(input))
    return "9";
  if (thousands === null || thousands === void 0) {
    thousands = delimiter === "," ? "." : ",";
  }
  let addThousands = (input2, thousands2) => {
    let output = "";
    let counter = 0;
    for (let i = input2.length - 1; i >= 0; i--) {
      if (input2[i] === thousands2)
        continue;
      if (counter === 3) {
        output = input2[i] + thousands2 + output;
        counter = 0;
      } else {
        output = input2[i] + output;
      }
      counter++;
    }
    return output;
  };
  let minus = input.startsWith("-") ? "-" : "";
  let strippedInput = input.replaceAll(new RegExp(`[^0-9\\${delimiter}]`, "g"), "");
  let template = Array.from({ length: strippedInput.split(delimiter)[0].length }).fill("9").join("");
  template = `${minus}${addThousands(template, thousands)}`;
  if (precision > 0 && input.includes(delimiter))
    template += `${delimiter}` + "9".repeat(precision);
  queueMicrotask(() => {
    if (this.el.value.endsWith(delimiter))
      return;
    if (this.el.value[this.el.selectionStart - 1] === delimiter) {
      this.el.setSelectionRange(this.el.selectionStart - 1, this.el.selectionStart - 1);
    }
  });
  return template;
}

// packages/mask/builds/module.js
var module_default = src_default;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  mask,
  stripDown
});
