import { useSyncExternalStore, useState, useRef, useEffect } from 'react';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import { jsx } from 'react/jsx-runtime';

var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __objRest = (source, exclude) => {
  var target = {};
  for (var prop in source)
    if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
      target[prop] = source[prop];
  if (source != null && __getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(source)) {
      if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
        target[prop] = source[prop];
    }
  return target;
};
function subscribePrefersReducedMotion(onStoreChange) {
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
  mq.addEventListener("change", onStoreChange);
  return () => mq.removeEventListener("change", onStoreChange);
}
function getPrefersReducedMotionSnapshot() {
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
}
function getPrefersReducedMotionServerSnapshot() {
  return false;
}
function useAtlasSummaryTypewriter(targetText, options) {
  var _a;
  const msPerChar = (_a = options == null ? void 0 : options.msPerChar) != null ? _a : 8;
  const reduceMotion = useSyncExternalStore(
    subscribePrefersReducedMotion,
    getPrefersReducedMotionSnapshot,
    getPrefersReducedMotionServerSnapshot
  );
  const [charCount, setCharCount] = useState(0);
  const previousTargetRef = useRef(null);
  useEffect(() => {
    let cancelled = false;
    const frameId = requestAnimationFrame(() => {
      if (cancelled) return;
      if (!targetText) {
        previousTargetRef.current = null;
        setCharCount(0);
        return;
      }
      if (targetText !== previousTargetRef.current) {
        previousTargetRef.current = targetText;
        setCharCount(0);
      }
    });
    return () => {
      cancelled = true;
      cancelAnimationFrame(frameId);
    };
  }, [targetText]);
  useEffect(() => {
    if (!targetText || !reduceMotion) {
      return;
    }
    let cancelled = false;
    const frameId = requestAnimationFrame(() => {
      if (!cancelled) {
        setCharCount(targetText.length);
      }
    });
    return () => {
      cancelled = true;
      cancelAnimationFrame(frameId);
    };
  }, [targetText, reduceMotion]);
  useEffect(() => {
    if (!targetText || reduceMotion) {
      return;
    }
    if (charCount >= targetText.length) {
      return;
    }
    const timeoutId = window.setTimeout(() => {
      setCharCount((current) => Math.min(current + 1, targetText.length));
    }, msPerChar);
    return () => window.clearTimeout(timeoutId);
  }, [targetText, charCount, msPerChar, reduceMotion]);
  const visibleText = targetText == null ? "" : reduceMotion ? targetText : targetText.slice(0, charCount);
  const isComplete = Boolean(targetText && visibleText.length >= targetText.length);
  return { visibleText, isComplete };
}
var SHUFFLE_TEXT_DEFAULT_SYMBOLS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
function subscribePrefersReducedMotion2(onStoreChange) {
  const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
  mq.addEventListener("change", onStoreChange);
  return () => mq.removeEventListener("change", onStoreChange);
}
function getPrefersReducedMotionSnapshot2() {
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
}
function getPrefersReducedMotionServerSnapshot2() {
  return false;
}
function getShuffleTextAtFrame(text, frame, {
  charStartFrameOffset = 2,
  shuffleFrameCount = 15,
  pickSymbol
}) {
  const resolveSymbol = pickSymbol != null ? pickSymbol : (() => SHUFFLE_TEXT_DEFAULT_SYMBOLS[Math.floor(Math.random() * SHUFFLE_TEXT_DEFAULT_SYMBOLS.length)]);
  const chars = text.split("");
  let isComplete = true;
  const resolved = chars.map((char, index) => {
    if (char === " ") {
      return " ";
    }
    const startFrame = index * charStartFrameOffset;
    const endFrame = startFrame + shuffleFrameCount;
    if (frame < startFrame) {
      isComplete = false;
      return "";
    }
    if (frame < endFrame) {
      isComplete = false;
      return resolveSymbol();
    }
    return char;
  });
  return { chars: resolved, isComplete };
}
function useShuffleText(text, options) {
  var _a, _b, _c, _d, _e, _f;
  const charStartFrameOffset = (_a = options == null ? void 0 : options.charStartFrameOffset) != null ? _a : 2;
  const shuffleFrameCount = (_b = options == null ? void 0 : options.shuffleFrameCount) != null ? _b : 15;
  const frameMs = (_c = options == null ? void 0 : options.frameMs) != null ? _c : 30;
  const startDelayMs = (_d = options == null ? void 0 : options.startDelayMs) != null ? _d : 0;
  const symbols = (_e = options == null ? void 0 : options.symbols) != null ? _e : SHUFFLE_TEXT_DEFAULT_SYMBOLS;
  const enabled = (_f = options == null ? void 0 : options.enabled) != null ? _f : true;
  const reduceMotion = useSyncExternalStore(
    subscribePrefersReducedMotion2,
    getPrefersReducedMotionSnapshot2,
    getPrefersReducedMotionServerSnapshot2
  );
  const [chars, setChars] = useState(() => text.split(""));
  const [isComplete, setIsComplete] = useState(true);
  const pickSymbolRef = useRef(() => {
    var _a2;
    return (_a2 = symbols[0]) != null ? _a2 : "";
  });
  useEffect(() => {
    pickSymbolRef.current = () => symbols[Math.floor(Math.random() * symbols.length)];
  }, [symbols]);
  useEffect(() => {
    if (!enabled || reduceMotion) {
      const nextChars = text.split("");
      let cancelled2 = false;
      const frameId = requestAnimationFrame(() => {
        if (!cancelled2) {
          setChars(nextChars);
          setIsComplete(true);
        }
      });
      return () => {
        cancelled2 = true;
        cancelAnimationFrame(frameId);
      };
    }
    let cancelled = false;
    let frame = 0;
    let startTimeoutId = 0;
    let frameTimeoutId = 0;
    const update = () => {
      if (cancelled) return;
      const result = getShuffleTextAtFrame(text, frame, {
        charStartFrameOffset,
        shuffleFrameCount,
        pickSymbol: () => pickSymbolRef.current()
      });
      setChars(result.chars);
      setIsComplete(result.isComplete);
      frame += 1;
      if (!result.isComplete) {
        frameTimeoutId = window.setTimeout(() => {
          requestAnimationFrame(update);
        }, frameMs);
      }
    };
    setChars(text.split("").map((char) => char === " " ? " " : ""));
    setIsComplete(false);
    startTimeoutId = window.setTimeout(() => {
      update();
    }, startDelayMs);
    return () => {
      cancelled = true;
      window.clearTimeout(startTimeoutId);
      window.clearTimeout(frameTimeoutId);
    };
  }, [
    charStartFrameOffset,
    enabled,
    frameMs,
    reduceMotion,
    shuffleFrameCount,
    startDelayMs,
    text
  ]);
  return { chars, isComplete };
}
function cn(...inputs) {
  return twMerge(clsx(inputs));
}
function ShuffleText(_a) {
  var _b = _a, { text, className } = _b, options = __objRest(_b, ["text", "className"]);
  const { chars } = useShuffleText(text, options);
  return /* @__PURE__ */ jsx("span", { className: cn("inline-block min-w-0 max-w-full", className), children: chars.map((char, index) => /* @__PURE__ */ jsx("span", { className: "inline-block whitespace-pre", children: char }, index)) });
}

