@levi-gemcommerce/analytics 1.0.0-dev.27 → 1.0.0-dev.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  "use client"
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { Text, Box, InlineStack, Icon, InlineGrid, Tooltip as Tooltip$1, Button, BlockStack, Checkbox, RadioButton, Popover, ActionList, Link as Link$1, SkeletonDisplayText, List, Card, SkeletonBodyText, TextField, Collapsible, useBreakpoints, Select, Scrollable, OptionList, DatePicker, ButtonGroup, Divider } from '@shopify/polaris';
3
+ import { Text, Box, InlineStack, Icon, InlineGrid, Tooltip as Tooltip$1, Button, BlockStack, Checkbox, RadioButton, Popover, ActionList, Link, SkeletonDisplayText, List, Card, SkeletonBodyText, TextField, Collapsible, useBreakpoints, Select, Scrollable, OptionList, DatePicker, ButtonGroup, Divider } from '@shopify/polaris';
4
4
  import * as React from 'react';
5
5
  import React__default, { useMemo, useCallback, useState, useEffect, forwardRef, Fragment as Fragment$1, useRef, useImperativeHandle, createContext, useContext, createElement, useLayoutEffect, memo, Component } from 'react';
6
6
  import dayjs from 'dayjs';
@@ -12,6 +12,7 @@ import { useTranslation } from 'react-i18next';
12
12
  import { create } from 'zustand';
13
13
  import { useQuery } from '@tanstack/react-query';
14
14
  import { PolarisVizProvider, LineChart, DonutChart } from '@shopify/polaris-viz';
15
+ import { useSearchParams } from '@remix-run/react';
15
16
  import { unstable_batchedUpdates, createPortal } from 'react-dom';
16
17
  import { t as t$1 } from 'i18next';
17
18
 
@@ -955,7 +956,7 @@ const GTextLink = ({ linkAction, isDisabled, disabledFocus, children }) => {
955
956
  if (!linkAction || isDisabled) {
956
957
  return jsx(Fragment, { children: children });
957
958
  }
958
- return (jsx("span", { className: cls('GTextLink', { 'GTextLink--disabled-focus': disabledFocus }), children: jsx(Link$1, { ...linkAction, children: jsx(Fragment, { children: children }) }) }));
959
+ return (jsx("span", { className: cls('GTextLink', { 'GTextLink--disabled-focus': disabledFocus }), children: jsx(Link, { ...linkAction, children: jsx(Fragment, { children: children }) }) }));
959
960
  };
960
961
 
