UNPKG

react-secure-captcha

Version:

A professional customizable React Captcha component with Canvas and Math modes, animations with Framer Motion, and toast notifications via Sonner.

1,506 lines (1,421 loc) 289 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; 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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { CanvasCaptcha: () => CanvasCaptcha_default, Captcha: () => Captcha_default, MathCaptcha: () => MathCaptcha_default, useCaptcha: () => useCaptcha }); module.exports = __toCommonJS(index_exports); // src/components/Captcha.tsx var import_react25 = require("react"); // src/components/CanvasCaptcha.tsx var import_react = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var CanvasCaptcha = ({ text, width = 180, height = 50, fontSize = 28, fontFamily = "Arial", backgroundColor = "#f9f9f9", textColor = "#333", noise = 30 }) => { const canvasRef = (0, import_react.useRef)(null); (0, import_react.useEffect)(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.clearRect(0, 0, width, height); ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, width, height); for (let i = 0; i < noise; i++) { ctx.fillStyle = `rgba(0,0,0,${Math.random()})`; ctx.beginPath(); ctx.arc( Math.random() * width, Math.random() * height, Math.random() * 5, 0, 2 * Math.PI ); ctx.fill(); } ctx.font = `${fontSize}px ${fontFamily}`; ctx.fillStyle = textColor; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText(text, width / 2, height / 2); }, [ text, width, height, fontSize, fontFamily, backgroundColor, textColor, noise ]); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "canvas", { ref: canvasRef, width, height, className: "rounded-md border border-gray-300" } ); }; var CanvasCaptcha_default = CanvasCaptcha; // src/components/MathCaptcha.tsx var import_jsx_runtime2 = require("react/jsx-runtime"); var MathCaptcha = ({ question, width = 180, height = 50, fontSize = 28, fontFamily = "Arial", backgroundColor = "#f9f9f9", textColor = "#333", className = "" }) => { return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "div", { style: { width, height, backgroundColor }, className: `flex items-center justify-center rounded-md border border-gray-300 select-none ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "span", { style: { fontSize, fontFamily, color: textColor }, className: "font-bold", children: question } ) } ); }; var MathCaptcha_default = MathCaptcha; // node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs var import_jsx_runtime5 = require("react/jsx-runtime"); var import_react11 = require("react"); // node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs var import_react2 = require("react"); var LayoutGroupContext = (0, import_react2.createContext)({}); // node_modules/framer-motion/dist/es/utils/use-constant.mjs var import_react3 = require("react"); function useConstant(init) { const ref = (0, import_react3.useRef)(null); if (ref.current === null) { ref.current = init(); } return ref.current; } // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs var import_react4 = require("react"); // node_modules/framer-motion/dist/es/utils/is-browser.mjs var isBrowser = typeof window !== "undefined"; // node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs var useIsomorphicLayoutEffect = isBrowser ? import_react4.useLayoutEffect : import_react4.useEffect; // node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs var import_jsx_runtime4 = require("react/jsx-runtime"); var React3 = __toESM(require("react"), 1); var import_react8 = require("react"); // node_modules/framer-motion/dist/es/context/PresenceContext.mjs var import_react5 = require("react"); var PresenceContext = /* @__PURE__ */ (0, import_react5.createContext)(null); // node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs var import_jsx_runtime3 = require("react/jsx-runtime"); // node_modules/motion-utils/dist/es/array.mjs function addUniqueItem(arr, item) { if (arr.indexOf(item) === -1) arr.push(item); } function removeItem(arr, item) { const index = arr.indexOf(item); if (index > -1) arr.splice(index, 1); } // node_modules/motion-utils/dist/es/clamp.mjs var clamp = (min, max, v) => { if (v > max) return max; if (v < min) return min; return v; }; // node_modules/motion-utils/dist/es/format-error-message.mjs function formatErrorMessage(message, errorCode) { return errorCode ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}` : message; } // node_modules/motion-utils/dist/es/errors.mjs var warning = () => { }; var invariant = () => { }; if (process.env.NODE_ENV !== "production") { warning = (check, message, errorCode) => { if (!check && typeof console !== "undefined") { console.warn(formatErrorMessage(message, errorCode)); } }; invariant = (check, message, errorCode) => { if (!check) { throw new Error(formatErrorMessage(message, errorCode)); } }; } // node_modules/motion-utils/dist/es/global-config.mjs var MotionGlobalConfig = {}; // node_modules/motion-utils/dist/es/is-numerical-string.mjs var isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v); // node_modules/motion-utils/dist/es/is-object.mjs function isObject(value) { return typeof value === "object" && value !== null; } // node_modules/motion-utils/dist/es/is-zero-value-string.mjs var isZeroValueString = (v) => /^0[^.\s]+$/u.test(v); // node_modules/motion-utils/dist/es/memo.mjs // @__NO_SIDE_EFFECTS__ function memo(callback) { let result; return () => { if (result === void 0) result = callback(); return result; }; } // node_modules/motion-utils/dist/es/noop.mjs var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any; // node_modules/motion-utils/dist/es/pipe.mjs var combineFunctions = (a, b) => (v) => b(a(v)); var pipe = (...transformers) => transformers.reduce(combineFunctions); // node_modules/motion-utils/dist/es/progress.mjs var progress = /* @__NO_SIDE_EFFECTS__ */ (from, to, value) => { const toFromDifference = to - from; return toFromDifference === 0 ? 1 : (value - from) / toFromDifference; }; // node_modules/motion-utils/dist/es/subscription-manager.mjs var SubscriptionManager = class { constructor() { this.subscriptions = []; } add(handler) { addUniqueItem(this.subscriptions, handler); return () => removeItem(this.subscriptions, handler); } notify(a, b, c) { const numSubscriptions = this.subscriptions.length; if (!numSubscriptions) return; if (numSubscriptions === 1) { this.subscriptions[0](a, b, c); } else { for (let i = 0; i < numSubscriptions; i++) { const handler = this.subscriptions[i]; handler && handler(a, b, c); } } } getSize() { return this.subscriptions.length; } clear() { this.subscriptions.length = 0; } }; // node_modules/motion-utils/dist/es/time-conversion.mjs var secondsToMilliseconds = /* @__NO_SIDE_EFFECTS__ */ (seconds) => seconds * 1e3; var millisecondsToSeconds = /* @__NO_SIDE_EFFECTS__ */ (milliseconds) => milliseconds / 1e3; // node_modules/motion-utils/dist/es/velocity-per-second.mjs function velocityPerSecond(velocity, frameDuration) { return frameDuration ? velocity * (1e3 / frameDuration) : 0; } // node_modules/motion-utils/dist/es/warn-once.mjs var warned = /* @__PURE__ */ new Set(); function warnOnce(condition, message, errorCode) { if (condition || warned.has(message)) return; console.warn(formatErrorMessage(message, errorCode)); warned.add(message); } // node_modules/motion-utils/dist/es/easing/cubic-bezier.mjs var calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t; var subdivisionPrecision = 1e-7; var subdivisionMaxIterations = 12; function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) { let currentX; let currentT; let i = 0; do { currentT = lowerBound + (upperBound - lowerBound) / 2; currentX = calcBezier(currentT, mX1, mX2) - x; if (currentX > 0) { upperBound = currentT; } else { lowerBound = currentT; } } while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations); return currentT; } function cubicBezier(mX1, mY1, mX2, mY2) { if (mX1 === mY1 && mX2 === mY2) return noop; const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2); return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2); } // node_modules/motion-utils/dist/es/easing/modifiers/mirror.mjs var mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2; // node_modules/motion-utils/dist/es/easing/modifiers/reverse.mjs var reverseEasing = (easing) => (p) => 1 - easing(1 - p); // node_modules/motion-utils/dist/es/easing/back.mjs var backOut = /* @__PURE__ */ cubicBezier(0.33, 1.53, 0.69, 0.99); var backIn = /* @__PURE__ */ reverseEasing(backOut); var backInOut = /* @__PURE__ */ mirrorEasing(backIn); // node_modules/motion-utils/dist/es/easing/anticipate.mjs var anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1))); // node_modules/motion-utils/dist/es/easing/circ.mjs var circIn = (p) => 1 - Math.sin(Math.acos(p)); var circOut = reverseEasing(circIn); var circInOut = mirrorEasing(circIn); // node_modules/motion-utils/dist/es/easing/ease.mjs var easeIn = /* @__PURE__ */ cubicBezier(0.42, 0, 1, 1); var easeOut = /* @__PURE__ */ cubicBezier(0, 0, 0.58, 1); var easeInOut = /* @__PURE__ */ cubicBezier(0.42, 0, 0.58, 1); // node_modules/motion-utils/dist/es/easing/utils/is-easing-array.mjs var isEasingArray = (ease2) => { return Array.isArray(ease2) && typeof ease2[0] !== "number"; }; // node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.mjs var isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number"; // node_modules/motion-utils/dist/es/easing/utils/map.mjs var easingLookup = { linear: noop, easeIn, easeInOut, easeOut, circIn, circInOut, circOut, backIn, backInOut, backOut, anticipate }; var isValidEasing = (easing) => { return typeof easing === "string"; }; var easingDefinitionToFunction = (definition) => { if (isBezierDefinition(definition)) { invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length"); const [x1, y1, x2, y2] = definition; return cubicBezier(x1, y1, x2, y2); } else if (isValidEasing(definition)) { invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`, "invalid-easing-type"); return easingLookup[definition]; } return definition; }; // node_modules/motion-dom/dist/es/frameloop/order.mjs var stepsOrder = [ "setup", // Compute "read", // Read "resolveKeyframes", // Write/Read/Write/Read "preUpdate", // Compute "update", // Compute "preRender", // Compute "render", // Write "postRender" // Compute ]; // node_modules/motion-dom/dist/es/stats/buffer.mjs var statsBuffer = { value: null, addProjectionMetrics: null }; // node_modules/motion-dom/dist/es/frameloop/render-step.mjs function createRenderStep(runNextFrame, stepName) { let thisFrame = /* @__PURE__ */ new Set(); let nextFrame = /* @__PURE__ */ new Set(); let isProcessing = false; let flushNextFrame = false; const toKeepAlive = /* @__PURE__ */ new WeakSet(); let latestFrameData = { delta: 0, timestamp: 0, isProcessing: false }; let numCalls = 0; function triggerCallback(callback) { if (toKeepAlive.has(callback)) { step.schedule(callback); runNextFrame(); } numCalls++; callback(latestFrameData); } const step = { /** * Schedule a process to run on the next frame. */ schedule: (callback, keepAlive = false, immediate = false) => { const addToCurrentFrame = immediate && isProcessing; const queue = addToCurrentFrame ? thisFrame : nextFrame; if (keepAlive) toKeepAlive.add(callback); if (!queue.has(callback)) queue.add(callback); return callback; }, /** * Cancel the provided callback from running on the next frame. */ cancel: (callback) => { nextFrame.delete(callback); toKeepAlive.delete(callback); }, /** * Execute all schedule callbacks. */ process: (frameData2) => { latestFrameData = frameData2; if (isProcessing) { flushNextFrame = true; return; } isProcessing = true; [thisFrame, nextFrame] = [nextFrame, thisFrame]; thisFrame.forEach(triggerCallback); if (stepName && statsBuffer.value) { statsBuffer.value.frameloop[stepName].push(numCalls); } numCalls = 0; thisFrame.clear(); isProcessing = false; if (flushNextFrame) { flushNextFrame = false; step.process(frameData2); } } }; return step; } // node_modules/motion-dom/dist/es/frameloop/batcher.mjs var maxElapsed = 40; function createRenderBatcher(scheduleNextBatch, allowKeepAlive) { let runNextFrame = false; let useDefaultElapsed = true; const state = { delta: 0, timestamp: 0, isProcessing: false }; const flagRunNextFrame = () => runNextFrame = true; const steps = stepsOrder.reduce((acc, key) => { acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : void 0); return acc; }, {}); const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender } = steps; const processBatch = () => { const timestamp = MotionGlobalConfig.useManualTiming ? state.timestamp : performance.now(); runNextFrame = false; if (!MotionGlobalConfig.useManualTiming) { state.delta = useDefaultElapsed ? 1e3 / 60 : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1); } state.timestamp = timestamp; state.isProcessing = true; setup.process(state); read.process(state); resolveKeyframes.process(state); preUpdate.process(state); update.process(state); preRender.process(state); render.process(state); postRender.process(state); state.isProcessing = false; if (runNextFrame && allowKeepAlive) { useDefaultElapsed = false; scheduleNextBatch(processBatch); } }; const wake = () => { runNextFrame = true; useDefaultElapsed = true; if (!state.isProcessing) { scheduleNextBatch(processBatch); } }; const schedule = stepsOrder.reduce((acc, key) => { const step = steps[key]; acc[key] = (process2, keepAlive = false, immediate = false) => { if (!runNextFrame) wake(); return step.schedule(process2, keepAlive, immediate); }; return acc; }, {}); const cancel = (process2) => { for (let i = 0; i < stepsOrder.length; i++) { steps[stepsOrder[i]].cancel(process2); } }; return { schedule, cancel, state, steps }; } // node_modules/motion-dom/dist/es/frameloop/frame.mjs var { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true); // node_modules/motion-dom/dist/es/frameloop/sync-time.mjs var now; function clearTime() { now = void 0; } var time = { now: () => { if (now === void 0) { time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming ? frameData.timestamp : performance.now()); } return now; }, set: (newTime) => { now = newTime; queueMicrotask(clearTime); } }; // node_modules/motion-dom/dist/es/stats/animation-count.mjs var activeAnimations = { layout: 0, mainThread: 0, waapi: 0 }; // node_modules/motion-dom/dist/es/animation/utils/is-css-variable.mjs var checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token); var isCSSVariableName = /* @__PURE__ */ checkStringStartsWith("--"); var startsAsVariableToken = /* @__PURE__ */ checkStringStartsWith("var(--"); var isCSSVariableToken = (value) => { const startsWithToken = startsAsVariableToken(value); if (!startsWithToken) return false; return singleCssVariableRegex.test(value.split("/*")[0].trim()); }; var singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu; // node_modules/motion-dom/dist/es/value/types/numbers/index.mjs var number = { test: (v) => typeof v === "number", parse: parseFloat, transform: (v) => v }; var alpha = { ...number, transform: (v) => clamp(0, 1, v) }; var scale = { ...number, default: 1 }; // node_modules/motion-dom/dist/es/value/types/utils/sanitize.mjs var sanitize = (v) => Math.round(v * 1e5) / 1e5; // node_modules/motion-dom/dist/es/value/types/utils/float-regex.mjs var floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu; // node_modules/motion-dom/dist/es/value/types/utils/is-nullish.mjs function isNullish(v) { return v == null; } // node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.mjs var singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu; // node_modules/motion-dom/dist/es/value/types/color/utils.mjs var isColorString = (type, testProp) => (v) => { return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp)); }; var splitColor = (aName, bName, cName) => (v) => { if (typeof v !== "string") return v; const [a, b, c, alpha2] = v.match(floatRegex); return { [aName]: parseFloat(a), [bName]: parseFloat(b), [cName]: parseFloat(c), alpha: alpha2 !== void 0 ? parseFloat(alpha2) : 1 }; }; // node_modules/motion-dom/dist/es/value/types/color/rgba.mjs var clampRgbUnit = (v) => clamp(0, 255, v); var rgbUnit = { ...number, transform: (v) => Math.round(clampRgbUnit(v)) }; var rgba = { test: /* @__PURE__ */ isColorString("rgb", "red"), parse: /* @__PURE__ */ splitColor("red", "green", "blue"), transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")" }; // node_modules/motion-dom/dist/es/value/types/color/hex.mjs function parseHex(v) { let r = ""; let g = ""; let b = ""; let a = ""; if (v.length > 5) { r = v.substring(1, 3); g = v.substring(3, 5); b = v.substring(5, 7); a = v.substring(7, 9); } else { r = v.substring(1, 2); g = v.substring(2, 3); b = v.substring(3, 4); a = v.substring(4, 5); r += r; g += g; b += b; a += a; } return { red: parseInt(r, 16), green: parseInt(g, 16), blue: parseInt(b, 16), alpha: a ? parseInt(a, 16) / 255 : 1 }; } var hex = { test: /* @__PURE__ */ isColorString("#"), parse: parseHex, transform: rgba.transform }; // node_modules/motion-dom/dist/es/value/types/numbers/units.mjs var createUnitType = /* @__NO_SIDE_EFFECTS__ */ (unit) => ({ test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1, parse: parseFloat, transform: (v) => `${v}${unit}` }); var degrees = /* @__PURE__ */ createUnitType("deg"); var percent = /* @__PURE__ */ createUnitType("%"); var px = /* @__PURE__ */ createUnitType("px"); var vh = /* @__PURE__ */ createUnitType("vh"); var vw = /* @__PURE__ */ createUnitType("vw"); var progressPercentage = /* @__PURE__ */ (() => ({ ...percent, parse: (v) => percent.parse(v) / 100, transform: (v) => percent.transform(v * 100) }))(); // node_modules/motion-dom/dist/es/value/types/color/hsla.mjs var hsla = { test: /* @__PURE__ */ isColorString("hsl", "hue"), parse: /* @__PURE__ */ splitColor("hue", "saturation", "lightness"), transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => { return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")"; } }; // node_modules/motion-dom/dist/es/value/types/color/index.mjs var color = { test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v), parse: (v) => { if (rgba.test(v)) { return rgba.parse(v); } else if (hsla.test(v)) { return hsla.parse(v); } else { return hex.parse(v); } }, transform: (v) => { return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v); }, getAnimatableNone: (v) => { const parsed = color.parse(v); parsed.alpha = 0; return color.transform(parsed); } }; // node_modules/motion-dom/dist/es/value/types/utils/color-regex.mjs var colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu; // node_modules/motion-dom/dist/es/value/types/complex/index.mjs function test(v) { return isNaN(v) && typeof v === "string" && (v.match(floatRegex)?.length || 0) + (v.match(colorRegex)?.length || 0) > 0; } var NUMBER_TOKEN = "number"; var COLOR_TOKEN = "color"; var VAR_TOKEN = "var"; var VAR_FUNCTION_TOKEN = "var("; var SPLIT_TOKEN = "${}"; var complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu; function analyseComplexValue(value) { const originalValue = value.toString(); const values = []; const indexes = { color: [], number: [], var: [] }; const types = []; let i = 0; const tokenised = originalValue.replace(complexRegex, (parsedValue) => { if (color.test(parsedValue)) { indexes.color.push(i); types.push(COLOR_TOKEN); values.push(color.parse(parsedValue)); } else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) { indexes.var.push(i); types.push(VAR_TOKEN); values.push(parsedValue); } else { indexes.number.push(i); types.push(NUMBER_TOKEN); values.push(parseFloat(parsedValue)); } ++i; return SPLIT_TOKEN; }); const split = tokenised.split(SPLIT_TOKEN); return { values, split, indexes, types }; } function parseComplexValue(v) { return analyseComplexValue(v).values; } function createTransformer(source) { const { split, types } = analyseComplexValue(source); const numSections = split.length; return (v) => { let output = ""; for (let i = 0; i < numSections; i++) { output += split[i]; if (v[i] !== void 0) { const type = types[i]; if (type === NUMBER_TOKEN) { output += sanitize(v[i]); } else if (type === COLOR_TOKEN) { output += color.transform(v[i]); } else { output += v[i]; } } } return output; }; } var convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v; function getAnimatableNone(v) { const parsed = parseComplexValue(v); const transformer = createTransformer(v); return transformer(parsed.map(convertNumbersToZero)); } var complex = { test, parse: parseComplexValue, createTransformer, getAnimatableNone }; // node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.mjs function hueToRgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; } function hslaToRgba({ hue, saturation, lightness, alpha: alpha2 }) { hue /= 360; saturation /= 100; lightness /= 100; let red = 0; let green = 0; let blue = 0; if (!saturation) { red = green = blue = lightness; } else { const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation; const p = 2 * lightness - q; red = hueToRgb(p, q, hue + 1 / 3); green = hueToRgb(p, q, hue); blue = hueToRgb(p, q, hue - 1 / 3); } return { red: Math.round(red * 255), green: Math.round(green * 255), blue: Math.round(blue * 255), alpha: alpha2 }; } // node_modules/motion-dom/dist/es/utils/mix/immediate.mjs function mixImmediate(a, b) { return (p) => p > 0 ? b : a; } // node_modules/motion-dom/dist/es/utils/mix/number.mjs var mixNumber = (from, to, progress2) => { return from + (to - from) * progress2; }; // node_modules/motion-dom/dist/es/utils/mix/color.mjs var mixLinearColor = (from, to, v) => { const fromExpo = from * from; const expo = v * (to * to - fromExpo) + fromExpo; return expo < 0 ? 0 : Math.sqrt(expo); }; var colorTypes = [hex, rgba, hsla]; var getColorType = (v) => colorTypes.find((type) => type.test(v)); function asRGBA(color2) { const type = getColorType(color2); warning(Boolean(type), `'${color2}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable"); if (!Boolean(type)) return false; let model = type.parse(color2); if (type === hsla) { model = hslaToRgba(model); } return model; } var mixColor = (from, to) => { const fromRGBA = asRGBA(from); const toRGBA = asRGBA(to); if (!fromRGBA || !toRGBA) { return mixImmediate(from, to); } const blended = { ...fromRGBA }; return (v) => { blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v); blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v); blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v); blended.alpha = mixNumber(fromRGBA.alpha, toRGBA.alpha, v); return rgba.transform(blended); }; }; // node_modules/motion-dom/dist/es/utils/mix/visibility.mjs var invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]); function mixVisibility(origin, target) { if (invisibleValues.has(origin)) { return (p) => p <= 0 ? origin : target; } else { return (p) => p >= 1 ? target : origin; } } // node_modules/motion-dom/dist/es/utils/mix/complex.mjs function mixNumber2(a, b) { return (p) => mixNumber(a, b, p); } function getMixer(a) { if (typeof a === "number") { return mixNumber2; } else if (typeof a === "string") { return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex; } else if (Array.isArray(a)) { return mixArray; } else if (typeof a === "object") { return color.test(a) ? mixColor : mixObject; } return mixImmediate; } function mixArray(a, b) { const output = [...a]; const numValues = output.length; const blendValue = a.map((v, i) => getMixer(v)(v, b[i])); return (p) => { for (let i = 0; i < numValues; i++) { output[i] = blendValue[i](p); } return output; }; } function mixObject(a, b) { const output = { ...a, ...b }; const blendValue = {}; for (const key in output) { if (a[key] !== void 0 && b[key] !== void 0) { blendValue[key] = getMixer(a[key])(a[key], b[key]); } } return (v) => { for (const key in blendValue) { output[key] = blendValue[key](v); } return output; }; } function matchOrder(origin, target) { const orderedOrigin = []; const pointers = { color: 0, var: 0, number: 0 }; for (let i = 0; i < target.values.length; i++) { const type = target.types[i]; const originIndex = origin.indexes[type][pointers[type]]; const originValue = origin.values[originIndex] ?? 0; orderedOrigin[i] = originValue; pointers[type]++; } return orderedOrigin; } var mixComplex = (origin, target) => { const template = complex.createTransformer(target); const originStats = analyseComplexValue(origin); const targetStats = analyseComplexValue(target); const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length; if (canInterpolate) { if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) { return mixVisibility(origin, target); } return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template); } else { warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`, "complex-values-different"); return mixImmediate(origin, target); } }; // node_modules/motion-dom/dist/es/utils/mix/index.mjs function mix(from, to, p) { if (typeof from === "number" && typeof to === "number" && typeof p === "number") { return mixNumber(from, to, p); } const mixer = getMixer(from); return mixer(from, to); } // node_modules/motion-dom/dist/es/animation/drivers/frame.mjs var frameloopDriver = (update) => { const passTimestamp = ({ timestamp }) => update(timestamp); return { start: (keepAlive = true) => frame.update(passTimestamp, keepAlive), stop: () => cancelFrame(passTimestamp), /** * If we're processing this frame we can use the * framelocked timestamp to keep things in sync. */ now: () => frameData.isProcessing ? frameData.timestamp : time.now() }; }; // node_modules/motion-dom/dist/es/animation/waapi/utils/linear.mjs var generateLinearEasing = (easing, duration, resolution = 10) => { let points = ""; const numPoints = Math.max(Math.round(duration / resolution), 2); for (let i = 0; i < numPoints; i++) { points += Math.round(easing(i / (numPoints - 1)) * 1e4) / 1e4 + ", "; } return `linear(${points.substring(0, points.length - 2)})`; }; // node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.mjs var maxGeneratorDuration = 2e4; function calcGeneratorDuration(generator) { let duration = 0; const timeStep = 50; let state = generator.next(duration); while (!state.done && duration < maxGeneratorDuration) { duration += timeStep; state = generator.next(duration); } return duration >= maxGeneratorDuration ? Infinity : duration; } // node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs function createGeneratorEasing(options, scale2 = 100, createGenerator) { const generator = createGenerator({ ...options, keyframes: [0, scale2] }); const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration); return { type: "keyframes", ease: (progress2) => { return generator.next(duration * progress2).value / scale2; }, duration: millisecondsToSeconds(duration) }; } // node_modules/motion-dom/dist/es/animation/generators/utils/velocity.mjs var velocitySampleDuration = 5; function calcGeneratorVelocity(resolveValue, t, current) { const prevT = Math.max(t - velocitySampleDuration, 0); return velocityPerSecond(current - resolveValue(prevT), t - prevT); } // node_modules/motion-dom/dist/es/animation/generators/spring/defaults.mjs var springDefaults = { // Default spring physics stiffness: 100, damping: 10, mass: 1, velocity: 0, // Default duration/bounce-based options duration: 800, // in ms bounce: 0.3, visualDuration: 0.3, // in seconds // Rest thresholds restSpeed: { granular: 0.01, default: 2 }, restDelta: { granular: 5e-3, default: 0.5 }, // Limits minDuration: 0.01, // in seconds maxDuration: 10, // in seconds minDamping: 0.05, maxDamping: 1 }; // node_modules/motion-dom/dist/es/animation/generators/spring/find.mjs var safeMin = 1e-3; function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) { let envelope; let derivative; warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit"); let dampingRatio = 1 - bounce; dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio); duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration)); if (dampingRatio < 1) { envelope = (undampedFreq2) => { const exponentialDecay = undampedFreq2 * dampingRatio; const delta = exponentialDecay * duration; const a = exponentialDecay - velocity; const b = calcAngularFreq(undampedFreq2, dampingRatio); const c = Math.exp(-delta); return safeMin - a / b * c; }; derivative = (undampedFreq2) => { const exponentialDecay = undampedFreq2 * dampingRatio; const delta = exponentialDecay * duration; const d = delta * velocity + velocity; const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq2, 2) * duration; const f = Math.exp(-delta); const g = calcAngularFreq(Math.pow(undampedFreq2, 2), dampingRatio); const factor = -envelope(undampedFreq2) + safeMin > 0 ? -1 : 1; return factor * ((d - e) * f) / g; }; } else { envelope = (undampedFreq2) => { const a = Math.exp(-undampedFreq2 * duration); const b = (undampedFreq2 - velocity) * duration + 1; return -safeMin + a * b; }; derivative = (undampedFreq2) => { const a = Math.exp(-undampedFreq2 * duration); const b = (velocity - undampedFreq2) * (duration * duration); return a * b; }; } const initialGuess = 5 / duration; const undampedFreq = approximateRoot(envelope, derivative, initialGuess); duration = secondsToMilliseconds(duration); if (isNaN(undampedFreq)) { return { stiffness: springDefaults.stiffness, damping: springDefaults.damping, duration }; } else { const stiffness = Math.pow(undampedFreq, 2) * mass; return { stiffness, damping: dampingRatio * 2 * Math.sqrt(mass * stiffness), duration }; } } var rootIterations = 12; function approximateRoot(envelope, derivative, initialGuess) { let result = initialGuess; for (let i = 1; i < rootIterations; i++) { result = result - envelope(result) / derivative(result); } return result; } function calcAngularFreq(undampedFreq, dampingRatio) { return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio); } // node_modules/motion-dom/dist/es/animation/generators/spring/index.mjs var durationKeys = ["duration", "bounce"]; var physicsKeys = ["stiffness", "damping", "mass"]; function isSpringType(options, keys) { return keys.some((key) => options[key] !== void 0); } function getSpringOptions(options) { let springOptions = { velocity: springDefaults.velocity, stiffness: springDefaults.stiffness, damping: springDefaults.damping, mass: springDefaults.mass, isResolvedFromDuration: false, ...options }; if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) { if (options.visualDuration) { const visualDuration = options.visualDuration; const root = 2 * Math.PI / (visualDuration * 1.2); const stiffness = root * root; const damping = 2 * clamp(0.05, 1, 1 - (options.bounce || 0)) * Math.sqrt(stiffness); springOptions = { ...springOptions, mass: springDefaults.mass, stiffness, damping }; } else { const derived = findSpring(options); springOptions = { ...springOptions, ...derived, mass: springDefaults.mass }; springOptions.isResolvedFromDuration = true; } } return springOptions; } function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) { const options = typeof optionsOrVisualDuration !== "object" ? { visualDuration: optionsOrVisualDuration, keyframes: [0, 1], bounce } : optionsOrVisualDuration; let { restSpeed, restDelta } = options; const origin = options.keyframes[0]; const target = options.keyframes[options.keyframes.length - 1]; const state = { done: false, value: origin }; const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({ ...options, velocity: -millisecondsToSeconds(options.velocity || 0) }); const initialVelocity = velocity || 0; const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass)); const initialDelta = target - origin; const undampedAngularFreq = millisecondsToSeconds(Math.sqrt(stiffness / mass)); const isGranularScale = Math.abs(initialDelta) < 5; restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default); restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default); let resolveSpring; if (dampingRatio < 1) { const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio); resolveSpring = (t) => { const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t); return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t)); }; } else if (dampingRatio === 1) { resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t); } else { const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1); resolveSpring = (t) => { const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t); const freqForT = Math.min(dampedAngularFreq * t, 300); return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq; }; } const generator = { calculatedDuration: isResolvedFromDuration ? duration || null : null, next: (t) => { const current = resolveSpring(t); if (!isResolvedFromDuration) { let currentVelocity = t === 0 ? initialVelocity : 0; if (dampingRatio < 1) { currentVelocity = t === 0 ? secondsToMilliseconds(initialVelocity) : calcGeneratorVelocity(resolveSpring, t, current); } const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed; const isBelowDisplacementThreshold = Math.abs(target - current) <= restDelta; state.done = isBelowVelocityThreshold && isBelowDisplacementThreshold; } else { state.done = t >= duration; } state.value = state.done ? target : current; return state; }, toString: () => { const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration); const easing = generateLinearEasing((progress2) => generator.next(calculatedDuration * progress2).value, calculatedDuration, 30); return calculatedDuration + "ms " + easing; }, toTransition: () => { } }; return generator; } spring.applyToOptions = (options) => { const generatorOptions = createGeneratorEasing(options, 100, spring); options.ease = generatorOptions.ease; options.duration = secondsToMilliseconds(generatorOptions.duration); options.type = "keyframes"; return options; }; // node_modules/motion-dom/dist/es/animation/generators/inertia.mjs function inertia({ keyframes: keyframes2, velocity = 0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed }) { const origin = keyframes2[0]; const state = { done: false, value: origin }; const isOutOfBounds = (v) => min !== void 0 && v < min || max !== void 0 && v > max; const nearestBoundary = (v) => { if (min === void 0) return max; if (max === void 0) return min; return Math.abs(min - v) < Math.abs(max - v) ? min : max; }; let amplitude = power * velocity; const ideal = origin + amplitude; const target = modifyTarget === void 0 ? ideal : modifyTarget(ideal); if (target !== ideal) amplitude = target - origin; const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant); const calcLatest = (t) => target + calcDelta(t); const applyFriction = (t) => { const delta = calcDelta(t); const latest = calcLatest(t); state.done = Math.abs(delta) <= restDelta; state.value = state.done ? target : latest; }; let timeReachedBoundary; let spring$1; const checkCatchBoundary = (t) => { if (!isOutOfBounds(state.value)) return; timeReachedBoundary = t; spring$1 = spring({ keyframes: [state.value, nearestBoundary(state.value)], velocity: calcGeneratorVelocity(calcLatest, t, state.value), // TODO: This should be passing * 1000 damping: bounceDamping, stiffness: bounceStiffness, restDelta, restSpeed }); }; checkCatchBoundary(0); return { calculatedDuration: null, next: (t) => { let hasUpdatedFrame = false; if (!spring$1 && timeReachedBoundary === void 0) { hasUpdatedFrame = true; applyFriction(t); checkCatchBoundary(t); } if (timeReachedBoundary !== void 0 && t >= timeReachedBoundary) { return spring$1.next(t - timeReachedBoundary); } else { !hasUpdatedFrame && applyFriction(t); return state; } } }; } // node_modules/motion-dom/dist/es/utils/interpolate.mjs function createMixers(output, ease2, customMixer) { const mixers = []; const mixerFactory = customMixer || MotionGlobalConfig.mix || mix; const numMixers = output.length - 1; for (let i = 0; i < numMixers; i++) { let mixer = mixerFactory(output[i], output[i + 1]); if (ease2) { const easingFunction = Array.isArray(ease2) ? ease2[i] || noop : ease2; mixer = pipe(easingFunction, mixer); } mixers.push(mixer); } return mixers; } function interpolate(input, output, { clamp: isClamp = true, ease: ease2, mixer } = {}) { const inputLength = input.length; invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length"); if (inputLength === 1) return () => output[0]; if (inputLength === 2 && output[0] === output[1]) return () => output[1]; const isZeroDeltaRange = input[0] === input[1]; if (input[0] > input[inputLength - 1]) { input = [...input].reverse(); output = [...output].reverse(); } const mixers = createMixers(output, ease2, mixer); const numMixers = mixers.length; const interpolator = (v) => { if (isZeroDeltaRange && v < input[0]) return output[0]; let i = 0; if (numMixers > 1) { for (; i < input.length - 2; i++) { if (v < input[i + 1]) break; } } const progressInRange = progress(input[i], input[i + 1], v); return mixers[i](progressInRange); }; return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator; } // node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.mjs function fillOffset(offset, remaining) { const min = offset[offset.length - 1]; for (let i = 1; i <= remaining; i++) { const offsetProgress = progress(0, remaining, i); offset.push(mixNumber(min, 1, offsetProgress)); } } // node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.mjs function defaultOffset(arr) { const offset = [0]; fillOffset(offset, arr.length - 1); return offset; } // node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.mjs function convertOffsetToTimes(offset, duration) { return offset.map((o) => o * duration); } // node_modules/motion-dom/dist/es/animation/generators/keyframes.mjs function defaultEasing(values, easing) { return values.map(() => easing || easeInOut).splice(0, values.length - 1); } function keyframes({ duration = 300, keyframes: keyframeValues, times, ease: ease2 = "easeInOut" }) { const easingFunctions = isEasingArray(ease2) ? ease2.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease2); const state = { done: false, value: keyframeValues[0] }; const absoluteTimes = convertOffsetToTimes( // Only use the provided offsets if they're the correct length // TODO Maybe we should warn here if there's a length mismatch times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues), duration ); const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, { ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions) }); return { calculatedDuration: duration, next: (t) => { state.value = mapTimeToKeyframe(t); state.done = t >= duration; return state; } }; } // node_modules/motion-dom/dist/es/animation/keyframes/get-final.mjs var isNotNull = (value) => value !== null; function getFinalKeyframe(keyframes2, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) { const resolvedKeyframes = keyframes2.filter(isNotNull); const useFirstKeyframe = speed < 0 || repeat && repeatType !== "loop" && repeat % 2 === 1; const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1; return !index || finalKeyframe === void 0 ? resolvedKeyframes[index] : finalKeyframe; } // node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.mjs var transitionTypeMap = { decay: inertia, inertia, tween: keyframes, keyframes, spring }; function replaceTransitionType(transition) { if (typeof transition.type === "string") { transition.type = transitionTypeMap[transition.type]; } } // node_modules/motion-dom/dist/es/animation/utils/WithPromise.mjs var WithPromise = class { constructor() { this.updateFinished(); } get finished() { return this._finished; } updateFinished() { this._finished = new Promise((resolve) => { this.resolve = resolve; }); } notifyFinished() { this.resolve(); } /** * Allows the animation to be awaited. * * @deprecated Use `finished` instead. */ then(onResolve, onReject) { return this.finished.then(onResolve, onReject); } }; // node_modules/motion-dom/dist/es/animation/JSAnimation.mjs var percentToProgress = (percent2) => percent2 / 100; var JSAnimation = class extends WithPromise { constructor(options) { super(); this.state = "idle"; this.startTime = null; this.isStopped = false; this.currentTime = 0; this.holdTime = null; this.playbackSpeed = 1; this.stop = () => { const { motionValue: motionValue2 } = this.options; if (motionValue2 && motionValue2.updatedAt !== time.now()) { this.tick(time.now()); } this.isStopped = true; if (this.state === "idle") return; this.teardown(); this.options.onStop?.(); }; activeAnimations.mainThread++; this.options = options; this.initAnimation(); this.play(); if (options.autoplay === false) this.pause(); } initAnimation() { const { options } = this; replaceTransitionType(options); const { type = keyframes, repeat = 0, repeatDelay = 0, repeatType, velocity = 0 } = options; let { keyframes: keyframes$1 } = options; const generatorFactory = type || keyframes; if (process.env.NODE_ENV !== "production" && generatorFactory !== keyframes) { invariant(keyframes$1.length <= 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`, "spring-two-frames"); } if (generatorFactory !== keyframes && typeof keyframes$1[0] !== "number") { this.mixKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1])); keyframes$1 = [0, 100]; } const generator = generatorFactory({ ...options, keyframes: keyframes$1 }); if (repeatType === "mirror") { this.mirroredGenerator = generatorFactory({ ...options, keyframes: [...keyframes$1].reverse(), velocity: -velocity }); } if (generator.calculatedDuration === null) { generator.calculatedDuration = calcGen