+6
-4
apps/web/package.json
+6
-4
apps/web/package.json
···
27
27
"@radix-ui/react-dialog": "^1.1.4",
28
28
"@radix-ui/react-dropdown-menu": "^2.1.4",
29
29
"@radix-ui/react-icons": "^1.3.2",
30
-
"@radix-ui/react-label": "^2.1.0",
31
-
"@radix-ui/react-separator": "^1.1.0",
32
-
"@radix-ui/react-slot": "^1.1.0",
30
+
"@radix-ui/react-label": "^2.1.8",
31
+
"@radix-ui/react-separator": "^1.1.8",
32
+
"@radix-ui/react-slot": "^1.2.4",
33
33
"@radix-ui/react-tooltip": "^1.1.4",
34
34
"@tanstack/react-query": "^5.62.2",
35
35
"@tanstack/react-query-devtools": "^5.62.2",
···
54
54
"@types/node": "^22.10.1",
55
55
"@types/react": "^19.0.0",
56
56
"@types/react-dom": "^19.0.0",
57
+
"@vitejs/plugin-react": "^5.1.1",
57
58
"@vitejs/plugin-react-swc": "^3.5.0",
58
59
"autoprefixer": "^10.4.20",
60
+
"babel-plugin-react-compiler": "^1.0.0",
59
61
"cssnano": "^7.0.6",
60
62
"eslint": "^9.15.0",
61
63
"eslint-plugin-react-hooks": "^5.0.0",
···
66
68
"tailwindcss": "^3.4.16",
67
69
"typescript": "~5.6.2",
68
70
"typescript-eslint": "^8.15.0",
69
-
"vite": "^6.0.1"
71
+
"vite": "^7.2.4"
70
72
}
71
73
}
+3
-3
apps/web/src/components/query-placeholder.tsx
+3
-3
apps/web/src/components/query-placeholder.tsx
···
3
3
import { Skeleton } from './ui/skeleton';
4
4
import { Alert, AlertDescription, AlertTitle } from './ui/alert';
5
5
import { AlertCircle } from 'lucide-react';
6
-
import { XRPCError } from '@atcute/client';
6
+
import { isXRPCErrorPayload } from '@atcute/client';
7
7
8
8
type QueryPlaceholderProps<TData, TError> = PropsWithChildren<{
9
9
query: UseQueryResult<TData, TError>;
···
32
32
} else if (query.isError) {
33
33
const { error } = query;
34
34
let errMsg = 'Unknown';
35
-
if (error instanceof XRPCError) {
36
-
errMsg = error.kind ?? `HTTP_${error.status}`;
35
+
if (isXRPCErrorPayload(error)) {
36
+
errMsg = error.message ?? `XRPC_${error.error}`;
37
37
} if (error instanceof Error) {
38
38
errMsg = `${error.message} (${error.name})`;
39
39
}
+242
apps/web/src/components/ui/field.tsx
+242
apps/web/src/components/ui/field.tsx
···
1
+
import { useMemo } from "react"
2
+
import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+
import { cn } from "@/lib/utils"
5
+
import { Label } from "@/components/ui/label"
6
+
import { Separator } from "@/components/ui/separator"
7
+
8
+
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
9
+
return (
10
+
<fieldset
11
+
data-slot="field-set"
12
+
className={cn(
13
+
"flex flex-col gap-6",
14
+
"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
15
+
className
16
+
)}
17
+
{...props}
18
+
/>
19
+
)
20
+
}
21
+
22
+
function FieldLegend({
23
+
className,
24
+
variant = "legend",
25
+
...props
26
+
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
27
+
return (
28
+
<legend
29
+
data-slot="field-legend"
30
+
data-variant={variant}
31
+
className={cn(
32
+
"mb-3 font-medium",
33
+
"data-[variant=legend]:text-base",
34
+
"data-[variant=label]:text-sm",
35
+
className
36
+
)}
37
+
{...props}
38
+
/>
39
+
)
40
+
}
41
+
42
+
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
43
+
return (
44
+
<div
45
+
data-slot="field-group"
46
+
className={cn(
47
+
"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
48
+
className
49
+
)}
50
+
{...props}
51
+
/>
52
+
)
53
+
}
54
+
55
+
const fieldVariants = cva(
56
+
"group/field data-[invalid=true]:text-destructive flex w-full gap-3",
57
+
{
58
+
variants: {
59
+
orientation: {
60
+
vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
61
+
horizontal: [
62
+
"flex-row items-center",
63
+
"[&>[data-slot=field-label]]:flex-auto",
64
+
"has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px has-[>[data-slot=field-content]]:items-start",
65
+
],
66
+
responsive: [
67
+
"@md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto flex-col [&>*]:w-full [&>.sr-only]:w-auto",
68
+
"@md/field-group:[&>[data-slot=field-label]]:flex-auto",
69
+
"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
70
+
],
71
+
},
72
+
},
73
+
defaultVariants: {
74
+
orientation: "vertical",
75
+
},
76
+
}
77
+
)
78
+
79
+
function Field({
80
+
className,
81
+
orientation = "vertical",
82
+
...props
83
+
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
84
+
return (
85
+
<div
86
+
role="group"
87
+
data-slot="field"
88
+
data-orientation={orientation}
89
+
className={cn(fieldVariants({ orientation }), className)}
90
+
{...props}
91
+
/>
92
+
)
93
+
}
94
+
95
+
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
96
+
return (
97
+
<div
98
+
data-slot="field-content"
99
+
className={cn(
100
+
"group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
101
+
className
102
+
)}
103
+
{...props}
104
+
/>
105
+
)
106
+
}
107
+
108
+
function FieldLabel({
109
+
className,
110
+
...props
111
+
}: React.ComponentProps<typeof Label>) {
112
+
return (
113
+
<Label
114
+
data-slot="field-label"
115
+
className={cn(
116
+
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
117
+
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>[data-slot=field]]:p-4",
118
+
"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
119
+
className
120
+
)}
121
+
{...props}
122
+
/>
123
+
)
124
+
}
125
+
126
+
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
127
+
return (
128
+
<div
129
+
data-slot="field-label"
130
+
className={cn(
131
+
"flex w-fit items-center gap-2 text-sm font-medium leading-snug group-data-[disabled=true]/field:opacity-50",
132
+
className
133
+
)}
134
+
{...props}
135
+
/>
136
+
)
137
+
}
138
+
139
+
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
140
+
return (
141
+
<p
142
+
data-slot="field-description"
143
+
className={cn(
144
+
"text-muted-foreground text-sm font-normal leading-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
145
+
"nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5",
146
+
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
147
+
className
148
+
)}
149
+
{...props}
150
+
/>
151
+
)
152
+
}
153
+
154
+
function FieldSeparator({
155
+
children,
156
+
className,
157
+
...props
158
+
}: React.ComponentProps<"div"> & {
159
+
children?: React.ReactNode
160
+
}) {
161
+
return (
162
+
<div
163
+
data-slot="field-separator"
164
+
data-content={!!children}
165
+
className={cn(
166
+
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
167
+
className
168
+
)}
169
+
{...props}
170
+
>
171
+
<Separator className="absolute inset-0 top-1/2" />
172
+
{children && (
173
+
<span
174
+
className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
175
+
data-slot="field-separator-content"
176
+
>
177
+
{children}
178
+
</span>
179
+
)}
180
+
</div>
181
+
)
182
+
}
183
+
184
+
function FieldError({
185
+
className,
186
+
children,
187
+
errors,
188
+
...props
189
+
}: React.ComponentProps<"div"> & {
190
+
errors?: Array<{ message?: string } | undefined>
191
+
}) {
192
+
const content = useMemo(() => {
193
+
if (children) {
194
+
return children
195
+
}
196
+
197
+
if (!errors) {
198
+
return null
199
+
}
200
+
201
+
if (errors?.length === 1 && errors[0]?.message) {
202
+
return errors[0].message
203
+
}
204
+
205
+
return (
206
+
<ul className="ml-4 flex list-disc flex-col gap-1">
207
+
{errors.map(
208
+
(error, index) =>
209
+
error?.message && <li key={index}>{error.message}</li>
210
+
)}
211
+
</ul>
212
+
)
213
+
}, [children, errors])
214
+
215
+
if (!content) {
216
+
return null
217
+
}
218
+
219
+
return (
220
+
<div
221
+
role="alert"
222
+
data-slot="field-error"
223
+
className={cn("text-destructive text-sm font-normal", className)}
224
+
{...props}
225
+
>
226
+
{content}
227
+
</div>
228
+
)
229
+
}
230
+
231
+
export {
232
+
Field,
233
+
FieldLabel,
234
+
FieldDescription,
235
+
FieldError,
236
+
FieldGroup,
237
+
FieldLegend,
238
+
FieldSeparator,
239
+
FieldSet,
240
+
FieldContent,
241
+
FieldTitle,
242
+
}
+2
apps/web/src/components/ui/separator.tsx
+2
apps/web/src/components/ui/separator.tsx
+4
-17
apps/web/src/hooks/use-xrpc.tsx
+4
-17
apps/web/src/hooks/use-xrpc.tsx
···
1
-
import { SERVER_URL } from "@/lib/utils";
2
-
import { useAuth } from "@/state/auth";
3
-
import { Client, FetchHandler, FetchHandlerObject, ServiceProxyOptions, simpleFetchHandler } from "@atcute/client";
1
+
import { useClient } from "@/state/auth";
4
2
3
+
/** @deprecated Use `useClient` from `state/auth/client` instead. */
5
4
export function useXrpc() {
6
-
const { agent } = useAuth();
7
-
8
-
let handler: FetchHandler | FetchHandlerObject = simpleFetchHandler({ service: `https://${SERVER_URL}` });
9
-
let proxy: ServiceProxyOptions | null = null;
10
-
11
-
if (agent) {
12
-
handler = agent;
13
-
proxy = {
14
-
did: `did:web:${SERVER_URL}`,
15
-
serviceId: '#recipes_blue',
16
-
};
17
-
}
18
-
19
-
return new Client({ handler, proxy });
5
+
const client = useClient();
6
+
return client;
20
7
}
+12
-8
apps/web/src/main.tsx
+12
-8
apps/web/src/main.tsx
···
6
6
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
7
7
import { configureOAuth, defaultIdentityResolver } from '@atcute/oauth-browser-client';
8
8
import './index.css'
9
-
import { AuthProvider, useAuth } from './state/auth';
10
9
import { ThemeProvider } from './components/theme-provider';
11
10
import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver, XrpcHandleResolver } from '@atcute/identity-resolver';
12
-
import { SessionProvider } from './state/auth/session';
11
+
import { SessionProvider, useSession } from './state/auth/session';
12
+
import { ClientProvider, useClient } from './state/auth';
13
13
14
14
const router = createRouter({
15
15
routeTree,
16
16
context: {
17
-
auth: undefined!,
17
+
session: undefined!,
18
+
client: undefined!,
18
19
},
19
20
});
20
21
···
27
28
configureOAuth({
28
29
metadata: {
29
30
client_id: import.meta.env.VITE_OAUTH_CLIENT_ID,
30
-
redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URL,
31
+
redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URI,
31
32
},
32
33
identityResolver: defaultIdentityResolver({
33
34
handleResolver: new XrpcHandleResolver({ serviceUrl: 'https://slingshot.microcosm.blue' }),
···
51
52
});
52
53
53
54
const InnerApp = () => {
54
-
const auth = useAuth();
55
-
return <RouterProvider router={router} context={{ auth }} />
55
+
const session = useSession();
56
+
const client = useClient();
57
+
return <RouterProvider router={router} context={{ session, client }} />
56
58
};
57
59
58
60
createRoot(document.getElementById('root')!).render(
59
61
<StrictMode>
60
62
<SessionProvider>
61
-
<ThemeProvider defaultTheme="dark" storageKey="recipes-theme">
63
+
<ClientProvider>
64
+
<ThemeProvider defaultTheme="dark" storageKey="recipes-theme">
62
65
<QueryClientProvider client={queryClient}>
63
66
<InnerApp />
64
67
<ReactQueryDevtools initialIsOpen={false} />
65
68
</QueryClientProvider>
66
-
</ThemeProvider>
69
+
</ThemeProvider>
70
+
</ClientProvider>
67
71
</SessionProvider>
68
72
</StrictMode>,
69
73
)
+3
-3
apps/web/src/queries/recipe.ts
+3
-3
apps/web/src/queries/recipe.ts
···
5
5
import { notFound } from "@tanstack/react-router";
6
6
import { UseFormReturn } from "react-hook-form";
7
7
import { TID } from '@atproto/common-web';
8
-
import { recipeSchema } from "@/forms/recipe";
9
8
import { z } from "zod";
10
9
import { ActorIdentifier, Did } from "@atcute/lexicons";
11
10
12
11
import type {} from '@atcute/atproto';
13
12
import type {} from '@cookware/lexicons';
13
+
import { useClient } from "../state/auth/client";
14
14
15
15
const RQKEY_ROOT = 'posts';
16
16
export const RQKEY = (cursor: string, did: string, rkey: string) => [RQKEY_ROOT, cursor, did, rkey];
17
17
18
18
export const useRecipesQuery = (cursor: string, did?: Did) => {
19
-
const rpc = useXrpc();
19
+
const client = useClient();
20
20
return useQuery({
21
21
queryKey: RQKEY(cursor, did ?? '', ''),
22
22
queryFn: async () => {
23
-
const res = await rpc.get('blue.recipes.feed.getRecipes', {
23
+
const res = await client.get('blue.recipes.feed.getRecipes', {
24
24
params: { cursor, did },
25
25
});
26
26
return res.data;
+48
-46
apps/web/src/routes/_.(auth)/login.tsx
+48
-46
apps/web/src/routes/_.(auth)/login.tsx
···
13
13
CardHeader,
14
14
CardTitle,
15
15
} from '@/components/ui/card'
16
+
import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field'
16
17
import { Input } from '@/components/ui/input'
17
18
import { Label } from '@/components/ui/label'
18
19
import { Separator } from '@/components/ui/separator'
19
20
import { SidebarTrigger } from '@/components/ui/sidebar'
20
-
import { sleep } from '@/lib/utils'
21
21
import { useSession } from '@/state/auth/session'
22
-
import { isHandle } from '@atcute/lexicons/syntax'
23
-
import { createAuthorizationUrl } from '@atcute/oauth-browser-client'
24
22
import { useMutation } from '@tanstack/react-query'
25
23
import { createFileRoute } from '@tanstack/react-router'
26
24
import { useState } from 'react'
···
57
55
</div>
58
56
</header>
59
57
<div className="flex flex-1 flex-col items-center justify-center gap-4 p-4 pt-0">
60
-
<Card className="max-w-sm w-full">
61
-
<CardHeader>
62
-
<CardTitle>Log in</CardTitle>
63
-
<CardDescription>
64
-
Enter your handle below to sign in to your account.
65
-
</CardDescription>
66
-
</CardHeader>
67
-
<CardContent>
68
-
<div className="flex flex-col gap-2">
69
-
<Label htmlFor="handle">Handle</Label>
70
-
<Input
71
-
className={`${error ? 'border-destructive text-destructive' : ''}`}
72
-
type="text"
73
-
id="handle"
74
-
name="handle"
75
-
placeholder="johndoe.bsky.social"
76
-
required
77
-
value={handle}
78
-
onChange={(e) => setHandle(e.currentTarget.value)}
79
-
/>
80
-
{error && (
81
-
<p className="text-sm font-medium text-destructive">
82
-
{error.message}
83
-
</p>
84
-
)}
85
-
</div>
86
-
</CardContent>
87
-
<CardFooter className="grid gap-2">
88
-
<Button onClick={() => mutate()} disabled={isPending}>
89
-
Log in
90
-
</Button>
91
-
<p className="text-sm text-muted-foreground text-center">
92
-
Don't have an account?{' '}
93
-
<a
94
-
className="font-bold text-primary"
95
-
href="https://bsky.app/"
96
-
target="_blank"
97
-
>
98
-
Sign up on Bluesky!
99
-
</a>
100
-
</p>
101
-
</CardFooter>
102
-
</Card>
58
+
<form onSubmit={e => {
59
+
e.preventDefault();
60
+
mutate();
61
+
}}>
62
+
<Card className="max-w-sm w-full">
63
+
<CardHeader>
64
+
<CardTitle>Log in</CardTitle>
65
+
<CardDescription>
66
+
Enter your Atmosphere handle below to sign in to your account.
67
+
</CardDescription>
68
+
</CardHeader>
69
+
<CardContent>
70
+
<FieldGroup>
71
+
<Field data-invalid={error ? true : false}>
72
+
<FieldLabel htmlFor="handle">Handle</FieldLabel>
73
+
<Input
74
+
id="handle"
75
+
placeholder="johndoe.bsky.social"
76
+
required
77
+
autoComplete="username"
78
+
aria-invalid={error ? 'true' : 'false'}
79
+
tabIndex={0}
80
+
autoFocus
81
+
value={handle}
82
+
onChange={(e) => setHandle(e.currentTarget.value)}
83
+
/>
84
+
{error && <FieldError>{error.message}</FieldError>}
85
+
</Field>
86
+
</FieldGroup>
87
+
</CardContent>
88
+
<CardFooter className="grid gap-2">
89
+
<Button type="submit" disabled={isPending}>
90
+
Log in
91
+
</Button>
92
+
<p className="text-sm text-muted-foreground text-center">
93
+
Don't have an account?{' '}
94
+
<a
95
+
className="font-bold text-primary"
96
+
href="https://bsky.app/"
97
+
target="_blank"
98
+
>
99
+
Sign up on Bluesky!
100
+
</a>
101
+
</p>
102
+
</CardFooter>
103
+
</Card>
104
+
</form>
103
105
</div>
104
106
</>
105
107
)
+3
-2
apps/web/src/routes/__root.tsx
+3
-2
apps/web/src/routes/__root.tsx
···
3
3
SidebarInset,
4
4
SidebarProvider,
5
5
} from '@/components/ui/sidebar'
6
-
import { AuthContextType } from '@/state/auth';
6
+
import { ClientContext, SessionContext } from '@/state/auth';
7
7
import { Outlet, createRootRouteWithContext } from '@tanstack/react-router'
8
8
9
9
type RootContext = {
10
-
auth: AuthContextType;
10
+
session: SessionContext;
11
+
client: ClientContext['client'];
11
12
};
12
13
13
14
export const Route = createRootRouteWithContext<RootContext>()({
-83
apps/web/src/state/auth.tsx
-83
apps/web/src/state/auth.tsx
···
1
-
import { Did } from "@atcute/lexicons";
2
-
import { finalizeAuthorization, getSession, OAuthUserAgent, Session } from "@atcute/oauth-browser-client";
3
-
import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
4
-
5
-
export type AuthContextType = {
6
-
isLoggedIn: boolean;
7
-
hasProfile: boolean;
8
-
agent?: OAuthUserAgent;
9
-
logOut: () => Promise<void>;
10
-
};
11
-
12
-
const AuthContext = createContext<AuthContextType>({
13
-
isLoggedIn: false,
14
-
hasProfile: false,
15
-
logOut: async () => {},
16
-
});
17
-
18
-
export const AuthProvider = ({ children }: PropsWithChildren) => {
19
-
const [isReady, setIsReady] = useState(false);
20
-
const [isLoggedIn, setIsLoggedIn] = useState(false);
21
-
const [hasProfile, setHasProfile] = useState(false);
22
-
const [agent, setAgent] = useState<OAuthUserAgent | undefined>(undefined);
23
-
24
-
useEffect(() => {
25
-
const init = async () => {
26
-
const params = new URLSearchParams(location.hash.slice(1));
27
-
let session: Session | null = null;
28
-
29
-
if (params.has("state") && (params.has("code") || params.has("error"))) {
30
-
history.replaceState(null, "", location.pathname + location.search);
31
-
32
-
const session = await finalizeAuthorization(params);
33
-
const did = session.info.sub;
34
-
35
-
localStorage.setItem("lastSignedIn", did);
36
-
} else {
37
-
const lastSignedIn = localStorage.getItem("lastSignedIn");
38
-
39
-
if (lastSignedIn) {
40
-
try {
41
-
return await getSession(lastSignedIn as Did);
42
-
} catch (err) {
43
-
localStorage.removeItem("lastSignedIn");
44
-
throw err;
45
-
}
46
-
}
47
-
}
48
-
49
-
setAgent(new OAuthUserAgent(session!));
50
-
};
51
-
52
-
init()
53
-
.then(session => {
54
-
if (session) {
55
-
setAgent(new OAuthUserAgent(session));
56
-
setIsLoggedIn(true);
57
-
}
58
-
59
-
setIsReady(true)
60
-
})
61
-
.catch(() => {});
62
-
}, []);
63
-
64
-
if (!isReady) return null;
65
-
66
-
return (
67
-
<AuthContext.Provider value={{
68
-
isLoggedIn,
69
-
hasProfile,
70
-
agent,
71
-
logOut: async () => {
72
-
await agent?.signOut();
73
-
setIsLoggedIn(false);
74
-
},
75
-
}}>
76
-
{children}
77
-
</AuthContext.Provider>
78
-
);
79
-
};
80
-
81
-
export const useAuth = () => {
82
-
return useContext(AuthContext);
83
-
};
+38
apps/web/src/state/auth/client.tsx
+38
apps/web/src/state/auth/client.tsx
···
1
+
import { Client, simpleFetchHandler } from "@atcute/client";
2
+
import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
3
+
import { useSession } from "./session";
4
+
5
+
export type ClientContext = {
6
+
client: Client;
7
+
};
8
+
9
+
const clientContext = createContext<ClientContext>({
10
+
client: new Client({ handler: simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }) }),
11
+
});
12
+
13
+
export const ClientProvider = ({ children }: PropsWithChildren) => {
14
+
const { agent } = useSession();
15
+
const [client, setClient] = useState<Client>(
16
+
() => new Client({ handler: simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }) })
17
+
);
18
+
19
+
useEffect(() => {
20
+
setClient(new Client({
21
+
handler: agent ?? simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }),
22
+
proxy: {
23
+
did: 'did:web:localhost',
24
+
serviceId: '#api_service'
25
+
},
26
+
}));
27
+
}, [agent]);
28
+
29
+
return (
30
+
<clientContext.Provider value={{ client: client }}>
31
+
{children}
32
+
</clientContext.Provider>
33
+
);
34
+
}
35
+
36
+
export const useClient = () => {
37
+
return useContext(clientContext).client;
38
+
}
+19
-2
apps/web/src/state/auth/session.tsx
+19
-2
apps/web/src/state/auth/session.tsx
···
1
-
import { Did, isActorIdentifier, isHandle } from "@atcute/lexicons/syntax";
1
+
import { isDid, isActorIdentifier } from "@atcute/lexicons/syntax";
2
2
import { createAuthorizationUrl, deleteStoredSession, finalizeAuthorization, getSession, OAuthUserAgent, Session } from "@atcute/oauth-browser-client";
3
-
import { SessionState } from "node:http2";
4
3
import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react";
5
4
6
5
export type SessionContext = {
7
6
session: null | Session;
7
+
agent: null | OAuthUserAgent;
8
8
isLoading: boolean;
9
9
isLoggedIn: boolean;
10
10
signIn: (handle: string) => Promise<void>;
···
13
13
14
14
const sessionContext = createContext<SessionContext>({
15
15
session: null,
16
+
agent: null,
16
17
isLoading: false,
17
18
isLoggedIn: false,
18
19
signIn: async () => {
···
23
24
},
24
25
});
25
26
27
+
const LS_LAST_SIGNED_IN = "recipes:last-signed-in";
28
+
26
29
export const SessionProvider = ({ children }: PropsWithChildren<{}>) => {
27
30
const [initialized, setInitialized] = useState(false);
28
31
const [loading, setLoading] = useState(true);
···
38
41
if (params.has("state") && params.has("iss") && params.has("code")) {
39
42
// If there is an active auth attempt:
40
43
history.replaceState(null, "", location.pathname + location.search);
44
+
console.log("finalizing authorization...");
41
45
finalizeAuthorization(params)
42
46
.then(val => {
43
47
setSession(val.session);
···
51
55
setInitialized(true);
52
56
});
53
57
} else {
58
+
const lastSignedIn = localStorage.getItem(LS_LAST_SIGNED_IN);
59
+
if (lastSignedIn && isDid(lastSignedIn)) {
60
+
getSession(lastSignedIn, { allowStale: true })
61
+
.then((session) => {
62
+
setSession(session);
63
+
setAgent(new OAuthUserAgent(session));
64
+
})
65
+
.catch(err => {
66
+
console.error("Failed to initialize session:", err);
67
+
})
68
+
}
69
+
54
70
setLoading(false);
55
71
setInitialized(true);
56
72
}
···
89
105
isLoading: loading,
90
106
isLoggedIn: session !== null,
91
107
session,
108
+
agent,
92
109
signIn,
93
110
signOut,
94
111
}}>
+1
-1
apps/web/src/vite-env.d.ts
+1
-1
apps/web/src/vite-env.d.ts
+3
-2
apps/web/vite.config.ts
+3
-2
apps/web/vite.config.ts
···
1
1
import { defineConfig } from 'vite'
2
-
import react from '@vitejs/plugin-react-swc'
2
+
import react from '@vitejs/plugin-react'
3
3
import { tanstackRouter } from '@tanstack/router-plugin/vite'
4
4
import path from 'path'
5
5
import metadata from "./public/oauth-client-metadata.json" with { type: 'json' };
···
11
11
export default defineConfig({
12
12
plugins: [
13
13
tanstackRouter(),
14
-
react(),
14
+
react({ babel: { plugins: ['babel-plugin-react-compiler'] } }),
15
15
{
16
16
name: '_config',
17
17
config(_conf, { command }) {
···
29
29
`?redirect_uri=${encodeURIComponent(redirectUri)}` +
30
30
`&scope=${encodeURIComponent(metadata.scope)}`;
31
31
32
+
process.env.VITE_API_SERVICE = 'http://localhost:3000';
32
33
process.env.VITE_DEV_SERVER_PORT = '' + SERVER_PORT;
33
34
process.env.VITE_OAUTH_CLIENT_ID = clientId;
34
35
process.env.VITE_OAUTH_REDIRECT_URI = redirectUri;
+28
-156
bun.lock
+28
-156
bun.lock
···
76
76
"@radix-ui/react-dialog": "^1.1.4",
77
77
"@radix-ui/react-dropdown-menu": "^2.1.4",
78
78
"@radix-ui/react-icons": "^1.3.2",
79
-
"@radix-ui/react-label": "^2.1.0",
80
-
"@radix-ui/react-separator": "^1.1.0",
81
-
"@radix-ui/react-slot": "^1.1.0",
79
+
"@radix-ui/react-label": "^2.1.8",
80
+
"@radix-ui/react-separator": "^1.1.8",
81
+
"@radix-ui/react-slot": "^1.2.4",
82
82
"@radix-ui/react-tooltip": "^1.1.4",
83
83
"@tanstack/react-query": "^5.62.2",
84
84
"@tanstack/react-query-devtools": "^5.62.2",
···
103
103
"@types/node": "^22.10.1",
104
104
"@types/react": "^19.0.0",
105
105
"@types/react-dom": "^19.0.0",
106
+
"@vitejs/plugin-react": "^5.1.1",
106
107
"@vitejs/plugin-react-swc": "^3.5.0",
107
108
"autoprefixer": "^10.4.20",
109
+
"babel-plugin-react-compiler": "^1.0.0",
108
110
"cssnano": "^7.0.6",
109
111
"eslint": "^9.15.0",
110
112
"eslint-plugin-react-hooks": "^5.0.0",
···
115
117
"tailwindcss": "^3.4.16",
116
118
"typescript": "~5.6.2",
117
119
"typescript-eslint": "^8.15.0",
118
-
"vite": "^6.0.1",
120
+
"vite": "^7.2.4",
119
121
},
120
122
},
121
123
"libs/database": {
···
294
296
"@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ=="],
295
297
296
298
"@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="],
299
+
300
+
"@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
301
+
302
+
"@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
297
303
298
304
"@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="],
299
305
···
673
679
674
680
"@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
675
681
676
-
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
682
+
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.47", "", {}, "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw=="],
677
683
678
684
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.3", "", { "os": "android", "cpu": "arm" }, "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w=="],
679
685
···
791
797
792
798
"@typelex/emitter": ["@typelex/emitter@0.4.0", "", { "dependencies": { "@typespec/compiler": "^1.4.0" } }, "sha512-BaKny+8TA0yX5jZibkAodHHKLJ6l6xVe5ut7KeoUyTD63lSSuB9OXe8tWXrs2DbeR/hialCimHFZQ3xANleMow=="],
793
799
800
+
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
801
+
802
+
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
803
+
804
+
"@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
805
+
806
+
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
807
+
794
808
"@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="],
795
809
796
810
"@types/connect": ["@types/connect@3.4.36", "", { "dependencies": { "@types/node": "*" } }, "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w=="],
···
839
853
840
854
"@typespec/compiler": ["@typespec/compiler@1.6.0", "", { "dependencies": { "@babel/code-frame": "~7.27.1", "@inquirer/prompts": "^7.4.0", "ajv": "~8.17.1", "change-case": "~5.4.4", "env-paths": "^3.0.0", "globby": "~15.0.0", "is-unicode-supported": "^2.1.0", "mustache": "~4.2.0", "picocolors": "~1.1.1", "prettier": "~3.6.2", "semver": "^7.7.1", "tar": "^7.5.2", "temporal-polyfill": "^0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.12", "yaml": "~2.8.0", "yargs": "~18.0.0" }, "bin": { "tsp": "cmd/tsp.js", "tsp-server": "cmd/tsp-server.js" } }, "sha512-yxyV+ch8tnqiuU2gClv/mQEESoFwpkjo6177UkYfV0nVA9PzTg4zVVc7+WIMZk04wiLRRT3H1uc11FB1cwLY3g=="],
841
855
856
+
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.1", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.47", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA=="],
857
+
842
858
"@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.11.0", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.27", "@swc/core": "^1.12.11" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w=="],
843
859
844
860
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
···
878
894
"axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="],
879
895
880
896
"babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="],
897
+
898
+
"babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="],
881
899
882
900
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
883
901
···
1439
1457
1440
1458
"react-hook-form": ["react-hook-form@7.66.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-2KnjpgG2Rhbi+CIiIBQQ9Df6sMGH5ExNyFl4Hw9qO7pIqMBR8Bvu9RQyjl3JM4vehzCh9soiNUM/xYMswb2EiA=="],
1441
1459
1460
+
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
1461
+
1442
1462
"react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="],
1443
1463
1444
1464
"react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="],
···
1609
1629
1610
1630
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
1611
1631
1612
-
"vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="],
1632
+
"vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1613
1633
1614
1634
"vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="],
1615
1635
···
1751
1771
1752
1772
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="],
1753
1773
1754
-
"@tanstack/react-router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1755
-
1756
-
"@tanstack/router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1757
-
1758
-
"@tanstack/router-devtools-core/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="],
1759
-
1760
1774
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
1761
1775
1762
1776
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
1777
+
1778
+
"@vitejs/plugin-react-swc/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
1763
1779
1764
1780
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
1765
1781
···
1898
1914
"@radix-ui/react-roving-focus/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1899
1915
1900
1916
"@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
1901
-
1902
-
"@tanstack/react-router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1903
-
1904
-
"@tanstack/router-devtools-core/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1905
-
1906
-
"@tanstack/router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
1907
1917
1908
1918
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
1909
1919
···
2020
2030
"@inquirer/core/wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
2021
2031
2022
2032
"@inquirer/core/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
2023
-
2024
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2025
-
2026
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2027
-
2028
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2029
-
2030
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2031
-
2032
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2033
-
2034
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2035
-
2036
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2037
-
2038
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2039
-
2040
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2041
-
2042
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2043
-
2044
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2045
-
2046
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2047
-
2048
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2049
-
2050
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2051
-
2052
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2053
-
2054
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2055
-
2056
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2057
-
2058
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2059
-
2060
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2061
-
2062
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2063
-
2064
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2065
-
2066
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2067
-
2068
-
"@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2069
-
2070
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2071
-
2072
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2073
-
2074
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2075
-
2076
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2077
-
2078
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2079
-
2080
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2081
-
2082
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2083
-
2084
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2085
-
2086
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2087
-
2088
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2089
-
2090
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2091
-
2092
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2093
-
2094
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2095
-
2096
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2097
-
2098
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2099
-
2100
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2101
-
2102
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2103
-
2104
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2105
-
2106
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2107
-
2108
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2109
-
2110
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2111
-
2112
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2113
-
2114
-
"@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2115
-
2116
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
2117
-
2118
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
2119
-
2120
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="],
2121
-
2122
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="],
2123
-
2124
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="],
2125
-
2126
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="],
2127
-
2128
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="],
2129
-
2130
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="],
2131
-
2132
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="],
2133
-
2134
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="],
2135
-
2136
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="],
2137
-
2138
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="],
2139
-
2140
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="],
2141
-
2142
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="],
2143
-
2144
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="],
2145
-
2146
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="],
2147
-
2148
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="],
2149
-
2150
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="],
2151
-
2152
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="],
2153
-
2154
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="],
2155
-
2156
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="],
2157
-
2158
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="],
2159
-
2160
-
"@tanstack/router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
2161
2033
}
2162
2034
}