// src/motion/transitions/invoice-forward-morph.ts
var INVOICE_FORWARD_MORPH_DURATION_MS = 280;
var INVOICE_FORWARD_MORPH_DURATION_S = INVOICE_FORWARD_MORPH_DURATION_MS / 1e3;
var MORPH_CROSSFADE_RATIO = 80 / 300;
var SOURCE_CONTENT_FADE_RATIO = 80 / 300;
var SOURCE_CONTENT_FADE_START_RATIO = 32 / 300;
var SIBLING_FADE_LEAD_MS = 140;
var INVOICE_MORPH_SETTLE_BUFFER_MS = 160;
var INVOICE_MORPH_CROSSFADE_MS = Math.round(
  INVOICE_FORWARD_MORPH_DURATION_MS * MORPH_CROSSFADE_RATIO
);
var INVOICE_MORPH_CROSSFADE_S = INVOICE_MORPH_CROSSFADE_MS / 1e3;
var INVOICE_MORPH_CROSSFADE_START_MS = INVOICE_FORWARD_MORPH_DURATION_MS - INVOICE_MORPH_CROSSFADE_MS;
var INVOICE_NAV_SIBLING_FADE_MS = INVOICE_FORWARD_MORPH_DURATION_MS + SIBLING_FADE_LEAD_MS;
var INVOICE_NAV_SIBLING_FADE_DURATION_S = INVOICE_NAV_SIBLING_FADE_MS / 1e3;
var INVOICE_MORPH_SOURCE_CONTENT_FADE_MS = Math.round(
  INVOICE_FORWARD_MORPH_DURATION_MS * SOURCE_CONTENT_FADE_RATIO
);
var INVOICE_MORPH_SOURCE_CONTENT_FADE_DURATION_S = INVOICE_MORPH_SOURCE_CONTENT_FADE_MS / 1e3;
var INVOICE_MORPH_SOURCE_CONTENT_FADE_START_MS = Math.round(
  INVOICE_FORWARD_MORPH_DURATION_MS * SOURCE_CONTENT_FADE_START_RATIO
);
var INVOICE_NAV_HANDOFF_DELAY_MS = 0;
function getInvoiceNavNavigateDelayMs() {
  return INVOICE_NAV_HANDOFF_DELAY_MS;
}
var INVOICE_MORPH_EASE_IN_OUT = [0.645, 0.045, 0.355, 1];
var INVOICE_MORPH_EASE_OUT = [0.22, 1, 0.36, 1];
var invoiceForwardMorphTransition = {
  type: "tween",
  duration: INVOICE_FORWARD_MORPH_DURATION_S,
  ease: INVOICE_MORPH_EASE_IN_OUT
};
var invoiceMorphCrossfadeTransition = {
  type: "tween",
  duration: INVOICE_MORPH_CROSSFADE_S,
  ease: INVOICE_MORPH_EASE_OUT
};
var INVOICE_DETAIL_REVEAL_DELAY_S = INVOICE_MORPH_CROSSFADE_START_MS / 1e3;

