diff --git a/packages/pl-api/lib/client.ts b/packages/pl-api/lib/client.ts
index 47b40adbf..0ad6a52d4 100644
--- a/packages/pl-api/lib/client.ts
+++ b/packages/pl-api/lib/client.ts
@@ -4398,7 +4398,7 @@ class PlApiClient {
resolveReport: async (reportId: string, action_taken_comment?: string) => {
let response;
if (this.features.mastodonAdmin) {
- response = await this.request(`/api/v1/admin/reports/${reportId}/resolve`, { method: 'POST', body: { action_taken_comment } });
+ response = await this.request(`/api/v1/admin/reports/${reportId}/resolve`, { method: 'POST', body: { action_taken_comment } });
} else {
response = await this.request(`/api/v1/pleroma/admin/reports/${reportId}`, {
method: 'PATCH',
diff --git a/packages/pl-fe/package.json b/packages/pl-fe/package.json
index 1380564fd..94c8f3a97 100644
--- a/packages/pl-fe/package.json
+++ b/packages/pl-fe/package.json
@@ -123,7 +123,6 @@
"react-intl": "^7.0.4",
"react-motion": "^0.5.2",
"react-redux": "^9.0.4",
- "react-router-dom": "^5.3.4",
"react-sparklines": "^1.7.0",
"react-sticky-box": "^2.0.5",
"react-swipeable-views": "^0.14.0",
diff --git a/packages/pl-fe/src/actions/compose.ts b/packages/pl-fe/src/actions/compose.ts
index 12698cbb7..31f488243 100644
--- a/packages/pl-fe/src/actions/compose.ts
+++ b/packages/pl-fe/src/actions/compose.ts
@@ -18,6 +18,7 @@ import { uploadFile, updateMedia } from './media';
import { saveSettings } from './settings';
import { createStatus } from './statuses';
+import type { LinkOptions } from '@tanstack/react-router';
import type { EditorState } from 'lexical';
import type { Account, CreateStatusParams, CustomEmoji, Group, MediaAttachment, Status as BaseStatus, Tag, Poll, ScheduledStatus, InteractionPolicy, UpdateMediaParams } from 'pl-api';
import type { AutoSuggestion } from 'pl-fe/components/autosuggest-input';
@@ -306,14 +307,17 @@ const handleComposeSubmit = (dispatch: AppDispatch, getState: () => RootState, c
}
if (data.scheduled_at === null) {
+ const linkOptions: LinkOptions = (data.visibility === 'direct' && getClient(getState()).features.conversations)
+ ? { to: '/conversations' }
+ : { to: '/@{$username}/posts/$statusId', params: { username: data.account.acct, statusId: data.id } };
toast.success(redact ? messages.redactSuccess : edit ? messages.editSuccess : messages.success, {
actionLabel: messages.view,
- actionLink: (data.visibility === 'direct' && getClient(getState()).features.conversations) ? '/conversations' : `/@${data.account.acct}/posts/${data.id}`,
+ actionLinkOptions: linkOptions,
});
} else {
toast.success(messages.scheduledSuccess, {
actionLabel: messages.view,
- actionLink: '/scheduled_statuses',
+ actionLinkOptions: { to: '/scheduled_statuses' },
});
}
};
diff --git a/packages/pl-fe/src/actions/events.ts b/packages/pl-fe/src/actions/events.ts
index 65e2ed8f9..fe8c531fe 100644
--- a/packages/pl-fe/src/actions/events.ts
+++ b/packages/pl-fe/src/actions/events.ts
@@ -76,7 +76,10 @@ const submitEvent = ({
statusId ? messages.editSuccess : messages.success,
{
actionLabel: messages.view,
- actionLink: `/@${data.account.acct}/events/${data.id}`,
+ actionLinkOptions: {
+ to: '/@{$username}/events/$statusId',
+ params: { username: data.account.acct, statusId: data.id },
+ },
},
);
diff --git a/packages/pl-fe/src/components/account.tsx b/packages/pl-fe/src/components/account.tsx
index 4e2121475..607a3f076 100644
--- a/packages/pl-fe/src/components/account.tsx
+++ b/packages/pl-fe/src/components/account.tsx
@@ -220,7 +220,8 @@ const Account = ({
const LinkEl: any = withLinkToProfile ? Link : 'div';
const linkProps = withLinkToProfile ? {
- to: `/@${account.acct}`,
+ to: '/@{$username}',
+ params: { username: account.acct },
title: account.acct,
onClick: (event: React.MouseEvent) => event.stopPropagation(),
} : {};
diff --git a/packages/pl-fe/src/components/ui/toast.tsx b/packages/pl-fe/src/components/ui/toast.tsx
index dd5a1e77f..381cf8379 100644
--- a/packages/pl-fe/src/components/ui/toast.tsx
+++ b/packages/pl-fe/src/components/ui/toast.tsx
@@ -1,4 +1,4 @@
-import { Link } from '@tanstack/react-router';
+import { Link, type LinkOptions } from '@tanstack/react-router';
import clsx from 'clsx';
import React from 'react';
import toast, { Toast as RHToast } from 'react-hot-toast';
@@ -24,7 +24,7 @@ interface IToast {
message: ToastText;
type: ToastType;
action?(): void;
- actionLink?: string;
+ actionLinkOptions?: LinkOptions;
actionLabel?: ToastText;
summary?: string;
}
@@ -33,7 +33,7 @@ interface IToast {
* Customizable Toasts for in-app notifications.
*/
const Toast = (props: IToast) => {
- const { t, message, type, action, actionLink, actionLabel, summary } = props;
+ const { t, message, type, action, actionLinkOptions, actionLabel, summary } = props;
const dismissToast = () => toast.dismiss(t.id);
@@ -85,10 +85,10 @@ const Toast = (props: IToast) => {
);
}
- if (actionLink && actionLabel) {
+ if (actionLinkOptions && actionLabel) {
return (
({ id, shouldCondense, autoFocus, clickab
toast.success(messages.draftSaved, {
actionLabel: messages.view,
- actionLink: '/draft_statuses',
+ actionLinkOptions: { to: '/draft_statuses' },
});
};
diff --git a/packages/pl-fe/src/features/ui/index.tsx b/packages/pl-fe/src/features/ui/index.tsx
index f59f68947..8c8ca036b 100644
--- a/packages/pl-fe/src/features/ui/index.tsx
+++ b/packages/pl-fe/src/features/ui/index.tsx
@@ -2,7 +2,6 @@ import { Outlet, useNavigate } from '@tanstack/react-router';
import clsx from 'clsx';
import React, { Suspense, useEffect, useRef } from 'react';
import { Toaster } from 'react-hot-toast';
-import { Redirect, Switch, useLocation } from 'react-router-dom';
import { fetchConfig } from 'pl-fe/actions/admin';
import { fetchFilters } from 'pl-fe/actions/filters';
@@ -21,8 +20,6 @@ import { useDraggedFiles } from 'pl-fe/hooks/use-dragged-files';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { useInstance } from 'pl-fe/hooks/use-instance';
import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
-import DefaultLayout from 'pl-fe/layouts/default-layout';
-import EmptyLayout from 'pl-fe/layouts/empty-layout';
import { prefetchFollowRequests } from 'pl-fe/queries/accounts/use-follow-requests';
import { queryClient } from 'pl-fe/queries/client';
import { prefetchCustomEmojis } from 'pl-fe/queries/instance/use-custom-emojis';
@@ -39,81 +36,14 @@ import {
AccountHoverCard,
ChatWidget,
DropdownNavigation,
- GenericNotFound,
- Status,
StatusHoverCard,
} from './util/async-components';
import GlobalHotkeys from './util/global-hotkeys';
-import { WrappedRoute } from './util/react-router-helpers';
// Dummy import, to make sure that ends up in the application bundle.
// Without this it ends up in ~8 very commonly used bundles.
import 'pl-fe/components/status';
-interface ISwitchingColumnsArea {
- children: React.ReactNode;
-}
-
-const SwitchingColumnsArea: React.FC = React.memo(({ children }) => {
- const { search } = useLocation();
-
- // NOTE: Mastodon and Pleroma route some basenames to the backend.
- // When adding new routes, use a basename that does NOT conflict
- // with a known backend route, but DO redirect the backend route
- // to the corresponding component as a fallback.
- // Ex: use /login instead of /auth, but redirect /auth to /login
- return (
-
- {/* Mastodon web routes */}
-
-
-
-
-
-
-
-
- {/* Pleroma FE web routes */}
-
-
-
-
-
-
-
-
-
-
-
- {/* Iceshrimp.NET web routes */}
-
-
- {/* Mastodon rendered pages */}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* Pleroma hard-coded email URLs */}
-
-
-
-
-
-
- );
-});
-
-SwitchingColumnsArea.displayName = '_';
-
const UI: React.FC = React.memo(() => {
const navigate = useNavigate();
const dispatch = useAppDispatch();
diff --git a/packages/pl-fe/src/features/ui/components/error-column.tsx b/packages/pl-fe/src/features/ui/router/error-column.tsx
similarity index 88%
rename from packages/pl-fe/src/features/ui/components/error-column.tsx
rename to packages/pl-fe/src/features/ui/router/error-column.tsx
index 718df0439..36595b7a7 100644
--- a/packages/pl-fe/src/features/ui/components/error-column.tsx
+++ b/packages/pl-fe/src/features/ui/router/error-column.tsx
@@ -7,22 +7,19 @@ import Stack from 'pl-fe/components/ui/stack';
import Text from 'pl-fe/components/ui/text';
import { isNetworkError } from 'pl-fe/utils/errors';
+import type { ErrorRouteComponent } from '@tanstack/react-router';
+
const messages = defineMessages({
title: { id: 'bundle_column_error.title', defaultMessage: 'Network error' },
body: { id: 'bundle_column_error.body', defaultMessage: 'Something went wrong while loading this page.' },
retry: { id: 'bundle_column_error.retry', defaultMessage: 'Try again' },
});
-interface IErrorColumn {
- error: Error;
- onRetry?: () => void;
-}
-
-const ErrorColumn: React.FC = ({ error, onRetry = () => location.reload() }) => {
+const ErrorColumn: ErrorRouteComponent = ({ error, reset }) => {
const intl = useIntl();
const handleRetry = () => {
- onRetry?.();
+ reset();
};
if (!isNetworkError(error)) {
diff --git a/packages/pl-fe/src/features/ui/router.tsx b/packages/pl-fe/src/features/ui/router/index.tsx
similarity index 87%
rename from packages/pl-fe/src/features/ui/router.tsx
rename to packages/pl-fe/src/features/ui/router/index.tsx
index 9298d98ae..3ee5e997b 100644
--- a/packages/pl-fe/src/features/ui/router.tsx
+++ b/packages/pl-fe/src/features/ui/router/index.tsx
@@ -38,12 +38,11 @@ import StatusLayout from 'pl-fe/layouts/status-layout';
import { instanceInitialState } from 'pl-fe/reducers/instance';
import { isStandalone } from 'pl-fe/utils/state';
-import ChatPageMain from '../chats/components/chat-page/components/chat-page-main';
-import ChatPageNew from '../chats/components/chat-page/components/chat-page-new';
-import ChatPageSettings from '../chats/components/chat-page/components/chat-page-settings';
-import ChatPageShoutbox from '../chats/components/chat-page/components/chat-page-shoutbox';
-
-import ColumnLoading from './components/column-loading';
+import ChatPageMain from '../../chats/components/chat-page/components/chat-page-main';
+import ChatPageNew from '../../chats/components/chat-page/components/chat-page-new';
+import ChatPageSettings from '../../chats/components/chat-page/components/chat-page-settings';
+import ChatPageShoutbox from '../../chats/components/chat-page/components/chat-page-shoutbox';
+import ColumnLoading from '../components/column-loading';
import {
AboutPage,
AccountGallery,
@@ -146,7 +145,9 @@ import {
EditEvent,
Reports,
AwaitingApproval,
-} from './util/async-components';
+} from '../util/async-components';
+
+import ErrorColumn from './error-column';
import type { Features } from 'pl-api';
@@ -1184,6 +1185,82 @@ export const federationRestrictionsRoute = createRoute({
},
});
+// Redirect routes
+const redirectTagRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/tag/$id',
+ component: () => {
+ const { id } = redirectTagRoute.useParams();
+ return ;
+ },
+});
+const redirectNoticeStatusRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/notice/$statusId',
+ component: () => {
+ const { statusId } = redirectNoticeStatusRoute.useParams();
+ return ;
+ },
+});
+const redirectPleromaStatusRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/users/@{$username}/statuses/$statusId',
+ component: () => {
+ const { username, statusId } = redirectPleromaStatusRoute.useParams();
+ return ;
+ },
+});
+const redirectPleromaUsernameRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/users/@{$username}',
+ component: () => {
+ const { username } = redirectPleromaUsernameRoute.useParams();
+ return ;
+ },
+});
+const redirectIceshrimpStatusRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/notes/$statusId',
+ component: () => {
+ const { statusId } = redirectIceshrimpStatusRoute.useParams();
+ return ;
+ },
+});
+const redirectInviteRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/registration/$token',
+ component: () => {
+ const { token } = redirectInviteRoute.useParams();
+ return ;
+ },
+});
+const redirectRoutes = [
+ createRoute({ getParentRoute: () => rootRoute, path: '/timelines/home', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/timelines/public/local', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/timelines/public', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/timelines/direct', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/main/all', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/main/public', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/main/friends', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/user-settings', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/registration', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/admin', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/terms', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/settings/preferences', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/settings/two_factor_authentication_methods', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/settings/applications', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/auth/edit', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/auth/reset_password', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/auth/sign_in', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/auth/sign_out', component: () => }),
+ createRoute({ getParentRoute: () => rootRoute, path: '/auth/password/new', component: () => }),
+ redirectTagRoute,
+ redirectNoticeStatusRoute,
+ redirectPleromaStatusRoute,
+ redirectPleromaUsernameRoute,
+ redirectIceshrimpStatusRoute,
+];
+
const routeTree = rootRoute.addChildren([
layouts.admin.addChildren([
adminDashboardRoute,
@@ -1314,6 +1391,7 @@ const routeTree = rootRoute.addChildren([
statusRoute,
statusQuotesRoute,
]),
+ ...redirectRoutes,
]);
const FallbackLayout: React.FC<{ children: JSX.Element }> = ({ children }) => (
@@ -1344,6 +1422,7 @@ const router = createRouter({
},
defaultNotFoundComponent: GenericNotFound,
defaultPendingComponent: PendingComponent,
+ defaultErrorComponent: ErrorColumn,
scrollRestoration: true,
pathParamsAllowedCharacters: ['@'],
});
diff --git a/packages/pl-fe/src/features/ui/util/react-router-helpers.tsx b/packages/pl-fe/src/features/ui/util/react-router-helpers.tsx
deleted file mode 100644
index 2aedca14b..000000000
--- a/packages/pl-fe/src/features/ui/util/react-router-helpers.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import { Outlet } from '@tanstack/react-router';
-import React, { Suspense, useEffect, useRef } from 'react';
-import { ErrorBoundary, type FallbackProps } from 'react-error-boundary';
-import { Redirect, Route, useHistory, RouteProps, RouteComponentProps, match as MatchType, useLocation } from 'react-router-dom';
-
-import Layout from 'pl-fe/components/ui/layout';
-import { useOwnAccount } from 'pl-fe/hooks/use-own-account';
-
-import ColumnForbidden from '../components/column-forbidden';
-import ColumnLoading from '../components/column-loading';
-import ErrorColumn from '../components/error-column';
-
-type LayoutProps = {
- params?: MatchType['params'];
- children: React.ReactNode;
-};
-
-interface IWrappedRoute extends RouteProps {
- component: React.ExoticComponent;
- layout: React.ComponentType;
- content?: React.ReactNode;
- componentParams?: Record;
- publicRoute?: boolean;
- staffOnly?: boolean;
- adminOnly?: boolean;
-}
-
-const WrappedRoute: React.FC = ({
- component: Component,
- layout: Layout,
- content,
- componentParams = {},
- publicRoute = false,
- staffOnly = false,
- adminOnly = false,
- ...rest
-}) => {
- const history = useHistory();
-
- const { account } = useOwnAccount();
-
- const renderComponent = ({ match }: RouteComponentProps) => (
-
- }>
-
-
- {content}
-
-
-
-
- );
-
- const loginRedirect = () => {
- const actualUrl = encodeURIComponent(`${history.location.pathname}${history.location.search}`);
- localStorage.setItem('plfe:redirect_uri', actualUrl);
- return ;
- };
-
- const authorized = [
- account || publicRoute,
- staffOnly ? account && (account.is_admin || account.is_moderator) : true,
- adminOnly ? account && account.is_admin : true,
- ].every(c => c);
-
- if (!authorized) {
- if (!account) {
- return loginRedirect();
- } else {
- return ;
- }
- }
-
- return ;
-};
-
-interface IFallbackLayout {
- children: JSX.Element;
-}
-
-const FallbackLayout: React.FC = () => (
- <>
-
-
-
-
-
- >
-);
-
-const FallbackLoading: React.FC = () => (
-
-
-
-);
-
-const FallbackForbidden: React.FC = () => (
-
-
-
-);
-
-const FallbackError: React.FC = ({ error, resetErrorBoundary }) => {
- const location = useLocation();
- const firstUpdate = useRef(true);
-
- useEffect(() => {
- if (firstUpdate.current) {
- firstUpdate.current = false;
- } else {
- resetErrorBoundary();
- }
- }, [location]);
-
- return (
-
-
-
- );
-};
-
-export {
- WrappedRoute,
-};
diff --git a/packages/pl-fe/src/pages/statuses/status.tsx b/packages/pl-fe/src/pages/statuses/status.tsx
index a1dc29fe5..718920e96 100644
--- a/packages/pl-fe/src/pages/statuses/status.tsx
+++ b/packages/pl-fe/src/pages/statuses/status.tsx
@@ -37,7 +37,7 @@ const messages = defineMessages({
});
const StatusPage: React.FC = () => {
- const { statusId } = statusRoute.useParams();
+ const { username, statusId } = statusRoute.useParams();
const dispatch = useAppDispatch();
const intl = useIntl();
@@ -102,6 +102,12 @@ const StatusPage: React.FC = () => {
);
}
+ if (username && status && username !== status.account.acct) {
+ return (
+
+ );
+ }
+
if (!status && isLoaded) {
return (
diff --git a/packages/pl-fe/src/queries/statuses/use-event-interactions.ts b/packages/pl-fe/src/queries/statuses/use-event-interactions.ts
index b242d8cc8..d88230d34 100644
--- a/packages/pl-fe/src/queries/statuses/use-event-interactions.ts
+++ b/packages/pl-fe/src/queries/statuses/use-event-interactions.ts
@@ -42,7 +42,10 @@ const useJoinEventMutation = (statusId: string, withToast = true) => {
status.event?.join_state === 'pending' ? messages.joinRequestSuccess : messages.joinSuccess,
{
actionLabel: messages.view,
- actionLink: `/@${status.account.acct}/events/${status.id}`,
+ actionLinkOptions: {
+ to: '/@{$username}/events/$statusId',
+ params: { username: status.account.acct, statusId: status.id },
+ },
},
);
}
diff --git a/packages/pl-fe/src/queries/statuses/use-status-interactions.ts b/packages/pl-fe/src/queries/statuses/use-status-interactions.ts
index 7f19b5448..b73291677 100644
--- a/packages/pl-fe/src/queries/statuses/use-status-interactions.ts
+++ b/packages/pl-fe/src/queries/statuses/use-status-interactions.ts
@@ -197,7 +197,10 @@ const useBookmarkStatus = (statusId: string) => {
let opts: IToastOptions = {
actionLabel: messages.view,
- actionLink: folderId ? `/bookmarks/${folderId}` : '/bookmarks/all',
+ actionLinkOptions: {
+ to: '/bookmarks/$folderId',
+ params: { folderId: folderId || 'all' },
+ },
};
if (features.bookmarkFolders && typeof folderId !== 'string') {
diff --git a/packages/pl-fe/src/toast.tsx b/packages/pl-fe/src/toast.tsx
index 9a753ac33..744c6035b 100644
--- a/packages/pl-fe/src/toast.tsx
+++ b/packages/pl-fe/src/toast.tsx
@@ -6,13 +6,14 @@ import Toast from './components/ui/toast';
import { httpErrorMessages } from './utils/errors';
import type { PlfeResponse } from './api';
+import type { LinkOptions } from '@tanstack/react-router';
type ToastText = string | MessageDescriptor
type ToastType = 'success' | 'error' | 'info'
interface IToastOptions {
action?(): void;
- actionLink?: string;
+ actionLinkOptions?: LinkOptions;
actionLabel?: ToastText;
duration?: number;
summary?: string;
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5b3ef8a57..7735afe58 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -370,9 +370,6 @@ importers:
react-redux:
specifier: ^9.0.4
version: 9.2.0(@types/react@18.3.23)(react@18.3.1)(redux@5.0.1)
- react-router-dom:
- specifier: ^5.3.4
- version: 5.3.4(react@18.3.1)
react-sparklines:
specifier: ^1.7.0
version: 1.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -4253,9 +4250,6 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
- history@4.10.1:
- resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
-
hoist-non-react-statics@3.3.2:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
@@ -4537,9 +4531,6 @@ packages:
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
engines: {node: '>= 0.4'}
- isarray@0.0.1:
- resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
-
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@@ -5147,9 +5138,6 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
- path-to-regexp@1.9.0:
- resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==}
-
path-type@4.0.0:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
@@ -5597,16 +5585,6 @@ packages:
resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
engines: {node: '>=0.10.0'}
- react-router-dom@5.3.4:
- resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==}
- peerDependencies:
- react: '>=15'
-
- react-router@5.3.4:
- resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==}
- peerDependencies:
- react: '>=15'
-
react-sparklines@1.7.0:
resolution: {integrity: sha512-bJFt9K4c5Z0k44G8KtxIhbG+iyxrKjBZhdW6afP+R7EnIq+iKjbWbEFISrf3WKNFsda+C46XAfnX0StS5fbDcg==}
peerDependencies:
@@ -5724,9 +5702,6 @@ packages:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
- resolve-pathname@3.0.0:
- resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
-
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
@@ -6615,9 +6590,6 @@ packages:
typescript:
optional: true
- value-equal@1.0.1:
- resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==}
-
varint@6.0.0:
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
@@ -11304,15 +11276,6 @@ snapshots:
he@1.2.0: {}
- history@4.10.1:
- dependencies:
- '@babel/runtime': 7.28.2
- loose-envify: 1.4.0
- resolve-pathname: 3.0.0
- tiny-invariant: 1.3.3
- tiny-warning: 1.0.3
- value-equal: 1.0.1
-
hoist-non-react-statics@3.3.2:
dependencies:
react-is: 16.13.1
@@ -11582,8 +11545,6 @@ snapshots:
call-bound: 1.0.4
get-intrinsic: 1.3.0
- isarray@0.0.1: {}
-
isarray@2.0.5: {}
isbot@5.1.32: {}
@@ -12204,10 +12165,6 @@ snapshots:
lru-cache: 10.4.3
minipass: 7.1.2
- path-to-regexp@1.9.0:
- dependencies:
- isarray: 0.0.1
-
path-type@4.0.0: {}
pathe@0.2.0: {}
@@ -12616,30 +12573,6 @@ snapshots:
react-refresh@0.17.0: {}
- react-router-dom@5.3.4(react@18.3.1):
- dependencies:
- '@babel/runtime': 7.28.2
- history: 4.10.1
- loose-envify: 1.4.0
- prop-types: 15.8.1
- react: 18.3.1
- react-router: 5.3.4(react@18.3.1)
- tiny-invariant: 1.3.3
- tiny-warning: 1.0.3
-
- react-router@5.3.4(react@18.3.1):
- dependencies:
- '@babel/runtime': 7.28.2
- history: 4.10.1
- hoist-non-react-statics: 3.3.2
- loose-envify: 1.4.0
- path-to-regexp: 1.9.0
- prop-types: 15.8.1
- react: 18.3.1
- react-is: 16.13.1
- tiny-invariant: 1.3.3
- tiny-warning: 1.0.3
-
react-sparklines@1.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies:
prop-types: 15.8.1
@@ -12769,8 +12702,6 @@ snapshots:
resolve-from@5.0.0: {}
- resolve-pathname@3.0.0: {}
-
resolve-pkg-maps@1.0.0: {}
resolve@1.22.10:
@@ -13751,8 +13682,6 @@ snapshots:
optionalDependencies:
typescript: 5.9.2
- value-equal@1.0.1: {}
-
varint@6.0.0: {}
vite-node@2.1.9(@types/node@22.17.0)(sass-embedded@1.93.3)(sass@1.93.3)(terser@5.44.0):