961
962
  const GSkeletonDisplayText = (props) => {
@@ -1049,7 +1050,7 @@ const GViewBySelector = ({ activatorText, selected, options, minWidth, maxWidth,
1049
1050
  };
1050
1051
 
1051
1052
  const ChoiceHelpText = ({ item }) => {
1052
- return (jsxs(Text, { as: "p", variant: "bodyMd", children: [item.description, item.inlineAction && (jsx(Link$1, { monochrome: true, onClick: () => {
1053
+ return (jsxs(Text, { as: "p", variant: "bodyMd", children: [item.description, item.inlineAction && (jsx(Link, { monochrome: true, onClick: () => {
1053
1054
  if (item.inlineAction?.onAction) {
1054
1055
  item.inlineAction?.onAction();
1055
1056
  }
@@ -3239,1373 +3240,6 @@ const useFunnelChartStore = create()((set, get) => ({
3239
3240
  const MAX_FUNNEL_ADDITIONAL_LEVEL = 3;
3240
3241
  const FINAL_FUNNEL_FIXED_LEVEL = 3;
3241
3242
 
3242
- /**
3243
- * @remix-run/router v1.21.0
3244
- *
3245
- * Copyright (c) Remix Software Inc.
3246
- *
3247
- * This source code is licensed under the MIT license found in the
3248
- * LICENSE.md file in the root directory of this source tree.
3249
- *
3250
- * @license MIT
3251
- */
3252
- function _extends$2() {
3253
- _extends$2 = Object.assign ? Object.assign.bind() : function (target) {
3254
- for (var i = 1; i < arguments.length; i++) {
3255
- var source = arguments[i];
3256
- for (var key in source) {
3257
- if (Object.prototype.hasOwnProperty.call(source, key)) {
3258
- target[key] = source[key];
3259
- }
3260
- }
3261
- }
3262
- return target;
3263
- };
3264
- return _extends$2.apply(this, arguments);
3265
- }
3266
-
3267
- ////////////////////////////////////////////////////////////////////////////////
3268
- //#region Types and Constants
3269
- ////////////////////////////////////////////////////////////////////////////////
3270
- /**
3271
- * Actions represent the type of change to a location value.
3272
- */
3273
- var Action;
3274
- (function (Action) {
3275
- /**
3276
- * A POP indicates a change to an arbitrary index in the history stack, such
3277
- * as a back or forward navigation. It does not describe the direction of the
3278
- * navigation, only that the current index changed.
3279
- *
3280
- * Note: This is the default action for newly created history objects.
3281
- */
3282
- Action["Pop"] = "POP";
3283
- /**
3284
- * A PUSH indicates a new entry being added to the history stack, such as when
3285
- * a link is clicked and a new page loads. When this happens, all subsequent
3286
- * entries in the stack are lost.
3287
- */
3288
- Action["Push"] = "PUSH";
3289
- /**
3290
- * A REPLACE indicates the entry at the current index in the history stack
3291
- * being replaced by a new one.
3292
- */
3293
- Action["Replace"] = "REPLACE";
3294
- })(Action || (Action = {}));
3295
- function invariant(value, message) {
3296
- if (value === false || value === null || typeof value === "undefined") {
3297
- throw new Error(message);
3298
- }
3299
- }
3300
- function warning(cond, message) {
3301
- if (!cond) {
3302
- // eslint-disable-next-line no-console
3303
- if (typeof console !== "undefined") console.warn(message);
3304
- try {
3305
- // Welcome to debugging history!
3306
- //
3307
- // This error is thrown as a convenience, so you can more easily
3308
- // find the source for a warning that appears in the console by
3309
- // enabling "pause on exceptions" in your JavaScript debugger.
3310
- throw new Error(message);
3311
- // eslint-disable-next-line no-empty
3312
- } catch (e) {}
3313
- }
3314
- }
3315
- /**
3316
- * Creates a string URL path from the given pathname, search, and hash components.
3317
- */
3318
- function createPath(_ref) {
3319
- let {
3320
- pathname = "/",
3321
- search = "",
3322
- hash = ""
3323
- } = _ref;
3324
- if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
3325
- if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
3326
- return pathname;
3327
- }
3328
- /**
3329
- * Parses a string URL path into its separate pathname, search, and hash components.
3330
- */
3331
- function parsePath(path) {
3332
- let parsedPath = {};
3333
- if (path) {
3334
- let hashIndex = path.indexOf("#");
3335
- if (hashIndex >= 0) {
3336
- parsedPath.hash = path.substr(hashIndex);
3337
- path = path.substr(0, hashIndex);
3338
- }
3339
- let searchIndex = path.indexOf("?");
3340
- if (searchIndex >= 0) {
3341
- parsedPath.search = path.substr(searchIndex);
3342
- path = path.substr(0, searchIndex);
3343
- }
3344
- if (path) {
3345
- parsedPath.pathname = path;
3346
- }
3347
- }
3348
- return parsedPath;
3349
- }
3350
- //#endregion
3351
-
3352
- var ResultType;
3353
- (function (ResultType) {
3354
- ResultType["data"] = "data";
3355
- ResultType["deferred"] = "deferred";
3356
- ResultType["redirect"] = "redirect";
3357
- ResultType["error"] = "error";
3358
- })(ResultType || (ResultType = {}));
3359
- /**
3360
- * Performs pattern matching on a URL pathname and returns information about
3361
- * the match.
3362
- *
3363
- * @see https://reactrouter.com/v6/utils/match-path
3364
- */
3365
- function matchPath(pattern, pathname) {
3366
- if (typeof pattern === "string") {
3367
- pattern = {
3368
- path: pattern,
3369
- caseSensitive: false,
3370
- end: true
3371
- };
3372
- }
3373
- let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
3374
- let match = pathname.match(matcher);
3375
- if (!match) return null;
3376
- let matchedPathname = match[0];
3377
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
3378
- let captureGroups = match.slice(1);
3379
- let params = compiledParams.reduce((memo, _ref, index) => {
3380
- let {
3381
- paramName,
3382
- isOptional
3383
- } = _ref;
3384
- // We need to compute the pathnameBase here using the raw splat value
3385
- // instead of using params["*"] later because it will be decoded then
3386
- if (paramName === "*") {
3387
- let splatValue = captureGroups[index] || "";
3388
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
3389
- }
3390
- const value = captureGroups[index];
3391
- if (isOptional && !value) {
3392
- memo[paramName] = undefined;
3393
- } else {
3394
- memo[paramName] = (value || "").replace(/%2F/g, "/");
3395
- }
3396
- return memo;
3397
- }, {});
3398
- return {
3399
- params,
3400
- pathname: matchedPathname,
3401
- pathnameBase,
3402
- pattern
3403
- };
3404
- }
3405
- function compilePath(path, caseSensitive, end) {
3406
- if (caseSensitive === void 0) {
3407
- caseSensitive = false;
3408
- }
3409
- if (end === void 0) {
3410
- end = true;
3411
- }
3412
- warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\"."));
3413
- let params = [];
3414
- let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
3415
- .replace(/^\/*/, "/") // Make sure it has a leading /
3416
- .replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars
3417
- .replace(/\/:([\w-]+)(\?)?/g, (_, paramName, isOptional) => {
3418
- params.push({
3419
- paramName,
3420
- isOptional: isOptional != null
3421
- });
3422
- return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
3423
- });
3424
- if (path.endsWith("*")) {
3425
- params.push({
3426
- paramName: "*"
3427
- });
3428
- regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
3429
- : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
3430
- } else if (end) {
3431
- // When matching to the end, ignore trailing slashes
3432
- regexpSource += "\\/*$";
3433
- } else if (path !== "" && path !== "/") {
3434
- // If our path is non-empty and contains anything beyond an initial slash,
3435
- // then we have _some_ form of path in our regex, so we should expect to
3436
- // match only if we find the end of this path segment. Look for an optional
3437
- // non-captured trailing slash (to match a portion of the URL) or the end
3438
- // of the path (if we've matched to the end). We used to do this with a
3439
- // word boundary but that gives false positives on routes like
3440
- // /user-preferences since `-` counts as a word boundary.
3441
- regexpSource += "(?:(?=\\/|$))";
3442
- } else ;
3443
- let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
3444
- return [matcher, params];
3445
- }
3446
- /**
3447
- * @private
3448
- */
3449
- function stripBasename(pathname, basename) {
3450
- if (basename === "/") return pathname;
3451
- if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
3452
- return null;
3453
- }
3454
- // We want to leave trailing slash behavior in the user's control, so if they
3455
- // specify a basename with a trailing slash, we should support it
3456
- let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
3457
- let nextChar = pathname.charAt(startIndex);
3458
- if (nextChar && nextChar !== "/") {
3459
- // pathname does not start with basename/
3460
- return null;
3461
- }
3462
- return pathname.slice(startIndex) || "/";
3463
- }
3464
- /**
3465
- * Returns a resolved path object relative to the given pathname.
3466
- *
3467
- * @see https://reactrouter.com/v6/utils/resolve-path
3468
- */
3469
- function resolvePath(to, fromPathname) {
3470
- if (fromPathname === void 0) {
3471
- fromPathname = "/";
3472
- }
3473
- let {
3474
- pathname: toPathname,
3475
- search = "",
3476
- hash = ""
3477
- } = typeof to === "string" ? parsePath(to) : to;
3478
- let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;
3479
- return {
3480
- pathname,
3481
- search: normalizeSearch(search),
3482
- hash: normalizeHash(hash)
3483
- };
3484
- }
3485
- function resolvePathname(relativePath, fromPathname) {
3486
- let segments = fromPathname.replace(/\/+$/, "").split("/");
3487
- let relativeSegments = relativePath.split("/");
3488
- relativeSegments.forEach(segment => {
3489
- if (segment === "..") {
3490
- // Keep the root "" segment so the pathname starts at /
3491
- if (segments.length > 1) segments.pop();
3492
- } else if (segment !== ".") {
3493
- segments.push(segment);
3494
- }
3495
- });
3496
- return segments.length > 1 ? segments.join("/") : "/";
3497
- }
3498
- function getInvalidPathError(char, field, dest, path) {
3499
- return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in <Link to=\"...\"> and the router will parse it for you.";
3500
- }
3501
- /**
3502
- * @private
3503
- *
3504
- * When processing relative navigation we want to ignore ancestor routes that
3505
- * do not contribute to the path, such that index/pathless layout routes don't
3506
- * interfere.
3507
- *
3508
- * For example, when moving a route element into an index route and/or a
3509
- * pathless layout route, relative link behavior contained within should stay
3510
- * the same. Both of the following examples should link back to the root:
3511
- *
3512
- * <Route path="/">
3513
- * <Route path="accounts" element={<Link to=".."}>
3514
- * </Route>
3515
- *
3516
- * <Route path="/">
3517
- * <Route path="accounts">
3518
- * <Route element={<AccountsLayout />}> // <-- Does not contribute
3519
- * <Route index element={<Link to=".."} /> // <-- Does not contribute
3520
- * </Route
3521
- * </Route>
3522
- * </Route>
3523
- */
3524
- function getPathContributingMatches(matches) {
3525
- return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
3526
- }
3527
- // Return the array of pathnames for the current route matches - used to
3528
- // generate the routePathnames input for resolveTo()
3529
- function getResolveToMatches(matches, v7_relativeSplatPath) {
3530
- let pathMatches = getPathContributingMatches(matches);
3531
- // When v7_relativeSplatPath is enabled, use the full pathname for the leaf
3532
- // match so we include splat values for "." links. See:
3533
- // https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329
3534
- if (v7_relativeSplatPath) {
3535
- return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);
3536
- }
3537
- return pathMatches.map(match => match.pathnameBase);
3538
- }
3539
- /**
3540
- * @private
3541
- */
3542
- function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
3543
- if (isPathRelative === void 0) {
3544
- isPathRelative = false;
3545
- }
3546
- let to;
3547
- if (typeof toArg === "string") {
3548
- to = parsePath(toArg);
3549
- } else {
3550
- to = _extends$2({}, toArg);
3551
- invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to));
3552
- invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to));
3553
- invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to));
3554
- }
3555
- let isEmptyPath = toArg === "" || to.pathname === "";
3556
- let toPathname = isEmptyPath ? "/" : to.pathname;
3557
- let from;
3558
- // Routing is relative to the current pathname if explicitly requested.
3559
- //
3560
- // If a pathname is explicitly provided in `to`, it should be relative to the
3561
- // route context. This is explained in `Note on `<Link to>` values` in our
3562
- // migration guide from v5 as a means of disambiguation between `to` values
3563
- // that begin with `/` and those that do not. However, this is problematic for
3564
- // `to` values that do not provide a pathname. `to` can simply be a search or
3565
- // hash string, in which case we should assume that the navigation is relative
3566
- // to the current location's pathname and *not* the route pathname.
3567
- if (toPathname == null) {
3568
- from = locationPathname;
3569
- } else {
3570
- let routePathnameIndex = routePathnames.length - 1;
3571
- // With relative="route" (the default), each leading .. segment means
3572
- // "go up one route" instead of "go up one URL segment". This is a key
3573
- // difference from how <a href> works and a major reason we call this a
3574
- // "to" value instead of a "href".
3575
- if (!isPathRelative && toPathname.startsWith("..")) {
3576
- let toSegments = toPathname.split("/");
3577
- while (toSegments[0] === "..") {
3578
- toSegments.shift();
3579
- routePathnameIndex -= 1;
3580
- }
3581
- to.pathname = toSegments.join("/");
3582
- }
3583
- from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
3584
- }
3585
- let path = resolvePath(to, from);
3586
- // Ensure the pathname has a trailing slash if the original "to" had one
3587
- let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
3588
- // Or if this was a link to the current path which has a trailing slash
3589
- let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
3590
- if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
3591
- path.pathname += "/";
3592
- }
3593
- return path;
3594
- }
3595
- /**
3596
- * @private
3597
- */
3598
- const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/");
3599
- /**
3600
- * @private
3601
- */
3602
- const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
3603
- /**
3604
- * @private
3605
- */
3606
- const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
3607
-
3608
- const validMutationMethodsArr = ["post", "put", "patch", "delete"];
3609
- new Set(validMutationMethodsArr);
3610
- const validRequestMethodsArr = ["get", ...validMutationMethodsArr];
3611
- new Set(validRequestMethodsArr);
3612
-
3613
- /**
3614
- * React Router v6.28.1
3615
- *
3616
- * Copyright (c) Remix Software Inc.
3617
- *
3618
- * This source code is licensed under the MIT license found in the
3619
- * LICENSE.md file in the root directory of this source tree.
3620
- *
3621
- * @license MIT
3622
- */
3623
-
3624
- function _extends$1() {
3625
- _extends$1 = Object.assign ? Object.assign.bind() : function (target) {
3626
- for (var i = 1; i < arguments.length; i++) {
3627
- var source = arguments[i];
3628
- for (var key in source) {
3629
- if (Object.prototype.hasOwnProperty.call(source, key)) {
3630
- target[key] = source[key];
3631
- }
3632
- }
3633
- }
3634
- return target;
3635
- };
3636
- return _extends$1.apply(this, arguments);
3637
- }
3638
-
3639
- // Create react-specific types from the agnostic types in @remix-run/router to
3640
- // export from react-router
3641
- const DataRouterContext = /*#__PURE__*/React.createContext(null);
3642
- if (process.env.NODE_ENV !== "production") {
3643
- DataRouterContext.displayName = "DataRouter";
3644
- }
3645
- const DataRouterStateContext = /*#__PURE__*/React.createContext(null);
3646
- if (process.env.NODE_ENV !== "production") {
3647
- DataRouterStateContext.displayName = "DataRouterState";
3648
- }
3649
- const AwaitContext = /*#__PURE__*/React.createContext(null);
3650
- if (process.env.NODE_ENV !== "production") {
3651
- AwaitContext.displayName = "Await";
3652
- }
3653
-
3654
- /**
3655
- * A Navigator is a "location changer"; it's how you get to different locations.
3656
- *
3657
- * Every history instance conforms to the Navigator interface, but the
3658
- * distinction is useful primarily when it comes to the low-level `<Router>` API
3659
- * where both the location and a navigator must be provided separately in order
3660
- * to avoid "tearing" that may occur in a suspense-enabled app if the action
3661
- * and/or location were to be read directly from the history instance.
3662
- */
3663
-
3664
- const NavigationContext = /*#__PURE__*/React.createContext(null);
3665
- if (process.env.NODE_ENV !== "production") {
3666
- NavigationContext.displayName = "Navigation";
3667
- }
3668
- const LocationContext = /*#__PURE__*/React.createContext(null);
3669
- if (process.env.NODE_ENV !== "production") {
3670
- LocationContext.displayName = "Location";
3671
- }
3672
- const RouteContext = /*#__PURE__*/React.createContext({
3673
- outlet: null,
3674
- matches: [],
3675
- isDataRoute: false
3676
- });
3677
- if (process.env.NODE_ENV !== "production") {
3678
- RouteContext.displayName = "Route";
3679
- }
3680
- const RouteErrorContext = /*#__PURE__*/React.createContext(null);
3681
- if (process.env.NODE_ENV !== "production") {
3682
- RouteErrorContext.displayName = "RouteError";
3683
- }
3684
-
3685
- /**
3686
- * Returns the full href for the given "to" value. This is useful for building
3687
- * custom links that are also accessible and preserve right-click behavior.
3688
- *
3689
- * @see https://reactrouter.com/v6/hooks/use-href
3690
- */
3691
- function useHref(to, _temp) {
3692
- let {
3693
- relative
3694
- } = _temp === void 0 ? {} : _temp;
3695
- !useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
3696
- // router loaded. We can help them understand how to avoid that.
3697
- "useHref() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
3698
- let {
3699
- basename,
3700
- navigator
3701
- } = React.useContext(NavigationContext);
3702
- let {
3703
- hash,
3704
- pathname,
3705
- search
3706
- } = useResolvedPath(to, {
3707
- relative
3708
- });
3709
- let joinedPathname = pathname;
3710
-
3711
- // If we're operating within a basename, prepend it to the pathname prior
3712
- // to creating the href. If this is a root navigation, then just use the raw
3713
- // basename which allows the basename to have full control over the presence
3714
- // of a trailing slash on root links
3715
- if (basename !== "/") {
3716
- joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]);
3717
- }
3718
- return navigator.createHref({
3719
- pathname: joinedPathname,
3720
- search,
3721
- hash
3722
- });
3723
- }
3724
-
3725
- /**
3726
- * Returns true if this component is a descendant of a `<Router>`.
3727
- *
3728
- * @see https://reactrouter.com/v6/hooks/use-in-router-context
3729
- */
3730
- function useInRouterContext() {
3731
- return React.useContext(LocationContext) != null;
3732
- }
3733
-
3734
- /**
3735
- * Returns the current location object, which represents the current URL in web
3736
- * browsers.
3737
- *
3738
- * Note: If you're using this it may mean you're doing some of your own
3739
- * "routing" in your app, and we'd like to know what your use case is. We may
3740
- * be able to provide something higher-level to better suit your needs.
3741
- *
3742
- * @see https://reactrouter.com/v6/hooks/use-location
3743
- */
3744
- function useLocation() {
3745
- !useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
3746
- // router loaded. We can help them understand how to avoid that.
3747
- "useLocation() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
3748
- return React.useContext(LocationContext).location;
3749
- }
3750
-
3751
- /**
3752
- * The interface for the navigate() function returned from useNavigate().
3753
- */
3754
-
3755
- const navigateEffectWarning = "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.";
3756
-
3757
- // Mute warnings for calls to useNavigate in SSR environments
3758
- function useIsomorphicLayoutEffect$1(cb) {
3759
- let isStatic = React.useContext(NavigationContext).static;
3760
- if (!isStatic) {
3761
- // We should be able to get rid of this once react 18.3 is released
3762
- // See: https://github.com/facebook/react/pull/26395
3763
- // eslint-disable-next-line react-hooks/rules-of-hooks
3764
- React.useLayoutEffect(cb);
3765
- }
3766
- }
3767
-
3768
- /**
3769
- * Returns an imperative method for changing the location. Used by `<Link>`s, but
3770
- * may also be used by other elements to change the location.
3771
- *
3772
- * @see https://reactrouter.com/v6/hooks/use-navigate
3773
- */
3774
- function useNavigate() {
3775
- let {
3776
- isDataRoute
3777
- } = React.useContext(RouteContext);
3778
- // Conditional usage is OK here because the usage of a data router is static
3779
- // eslint-disable-next-line react-hooks/rules-of-hooks
3780
- return isDataRoute ? useNavigateStable() : useNavigateUnstable();
3781
- }
3782
- function useNavigateUnstable() {
3783
- !useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
3784
- // router loaded. We can help them understand how to avoid that.
3785
- "useNavigate() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
3786
- let dataRouterContext = React.useContext(DataRouterContext);
3787
- let {
3788
- basename,
3789
- future,
3790
- navigator
3791
- } = React.useContext(NavigationContext);
3792
- let {
3793
- matches
3794
- } = React.useContext(RouteContext);
3795
- let {
3796
- pathname: locationPathname
3797
- } = useLocation();
3798
- let routePathnamesJson = JSON.stringify(getResolveToMatches(matches, future.v7_relativeSplatPath));
3799
- let activeRef = React.useRef(false);
3800
- useIsomorphicLayoutEffect$1(() => {
3801
- activeRef.current = true;
3802
- });
3803
- let navigate = React.useCallback(function (to, options) {
3804
- if (options === void 0) {
3805
- options = {};
3806
- }
3807
- process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
3808
-
3809
- // Short circuit here since if this happens on first render the navigate
3810
- // is useless because we haven't wired up our history listener yet
3811
- if (!activeRef.current) return;
3812
- if (typeof to === "number") {
3813
- navigator.go(to);
3814
- return;
3815
- }
3816
- let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
3817
-
3818
- // If we're operating within a basename, prepend it to the pathname prior
3819
- // to handing off to history (but only if we're not in a data router,
3820
- // otherwise it'll prepend the basename inside of the router).
3821
- // If this is a root navigation, then we navigate to the raw basename
3822
- // which allows the basename to have full control over the presence of a
3823
- // trailing slash on root links
3824
- if (dataRouterContext == null && basename !== "/") {
3825
- path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
3826
- }
3827
- (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
3828
- }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);
3829
- return navigate;
3830
- }
3831
-
3832
- /**
3833
- * Resolves the pathname of the given `to` value against the current location.
3834
- *
3835
- * @see https://reactrouter.com/v6/hooks/use-resolved-path
3836
- */
3837
- function useResolvedPath(to, _temp2) {
3838
- let {
3839
- relative
3840
- } = _temp2 === void 0 ? {} : _temp2;
3841
- let {
3842
- future
3843
- } = React.useContext(NavigationContext);
3844
- let {
3845
- matches
3846
- } = React.useContext(RouteContext);
3847
- let {
3848
- pathname: locationPathname
3849
- } = useLocation();
3850
- let routePathnamesJson = JSON.stringify(getResolveToMatches(matches, future.v7_relativeSplatPath));
3851
- return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
3852
- }
3853
- var DataRouterHook$1 = /*#__PURE__*/function (DataRouterHook) {
3854
- DataRouterHook["UseBlocker"] = "useBlocker";
3855
- DataRouterHook["UseRevalidator"] = "useRevalidator";
3856
- DataRouterHook["UseNavigateStable"] = "useNavigate";
3857
- return DataRouterHook;
3858
- }(DataRouterHook$1 || {});
3859
- var DataRouterStateHook$1 = /*#__PURE__*/function (DataRouterStateHook) {
3860
- DataRouterStateHook["UseBlocker"] = "useBlocker";
3861
- DataRouterStateHook["UseLoaderData"] = "useLoaderData";
3862
- DataRouterStateHook["UseActionData"] = "useActionData";
3863
- DataRouterStateHook["UseRouteError"] = "useRouteError";
3864
- DataRouterStateHook["UseNavigation"] = "useNavigation";
3865
- DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData";
3866
- DataRouterStateHook["UseMatches"] = "useMatches";
3867
- DataRouterStateHook["UseRevalidator"] = "useRevalidator";
3868
- DataRouterStateHook["UseNavigateStable"] = "useNavigate";
3869
- DataRouterStateHook["UseRouteId"] = "useRouteId";
3870
- return DataRouterStateHook;
3871
- }(DataRouterStateHook$1 || {});
3872
- function getDataRouterConsoleError$1(hookName) {
3873
- return hookName + " must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.";
3874
- }
3875
- function useDataRouterContext$1(hookName) {
3876
- let ctx = React.useContext(DataRouterContext);
3877
- !ctx ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
3878
- return ctx;
3879
- }
3880
- function useRouteContext(hookName) {
3881
- let route = React.useContext(RouteContext);
3882
- !route ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
3883
- return route;
3884
- }
3885
-
3886
- // Internal version with hookName-aware debugging
3887
- function useCurrentRouteId(hookName) {
3888
- let route = useRouteContext(hookName);
3889
- let thisRoute = route.matches[route.matches.length - 1];
3890
- !thisRoute.route.id ? process.env.NODE_ENV !== "production" ? invariant(false, hookName + " can only be used on routes that contain a unique \"id\"") : invariant(false) : void 0;
3891
- return thisRoute.route.id;
3892
- }
3893
-
3894
- /**
3895
- * Returns the ID for the nearest contextual route
3896
- */
3897
- function useRouteId() {
3898
- return useCurrentRouteId(DataRouterStateHook$1.UseRouteId);
3899
- }
3900
-
3901
- /**
3902
- * Stable version of useNavigate that is used when we are in the context of
3903
- * a RouterProvider.
3904
- */
3905
- function useNavigateStable() {
3906
- let {
3907
- router
3908
- } = useDataRouterContext$1(DataRouterHook$1.UseNavigateStable);
3909
- let id = useCurrentRouteId(DataRouterStateHook$1.UseNavigateStable);
3910
- let activeRef = React.useRef(false);
3911
- useIsomorphicLayoutEffect$1(() => {
3912
- activeRef.current = true;
3913
- });
3914
- let navigate = React.useCallback(function (to, options) {
3915
- if (options === void 0) {
3916
- options = {};
3917
- }
3918
- process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
3919
-
3920
- // Short circuit here since if this happens on first render the navigate
3921
- // is useless because we haven't wired up our router subscriber yet
3922
- if (!activeRef.current) return;
3923
- if (typeof to === "number") {
3924
- router.navigate(to);
3925
- } else {
3926
- router.navigate(to, _extends$1({
3927
- fromRouteId: id
3928
- }, options));
3929
- }
3930
- }, [router, id]);
3931
- return navigate;
3932
- }
3933
- new Promise(() => {});
3934
-
3935
- /**
3936
- * React Router DOM v6.28.1
3937
- *
3938
- * Copyright (c) Remix Software Inc.
3939
- *
3940
- * This source code is licensed under the MIT license found in the
3941
- * LICENSE.md file in the root directory of this source tree.
3942
- *
3943
- * @license MIT
3944
- */
3945
-
3946
- function _extends() {
3947
- _extends = Object.assign ? Object.assign.bind() : function (target) {
3948
- for (var i = 1; i < arguments.length; i++) {
3949
- var source = arguments[i];
3950
- for (var key in source) {
3951
- if (Object.prototype.hasOwnProperty.call(source, key)) {
3952
- target[key] = source[key];
3953
- }
3954
- }
3955
- }
3956
- return target;
3957
- };
3958
- return _extends.apply(this, arguments);
3959
- }
3960
- function _objectWithoutPropertiesLoose(source, excluded) {
3961
- if (source == null) return {};
3962
- var target = {};
3963
- var sourceKeys = Object.keys(source);
3964
- var key, i;
3965
- for (i = 0; i < sourceKeys.length; i++) {
3966
- key = sourceKeys[i];
3967
- if (excluded.indexOf(key) >= 0) continue;
3968
- target[key] = source[key];
3969
- }
3970
- return target;
3971
- }
3972
-
3973
- const defaultMethod = "get";
3974
- const defaultEncType = "application/x-www-form-urlencoded";
3975
- function isHtmlElement(object) {
3976
- return object != null && typeof object.tagName === "string";
3977
- }
3978
- function isButtonElement(object) {
3979
- return isHtmlElement(object) && object.tagName.toLowerCase() === "button";
3980
- }
3981
- function isFormElement(object) {
3982
- return isHtmlElement(object) && object.tagName.toLowerCase() === "form";
3983
- }
3984
- function isInputElement(object) {
3985
- return isHtmlElement(object) && object.tagName.toLowerCase() === "input";
3986
- }
3987
- function isModifiedEvent(event) {
3988
- return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
3989
- }
3990
- function shouldProcessLinkClick(event, target) {
3991
- return event.button === 0 && (
3992
- // Ignore everything but left clicks
3993
- !target || target === "_self") &&
3994
- // Let browser handle "target=_blank" etc.
3995
- !isModifiedEvent(event) // Ignore clicks with modifier keys
3996
- ;
3997
- }
3998
- /**
3999
- * Creates a URLSearchParams object using the given initializer.
4000
- *
4001
- * This is identical to `new URLSearchParams(init)` except it also
4002
- * supports arrays as values in the object form of the initializer
4003
- * instead of just strings. This is convenient when you need multiple
4004
- * values for a given key, but don't want to use an array initializer.
4005
- *
4006
- * For example, instead of:
4007
- *
4008
- * let searchParams = new URLSearchParams([
4009
- * ['sort', 'name'],
4010
- * ['sort', 'price']
4011
- * ]);
4012
- *
4013
- * you can do:
4014
- *
4015
- * let searchParams = createSearchParams({
4016
- * sort: ['name', 'price']
4017
- * });
4018
- */
4019
- function createSearchParams(init) {
4020
- if (init === void 0) {
4021
- init = "";
4022
- }
4023
- return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
4024
- let value = init[key];
4025
- return memo.concat(Array.isArray(value) ? value.map(v => [key, v]) : [[key, value]]);
4026
- }, []));
4027
- }
4028
- function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
4029
- let searchParams = createSearchParams(locationSearch);
4030
- if (defaultSearchParams) {
4031
- // Use `defaultSearchParams.forEach(...)` here instead of iterating of
4032
- // `defaultSearchParams.keys()` to work-around a bug in Firefox related to
4033
- // web extensions. Relevant Bugzilla tickets:
4034
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1414602
4035
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1023984
4036
- defaultSearchParams.forEach((_, key) => {
4037
- if (!searchParams.has(key)) {
4038
- defaultSearchParams.getAll(key).forEach(value => {
4039
- searchParams.append(key, value);
4040
- });
4041
- }
4042
- });
4043
- }
4044
- return searchParams;
4045
- }
4046
- // One-time check for submitter support
4047
- let _formDataSupportsSubmitter = null;
4048
- function isFormDataSubmitterSupported() {
4049
- if (_formDataSupportsSubmitter === null) {
4050
- try {
4051
- new FormData(document.createElement("form"),
4052
- // @ts-expect-error if FormData supports the submitter parameter, this will throw
4053
- 0);
4054
- _formDataSupportsSubmitter = false;
4055
- } catch (e) {
4056
- _formDataSupportsSubmitter = true;
4057
- }
4058
- }
4059
- return _formDataSupportsSubmitter;
4060
- }
4061
- const supportedFormEncTypes = new Set(["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]);
4062
- function getFormEncType(encType) {
4063
- if (encType != null && !supportedFormEncTypes.has(encType)) {
4064
- process.env.NODE_ENV !== "production" ? warning(false, "\"" + encType + "\" is not a valid `encType` for `<Form>`/`<fetcher.Form>` " + ("and will default to \"" + defaultEncType + "\"")) : void 0;
4065
- return null;
4066
- }
4067
- return encType;
4068
- }
4069
- function getFormSubmissionInfo(target, basename) {
4070
- let method;
4071
- let action;
4072
- let encType;
4073
- let formData;
4074
- let body;
4075
- if (isFormElement(target)) {
4076
- // When grabbing the action from the element, it will have had the basename
4077
- // prefixed to ensure non-JS scenarios work, so strip it since we'll
4078
- // re-prefix in the router
4079
- let attr = target.getAttribute("action");
4080
- action = attr ? stripBasename(attr, basename) : null;
4081
- method = target.getAttribute("method") || defaultMethod;
4082
- encType = getFormEncType(target.getAttribute("enctype")) || defaultEncType;
4083
- formData = new FormData(target);
4084
- } else if (isButtonElement(target) || isInputElement(target) && (target.type === "submit" || target.type === "image")) {
4085
- let form = target.form;
4086
- if (form == null) {
4087
- throw new Error("Cannot submit a <button> or <input type=\"submit\"> without a <form>");
4088
- }
4089
- // <button>/<input type="submit"> may override attributes of <form>
4090
- // When grabbing the action from the element, it will have had the basename
4091
- // prefixed to ensure non-JS scenarios work, so strip it since we'll
4092
- // re-prefix in the router
4093
- let attr = target.getAttribute("formaction") || form.getAttribute("action");
4094
- action = attr ? stripBasename(attr, basename) : null;
4095
- method = target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
4096
- encType = getFormEncType(target.getAttribute("formenctype")) || getFormEncType(form.getAttribute("enctype")) || defaultEncType;
4097
- // Build a FormData object populated from a form and submitter
4098
- formData = new FormData(form, target);
4099
- // If this browser doesn't support the `FormData(el, submitter)` format,
4100
- // then tack on the submitter value at the end. This is a lightweight
4101
- // solution that is not 100% spec compliant. For complete support in older
4102
- // browsers, consider using the `formdata-submitter-polyfill` package
4103
- if (!isFormDataSubmitterSupported()) {
4104
- let {
4105
- name,
4106
- type,
4107
- value
4108
- } = target;
4109
- if (type === "image") {
4110
- let prefix = name ? name + "." : "";
4111
- formData.append(prefix + "x", "0");
4112
- formData.append(prefix + "y", "0");
4113
- } else if (name) {
4114
- formData.append(name, value);
4115
- }
4116
- }
4117
- } else if (isHtmlElement(target)) {
4118
- throw new Error("Cannot submit element that is not <form>, <button>, or " + "<input type=\"submit|image\">");
4119
- } else {
4120
- method = defaultMethod;
4121
- action = null;
4122
- encType = defaultEncType;
4123
- body = target;
4124
- }
4125
- // Send body for <Form encType="text/plain" so we encode it into text
4126
- if (formData && encType === "text/plain") {
4127
- body = formData;
4128
- formData = undefined;
4129
- }
4130
- return {
4131
- action,
4132
- method: method.toLowerCase(),
4133
- encType,
4134
- formData,
4135
- body
4136
- };
4137
- }
4138
-
4139
- const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state", "target", "to", "preventScrollReset", "viewTransition"],
4140
- _excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "viewTransition", "children"],
4141
- _excluded3 = ["fetcherKey", "navigate", "reloadDocument", "replace", "state", "method", "action", "onSubmit", "relative", "preventScrollReset", "viewTransition"];
4142
- // HEY YOU! DON'T TOUCH THIS VARIABLE!
4143
- //
4144
- // It is replaced with the proper version at build time via a babel plugin in
4145
- // the rollup config.
4146
- //
4147
- // Export a global property onto the window for React Router detection by the
4148
- // Core Web Vitals Technology Report. This way they can configure the `wappalyzer`
4149
- // to detect and properly classify live websites as being built with React Router:
4150
- // https://github.com/HTTPArchive/wappalyzer/blob/main/src/technologies/r.json
4151
- const REACT_ROUTER_VERSION = "6";
4152
- try {
4153
- window.__reactRouterVersion = REACT_ROUTER_VERSION;
4154
- } catch (e) {
4155
- // no-op
4156
- }
4157
- const ViewTransitionContext = /*#__PURE__*/React.createContext({
4158
- isTransitioning: false
4159
- });
4160
- if (process.env.NODE_ENV !== "production") {
4161
- ViewTransitionContext.displayName = "ViewTransition";
4162
- }
4163
- const FetchersContext = /*#__PURE__*/React.createContext(new Map());
4164
- if (process.env.NODE_ENV !== "production") {
4165
- FetchersContext.displayName = "Fetchers";
4166
- }
4167
- if (process.env.NODE_ENV !== "production") ;
4168
- const isBrowser$1 = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
4169
- const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
4170
- /**
4171
- * The public API for rendering a history-aware `<a>`.
4172
- */
4173
- const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref7, ref) {
4174
- let {
4175
- onClick,
4176
- relative,
4177
- reloadDocument,
4178
- replace,
4179
- state,
4180
- target,
4181
- to,
4182
- preventScrollReset,
4183
- viewTransition
4184
- } = _ref7,
4185
- rest = _objectWithoutPropertiesLoose(_ref7, _excluded);
4186
- let {
4187
- basename
4188
- } = React.useContext(NavigationContext);
4189
- // Rendered into <a href> for absolute URLs
4190
- let absoluteHref;
4191
- let isExternal = false;
4192
- if (typeof to === "string" && ABSOLUTE_URL_REGEX.test(to)) {
4193
- // Render the absolute href server- and client-side
4194
- absoluteHref = to;
4195
- // Only check for external origins client-side
4196
- if (isBrowser$1) {
4197
- try {
4198
- let currentUrl = new URL(window.location.href);
4199
- let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
4200
- let path = stripBasename(targetUrl.pathname, basename);
4201
- if (targetUrl.origin === currentUrl.origin && path != null) {
4202
- // Strip the protocol/origin/basename for same-origin absolute URLs
4203
- to = path + targetUrl.search + targetUrl.hash;
4204
- } else {
4205
- isExternal = true;
4206
- }
4207
- } catch (e) {
4208
- // We can't do external URL detection without a valid URL
4209
- process.env.NODE_ENV !== "production" ? warning(false, "<Link to=\"" + to + "\"> contains an invalid URL which will probably break " + "when clicked - please update to a valid URL path.") : void 0;
4210
- }
4211
- }
4212
- }
4213
- // Rendered into <a href> for relative URLs
4214
- let href = useHref(to, {
4215
- relative
4216
- });
4217
- let internalOnClick = useLinkClickHandler(to, {
4218
- replace,
4219
- state,
4220
- target,
4221
- preventScrollReset,
4222
- relative,
4223
- viewTransition
4224
- });
4225
- function handleClick(event) {
4226
- if (onClick) onClick(event);
4227
- if (!event.defaultPrevented) {
4228
- internalOnClick(event);
4229
- }
4230
- }
4231
- return (
4232
- /*#__PURE__*/
4233
- // eslint-disable-next-line jsx-a11y/anchor-has-content
4234
- React.createElement("a", _extends({}, rest, {
4235
- href: absoluteHref || href,
4236
- onClick: isExternal || reloadDocument ? onClick : handleClick,
4237
- ref: ref,
4238
- target: target
4239
- }))
4240
- );
4241
- });
4242
- if (process.env.NODE_ENV !== "production") {
4243
- Link.displayName = "Link";
4244
- }
4245
- /**
4246
- * A `<Link>` wrapper that knows if it's "active" or not.
4247
- */
4248
- const NavLink = /*#__PURE__*/React.forwardRef(function NavLinkWithRef(_ref8, ref) {
4249
- let {
4250
- "aria-current": ariaCurrentProp = "page",
4251
- caseSensitive = false,
4252
- className: classNameProp = "",
4253
- end = false,
4254
- style: styleProp,
4255
- to,
4256
- viewTransition,
4257
- children
4258
- } = _ref8,
4259
- rest = _objectWithoutPropertiesLoose(_ref8, _excluded2);
4260
- let path = useResolvedPath(to, {
4261
- relative: rest.relative
4262
- });
4263
- let location = useLocation();
4264
- let routerState = React.useContext(DataRouterStateContext);
4265
- let {
4266
- navigator,
4267
- basename
4268
- } = React.useContext(NavigationContext);
4269
- let isTransitioning = routerState != null &&
4270
- // Conditional usage is OK here because the usage of a data router is static
4271
- // eslint-disable-next-line react-hooks/rules-of-hooks
4272
- useViewTransitionState(path) && viewTransition === true;
4273
- let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname;
4274
- let locationPathname = location.pathname;
4275
- let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null;
4276
- if (!caseSensitive) {
4277
- locationPathname = locationPathname.toLowerCase();
4278
- nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;
4279
- toPathname = toPathname.toLowerCase();
4280
- }
4281
- if (nextLocationPathname && basename) {
4282
- nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
4283
- }
4284
- // If the `to` has a trailing slash, look at that exact spot. Otherwise,
4285
- // we're looking for a slash _after_ what's in `to`. For example:
4286
- //
4287
- // <NavLink to="/users"> and <NavLink to="/users/">
4288
- // both want to look for a / at index 6 to match URL `/users/matt`
4289
- const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
4290
- let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
4291
- let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/");
4292
- let renderProps = {
4293
- isActive,
4294
- isPending,
4295
- isTransitioning
4296
- };
4297
- let ariaCurrent = isActive ? ariaCurrentProp : undefined;
4298
- let className;
4299
- if (typeof classNameProp === "function") {
4300
- className = classNameProp(renderProps);
4301
- } else {
4302
- // If the className prop is not a function, we use a default `active`
4303
- // class for <NavLink />s that are active. In v5 `active` was the default
4304
- // value for `activeClassName`, but we are removing that API and can still
4305
- // use the old default behavior for a cleaner upgrade path and keep the
4306
- // simple styling rules working as they currently do.
4307
- className = [classNameProp, isActive ? "active" : null, isPending ? "pending" : null, isTransitioning ? "transitioning" : null].filter(Boolean).join(" ");
4308
- }
4309
- let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp;
4310
- return /*#__PURE__*/React.createElement(Link, _extends({}, rest, {
4311
- "aria-current": ariaCurrent,
4312
- className: className,
4313
- ref: ref,
4314
- style: style,
4315
- to: to,
4316
- viewTransition: viewTransition
4317
- }), typeof children === "function" ? children(renderProps) : children);
4318
- });
4319
- if (process.env.NODE_ENV !== "production") {
4320
- NavLink.displayName = "NavLink";
4321
- }
4322
- /**
4323
- * A `@remix-run/router`-aware `<form>`. It behaves like a normal form except
4324
- * that the interaction with the server is with `fetch` instead of new document
4325
- * requests, allowing components to add nicer UX to the page as the form is
4326
- * submitted and returns with data.
4327
- */
4328
- const Form = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
4329
- let {
4330
- fetcherKey,
4331
- navigate,
4332
- reloadDocument,
4333
- replace,
4334
- state,
4335
- method = defaultMethod,
4336
- action,
4337
- onSubmit,
4338
- relative,
4339
- preventScrollReset,
4340
- viewTransition
4341
- } = _ref9,
4342
- props = _objectWithoutPropertiesLoose(_ref9, _excluded3);
4343
- let submit = useSubmit();
4344
- let formAction = useFormAction(action, {
4345
- relative
4346
- });
4347
- let formMethod = method.toLowerCase() === "get" ? "get" : "post";
4348
- let submitHandler = event => {
4349
- onSubmit && onSubmit(event);
4350
- if (event.defaultPrevented) return;
4351
- event.preventDefault();
4352
- let submitter = event.nativeEvent.submitter;
4353
- let submitMethod = (submitter == null ? void 0 : submitter.getAttribute("formmethod")) || method;
4354
- submit(submitter || event.currentTarget, {
4355
- fetcherKey,
4356
- method: submitMethod,
4357
- navigate,
4358
- replace,
4359
- state,
4360
- relative,
4361
- preventScrollReset,
4362
- viewTransition
4363
- });
4364
- };
4365
- return /*#__PURE__*/React.createElement("form", _extends({
4366
- ref: forwardedRef,
4367
- method: formMethod,
4368
- action: formAction,
4369
- onSubmit: reloadDocument ? onSubmit : submitHandler
4370
- }, props));
4371
- });
4372
- if (process.env.NODE_ENV !== "production") {
4373
- Form.displayName = "Form";
4374
- }
4375
- if (process.env.NODE_ENV !== "production") ;
4376
- //#endregion
4377
- ////////////////////////////////////////////////////////////////////////////////
4378
- //#region Hooks
4379
- ////////////////////////////////////////////////////////////////////////////////
4380
- var DataRouterHook;
4381
- (function (DataRouterHook) {
4382
- DataRouterHook["UseScrollRestoration"] = "useScrollRestoration";
4383
- DataRouterHook["UseSubmit"] = "useSubmit";
4384
- DataRouterHook["UseSubmitFetcher"] = "useSubmitFetcher";
4385
- DataRouterHook["UseFetcher"] = "useFetcher";
4386
- DataRouterHook["useViewTransitionState"] = "useViewTransitionState";
4387
- })(DataRouterHook || (DataRouterHook = {}));
4388
- var DataRouterStateHook;
4389
- (function (DataRouterStateHook) {
4390
- DataRouterStateHook["UseFetcher"] = "useFetcher";
4391
- DataRouterStateHook["UseFetchers"] = "useFetchers";
4392
- DataRouterStateHook["UseScrollRestoration"] = "useScrollRestoration";
4393
- })(DataRouterStateHook || (DataRouterStateHook = {}));
4394
- // Internal hooks
4395
- function getDataRouterConsoleError(hookName) {
4396
- return hookName + " must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.";
4397
- }
4398
- function useDataRouterContext(hookName) {
4399
- let ctx = React.useContext(DataRouterContext);
4400
- !ctx ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError(hookName)) : invariant(false) : void 0;
4401
- return ctx;
4402
- }
4403
- // External hooks
4404
- /**
4405
- * Handles the click behavior for router `<Link>` components. This is useful if
4406
- * you need to create custom `<Link>` components with the same click behavior we
4407
- * use in our exported `<Link>`.
4408
- */
4409
- function useLinkClickHandler(to, _temp) {
4410
- let {
4411
- target,
4412
- replace: replaceProp,
4413
- state,
4414
- preventScrollReset,
4415
- relative,
4416
- viewTransition
4417
- } = _temp === void 0 ? {} : _temp;
4418
- let navigate = useNavigate();
4419
- let location = useLocation();
4420
- let path = useResolvedPath(to, {
4421
- relative
4422
- });
4423
- return React.useCallback(event => {
4424
- if (shouldProcessLinkClick(event, target)) {
4425
- event.preventDefault();
4426
- // If the URL hasn't changed, a regular <a> will do a replace instead of
4427
- // a push, so do the same here unless the replace prop is explicitly set
4428
- let replace = replaceProp !== undefined ? replaceProp : createPath(location) === createPath(path);
4429
- navigate(to, {
4430
- replace,
4431
- state,
4432
- preventScrollReset,
4433
- relative,
4434
- viewTransition
4435
- });
4436
- }
4437
- }, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, viewTransition]);
4438
- }
4439
- /**
4440
- * A convenient wrapper for reading and writing search parameters via the
4441
- * URLSearchParams interface.
4442
- */
4443
- function useSearchParams(defaultInit) {
4444
- process.env.NODE_ENV !== "production" ? warning(typeof URLSearchParams !== "undefined", "You cannot use the `useSearchParams` hook in a browser that does not " + "support the URLSearchParams API. If you need to support Internet " + "Explorer 11, we recommend you load a polyfill such as " + "https://github.com/ungap/url-search-params.") : void 0;
4445
- let defaultSearchParamsRef = React.useRef(createSearchParams(defaultInit));
4446
- let hasSetSearchParamsRef = React.useRef(false);
4447
- let location = useLocation();
4448
- let searchParams = React.useMemo(() =>
4449
- // Only merge in the defaults if we haven't yet called setSearchParams.
4450
- // Once we call that we want those to take precedence, otherwise you can't
4451
- // remove a param with setSearchParams({}) if it has an initial value
4452
- getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current), [location.search]);
4453
- let navigate = useNavigate();
4454
- let setSearchParams = React.useCallback((nextInit, navigateOptions) => {
4455
- const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(searchParams) : nextInit);
4456
- hasSetSearchParamsRef.current = true;
4457
- navigate("?" + newSearchParams, navigateOptions);
4458
- }, [navigate, searchParams]);
4459
- return [searchParams, setSearchParams];
4460
- }
4461
- function validateClientSideSubmission() {
4462
- if (typeof document === "undefined") {
4463
- throw new Error("You are calling submit during the server render. " + "Try calling submit within a `useEffect` or callback instead.");
4464
- }
4465
- }
4466
- let fetcherId = 0;
4467
- let getUniqueFetcherId = () => "__" + String(++fetcherId) + "__";
4468
- /**
4469
- * Returns a function that may be used to programmatically submit a form (or
4470
- * some arbitrary data) to the server.
4471
- */
4472
- function useSubmit() {
4473
- let {
4474
- router
4475
- } = useDataRouterContext(DataRouterHook.UseSubmit);
4476
- let {
4477
- basename
4478
- } = React.useContext(NavigationContext);
4479
- let currentRouteId = useRouteId();
4480
- return React.useCallback(function (target, options) {
4481
- if (options === void 0) {
4482
- options = {};
4483
- }
4484
- validateClientSideSubmission();
4485
- let {
4486
- action,
4487
- method,
4488
- encType,
4489
- formData,
4490
- body
4491
- } = getFormSubmissionInfo(target, basename);
4492
- if (options.navigate === false) {
4493
- let key = options.fetcherKey || getUniqueFetcherId();
4494
- router.fetch(key, currentRouteId, options.action || action, {
4495
- preventScrollReset: options.preventScrollReset,
4496
- formData,
4497
- body,
4498
- formMethod: options.method || method,
4499
- formEncType: options.encType || encType,
4500
- flushSync: options.flushSync
4501
- });
4502
- } else {
4503
- router.navigate(options.action || action, {
4504
- preventScrollReset: options.preventScrollReset,
4505
- formData,
4506
- body,
4507
- formMethod: options.method || method,
4508
- formEncType: options.encType || encType,
4509
- replace: options.replace,
4510
- state: options.state,
4511
- fromRouteId: currentRouteId,
4512
- flushSync: options.flushSync,
4513
- viewTransition: options.viewTransition
4514
- });
4515
- }
4516
- }, [router, basename, currentRouteId]);
4517
- }
4518
- // v7: Eventually we should deprecate this entirely in favor of using the
4519
- // router method directly?
4520
- function useFormAction(action, _temp2) {
4521
- let {
4522
- relative
4523
- } = _temp2 === void 0 ? {} : _temp2;
4524
- let {
4525
- basename
4526
- } = React.useContext(NavigationContext);
4527
- let routeContext = React.useContext(RouteContext);
4528
- !routeContext ? process.env.NODE_ENV !== "production" ? invariant(false, "useFormAction must be used inside a RouteContext") : invariant(false) : void 0;
4529
- let [match] = routeContext.matches.slice(-1);
4530
- // Shallow clone path so we can modify it below, otherwise we modify the
4531
- // object referenced by useMemo inside useResolvedPath
4532
- let path = _extends({}, useResolvedPath(action ? action : ".", {
4533
- relative
4534
- }));
4535
- // If no action was specified, browsers will persist current search params
4536
- // when determining the path, so match that behavior
4537
- // https://github.com/remix-run/remix/issues/927
4538
- let location = useLocation();
4539
- if (action == null) {
4540
- // Safe to write to this directly here since if action was undefined, we
4541
- // would have called useResolvedPath(".") which will never include a search
4542
- path.search = location.search;
4543
- // When grabbing search params from the URL, remove any included ?index param
4544
- // since it might not apply to our contextual route. We add it back based
4545
- // on match.route.index below
4546
- let params = new URLSearchParams(path.search);
4547
- let indexValues = params.getAll("index");
4548
- let hasNakedIndexParam = indexValues.some(v => v === "");
4549
- if (hasNakedIndexParam) {
4550
- params.delete("index");
4551
- indexValues.filter(v => v).forEach(v => params.append("index", v));
4552
- let qs = params.toString();
4553
- path.search = qs ? "?" + qs : "";
4554
- }
4555
- }
4556
- if ((!action || action === ".") && match.route.index) {
4557
- path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
4558
- }
4559
- // If we're operating within a basename, prepend it to the pathname prior
4560
- // to creating the form action. If this is a root navigation, then just use
4561
- // the raw basename which allows the basename to have full control over the
4562
- // presence of a trailing slash on root actions
4563
- if (basename !== "/") {
4564
- path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
4565
- }
4566
- return createPath(path);
4567
- }
4568
- /**
4569
- * Return a boolean indicating if there is an active view transition to the
4570
- * given href. You can use this value to render CSS classes or viewTransitionName
4571
- * styles onto your elements
4572
- *
4573
- * @param href The destination href
4574
- * @param [opts.relative] Relative routing type ("route" | "path")
4575
- */
4576
- function useViewTransitionState(to, opts) {
4577
- if (opts === void 0) {
4578
- opts = {};
4579
- }
4580
- let vtContext = React.useContext(ViewTransitionContext);
4581
- !(vtContext != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. " + "Did you accidentally import `RouterProvider` from `react-router`?") : invariant(false) : void 0;
4582
- let {
4583
- basename
4584
- } = useDataRouterContext(DataRouterHook.useViewTransitionState);
4585
- let path = useResolvedPath(to, {
4586
- relative: opts.relative
4587
- });
4588
- if (!vtContext.isTransitioning) {
4589
- return false;
4590
- }
4591
- let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
4592
- let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
4593
- // Transition is active if we're going to or coming from the indicated
4594
- // destination. This ensures that other PUSH navigations that reverse
4595
- // an indicated transition apply. I.e., on the list view you have:
4596
- //
4597
- // <NavLink to="/details/1" viewTransition>
4598
- //
4599
- // If you click the breadcrumb back to the list view:
4600
- //
4601
- // <NavLink to="/list" viewTransition>
4602
- //
4603
- // We should apply the transition because it's indicated as active going
4604
- // from /list -> /details/1 and therefore should be active on the reverse
4605
- // (even though this isn't strictly a POP reverse)
4606
- return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
4607
- }
4608
-
4609
3243
  const usePathAnalysisFunnel = ({ pathAnalytics, pathAnalysisCacheKey, dataFirstLevels, }) => {
4610
3244
  const [searchParams] = useSearchParams();
4611
3245
  const setFirstLevelLocationPath = usePathAnalysisStore((state) => state.setFirstLevelLocationPath);
@@ -4916,7 +3550,7 @@ const usePathAnalysisChart = () => {
4916
3550
  return [
4917
3551
  {
4918
3552
  value: Number(totalAddedToCart ?? 0),
4919
- key: METRICS_COLUMNS[IPAMetricKey.PAGE_ADDED_TO_CART].label,
3553
+ key: METRICS_COLUMNS[IPAMetricKey.PAGE_ADDED_TO_CART]?.label ?? t('Added to cart'),
4920
3554
  labelTooltip: PA_METRIC_TOOLTIP[IPAMetricKey.PAGE_CART_ADDITION],
4921
3555
  },
4922
3556
  {