// src/motion/transitions/card-resize.ts
var CARD_RESIZE_DURATION_MS = 300;
var CARD_RESIZE_DURATION_S = CARD_RESIZE_DURATION_MS / 1e3;
var CARD_RESIZE_EASE = [0.22, 1, 0.36, 1];
var CARD_RESIZE_EASE_CSS = "cubic-bezier(0.22, 1, 0.36, 1)";
var cardResizeFramerLayoutTransition = {
  layout: {
    type: "tween",
    duration: CARD_RESIZE_DURATION_S,
    ease: CARD_RESIZE_EASE
  }
};
var INVOICE_NAV_PREPARE_MS = 50;
var INVOICE_NAV_PREPARE_DURATION_S = INVOICE_NAV_PREPARE_MS / 1e3;
var invoiceNavPrepareTransition = {
  duration: INVOICE_NAV_PREPARE_DURATION_S,
  ease: CARD_RESIZE_EASE
};
var invoiceNavSiblingFadeTransition = {
  duration: INVOICE_NAV_SIBLING_FADE_DURATION_S,
  ease: CARD_RESIZE_EASE
};
var invoiceMorphSourceContentFadeTransition = {
  duration: INVOICE_MORPH_SOURCE_CONTENT_FADE_DURATION_S,
  ease: CARD_RESIZE_EASE
};
function getInvoiceNavMorphClearMs() {
  return INVOICE_NAV_PREPARE_MS + CARD_RESIZE_DURATION_MS + 80;
}

export { CARD_RESIZE_DURATION_MS, CARD_RESIZE_DURATION_S, CARD_RESIZE_EASE, CARD_RESIZE_EASE_CSS, INVOICE_DETAIL_REVEAL_DELAY_S, INVOICE_FORWARD_MORPH_DURATION_MS, INVOICE_FORWARD_MORPH_DURATION_S, INVOICE_MORPH_CROSSFADE_MS, INVOICE_MORPH_CROSSFADE_S, INVOICE_MORPH_CROSSFADE_START_MS, INVOICE_MORPH_EASE_IN_OUT, INVOICE_MORPH_EASE_OUT, INVOICE_MORPH_SETTLE_BUFFER_MS, INVOICE_MORPH_SOURCE_CONTENT_FADE_DURATION_S, INVOICE_MORPH_SOURCE_CONTENT_FADE_MS, INVOICE_MORPH_SOURCE_CONTENT_FADE_START_MS, INVOICE_NAV_HANDOFF_DELAY_MS, INVOICE_NAV_PREPARE_DURATION_S, INVOICE_NAV_PREPARE_MS, INVOICE_NAV_SIBLING_FADE_DURATION_S, INVOICE_NAV_SIBLING_FADE_MS, SHUFFLE_TEXT_DEFAULT_SYMBOLS, ShuffleText, cardResizeFramerLayoutTransition, getInvoiceNavMorphClearMs, getInvoiceNavNavigateDelayMs, getShuffleTextAtFrame, invoiceForwardMorphTransition, invoiceMorphCrossfadeTransition, invoiceMorphSourceContentFadeTransition, invoiceNavPrepareTransition, invoiceNavSiblingFadeTransition, useAtlasSummaryTypewriter, useShuffleText };
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map