diff --git a/.gitignore b/.gitignore index 809682214c..371757fac0 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ tf/.terraform.lock.hcl frontend/.env.* frontend/dist/ frontend/node_modules/ +frontend/.tanstack # Site site/.next/ diff --git a/frontend/.env b/frontend/.env index 04d5e84ed2..43f338cc7f 100644 --- a/frontend/.env +++ b/frontend/.env @@ -5,6 +5,7 @@ VITE_APP_SENTRY_PROJECT_ID="4506435887366144" # This is a public-facing token, safe to commit to repo VITE_APP_POSTHOG_API_KEY=phc_6kfTNEAVw7rn1LA51cO3D69FefbKupSWFaM7OUgEpEo VITE_APP_POSTHOG_HOST=https://ph.rivet.gg +VITE_APP_CLOUD_API_URL=https://cloud.rivet.gg/api # Overridden in CI SENTRY_AUTH_TOKEN= diff --git a/frontend/package.json b/frontend/package.json index 9171c999d1..00ba6c9ba8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,14 +7,20 @@ "dev": "pnpm run '/^dev:.*/'", "dev:inspector": "vite --config vite.inspector.config.ts", "dev:engine": "vite --config vite.engine.config.ts", + "dev:cloud": "vite --config vite.cloud.config.ts", "ts-check": "tsc --noEmit", "build": "echo 'Please use build:engine or build:inspector' && exit 1", "build:inspector": "vite build --mode=production --config vite.inspector.config.ts", "build:engine": "vite build --mode=production --config vite.engine.config.ts", + "build:cloud": "vite build --mode=production --config vite.cloud.config.ts", "preview:inspector": "vite preview --config vite.inspector.config.ts", - "preview:engine": "vite preview --config vite.engine.config.ts" + "preview:engine": "vite preview --config vite.engine.config.ts", + "preview:cloud": "vite preview --config vite.cloud.config.ts" }, "dependencies": { + "@clerk/clerk-js": "^5.91.2", + "@clerk/clerk-react": "^5.46.1", + "@clerk/themes": "^2.4.17", "@codemirror/commands": "^6.8.1", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/lang-json": "^6.0.1", @@ -49,6 +55,7 @@ "@radix-ui/react-toggle-group": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.1", "@radix-ui/react-visually-hidden": "^1.0.3", + "@rivet-gg/cloud": "file:./vendor/rivet-cloud.tgz", "@rivet-gg/icons": "file:./vendor/rivet-icons.tgz", "rivetkit": "*", "@rivetkit/engine-api-full": "workspace:*", @@ -109,6 +116,7 @@ "tailwind-merge": "^2.2.2", "tailwindcss": "^3.4.1", "tailwindcss-animate": "^1.0.7", + "ts-pattern": "^5.8.0", "typescript": "^5.5.4", "usehooks-ts": "^3.1.0", "vite": "^5.2.0", diff --git a/frontend/src/app/dialogs/create-project-dialog.tsx b/frontend/src/app/dialogs/create-project-dialog.tsx new file mode 100644 index 0000000000..d4cbb8a252 --- /dev/null +++ b/frontend/src/app/dialogs/create-project-dialog.tsx @@ -0,0 +1,60 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; +import { useNavigate } from "@tanstack/react-router"; +import * as CreateProjectForm from "@/app/forms/create-project-form"; +import { DialogFooter, DialogHeader, DialogTitle, Flex } from "@/components"; +import { convertStringToId } from "@/lib/utils"; +import { + createProjectMutationOptions, + projectsQueryOptions, +} from "@/queries/manager-cloud"; +import { + managerClient, + namespacesQueryOptions, +} from "@/queries/manager-engine"; + +export default function CreateProjectDialogContent() { + const queryClient = useQueryClient(); + const navigate = useNavigate(); + + const { mutateAsync } = useMutation( + createProjectMutationOptions({ + onSuccess: async (values) => { + await queryClient.invalidateQueries({ + ...projectsQueryOptions(), + }); + navigate({ + to: "/orgs/$organization/projects/$project", + params: { + organization: values.organizationId, + project: values.name, + }, + }); + }, + }), + ); + + return ( + { + await mutateAsync({ + displayName: values.name, + nameId: values.slug || convertStringToId(values.name), + }); + }} + defaultValues={{ name: "", slug: "" }} + > + + Create New Project + + + + + + + + Create + + + + ); +} diff --git a/frontend/src/app/forms/create-project-form.tsx b/frontend/src/app/forms/create-project-form.tsx new file mode 100644 index 0000000000..29c968d342 --- /dev/null +++ b/frontend/src/app/forms/create-project-form.tsx @@ -0,0 +1,90 @@ +import { type UseFormReturn, useFormContext } from "react-hook-form"; +import z from "zod"; +import { + createSchemaForm, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, + Input, +} from "@/components"; +import { convertStringToId } from "@/lib/utils"; + +export const formSchema = z.object({ + name: z + .string() + .max(25) + .refine((value) => value.trim() !== "" && value.trim() === value, { + message: "Name cannot be empty or contain whitespaces", + }), + slug: z.string().max(25).optional(), +}); + +export type FormValues = z.infer; +export type SubmitHandler = ( + values: FormValues, + form: UseFormReturn, +) => Promise; + +const { Form, Submit, SetValue } = createSchemaForm(formSchema); +export { Form, Submit, SetValue }; + +export const Name = ({ className }: { className?: string }) => { + const { control } = useFormContext(); + return ( + ( + + Name + + + + + + )} + /> + ); +}; + +export const Slug = ({ className }: { className?: string }) => { + const { control, watch } = useFormContext(); + + const name = watch("name"); + + return ( + ( + + Slug + + { + const value = convertStringToId( + event.target.value, + ); + field.onChange({ target: { value } }); + }} + /> + + + + )} + /> + ); +}; diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index f134e58a90..37ffabec4d 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,3 +1,4 @@ +import { OrganizationSwitcher, useClerk } from "@clerk/clerk-react"; import { faArrowUpRight, faLink, @@ -6,7 +7,12 @@ import { Icon, } from "@rivet-gg/icons"; import { useQuery } from "@tanstack/react-query"; -import { Link, useMatchRoute, useNavigate } from "@tanstack/react-router"; +import { + Link, + useMatch, + useMatchRoute, + useNavigate, +} from "@tanstack/react-router"; import { type ComponentProps, createContext, @@ -20,8 +26,10 @@ import { useState, } from "react"; import type { ImperativePanelGroupHandle } from "react-resizable-panels"; +import { match } from "ts-pattern"; import { Button, + type ButtonProps, cn, DocsSheet, type ImperativePanelHandle, @@ -146,13 +154,25 @@ const Sidebar = ({ />
- {__APP_TYPE__ === "inspector" ? ( - - ) : null} - {__APP_TYPE__ === "engine" ? : null} - - - + {match(__APP_TYPE__) + .with("engine", () => ( + <> + + + + + + )) + .with("inspector", () => ( + <> + + + + + + )) + .with("cloud", () => ) + .exhaustive()}
@@ -241,7 +261,7 @@ const Footer = () => { export { Root, Main, Header, Footer, VisibleInFull, Sidebar }; -const Breadcrumbs = () => { +const Breadcrumbs = (): ReactNode => { const matchRoute = useMatchRoute(); const nsMatch = matchRoute({ to: "/ns/$namespace", @@ -341,14 +361,10 @@ const Subnav = () => { function HeaderLink({ icon, children, className, ...props }: HeaderLinkProps) { return ( - ); } -function ConnectionStatus() { +function ConnectionStatus(): ReactNode { const { endpoint, ...queries } = useManager(); const { setCredentials } = useInspectorCredentials(); const { isLoading, isError, isSuccess } = useQuery( @@ -414,4 +445,48 @@ function ConnectionStatus() {
); } + + return null; +} + +function CloudSidebar(): ReactNode { + const match = useMatch({ + from: "/_layout/orgs/$organization/", + shouldThrow: false, + }); + + const clerk = useClerk(); + return ( + <> + + + +
+ + Projects + + { + clerk.openUserProfile({ + __experimental_startPath: "/billing", + }); + }} + > + Billing + + { + clerk.openUserProfile(); + }} + > + Settings + +
+
+ + ); } diff --git a/frontend/src/app/use-dialog.tsx b/frontend/src/app/use-dialog.tsx index 10bd1252a9..ecb0e9643d 100644 --- a/frontend/src/app/use-dialog.tsx +++ b/frontend/src/app/use-dialog.tsx @@ -8,6 +8,9 @@ export const useDialog = { CreateNamespace: createDialogHook( import("@/app/dialogs/create-namespace-dialog"), ), + CreateProject: createDialogHook( + import("@/app/dialogs/create-project-dialog"), + ), ProvideEngineCredentials: createDialogHook( import("@/app/dialogs/provide-engine-credentials-dialog"), ), diff --git a/frontend/src/components/header/header-link.tsx b/frontend/src/components/header/header-link.tsx index 8dfd50a1bc..60dccc87e1 100644 --- a/frontend/src/components/header/header-link.tsx +++ b/frontend/src/components/header/header-link.tsx @@ -29,10 +29,8 @@ export function HeaderLink({ icon ? : undefined } > - - {children} -
- + {children} +
); } diff --git a/frontend/src/lib/auth.ts b/frontend/src/lib/auth.ts new file mode 100644 index 0000000000..b28c4da01b --- /dev/null +++ b/frontend/src/lib/auth.ts @@ -0,0 +1,4 @@ +import { Clerk } from "@clerk/clerk-js"; +import { cloudEnv } from "./env"; + +export const clerk = new Clerk(cloudEnv().VITE_CLERK_PUBLISHABLE_KEY); diff --git a/frontend/src/lib/env.ts b/frontend/src/lib/env.ts new file mode 100644 index 0000000000..89dc93e950 --- /dev/null +++ b/frontend/src/lib/env.ts @@ -0,0 +1,9 @@ +import z from "zod"; + +export const cloudEnvSchema = z.object({ + VITE_APP_API_URL: z.string().url(), + VITE_APP_CLOUD_API_URL: z.string().url(), + VITE_CLERK_PUBLISHABLE_KEY: z.string(), +}); + +export const cloudEnv = () => cloudEnvSchema.parse(import.meta.env); diff --git a/frontend/src/queries/manager-cloud.ts b/frontend/src/queries/manager-cloud.ts new file mode 100644 index 0000000000..ffefdc0fec --- /dev/null +++ b/frontend/src/queries/manager-cloud.ts @@ -0,0 +1,443 @@ +import { + type Rivet as CloudRivet, + RivetClient as CloudRivetClient, +} from "@rivet-gg/cloud"; +import { ActorFeature } from "@rivetkit/core/inspector"; +import { type Rivet, RivetClient } from "@rivetkit/engine-api-full"; +import { + infiniteQueryOptions, + queryOptions, + skipToken, +} from "@tanstack/react-query"; +import z from "zod"; +import { getConfig } from "@/components"; +import type { + Actor, + ActorId, + CrashPolicy, + ManagerContext, +} from "@/components/actors"; +import { + ACTORS_PER_PAGE, + ActorQueryOptionsSchema, + createDefaultManagerContext, +} from "@/components/actors/manager-context"; +import { clerk } from "@/lib/auth"; +import { cloudEnv } from "@/lib/env"; + +const client = new RivetClient({ + baseUrl: () => getConfig().apiUrl, + environment: "", +}); + +const cloudClient = new CloudRivetClient({ + baseUrl: () => cloudEnv().VITE_APP_CLOUD_API_URL, + environment: "", + token: async () => { + console.log(await clerk.session?.getToken()); + return (await clerk.session?.getToken()) || ""; + }, +}); + +export { client as managerClient }; + +export const createCloudManagerContext = ({ + namespace, +}: { + namespace: string; +}) => { + const def = createDefaultManagerContext(); + return { + ...def, + features: { + canCreateActors: true, + canDeleteActors: true, + }, + managerStatusQueryOptions() { + return queryOptions({ + ...def.managerStatusQueryOptions(), + enabled: true, + queryFn: async () => { + return true; + }, + }); + }, + regionsQueryOptions() { + return infiniteQueryOptions({ + ...def.regionsQueryOptions(), + enabled: true, + queryFn: async () => { + const data = await client.datacenters.list(); + return { + regions: data.datacenters.map((dc) => ({ + id: dc.name, + name: dc.name, + })), + pagination: data.pagination, + }; + }, + }); + }, + regionQueryOptions(regionId: string) { + return queryOptions({ + ...def.regionQueryOptions(regionId), + queryKey: ["region", regionId], + queryFn: async ({ client }) => { + const regions = await client.ensureInfiniteQueryData( + this.regionsQueryOptions(), + ); + + for (const page of regions.pages) { + for (const region of page.regions) { + if (region.id === regionId) { + return region; + } + } + } + + throw new Error(`Region not found: ${regionId}`); + }, + }); + }, + actorQueryOptions(actorId) { + return queryOptions({ + ...def.actorQueryOptions(actorId), + queryKey: [namespace, "actor", actorId], + enabled: true, + queryFn: async ({ signal: abortSignal }) => { + const data = await client.actorsGet( + actorId, + { namespace }, + { abortSignal }, + ); + + return transformActor(data.actor); + }, + }); + }, + actorsQueryOptions(opts) { + return infiniteQueryOptions({ + ...def.actorsQueryOptions(opts), + queryKey: [namespace, "actors", opts], + enabled: true, + initialPageParam: undefined, + queryFn: async ({ + signal: abortSignal, + pageParam, + queryKey: [, , _opts], + }) => { + const { success, data: opts } = + ActorQueryOptionsSchema.safeParse(_opts || {}); + + if ( + (opts?.n?.length === 0 || !opts?.n) && + (opts?.filters?.id?.value?.length === 0 || + !opts?.filters?.id?.value || + opts?.filters.key?.value?.length === 0 || + !opts?.filters.key?.value) + ) { + // If there are no names specified, we can return an empty result + return { + actors: [], + pagination: { + cursor: undefined, + }, + }; + } + + const data = await client.actorsList( + { + namespace, + cursor: pageParam ?? undefined, + actorIds: opts?.filters?.id?.value?.join(","), + key: opts?.filters?.key?.value?.join(","), + includeDestroyed: + success && + (opts?.filters?.showDestroyed?.value.includes( + "true", + ) || + opts?.filters?.showDestroyed?.value.includes( + "1", + )), + limit: ACTORS_PER_PAGE, + name: opts?.filters?.id?.value + ? undefined + : opts?.n?.join(","), + }, + { abortSignal }, + ); + + return { + ...data, + pagination: { + cursor: data.pagination.cursor || null, + }, + actors: data.actors.map((actor) => + transformActor(actor), + ), + }; + }, + getNextPageParam: (lastPage) => { + if (lastPage.actors.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + }); + }, + buildsQueryOptions() { + return infiniteQueryOptions({ + ...def.buildsQueryOptions(), + queryKey: [namespace, "builds"], + enabled: true, + queryFn: async ({ signal: abortSignal, pageParam }) => { + const data = await client.actorsListNames( + { + namespace, + cursor: pageParam ?? undefined, + limit: ACTORS_PER_PAGE, + }, + { abortSignal }, + ); + + return { + pagination: data.pagination, + builds: Object.keys(data.names) + .sort() + .map((build) => ({ + id: build, + name: build, + })), + }; + }, + getNextPageParam: (lastPage) => { + if (lastPage.builds.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + }); + }, + createActorMutationOptions() { + return { + ...def.createActorMutationOptions(), + mutationKey: [namespace, "actors"], + mutationFn: async (data) => { + const response = await client.actorsCreate({ + namespace, + name: data.name, + key: data.key, + crashPolicy: data.crashPolicy, + runnerNameSelector: data.runnerNameSelector, + input: JSON.stringify(data.input), + }); + + return response.actor.actorId; + }, + onSuccess: () => {}, + }; + }, + actorDestroyMutationOptions(actorId) { + return { + ...def.actorDestroyMutationOptions(actorId), + mutationFn: async () => { + await client.actorsDelete(actorId); + }, + }; + }, + } satisfies ManagerContext; +}; + +export const NamespaceNameId = z.string().brand(); +export type NamespaceNameId = z.infer; + +export const projectsQueryOptions = ({ orgId }: { orgId: string }) => { + return infiniteQueryOptions({ + queryKey: [orgId, "projects"], + initialPageParam: undefined as string | undefined, + queryFn: async ({ signal: abortSignal, pageParam }) => { + const data = await cloudClient.projects.list( + { + cursor: pageParam ?? undefined, + limit: ACTORS_PER_PAGE, + }, + { + abortSignal, + }, + ); + return data; + }, + getNextPageParam: (lastPage) => { + if (lastPage.projects.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + select: (data) => data.pages.flatMap((page) => page.projects), + }); +}; + +export const runnersQueryOptions = (opts: { namespace: NamespaceNameId }) => { + return infiniteQueryOptions({ + queryKey: [opts.namespace, "runners"], + initialPageParam: undefined as string | undefined, + queryFn: async ({ pageParam, signal: abortSignal }) => { + const data = await client.runners.list( + { + namespace: opts.namespace, + cursor: pageParam ?? undefined, + limit: ACTORS_PER_PAGE, + }, + { abortSignal }, + ); + return data; + }, + getNextPageParam: (lastPage) => { + if (lastPage.runners.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + select: (data) => data.pages.flatMap((page) => page.runners), + }); +}; + +export const runnerQueryOptions = (opts: { + namespace: NamespaceNameId; + runnerId: string; +}) => { + return queryOptions({ + queryKey: [opts.namespace, "runner", opts.runnerId], + enabled: !!opts.runnerId, + queryFn: async ({ signal: abortSignal }) => { + const data = await client.runners.get( + opts.runnerId, + { namespace: opts.namespace }, + { + abortSignal, + }, + ); + return data.runner; + }, + }); +}; + +export const runnerNamesQueryOptions = (opts: { + namespace: NamespaceNameId; +}) => { + return infiniteQueryOptions({ + queryKey: [opts.namespace, "runner", "names"], + initialPageParam: undefined as string | undefined, + queryFn: async ({ signal: abortSignal, pageParam }) => { + const data = await client.runners.listNames( + { + namespace: opts.namespace, + cursor: pageParam ?? undefined, + limit: ACTORS_PER_PAGE, + }, + { + abortSignal, + }, + ); + return data; + }, + getNextPageParam: (lastPage) => { + if (lastPage.names.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + select: (data) => data.pages.flatMap((page) => page.names), + }); +}; + +export const namespacesQueryOptions = () => { + return infiniteQueryOptions({ + queryKey: ["namespaces"], + initialPageParam: undefined as string | undefined, + queryFn: async ({ pageParam, signal: abortSignal }) => { + const data = await client.namespaces.list( + { + limit: ACTORS_PER_PAGE, + cursor: pageParam ?? undefined, + }, + { abortSignal }, + ); + return data; + }, + getNextPageParam: (lastPage) => { + if (lastPage.namespaces.length < ACTORS_PER_PAGE) { + return undefined; + } + return lastPage.pagination.cursor; + }, + select: (data) => data.pages.flatMap((page) => page.namespaces), + }); +}; + +export const namespaceQueryOptions = ( + namespace: NamespaceNameId | undefined, +) => { + return queryOptions({ + queryKey: ["namespace", namespace], + enabled: !!namespace, + queryFn: namespace + ? async ({ signal: abortSignal }) => { + const data = await client.namespaces.get(namespace, { + abortSignal, + }); + return data.namespace; + } + : skipToken, + }); +}; + +function transformActor(a: Rivet.Actor): Actor { + return { + id: a.actorId as ActorId, + name: a.name, + key: a.key ? a.key : undefined, + connectableAt: a.connectableTs + ? new Date(a.connectableTs).toISOString() + : undefined, + region: a.datacenter, + createdAt: new Date(a.createTs).toISOString(), + startedAt: a.startTs ? new Date(a.startTs).toISOString() : undefined, + destroyedAt: a.destroyTs + ? new Date(a.destroyTs).toISOString() + : undefined, + sleepingAt: a.sleepTs ? new Date(a.sleepTs).toISOString() : undefined, + pendingAllocationAt: a.pendingAllocationTs + ? new Date(a.pendingAllocationTs).toISOString() + : undefined, + crashPolicy: a.crashPolicy as CrashPolicy, + runner: a.runnerNameSelector, + features: [ + ActorFeature.Config, + ActorFeature.Connections, + ActorFeature.State, + ActorFeature.Console, + ActorFeature.Database, + ActorFeature.EventsMonitoring, + ], + }; +} + +export function createProjectMutationOptions({ + onSuccess, +}: { + onSuccess?: (data: CloudRivet.Project) => void; +} = {}) { + return { + mutationKey: ["projects"], + mutationFn: async (data: { displayName: string; nameId: string }) => { + const response = await cloudClient.projects.create({ + displayName: data.displayName, + name: data.nameId, + }); + + return response; + }, + onSuccess, + }; +} diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index 3f8bd2201b..56afa0cb05 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -13,8 +13,10 @@ import { Route as LayoutRouteImport } from './routes/_layout' import { Route as LayoutIndexRouteImport } from './routes/_layout/index' import { Route as LayoutNamespacesRouteImport } from './routes/_layout/namespaces' import { Route as LayoutNsNamespaceRouteImport } from './routes/_layout/ns.$namespace' +import { Route as LayoutOrgsOrganizationIndexRouteImport } from './routes/_layout/orgs.$organization/index' import { Route as LayoutNsNamespaceIndexRouteImport } from './routes/_layout/ns.$namespace/index' import { Route as LayoutNsNamespaceRunnersRouteImport } from './routes/_layout/ns.$namespace/runners' +import { Route as LayoutOrgsOrganizationProjectsProjectIndexRouteImport } from './routes/_layout/orgs.$organization/projects.$project/index' const LayoutRoute = LayoutRouteImport.update({ id: '/_layout', @@ -35,6 +37,12 @@ const LayoutNsNamespaceRoute = LayoutNsNamespaceRouteImport.update({ path: '/ns/$namespace', getParentRoute: () => LayoutRoute, } as any) +const LayoutOrgsOrganizationIndexRoute = + LayoutOrgsOrganizationIndexRouteImport.update({ + id: '/orgs/$organization/', + path: '/orgs/$organization/', + getParentRoute: () => LayoutRoute, + } as any) const LayoutNsNamespaceIndexRoute = LayoutNsNamespaceIndexRouteImport.update({ id: '/', path: '/', @@ -46,6 +54,12 @@ const LayoutNsNamespaceRunnersRoute = path: '/runners', getParentRoute: () => LayoutNsNamespaceRoute, } as any) +const LayoutOrgsOrganizationProjectsProjectIndexRoute = + LayoutOrgsOrganizationProjectsProjectIndexRouteImport.update({ + id: '/orgs/$organization/projects/$project/', + path: '/orgs/$organization/projects/$project/', + getParentRoute: () => LayoutRoute, + } as any) export interface FileRoutesByFullPath { '/namespaces': typeof LayoutNamespacesRoute @@ -53,12 +67,16 @@ export interface FileRoutesByFullPath { '/ns/$namespace': typeof LayoutNsNamespaceRouteWithChildren '/ns/$namespace/runners': typeof LayoutNsNamespaceRunnersRoute '/ns/$namespace/': typeof LayoutNsNamespaceIndexRoute + '/orgs/$organization': typeof LayoutOrgsOrganizationIndexRoute + '/orgs/$organization/projects/$project': typeof LayoutOrgsOrganizationProjectsProjectIndexRoute } export interface FileRoutesByTo { '/namespaces': typeof LayoutNamespacesRoute '/': typeof LayoutIndexRoute '/ns/$namespace/runners': typeof LayoutNsNamespaceRunnersRoute '/ns/$namespace': typeof LayoutNsNamespaceIndexRoute + '/orgs/$organization': typeof LayoutOrgsOrganizationIndexRoute + '/orgs/$organization/projects/$project': typeof LayoutOrgsOrganizationProjectsProjectIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport @@ -68,6 +86,8 @@ export interface FileRoutesById { '/_layout/ns/$namespace': typeof LayoutNsNamespaceRouteWithChildren '/_layout/ns/$namespace/runners': typeof LayoutNsNamespaceRunnersRoute '/_layout/ns/$namespace/': typeof LayoutNsNamespaceIndexRoute + '/_layout/orgs/$organization/': typeof LayoutOrgsOrganizationIndexRoute + '/_layout/orgs/$organization/projects/$project/': typeof LayoutOrgsOrganizationProjectsProjectIndexRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath @@ -77,8 +97,16 @@ export interface FileRouteTypes { | '/ns/$namespace' | '/ns/$namespace/runners' | '/ns/$namespace/' + | '/orgs/$organization' + | '/orgs/$organization/projects/$project' fileRoutesByTo: FileRoutesByTo - to: '/namespaces' | '/' | '/ns/$namespace/runners' | '/ns/$namespace' + to: + | '/namespaces' + | '/' + | '/ns/$namespace/runners' + | '/ns/$namespace' + | '/orgs/$organization' + | '/orgs/$organization/projects/$project' id: | '__root__' | '/_layout' @@ -87,6 +115,8 @@ export interface FileRouteTypes { | '/_layout/ns/$namespace' | '/_layout/ns/$namespace/runners' | '/_layout/ns/$namespace/' + | '/_layout/orgs/$organization/' + | '/_layout/orgs/$organization/projects/$project/' fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -123,6 +153,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutNsNamespaceRouteImport parentRoute: typeof LayoutRoute } + '/_layout/orgs/$organization/': { + id: '/_layout/orgs/$organization/' + path: '/orgs/$organization' + fullPath: '/orgs/$organization' + preLoaderRoute: typeof LayoutOrgsOrganizationIndexRouteImport + parentRoute: typeof LayoutRoute + } '/_layout/ns/$namespace/': { id: '/_layout/ns/$namespace/' path: '/' @@ -137,6 +174,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof LayoutNsNamespaceRunnersRouteImport parentRoute: typeof LayoutNsNamespaceRoute } + '/_layout/orgs/$organization/projects/$project/': { + id: '/_layout/orgs/$organization/projects/$project/' + path: '/orgs/$organization/projects/$project' + fullPath: '/orgs/$organization/projects/$project' + preLoaderRoute: typeof LayoutOrgsOrganizationProjectsProjectIndexRouteImport + parentRoute: typeof LayoutRoute + } } } @@ -157,12 +201,17 @@ interface LayoutRouteChildren { LayoutNamespacesRoute: typeof LayoutNamespacesRoute LayoutIndexRoute: typeof LayoutIndexRoute LayoutNsNamespaceRoute: typeof LayoutNsNamespaceRouteWithChildren + LayoutOrgsOrganizationIndexRoute: typeof LayoutOrgsOrganizationIndexRoute + LayoutOrgsOrganizationProjectsProjectIndexRoute: typeof LayoutOrgsOrganizationProjectsProjectIndexRoute } const LayoutRouteChildren: LayoutRouteChildren = { LayoutNamespacesRoute: LayoutNamespacesRoute, LayoutIndexRoute: LayoutIndexRoute, LayoutNsNamespaceRoute: LayoutNsNamespaceRouteWithChildren, + LayoutOrgsOrganizationIndexRoute: LayoutOrgsOrganizationIndexRoute, + LayoutOrgsOrganizationProjectsProjectIndexRoute: + LayoutOrgsOrganizationProjectsProjectIndexRoute, } const LayoutRouteWithChildren = diff --git a/frontend/src/routes/__root.tsx b/frontend/src/routes/__root.tsx index ff40ffae0f..5f05b309cb 100644 --- a/frontend/src/routes/__root.tsx +++ b/frontend/src/routes/__root.tsx @@ -1,6 +1,10 @@ +import { ClerkProvider } from "@clerk/clerk-react"; +import { dark } from "@clerk/themes"; import { createRootRouteWithContext, Outlet } from "@tanstack/react-router"; import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; +import { match } from "ts-pattern"; import { FullscreenLoading } from "@/components"; +import { clerk } from "@/lib/auth"; function RootRoute() { return ( @@ -13,8 +17,28 @@ function RootRoute() { ); } +function CloudRootRoute() { + const PUBLISHABLE_KEY = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY; + + if (!PUBLISHABLE_KEY) { + throw new Error("Add your Clerk Publishable Key to the .env file"); + } + + return ( + + + + ); +} + export const Route = createRootRouteWithContext()({ - component: RootRoute, + component: match(__APP_TYPE__) + .with("cloud", () => CloudRootRoute) + .otherwise(() => RootRoute), pendingComponent: FullscreenLoading, wrapInSuspense: true, }); diff --git a/frontend/src/routes/_layout.tsx b/frontend/src/routes/_layout.tsx index aad64c9f85..70985195aa 100644 --- a/frontend/src/routes/_layout.tsx +++ b/frontend/src/routes/_layout.tsx @@ -1,6 +1,19 @@ +import { + SignedIn, + SignedOut, + SignInButton, + useOrganization, +} from "@clerk/clerk-react"; import { faNodeJs, faReact, Icon } from "@rivet-gg/icons"; -import { createFileRoute, Outlet, useMatch } from "@tanstack/react-router"; +import { + createFileRoute, + Navigate, + Outlet, + useMatch, + useNavigate, +} from "@tanstack/react-router"; import { zodValidator } from "@tanstack/zod-adapter"; +import { C } from "node_modules/@clerk/clerk-react/dist/useAuth-BVxIa9U7.mjs"; import { usePostHog } from "posthog-js/react"; import { type ComponentProps, @@ -12,6 +25,7 @@ import { useRef, useState, } from "react"; +import { match } from "ts-pattern"; import z from "zod"; import { type InspectorCredentials, @@ -61,7 +75,9 @@ const searchSchema = z export const Route = createFileRoute("/_layout")({ validateSearch: zodValidator(searchSchema), - component: RouteComponent, + component: match(__APP_TYPE__) + .with("cloud", () => CloudRouteComponent) + .otherwise(() => RouteComponent), }); function RouteComponent() { @@ -386,3 +402,60 @@ function Connect({
); } + +function CloudRouteComponent() { + return ( + <> + + + + + + + + + + ); +} + +function NavigateToLatestOrganization() { + const { isLoaded, organization } = useOrganization(); + + if (!isLoaded || !organization) { + return null; + } + + return ( + + ); +} + +function CloudModals() { + const navigate = useNavigate(); + const search = Route.useSearch(); + + const CreateProjectDialog = useDialog.CreateProject.Dialog; + return ( + <> + { + if (!value) { + navigate({ + to: ".", + search: (old) => ({ + ...old, + modal: undefined, + }), + }); + } + }, + }} + /> + + ); +} diff --git a/frontend/src/routes/_layout/index.tsx b/frontend/src/routes/_layout/index.tsx index 7691fa1ad0..315421b54d 100644 --- a/frontend/src/routes/_layout/index.tsx +++ b/frontend/src/routes/_layout/index.tsx @@ -1,12 +1,17 @@ +import { useOrganization } from "@clerk/clerk-react"; import { useInfiniteQuery } from "@tanstack/react-query"; import { createFileRoute, Navigate } from "@tanstack/react-router"; +import { match } from "ts-pattern"; import { Card, CardContent, CardHeader, CardTitle } from "@/components"; import { namespacesQueryOptions } from "@/queries/manager-engine"; import { RouteComponent as NamespaceRouteComponent } from "./ns.$namespace/index"; export const Route = createFileRoute("/_layout/")({ - component: - __APP_TYPE__ === "engine" ? RouteComponent : NamespaceRouteComponent, + component: match(__APP_TYPE__) + .with("engine", () => RouteComponent) + .with("inspector", () => NamespaceRouteComponent) + .with("cloud", () => () => CloudRouteComponent) + .exhaustive(), }); function RouteComponent() { @@ -36,3 +41,18 @@ function RouteComponent() {
); } + +function CloudRouteComponent() { + const { isLoaded, organization } = useOrganization(); + + if (!isLoaded || !organization) { + return null; + } + + return ( + + ); +} diff --git a/frontend/src/routes/_layout/orgs.$organization/index.tsx b/frontend/src/routes/_layout/orgs.$organization/index.tsx new file mode 100644 index 0000000000..48e7692d14 --- /dev/null +++ b/frontend/src/routes/_layout/orgs.$organization/index.tsx @@ -0,0 +1,128 @@ +import type { Rivet } from "@rivet-gg/cloud"; +import { faChevronRight, faRefresh, Icon } from "@rivet-gg/icons"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { createFileRoute, Link, notFound } from "@tanstack/react-router"; +import { match } from "ts-pattern"; +import { Button, H1, Skeleton, Text, WithTooltip } from "@/components"; +import { VisibilitySensor } from "@/components/visibility-sensor"; +import { projectsQueryOptions } from "@/queries/manager-cloud"; + +export const Route = createFileRoute("/_layout/orgs/$organization/")({ + component: match(__APP_TYPE__) + .with("cloud", () => RouteComponent) + .otherwise(() => { + throw notFound(); + }), +}); + +function RouteComponent() { + const { organization } = Route.useParams(); + const { + data: projects, + isRefetching, + isSuccess, + hasNextPage, + fetchNextPage, + isFetchingNextPage, + isLoading, + refetch, + } = useInfiniteQuery(projectsQueryOptions({ orgId: organization })); + + return ( +
+
+

Projects

+
+ refetch()} + > + + + } + /> +
+
+ +
+ +
+
+
+ {isSuccess + ? projects.map((project) => ( + + )) + : null} + + ({ + ...old, + modal: "create-project", + })} + > +
+ + + Create New + + + +
+ + + {hasNextPage ? ( + + ) : null} + + {isLoading || isFetchingNextPage ? ( + <> + + + + + + + + ) : null} +
+
+
+
+ ); +} + +function TileSkeleton() { + return ( +
+ + + +
+ ); +} + +function Row(project: Rivet.Project) { + const { organization } = Route.useParams(); + return ( + + + {project.name} + + + View + + + + ); +} diff --git a/frontend/src/routes/_layout/orgs.$organization/projects.$project/index.tsx b/frontend/src/routes/_layout/orgs.$organization/projects.$project/index.tsx new file mode 100644 index 0000000000..be2d7e01c1 --- /dev/null +++ b/frontend/src/routes/_layout/orgs.$organization/projects.$project/index.tsx @@ -0,0 +1,129 @@ +import type { Rivet } from "@rivet-gg/cloud"; +import { + faAdd, + faArrowRight, + faChevronRight, + faRefresh, + Icon, +} from "@rivet-gg/icons"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { createFileRoute, Link, notFound } from "@tanstack/react-router"; +import { match } from "ts-pattern"; +import { Button, H1, Skeleton, Text, WithTooltip } from "@/components"; +import { VisibilitySensor } from "@/components/visibility-sensor"; +import { projectsQueryOptions } from "@/queries/manager-cloud"; + +export const Route = createFileRoute( + "/_layout/orgs/$organization/projects/$project/", +)({ + component: match(__APP_TYPE__) + .with("cloud", () => RouteComponent) + .otherwise(() => { + throw notFound(); + }), +}); + +function RouteComponent() { + const { + data: projects, + isRefetching, + isSuccess, + hasNextPage, + fetchNextPage, + isFetchingNextPage, + isLoading, + isError, + refetch, + } = useInfiniteQuery(projectsQueryOptions()); + + return ( +
+
+

Projects

+
+ refetch()} + > + + + } + /> +
+
+ +
+ +
+
+
+ {isSuccess + ? projects.map((project) => ( + + )) + : null} + + ({ + ...old, + modal: "create-project", + })} + > +
+ + + Create New Project + + + +
+ + + {hasNextPage ? ( + + ) : null} + + {isLoading || isFetchingNextPage ? ( + <> + + + + + + + + ) : null} +
+
+
+
+ ); +} + +function TileSkeleton() { + return ( +
+ + + +
+ ); +} + +function Row(project: Rivet.Project) { + return ( +
+ {project.name} + {/* + {project.} + */} + +
+ ); +} diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts index 7513f0c6b4..bf31e308a8 100644 --- a/frontend/src/vite-env.d.ts +++ b/frontend/src/vite-env.d.ts @@ -1,4 +1,4 @@ /// declare const __APP_BUILD_ID__: string; -declare const __APP_TYPE__: "engine" | "inspector"; +declare const __APP_TYPE__: "engine" | "inspector" | "cloud"; diff --git a/frontend/vendor/rivet-cloud.tgz b/frontend/vendor/rivet-cloud.tgz new file mode 100644 index 0000000000..4f0118347a --- /dev/null +++ b/frontend/vendor/rivet-cloud.tgz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a057b5bfc514b5f078d61eb5523cc61771617d2348ab57c7fc2d719731b5838c +size 176433 diff --git a/frontend/vite.cloud.config.ts b/frontend/vite.cloud.config.ts new file mode 100644 index 0000000000..6def6f2ef7 --- /dev/null +++ b/frontend/vite.cloud.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, loadEnv, mergeConfig } from "vite"; +import { cloudEnvSchema } from "./src/lib/env"; +import engineConfig from "./vite.engine.config"; + +// https://vitejs.dev/config/ +export default defineConfig((config) => { + const env = loadEnv(config.mode, process.cwd(), ""); + cloudEnvSchema.parse(env); + return mergeConfig( + engineConfig(config), + defineConfig({ + base: "/", + define: { + __APP_TYPE__: JSON.stringify("cloud"), + }, + server: { + port: 43710, + proxy: {}, + }, + preview: { + port: 43710, + }, + }), + ); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2dc24f6c8..33ae3544af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,15 @@ importers: frontend: dependencies: + '@clerk/clerk-js': + specifier: ^5.91.2 + version: 5.95.0(@types/react@18.3.23)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.8.2)(use-sync-external-store@1.5.0(react@19.1.1))(zod@3.25.76) + '@clerk/clerk-react': + specifier: ^5.46.1 + version: 5.48.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@clerk/themes': + specifier: ^2.4.17 + version: 2.4.21 '@codemirror/commands': specifier: ^6.8.1 version: 6.8.1 @@ -153,9 +162,12 @@ importers: '@radix-ui/react-visually-hidden': specifier: ^1.0.3 version: 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@rivet-gg/cloud': + specifier: file:./vendor/rivet-cloud.tgz + version: file:frontend/vendor/rivet-cloud.tgz '@rivet-gg/icons': specifier: file:./vendor/rivet-icons.tgz - version: file:frontend/vendor/rivet-icons.tgz(@fortawesome/fontawesome-svg-core@6.7.2)(@fortawesome/free-brands-svg-icons@6.7.2)(@fortawesome/free-solid-svg-icons@6.7.2)(@fortawesome/react-fontawesome@0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1))(@types/node@20.19.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.43.1) + version: file:frontend/vendor/rivet-icons.tgz(@fortawesome/fontawesome-svg-core@6.7.2)(@fortawesome/free-brands-svg-icons@6.7.2)(@fortawesome/free-solid-svg-icons@6.7.2)(@fortawesome/react-fontawesome@0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1))(@types/node@20.19.9)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.43.1) '@rivetkit/engine-api-full': specifier: workspace:* version: link:../sdks/typescript/api-full @@ -333,6 +345,9 @@ importers: tailwindcss-animate: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.17) + ts-pattern: + specifier: ^5.8.0 + version: 5.8.0 typescript: specifier: ^5.5.4 version: 5.8.2 @@ -585,7 +600,7 @@ importers: version: 0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1) dedent: specifier: ^1.5.3 - version: 1.6.0 + version: 1.6.0(babel-plugin-macros@3.1.0) local-pkg: specifier: ^0.5.0 version: 0.5.1 @@ -810,7 +825,7 @@ importers: version: 15.5.2(@mdx-js/loader@3.1.1(webpack@5.101.3(esbuild@0.25.8)))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@19.1.1)) '@next/third-parties': specifier: latest - version: 15.5.2(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) + version: 15.5.2(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) '@rivet-gg/api': specifier: ^0.0.1-rc19 version: 0.0.1-rc8 @@ -858,7 +873,7 @@ importers: version: 3.6.0 dedent: specifier: ^1.5.3 - version: 1.6.0 + version: 1.6.0(babel-plugin-macros@3.1.0) esast-util-from-js: specifier: ^2.0.1 version: 2.0.1 @@ -891,13 +906,13 @@ importers: version: 0.1.4 next: specifier: ^15.2.4 - version: 15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) next-router-mock: specifier: ^0.9.7 - version: 0.9.13(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) + version: 0.9.13(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)) + version: 4.2.3(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)) postcss: specifier: ^8.4.24 version: 8.5.6 @@ -1016,6 +1031,9 @@ importers: packages: + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@alloc/quick-lru@5.2.0': resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -1189,6 +1207,9 @@ packages: peerDependencies: '@bare-ts/lib': '>=0.3.0 <=0.4.0' + '@base-org/account@2.0.1': + resolution: {integrity: sha512-tySVNx+vd6XEynZL0uvB10uKiwnAfThr8AbKTwILVG86mPbLAhEOInQIk+uDnvpTvfdUhC1Bi5T/46JvFoLZQQ==} + '@biomejs/biome@2.1.4': resolution: {integrity: sha512-QWlrqyxsU0FCebuMnkvBIkxvPqH89afiJzjMl+z67ybutse590jgeaFdDurE9XYtzpjRGTI1tlUZPGWmbKsElA==} engines: {node: '>=14.21.3'} @@ -1272,6 +1293,44 @@ packages: cpu: [x64] os: [win32] + '@clerk/clerk-js@5.95.0': + resolution: {integrity: sha512-SLIgFPymcL9tV0D/c02TF86F5+C5NecPrd0qVkMzbnQ0cqo5W6RPuQE4ogOHuV+4NH4kQRu2hRHm8crBei2fOg==} + engines: {node: '>=18.17.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + + '@clerk/clerk-react@5.48.1': + resolution: {integrity: sha512-RXaP5+LzgHURWXmunCj129s79qFLuvsKFu7JHBhvClP6FhY/UbgHi5jaIwvDh5JpmTtuvcTZsBViqQgxPoxOvQ==} + engines: {node: '>=18.17.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + + '@clerk/localizations@3.25.3': + resolution: {integrity: sha512-9/R3PzktThQTmcimUGeag1TGSCwAVf1ZtEsJcpSbzQYe/RpWjSg13CiHsvw+jegFkSEuDcI0nH73k+KgYlMDHw==} + engines: {node: '>=18.17.0'} + + '@clerk/shared@3.26.1': + resolution: {integrity: sha512-84dAJutr7JAwKwRI0fRj6mFy3D521okNIiCkJ+ffMp0lniQr5IXQSFqkCEd+cQ3bImr1YHKCGVMLkahZI6s9Ng==} + engines: {node: '>=18.17.0'} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@clerk/themes@2.4.21': + resolution: {integrity: sha512-nvahR5uOF/bSn34SiK4Zub2n2zn5AJWy+AAzKy0uZYNSl1cjgcZcmQ8CsB078jEeTDmXxKqUa6OMLtYMimH27A==} + engines: {node: '>=18.17.0'} + + '@clerk/types@4.88.0': + resolution: {integrity: sha512-OAepuiszOrheIThdCtBRiRSq0A3grlD2yhUUO8kvMFv4Uys95gSzkzuvQjUWXZZ23yOdTl6eRUXjtjCGto116w==} + engines: {node: '>=18.17.0'} + '@codemirror/autocomplete@6.18.6': resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==} @@ -1305,6 +1364,9 @@ packages: '@codemirror/view@6.38.1': resolution: {integrity: sha512-RmTOkE7hRU3OVREqFVITWHz6ocgBjv08GoePscAakgVQfciA3SGCEk7mb9IzwW61cKKmlTpHXG6DUE5Ubx+MGQ==} + '@coinbase/wallet-sdk@4.3.0': + resolution: {integrity: sha512-T3+SNmiCw4HzDm4we9wCHCxlP0pqCiwKe4sOwPH3YAK2KSKjxPRydKu6UQJrdONFVLG7ujXvbd/6ZqmvJb8rkw==} + '@corex/deepmerge@4.0.43': resolution: {integrity: sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==} @@ -1314,6 +1376,50 @@ packages: '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + + '@emotion/cache@11.11.0': + resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + + '@emotion/memoize@0.8.1': + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/react@11.11.1': + resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0': + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + + '@emotion/weak-memoize@0.3.1': + resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} engines: {node: '>=12'} @@ -1768,9 +1874,18 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' + '@floating-ui/react@0.27.12': + resolution: {integrity: sha512-kKlWNrpIQxF1B/a2MZvE0/uyKby4960yjO91W7nVyNKmmfNi62xU9HCjL1M1eWzx/LFj/VPSwJVbwQk9Pq/68A==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@formkit/auto-animate@0.8.4': + resolution: {integrity: sha512-DHHC01EJ1p70Q0z/ZFRBIY8NDnmfKccQoyoM84Tgb6omLMat6jivCdf272Y8k3nf4Lzdin/Y4R9q8uFtU0GbnA==} + '@fortawesome/fontawesome-common-types@6.7.2': resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==} engines: {node: '>=6'} @@ -2295,6 +2410,26 @@ packages: next: ^13.0.0 || ^14.0.0 || ^15.0.0 react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2898,6 +3033,10 @@ packages: '@rivet-gg/api@0.0.1-rc8': resolution: {integrity: sha512-aGJVImxsmz8fLLzeZHUlFRJ/7Y/xBrke9bOvMpooVaJpHor/XmiP19QeEtB2hmQUOPlgS3dz5o8UtCZ5+LcQGg==} + '@rivet-gg/cloud@file:frontend/vendor/rivet-cloud.tgz': + resolution: {integrity: sha512-PbR+zVclhb53/mxqtRk6uGDparY2d3u72QZ34fPIAW0D8vp2QBcEeWqBZ92m+0SXsXy0a63R1tUmqrAmXrBSlg==, tarball: file:frontend/vendor/rivet-cloud.tgz} + version: 0.0.0 + '@rivet-gg/icons@file:frontend/vendor/rivet-icons.tgz': resolution: {integrity: sha512-bA9qDpD/bhE9jycLN+PovCCfweFpSq+AIOl8W0/o5sZ8l8kF732DvXgvsAOLLzTUEpjsmU4U/RNGtRv/h5K17A==, tarball: file:frontend/vendor/rivet-icons.tgz} version: 25.5.3 @@ -3065,6 +3204,15 @@ packages: '@rushstack/ts-command-line@4.19.1': resolution: {integrity: sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==} + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@sentry-internal/browser-utils@8.55.0': resolution: {integrity: sha512-ROgqtQfpH/82AQIpESPqPQe0UyWywKJsmVIqi3c5Fh+zkds5LUxnssTj3yNd1x+kxaPDVB023jAP+3ibNgeNDw==} engines: {node: '>=14.18'} @@ -3215,6 +3363,10 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@stripe/stripe-js@5.6.0': + resolution: {integrity: sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw==} + engines: {node: '>=12.16'} + '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} @@ -3496,6 +3648,9 @@ packages: '@types/node@24.3.0': resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -3698,6 +3853,34 @@ packages: '@xtuc/long@4.2.2': resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + '@zxcvbn-ts/core@3.0.4': + resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==} + + '@zxcvbn-ts/language-common@3.0.4': + resolution: {integrity: sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==} + + abitype@1.1.0: + resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.1.1: + resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -3766,6 +3949,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + alien-signals@2.0.6: + resolution: {integrity: sha512-P3TxJSe31bUHBiblg59oU1PpaWPtmxF9GhJ/cB7OkgJ0qN/ifFSKUI25/v8ZhsT+lIG6ac8DpTOplXxORX6F3Q==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -3910,6 +4096,10 @@ packages: babel-dead-code-elimination@1.0.10: resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==} + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -3980,6 +4170,9 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browser-tabs-lock@1.3.0: + resolution: {integrity: sha512-g6nHaobTiT0eMZ7jh16YpD2kcjAp+PInbiVq3M1x6KKaEIVhT4v9oURNIpZLOZ3LQbQ3XYfNhMAb/9hzNLIWrw==} + browserslist@4.25.2: resolution: {integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4098,6 +4291,10 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -4163,6 +4360,9 @@ packages: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -4173,6 +4373,12 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + core-js@3.41.0: + resolution: {integrity: sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA==} + core-js@3.45.0: resolution: {integrity: sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==} @@ -4183,13 +4389,23 @@ packages: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -4430,6 +4646,9 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-abstract@1.24.0: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} @@ -4663,6 +4882,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -4712,6 +4934,10 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -4751,6 +4977,9 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -5034,6 +5263,9 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -5096,6 +5328,9 @@ packages: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} @@ -5245,6 +5480,11 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + iterator.prototype@1.1.5: resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} engines: {node: '>= 0.4'} @@ -5294,6 +5534,10 @@ packages: js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-sdsl@4.4.2: resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} @@ -5964,6 +6208,22 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.6: + resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -5993,6 +6253,10 @@ packages: parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} @@ -6158,6 +6422,9 @@ packages: rrweb-snapshot: optional: true + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + preact@10.27.0: resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==} @@ -6274,6 +6541,11 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qrcode.react@4.2.0: + resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -6459,6 +6731,9 @@ packages: resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regex-recursion@5.1.1: resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} @@ -6763,6 +7038,10 @@ packages: source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -6892,6 +7171,9 @@ packages: babel-plugin-macros: optional: true + stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -6909,6 +7191,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + swr@2.3.4: + resolution: {integrity: sha512-bYd2lrhc+VarcpkgWclcUi92wYCpOgMws9Sd1hG1ntAu0NEy+14CbotuFjshBU2kt9rYj9TSmDcybpxpeTU1fg==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} @@ -7021,6 +7308,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -7043,6 +7333,9 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-pattern@5.8.0: + resolution: {integrity: sha512-kIjN2qmWiHnhgr5DAkAafF9fwb0T5OhMVSWrm8XEdTFnX6+wfXwYOFjeF86UZ54vduqiR7BfqScFmXSzSaH8oA==} + tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -7323,6 +7616,14 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + viem@2.37.8: + resolution: {integrity: sha512-mL+5yvCQbRIR6QvngDQMfEiZTfNWfd+/QL5yFaOoYbpH3b1Q2ddwF7YG2eI2AcYSh9LE1gtUkbzZLFUAVyj4oQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + vite-node@1.6.1: resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -7555,6 +7856,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + yaml@2.8.1: resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} engines: {node: '>= 14.6'} @@ -7595,11 +7900,31 @@ packages: react: optional: true + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} snapshots: + '@adraffy/ens-normalize@1.11.1': {} + '@alloc/quick-lru@5.2.0': {} '@ampproject/remapping@2.3.0': @@ -7819,6 +8144,26 @@ snapshots: '@bare-ts/lib': 0.4.0 commander: 11.1.0 + '@base-org/account@2.0.1(@types/react@18.3.23)(react@19.1.1)(typescript@5.8.2)(use-sync-external-store@1.5.0(react@19.1.1))(zod@3.25.76)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.8.2)(zod@3.25.76) + preact: 10.24.2 + viem: 2.37.8(typescript@5.8.2)(zod@3.25.76) + zustand: 5.0.3(@types/react@18.3.23)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + '@biomejs/biome@2.1.4': optionalDependencies: '@biomejs/cli-darwin-arm64': 2.1.4 @@ -7872,6 +8217,77 @@ snapshots: '@cbor-extract/cbor-extract-win32-x64@2.2.0': optional: true + '@clerk/clerk-js@5.95.0(@types/react@18.3.23)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(typescript@5.8.2)(use-sync-external-store@1.5.0(react@19.1.1))(zod@3.25.76)': + dependencies: + '@base-org/account': 2.0.1(@types/react@18.3.23)(react@19.1.1)(typescript@5.8.2)(use-sync-external-store@1.5.0(react@19.1.1))(zod@3.25.76) + '@clerk/localizations': 3.25.3 + '@clerk/shared': 3.26.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@clerk/types': 4.88.0 + '@coinbase/wallet-sdk': 4.3.0 + '@emotion/cache': 11.11.0 + '@emotion/react': 11.11.1(@types/react@18.3.23)(react@19.1.1) + '@floating-ui/react': 0.27.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/react-dom': 2.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@formkit/auto-animate': 0.8.4 + '@stripe/stripe-js': 5.6.0 + '@swc/helpers': 0.5.17 + '@zxcvbn-ts/core': 3.0.4 + '@zxcvbn-ts/language-common': 3.0.4 + alien-signals: 2.0.6 + browser-tabs-lock: 1.3.0 + copy-to-clipboard: 3.3.3 + core-js: 3.41.0 + crypto-js: 4.2.0 + dequal: 2.0.3 + input-otp: 1.4.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + qrcode.react: 4.2.0(react@19.1.1) + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + regenerator-runtime: 0.14.1 + swr: 2.3.4(react@19.1.1) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - supports-color + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@clerk/clerk-react@5.48.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@clerk/shared': 3.26.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@clerk/types': 4.88.0 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tslib: 2.8.1 + + '@clerk/localizations@3.25.3': + dependencies: + '@clerk/types': 4.88.0 + + '@clerk/shared@3.26.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@clerk/types': 4.88.0 + dequal: 2.0.3 + glob-to-regexp: 0.4.1 + js-cookie: 3.0.5 + std-env: 3.9.0 + swr: 2.3.4(react@19.1.1) + optionalDependencies: + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + + '@clerk/themes@2.4.21': + dependencies: + '@clerk/types': 4.88.0 + tslib: 2.8.1 + + '@clerk/types@4.88.0': + dependencies: + csstype: 3.1.3 + '@codemirror/autocomplete@6.18.6': dependencies: '@codemirror/language': 6.11.3 @@ -7948,6 +8364,13 @@ snapshots: style-mod: 4.1.2 w3c-keyname: 2.2.8 + '@coinbase/wallet-sdk@4.3.0': + dependencies: + '@noble/hashes': 1.8.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + preact: 10.27.0 + '@corex/deepmerge@4.0.43': {} '@date-fns/utc@1.2.0': {} @@ -7957,6 +8380,72 @@ snapshots: tslib: 2.8.1 optional: true + '@emotion/babel-plugin@11.13.5': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/runtime': 7.28.3 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + + '@emotion/cache@11.11.0': + dependencies: + '@emotion/memoize': 0.8.1 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.3.1 + stylis: 4.2.0 + + '@emotion/hash@0.9.2': {} + + '@emotion/memoize@0.8.1': {} + + '@emotion/memoize@0.9.0': {} + + '@emotion/react@11.11.1(@types/react@18.3.23)(react@19.1.1)': + dependencies: + '@babel/runtime': 7.28.3 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.11.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.3.1 + hoist-non-react-statics: 3.3.2 + react: 19.1.1 + optionalDependencies: + '@types/react': 18.3.23 + transitivePeerDependencies: + - supports-color + + '@emotion/serialize@1.3.3': + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.1.3 + + '@emotion/sheet@1.4.0': {} + + '@emotion/unitless@0.10.0': {} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.1)': + dependencies: + react: 19.1.1 + + '@emotion/utils@1.4.2': {} + + '@emotion/weak-memoize@0.3.1': {} + '@esbuild/aix-ppc64@0.19.12': optional: true @@ -8210,8 +8699,18 @@ snapshots: react-dom: 19.1.1(react@19.1.1) tabbable: 6.2.0 + '@floating-ui/react@0.27.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + dependencies: + '@floating-ui/react-dom': 2.1.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@floating-ui/utils': 0.2.10 + react: 19.1.1 + react-dom: 19.1.1(react@19.1.1) + tabbable: 6.2.0 + '@floating-ui/utils@0.2.10': {} + '@formkit/auto-animate@0.8.4': {} + '@fortawesome/fontawesome-common-types@6.7.2': {} '@fortawesome/fontawesome-svg-core@6.7.2': @@ -8788,12 +9287,26 @@ snapshots: '@next/swc-win32-x64-msvc@15.5.2': optional: true - '@next/third-parties@15.5.2(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)': + '@next/third-parties@15.5.2(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)': dependencies: - next: 15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + next: 15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 third-party-capital: 1.0.20 + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.8.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -9443,13 +9956,25 @@ snapshots: transitivePeerDependencies: - debug - '@rivet-gg/icons@file:frontend/vendor/rivet-icons.tgz(@fortawesome/fontawesome-svg-core@6.7.2)(@fortawesome/free-brands-svg-icons@6.7.2)(@fortawesome/free-solid-svg-icons@6.7.2)(@fortawesome/react-fontawesome@0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1))(@types/node@20.19.9)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.43.1)': + '@rivet-gg/cloud@file:frontend/vendor/rivet-cloud.tgz': + dependencies: + cross-fetch: 4.1.0 + form-data: 4.0.4 + js-base64: 3.7.7 + node-fetch: 2.7.0 + qs: 6.14.0 + readable-stream: 4.7.0 + url-join: 5.0.0 + transitivePeerDependencies: + - encoding + + '@rivet-gg/icons@file:frontend/vendor/rivet-icons.tgz(@fortawesome/fontawesome-svg-core@6.7.2)(@fortawesome/free-brands-svg-icons@6.7.2)(@fortawesome/free-solid-svg-icons@6.7.2)(@fortawesome/react-fontawesome@0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1))(@types/node@20.19.9)(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(terser@5.43.1)': dependencies: '@fortawesome/fontawesome-svg-core': 6.7.2 '@fortawesome/free-brands-svg-icons': 6.7.2 '@fortawesome/free-solid-svg-icons': 6.7.2 '@fortawesome/react-fontawesome': 0.2.3(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.1.1) - dedent: 1.6.0 + dedent: 1.6.0(babel-plugin-macros@3.1.0) local-pkg: 0.5.1 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) @@ -9652,6 +10177,19 @@ snapshots: - '@types/node' optional: true + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@sentry-internal/browser-utils@8.55.0': dependencies: '@sentry/core': 8.55.0 @@ -9842,6 +10380,8 @@ snapshots: '@standard-schema/spec@1.0.0': {} + '@stripe/stripe-js@5.6.0': {} + '@swc/helpers@0.5.15': dependencies: tslib: 2.8.1 @@ -10159,6 +10699,8 @@ snapshots: dependencies: undici-types: 7.10.0 + '@types/parse-json@4.0.2': {} + '@types/prop-types@15.7.15': {} '@types/qs@6.9.8': {} @@ -10436,6 +10978,22 @@ snapshots: '@xtuc/long@4.2.2': {} + '@zxcvbn-ts/core@3.0.4': + dependencies: + fastest-levenshtein: 1.0.16 + + '@zxcvbn-ts/language-common@3.0.4': {} + + abitype@1.1.0(typescript@5.8.2)(zod@3.25.76): + optionalDependencies: + typescript: 5.8.2 + zod: 3.25.76 + + abitype@1.1.1(typescript@5.8.2)(zod@3.25.76): + optionalDependencies: + typescript: 5.8.2 + zod: 3.25.76 + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -10502,6 +11060,8 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + alien-signals@2.0.6: {} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -10670,6 +11230,12 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.28.3 + cosmiconfig: 7.1.0 + resolve: 1.22.10 + bail@2.0.2: {} balanced-match@1.0.2: {} @@ -10732,6 +11298,10 @@ snapshots: dependencies: fill-range: 7.1.1 + browser-tabs-lock@1.3.0: + dependencies: + lodash: 4.17.21 + browserslist@4.25.2: dependencies: caniuse-lite: 1.0.30001735 @@ -10865,6 +11435,8 @@ snapshots: client-only@0.0.1: {} + clsx@1.2.1: {} + clsx@2.1.1: {} cmdk@1.1.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): @@ -10930,12 +11502,20 @@ snapshots: consola@3.4.2: {} + convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} cookie-es@1.2.2: {} cookie@0.7.2: {} + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + core-js@3.41.0: {} + core-js@3.45.0: {} core-util-is@1.0.3: {} @@ -10945,14 +11525,30 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + crelt@1.0.6: {} + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -11045,7 +11641,9 @@ snapshots: dependencies: mimic-response: 3.1.0 - dedent@1.6.0: {} + dedent@1.6.0(babel-plugin-macros@3.1.0): + optionalDependencies: + babel-plugin-macros: 3.1.0 deep-eql@4.1.4: dependencies: @@ -11165,6 +11763,10 @@ snapshots: entities@4.5.0: {} + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + es-abstract@1.24.0: dependencies: array-buffer-byte-length: 1.0.2 @@ -11625,6 +12227,8 @@ snapshots: eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + events@3.3.0: {} execa@8.0.1: @@ -11673,6 +12277,8 @@ snapshots: fast-uri@3.1.0: {} + fastest-levenshtein@1.0.16: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -11709,6 +12315,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + find-root@1.1.0: {} + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -12090,6 +12698,8 @@ snapshots: dependencies: safer-buffer: 2.1.2 + idb-keyval@6.2.1: {} + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -12146,6 +12756,8 @@ snapshots: call-bound: 1.0.4 get-intrinsic: 1.3.0 + is-arrayish@0.2.1: {} + is-arrayish@0.3.2: {} is-async-function@2.1.1: @@ -12281,6 +12893,10 @@ snapshots: isexe@2.0.0: {} + isows@1.0.7(ws@8.18.3): + dependencies: + ws: 8.18.3 + iterator.prototype@1.1.5: dependencies: define-data-property: 1.1.4 @@ -12321,6 +12937,8 @@ snapshots: js-base64@3.7.7: {} + js-cookie@3.0.5: {} + js-sdsl@4.4.2: {} js-tokens@4.0.0: {} @@ -13085,20 +13703,20 @@ snapshots: neo-async@2.6.2: {} - next-router-mock@0.9.13(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1): + next-router-mock@0.9.13(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1): dependencies: - next: 15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + next: 15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 - next-sitemap@4.2.3(next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): + next-sitemap@4.2.3(next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.11 fast-glob: 3.3.3 minimist: 1.2.8 - next: 15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + next: 15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) - next@15.5.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + next@15.5.2(babel-plugin-macros@3.1.0)(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: '@next/env': 15.5.2 '@swc/helpers': 0.5.15 @@ -13106,7 +13724,7 @@ snapshots: postcss: 8.4.31 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) - styled-jsx: 5.1.6(react@19.1.1) + styled-jsx: 5.1.6(babel-plugin-macros@3.1.0)(react@19.1.1) optionalDependencies: '@next/swc-darwin-arm64': 15.5.2 '@next/swc-darwin-x64': 15.5.2 @@ -13237,6 +13855,35 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + ox@0.6.9(typescript@5.8.2)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.8.2)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.8.2)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.8.2)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - zod + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -13273,6 +13920,13 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + parse5@6.0.1: {} path-browserify@1.0.1: {} @@ -13413,6 +14067,8 @@ snapshots: preact: 10.27.0 web-vitals: 4.2.4 + preact@10.24.2: {} + preact@10.27.0: {} prebuild-install@7.1.3: @@ -13475,6 +14131,10 @@ snapshots: punycode@2.3.1: {} + qrcode.react@4.2.0(react@19.1.1): + dependencies: + react: 19.1.1 + qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -13711,6 +14371,8 @@ snapshots: get-proto: 1.0.1 which-builtin-type: 1.2.1 + regenerator-runtime@0.14.1: {} + regex-recursion@5.1.1: dependencies: regex: 5.1.1 @@ -14214,6 +14876,8 @@ snapshots: buffer-from: 1.1.2 source-map: 0.6.1 + source-map@0.5.7: {} + source-map@0.6.1: {} source-map@0.7.6: {} @@ -14351,10 +15015,14 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(react@19.1.1): + styled-jsx@5.1.6(babel-plugin-macros@3.1.0)(react@19.1.1): dependencies: client-only: 0.0.1 react: 19.1.1 + optionalDependencies: + babel-plugin-macros: 3.1.0 + + stylis@4.2.0: {} sucrase@3.35.0: dependencies: @@ -14376,6 +15044,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + swr@2.3.4(react@19.1.1): + dependencies: + dequal: 2.0.3 + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) + tabbable@6.2.0: {} tailwind-merge@2.6.0: {} @@ -14511,6 +15185,8 @@ snapshots: dependencies: is-number: 7.0.0 + toggle-selection@1.0.6: {} + tr46@0.0.3: {} tr46@1.0.1: @@ -14527,6 +15203,8 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-pattern@5.8.0: {} + tsconfck@3.1.6(typescript@5.8.2): optionalDependencies: typescript: 5.8.2 @@ -14922,6 +15600,23 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + viem@2.37.8(typescript@5.8.2)(zod@3.25.76): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.8.2)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3) + ox: 0.9.6(typescript@5.8.2)(zod@3.25.76) + ws: 8.18.3 + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + vite-node@1.6.1(@types/node@22.17.0)(terser@5.43.1): dependencies: cac: 6.7.14 @@ -15223,6 +15918,8 @@ snapshots: yallist@4.0.0: {} + yaml@1.10.2: {} + yaml@2.8.1: {} yocto-queue@0.1.0: {} @@ -15248,4 +15945,10 @@ snapshots: '@types/react': 18.3.23 react: 19.1.1 + zustand@5.0.3(@types/react@18.3.23)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)): + optionalDependencies: + '@types/react': 18.3.23 + react: 19.1.1 + use-sync-external-store: 1.5.0(react@19.1.1) + zwitch@2.0.4: {}