: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
const callback = observerCallbacks.get(entry.target);
callback && callback(entry);
const fireAllObserverCallbacks = (entries) => {
entries.forEach(fireObserverCallback);
function initIntersectionObserver({ root, ...options }) {
const lookupRoot = root || document;
* If we don't have an observer lookup map for this root, create one.
if (!observers.has(lookupRoot)) {
observers.set(lookupRoot, {});
const rootObservers = observers.get(lookupRoot);
const key = JSON.stringify(options);
* If we don't have an observer for this combination of root and settings,
if (!rootObservers[key]) {
rootObservers[key] = new IntersectionObserver(fireAllObserverCallbacks, { root, ...options });
return rootObservers[key];
function observeIntersection(element, options, callback) {
const rootInteresectionObserver = initIntersectionObserver(options);
observerCallbacks.set(element, callback);
rootInteresectionObserver.observe(element);
observerCallbacks.delete(element);
rootInteresectionObserver.unobserve(element);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/motion/features/viewport/index.mjs
class InViewFeature extends Feature {
this.hasEnteredView = false;
const { viewport = {} } = this.node.getProps();
const { root, margin: rootMargin, amount = "some", once } = viewport;
root: root ? root.current : undefined,
threshold: typeof amount === "number" ? amount : thresholdNames[amount],
const onIntersectionUpdate = (entry) => {
const { isIntersecting } = entry;
* If there's been no change in the viewport state, early return.
if (this.isInView === isIntersecting)
this.isInView = isIntersecting;
* Handle hasEnteredView. If this is only meant to run once, and
* element isn't visible, early return. Otherwise set hasEnteredView to true.
if (once && !isIntersecting && this.hasEnteredView) {
else if (isIntersecting) {
this.hasEnteredView = true;
if (this.node.animationState) {
this.node.animationState.setActive("whileInView", isIntersecting);
* Use the latest committed props rather than the ones in scope
* when this observer is created
const { onViewportEnter, onViewportLeave } = this.node.getProps();
const callback = isIntersecting ? onViewportEnter : onViewportLeave;
callback && callback(entry);
return observeIntersection(this.node.current, options, onIntersectionUpdate);
if (typeof IntersectionObserver === "undefined")
const { props, prevProps } = this.node;
const hasOptionsChanged = ["amount", "margin", "root"].some(hasViewportOptionChanged(props, prevProps));
function hasViewportOptionChanged({ viewport = {} }, { viewport: prevViewport = {} } = {}) {
return (name) => viewport[name] !== prevViewport[name];
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/motion/features/gestures.mjs
const gestureAnimations = {
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/shallow-compare.mjs
function shallowCompare(next, prev) {
if (!Array.isArray(prev))
const prevLength = prev.length;
if (prevLength !== next.length)
for (let i = 0; i < prevLength; i++) {
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/utils/resolve-dynamic-variants.mjs
function resolveVariant(visualElement, definition, custom) {
const props = visualElement.getProps();
return resolveVariantFromProps(props, definition, custom !== undefined ? custom : props.custom, visualElement);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/time-conversion.mjs
* Converts seconds to milliseconds
* @param seconds - Time in seconds.
* @return milliseconds - Converted time in milliseconds.
const secondsToMilliseconds = (seconds) => seconds * 1000;
const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/animation/utils/default-transitions.mjs
const underDampedSpring = {
const criticallyDampedSpring = (target) => ({
damping: target === 0 ? 2 * Math.sqrt(550) : 30,
const keyframesTransition = {
* Default easing curve is a slightly shallower version of
* the default browser easing curve.
ease: [0.25, 0.1, 0.35, 1],
const getDefaultTransition = (valueKey, { keyframes }) => {
if (keyframes.length > 2) {
return keyframesTransition;
else if (transformProps.has(valueKey)) {
return valueKey.startsWith("scale")
? criticallyDampedSpring(keyframes[1])
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/animation/utils/transitions.mjs
* Decide whether a transition is defined on a given Transition.
* This filters out orchestration options and returns true
* if any options are left.
function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
return !!Object.keys(transition).length;
function getValueTransition(transition, key) {
return (transition[key] ||
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/use-instant-transition-state.mjs
const instantAnimationState = {
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/animation/animators/waapi/utils/get-final-keyframe.mjs
const isNotNull = (value) => value !== null;
function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
const resolvedKeyframes = keyframes.filter(isNotNull);
const index = repeat && repeatType !== "loop" && repeat % 2 === 1
: resolvedKeyframes.length - 1;
return !index || finalKeyframe === undefined
? resolvedKeyframes[index]
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/frameloop/sync-time.mjs
* An eventloop-synchronous alternative to performance.now().
* Ensures that time measurements remain consistent within a synchronous context.
* Usually calling performance.now() twice within the same synchronous context
* will return different values which isn't useful for animations when we're usually
* trying to sync animations to the same frame.
time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming
queueMicrotask(clearTime);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/is-zero-value-string.mjs
* Check if the value is a zero value string like "0px" or "0%"
const isZeroValueString = (v) => /^0[^.\s]+$/u.test(v);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/animation/utils/is-none.mjs
if (typeof value === "number") {
else if (value !== null) {
return value === "none" || value === "0" || isZeroValueString(value);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/errors.mjs
let errors_invariant = noop_noop;
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/utils/is-numerical-string.mjs
* Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/dom/utils/css-variables-conversion.mjs
* Parse Framer's special CSS variable format into a CSS token and a fallback.
* `var(--foo, #fff)` => [`--foo`, '#fff']
const splitCSSVariableRegex =
// eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
/^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
function parseCSSVariable(current) {
const match = splitCSSVariableRegex.exec(current);
const [, token1, token2, fallback] = match;
return [`--${token1 !== null && token1 !== void 0 ? token1 : token2}`, fallback];
function getVariableValue(current, element, depth = 1) {
errors_invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`);
const [token, fallback] = parseCSSVariable(current);
// No CSS variable detected
// Attempt to read this CSS variable off the element
const resolved = window.getComputedStyle(element).getPropertyValue(token);
const trimmed = resolved.trim();
return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
return isCSSVariableToken(fallback)
? getVariableValue(fallback, element, depth + 1)
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/dom/utils/unit-conversion.mjs
const positionalKeys = new Set([
const isNumOrPxType = (v) => v === number || v === px;
const getPosFromMatrix = (matrix, pos) => parseFloat(matrix.split(", ")[pos]);
const getTranslateFromMatrix = (pos2, pos3) => (_bbox, { transform }) => {
if (transform === "none" || !transform)
const matrix3d = transform.match(/^matrix3d\((.+)\)$/u);
return getPosFromMatrix(matrix3d[1], pos3);
const matrix = transform.match(/^matrix\((.+)\)$/u);
return getPosFromMatrix(matrix[1], pos2);
const transformKeys = new Set(["x", "y", "z"]);
const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
function removeNonTranslationalTransform(visualElement) {
const removedTransforms = [];
nonTranslationalTransformKeys.forEach((key) => {
const value = visualElement.getValue(key);
if (value !== undefined) {
removedTransforms.push([key, value.get()]);
value.set(key.startsWith("scale") ? 1 : 0);
return removedTransforms;
const positionalValues = {
width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
top: (_bbox, { top }) => parseFloat(top),
left: (_bbox, { left }) => parseFloat(left),
bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
x: getTranslateFromMatrix(4, 13),
y: getTranslateFromMatrix(5, 14),
// Alias translate longform names
positionalValues.translateX = positionalValues.x;
positionalValues.translateY = positionalValues.y;
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/dom/value-types/test.mjs
* Tests a provided value against a ValueType
const testValueType = (v) => (type) => type.test(v);
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/dom/value-types/type-auto.mjs
test: (v) => v === "auto",
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/dom/value-types/dimensions.mjs
* A list of value types commonly used for dimensions
const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
* Tests a dimensional value against the list of dimension ValueTypes
const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
;// CONCATENATED MODULE: ./node_modules/framer-motion/dist/es/render/utils/KeyframesResolver.mjs
const toResolve = new Set();
let anyNeedsMeasurement = false;
function measureAllKeyframes() {
if (anyNeedsMeasurement) {
const resolversToMeasure = Array.from(toResolve).filter((resolver) => resolver.needsMeasurement);
const elementsToMeasure = new Set(resolversToMeasure.map((resolver) => resolver.element));
const transformsToRestore = new Map();
* If we're measuring elements we want to remove bounding box-changing transforms.
elementsToMeasure.forEach((element) => {
const removedTransforms = removeNonTranslationalTransform(element);
if (!removedTransforms.length)
transformsToRestore.set(element, removedTransforms);
resolversToMeasure.forEach((resolver) => resolver.measureInitialState());