Repository: mozzius/community-handles
Branch: main
Commit: d33bb244e852
Files: 53
Total size: 131.2 KB
Directory structure:
gitextract_49tax7zj/
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .prettierignore
├── .vscode/
│ └── settings.json
├── README.md
├── app/
│ ├── [domain]/
│ │ ├── [handle]/
│ │ │ ├── .well-known/
│ │ │ │ └── atproto-did/
│ │ │ │ └── route.ts
│ │ │ ├── opengraph-image.tsx
│ │ │ └── page.tsx
│ │ ├── community/
│ │ │ ├── loading.tsx
│ │ │ └── page.tsx
│ │ ├── create-your-own/
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ └── page.tsx
│ └── layout.tsx
├── components/
│ ├── avatar.tsx
│ ├── icons.tsx
│ ├── layout.tsx
│ ├── link.tsx
│ ├── load-more.tsx
│ ├── main-nav.tsx
│ ├── profile.tsx
│ ├── site-header.tsx
│ ├── stage.tsx
│ ├── tailwind-indicator.tsx
│ ├── theme-provider.tsx
│ ├── theme-toggle.tsx
│ └── ui/
│ ├── button.tsx
│ ├── dialog.tsx
│ ├── input.tsx
│ ├── label.tsx
│ └── tabs.tsx
├── config/
│ └── site.ts
├── lib/
│ ├── atproto.ts
│ ├── db.ts
│ ├── fonts.ts
│ ├── slurs.ts
│ └── utils.ts
├── middleware.ts
├── next-env.d.ts
├── next.config.mjs
├── package.json
├── postcss.config.js
├── prettier.config.js
├── prisma/
│ ├── export.ts
│ ├── schema.prisma
│ └── seed.ts
├── styles/
│ └── globals.css
├── tailwind.config.js
├── tsconfig.json
├── tsconfig.tsbuildinfo
└── types/
└── nav.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
================================================
FILE: .eslintignore
================================================
dist/*
.cache
public
node_modules
*.esm.js
================================================
FILE: .eslintrc.json
================================================
{
"$schema": "https://json.schemastore.org/eslintrc",
"root": true,
"extends": [
"next/core-web-vitals",
"prettier",
"plugin:tailwindcss/recommended"
],
"plugins": ["tailwindcss"],
"rules": {
"@next/next/no-html-link-for-pages": "off",
"react/jsx-key": "off",
"tailwindcss/no-custom-classname": "off"
},
"settings": {
"tailwindcss": {
"callees": ["cn"],
"config": "./tailwind.config.js"
},
"next": {
"rootDir": ["./"]
}
},
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"parser": "@typescript-eslint/parser"
}
]
}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
.pnp
.pnp.js
# testing
coverage
# next.js
.next/
out/
build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# turbo
.turbo
.contentlayer
.env
.vercel
export/
================================================
FILE: .prettierignore
================================================
cache
.cache
package.json
package-lock.json
public
CHANGELOG.md
.yarn
dist
node_modules
.next
build
.contentlayer
================================================
FILE: .vscode/settings.json
================================================
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
================================================
FILE: README.md
================================================
# Bluesky Community Handles tool
Get your own community handle for Bluesky!
Go to https://swifties.social to join the swifties.social community.
## What is a community handle?
A domain that other people can have their own subdomain on. For example, [@mozzius.swifties.social](https://mozzius.swifties.social) is a community handle that is part of the https://swifties.social community.
## How do I get a community handle?
This tool lets members of your community easily get a community handle. Simply go to the domain, such as https://swifties.social, and follow the instructions.
## How do I host my own community handle tool?
If you want to set up your own community handle for your own community, you can use this tool. It's free and open source, and you can host it yourself.
> These instructions assume you have a basic understanding of Git, GitHub, and Vercel. It not the only way to host it (it's just a Next.js app) but it is probably the simplest way.
You will need to own a domain you want to use, and have a Vercel account linked to your GitHub.
### 1. Fork this repository
Fork this repository to your own GitHub account, and clone it to your local machine.
### 2. Add the project to Vercel
Add the project to Vercel using the "Add New..." button. You will need to link your GitHub account to Vercel if you haven't already.
It will detect that it's a Next.js project and set up the build settings for you. That's all fine, but you will need to set up the environment variables.
Once that's done, deploy the app
### 3. Set up the domain
Once it's done, go to Settings > Domains and add the domain you want to use. **Don't do the redirect stuff it recommends, just use the plain domain. It's the third option on the list**. It'll give you the nameservers your need to point the domain to - go back to your registrar and do that.
> IMPORTANT: Make sure you use nameservers, not DNS records. If you use DNS records, it won't work.
You'll then want to add a wildcard domain using a `*`, such as `*.swifties.social`. This catches all the requests to subdomains - we use Next.js middleware to route them to the right place.
### 4. Add your database
You'll need to add a database to store the community handles. We recommend using [Railway](https://railway.app), but you can use whatever you want - if it's not Postgres, you'll likely need to modify the Prisma file. Railway will likely be the simply way to set it up.
Create a Postgres database via Railway, then get the connection string once it's ready. You'll need to add the connection strings to the environment variables. Create a file called `.env` in the root of the project, and add the following:
```env
DATABASE_URL=
```
Then run the following commands in your terminal, in the project directory:
```bash
pnpm i
pnpm prisma db push
```
Then, in Vercel, go to Settings > Environment Variables and add the `DATABASE_URL` variable with the connection string. Re-deploy the Vercel app.
### 5. Done!
That's it! You should now be able to go to your domain and use the community handle tool.
> Remember it takes a few minutes for DNS to propagate, so it might not work straight away.
If you like the project, you can [sponsor me](https://github.com/sponsors/mozzius)! It's not required, but it's appreciated :)
================================================
FILE: app/[domain]/[handle]/.well-known/atproto-did/route.ts
================================================
import { type NextRequest } from "next/server"
import { prisma } from "@/lib/db"
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, OPTIONS",
"Access-Control-Allow-Headers": "*",
}
export const OPTIONS = async () => {
return new Response(null, {
status: 204,
headers: corsHeaders,
})
}
export const GET = async (
_req: NextRequest,
{ params }: { params: { domain: string; handle: string } }
) => {
const { did } = await prisma.user.findFirstOrThrow({
where: { handle: params.handle, domain: { name: params.domain } },
})
return new Response(did, {
headers: {
"content-type": "text/plain",
...corsHeaders,
},
})
}
================================================
FILE: app/[domain]/[handle]/opengraph-image.tsx
================================================
/* eslint-disable @next/next/no-img-element */
import { ImageResponse } from "next/og"
import { agent } from "@/lib/atproto"
export const size = {
width: 800,
height: 400,
}
export const contentType = "image/png"
export const runtime = "edge"
export default async function og({
params,
}: {
params: { domain: string; handle: string }
}) {
const { domain, handle } = params
const {
data: { did },
} = await agent.resolveHandle({ handle: `${handle}.${domain}` })
const profile = await agent.getProfile({
actor: did,
})
const fetchAvatar = profile.data.avatar
? fetch(profile.data.avatar).then((res) => res.arrayBuffer())
: Promise.resolve(null)
const fetchBanner = profile.data.banner
? fetch(profile.data.banner).then((res) => res.arrayBuffer())
: Promise.resolve(null)
const [avatar, banner] = await Promise.all([fetchAvatar, fetchBanner])
return new ImageResponse(
(
{banner && (
)}
{avatar ? (
) : (
)}
{profile.data.displayName && (
{profile.data.displayName}
)}
@{profile.data.handle}
),
{ ...size }
)
}
================================================
FILE: app/[domain]/[handle]/page.tsx
================================================
import { Metadata } from "next"
import { agent } from "@/lib/atproto"
import { prisma } from "@/lib/db"
import { Profile } from "@/components/profile"
interface Props {
params: { handle: string; domain: string }
}
export async function generateMetadata({ params }: Props): Promise {
const domain = params.domain
const user = await prisma.user.findFirst({
where: { handle: params.handle, domain: { name: domain } },
})
if (!user) {
return {
title: "Profile not found",
description: ":(",
}
}
const profile = await agent.getProfile({
actor: user.did,
})
return {
title: `${profile.data.displayName} - @${profile.data.handle}`,
description: profile.data.description,
}
}
export default async function HandlePage({ params }: Props) {
const { domain, handle } = params
try {
const user = await prisma.user.findFirstOrThrow({
where: { handle, domain: { name: domain } },
})
const profile = await agent.getProfile({
actor: user.did,
})
return (
)
} catch (e) {
console.error(e)
return (
)
}
}
================================================
FILE: app/[domain]/community/loading.tsx
================================================
import { LoaderIcon } from "lucide-react"
export default function Loading() {
return (
)
}
================================================
FILE: app/[domain]/community/page.tsx
================================================
import { type Metadata } from "next"
import { AppBskyActorDefs } from "@atproto/api"
import { agent } from "@/lib/atproto"
import { prisma } from "@/lib/db"
import { Link } from "@/components/link"
import { LoadMore } from "@/components/load-more"
import { Profile } from "@/components/profile"
export const revalidate = 3600
interface Props {
params: { domain: string }
}
export async function generateMetadata({ params }: Props): Promise {
const domain = params.domain
return {
title: `The ${domain} Community`,
description: `See all the members of the ${domain} community.`,
}
}
const PAGE_SIZE = 100
export default async function CommunityPage({ params }: Props) {
const domain = params.domain
const [count, { profiles: initialProfiles, nextOffset }] = await Promise.all([
prisma.user.count({
where: { domain: { name: domain } },
}),
getUsers(domain),
])
return (
The {domain}
community
Want to join the {count} members of the {domain} community? Get your
own{" "}
{domain} handle
.
)
}
function ProfileListSection({
profiles,
}: {
profiles: AppBskyActorDefs.ProfileViewDetailed[]
}) {
return profiles.map((profile) => (
))
}
async function getUsers(domain: string, offset = 0) {
const users = await prisma.user.findMany({
where: { domain: { name: domain } },
select: { did: true },
take: PAGE_SIZE,
skip: offset,
})
const nextOffset = users.length >= PAGE_SIZE ? offset + PAGE_SIZE : null
if (users.length === 0) {
return {
profiles: [],
nextOffset,
}
}
// fetch profiles in chunks of 25
const chunks = []
for (let i = 0; i < PAGE_SIZE; i += 25) {
const chunk = users.slice(i, i + 25).map(({ did }) => did)
if (chunk.length > 0) {
chunks.push(chunk)
}
}
// jealous of postfix await :(
const responses = await Promise.all(
chunks.map((actors) => agent.getProfiles({ actors }))
)
const profiles = responses
.flatMap((response) => response.data.profiles)
.filter(
(value, index, array) =>
array.findIndex(({ did }) => did === value.did) === index &&
value.handle.endsWith(domain)
)
return {
profiles,
nextOffset,
}
}
async function loadMoreUsers(domain: string, offset = 0) {
"use server"
const { profiles, nextOffset } = await getUsers(domain, offset)
return [
,
nextOffset,
] as const
}
================================================
FILE: app/[domain]/create-your-own/page.tsx
================================================
import { ArrowRight } from "lucide-react"
import { Button, buttonVariants } from "@/components/ui/button"
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Stage } from "@/components/stage"
export const metadata = {
title: "Create a Community Handle for your community",
description: "Host your own tool",
}
export default function CommunityPage() {
return (
Create a Community Handle
for your community
Want a custom community handle for your community, like
@alex.swifties.social, @jay.army.social, or @jane.kawaii.social? Follow
these steps to get one.
Buy a domain from a domain registrar. We use{" "}
Namecheap
, but it doesn't matter which one you use. Just make sure you
are able to change where you point the nameservers.
You then need to host the tool.
If you want to host it yourself,{" "}
fork the project on GitHub
. It{"'"}s a Next.js project, so you can deploy it however you like.
Check out the README for the recommended solution, using Vercel and
Railway.
Using the hosted version? (no longer available){" "}
Go to the billing portal
.
)
}
================================================
FILE: app/[domain]/layout.tsx
================================================
import NextPlausible from "next-plausible"
import { siteConfig } from "@/config/site"
import { MainNav } from "@/components/main-nav"
import { SiteHeader } from "@/components/site-header"
interface Props {
children: React.ReactNode
params: { domain: string }
}
export default function DomainLayout({ children, params }: Props) {
return (
<>
{children}
>
)
}
================================================
FILE: app/[domain]/page.tsx
================================================
import { AppBskyActorDefs } from "@atproto/api"
import { Check, X } from "lucide-react"
import { agent } from "@/lib/atproto"
import { prisma } from "@/lib/db"
import { hasExplicitSlur } from "@/lib/slurs"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Profile } from "@/components/profile"
import { Stage } from "@/components/stage"
export function generateMetadata({ params }: { params: { domain: string } }) {
const domain = params.domain
return {
title: `${domain} - get your community handle for Bluesky`,
description: `get your own ${domain} handle`,
}
}
export default async function IndexPage({
params,
searchParams,
}: {
params: {
domain: string
}
searchParams: {
handle?: string
"new-handle"?: string
}
}) {
const domain = params.domain
let handle = searchParams.handle
let newHandle = searchParams["new-handle"]
let profile: AppBskyActorDefs.ProfileView | undefined
let error1: string | undefined
let error2: string | undefined
if (handle) {
try {
if (!handle.includes(".")) {
handle += ".bsky.social"
}
console.log("fetching profile", handle)
const actor = await agent.getProfile({
actor: handle,
})
if (!actor.success) throw new Error("fetch was not a success")
profile = actor.data
} catch (e) {
console.error(e)
error1 = (e as Error)?.message ?? "unknown error"
}
if (newHandle && profile) {
newHandle = newHandle.trim().toLowerCase()
if (!newHandle.includes(".")) {
newHandle += "." + domain
}
if (!error1) {
// regex: (alphanumeric, -, _).(domain)
const validHandle = newHandle.match(
new RegExp(`^[a-zA-Z0-9-_]+.${domain}$`)
)
if (validHandle) {
try {
const handle = newHandle.replace(`.${domain}`, "")
if (hasExplicitSlur(handle)) {
throw new Error("slur")
}
if (domain === "army.social" && RESERVED.includes(handle)) {
throw new Error("reserved")
}
const existing = await prisma.user.findFirst({
where: { handle },
include: { domain: true },
})
if (existing && existing.domain.name === domain) {
if (existing.did !== profile.did) {
error2 = "handle taken"
}
} else {
await prisma.user.create({
data: {
handle,
did: profile.did,
domain: {
connectOrCreate: {
where: { name: domain },
create: { name: domain },
},
},
},
})
}
} catch (e) {
console.error(e)
error2 = (e as Error)?.message ?? "unknown error"
}
} else {
error2 = "invalid handle"
}
}
}
}
return (
Get your own {domain}
handle for Bluesky
Follow the instructions below to get your own {domain} handle
Go to Settings {">"} Advanced {">"} Change my handle. Select "I
have my own domain" and enter{" "}
{newHandle ? `"${newHandle}"` : "your new handle"}. Finally, tap
"Verify DNS Record".
If you like this project, consider{" "}
sponsoring my work
.
)
}
const RESERVED = [
"Jungkook",
"JeonJungkook",
"Jeon",
"JK",
"JJK",
"Kim",
"KimTaehyung",
"V",
"Taehyung",
"Tae",
"Jin",
"Seokjin",
"KimSeokjin",
"RM",
"Namjoon",
"Nam",
"KimNamjoon",
"MinYoongi",
"Yoongi",
"Yoon",
"AgustD",
"MYG",
"Suga",
"PJM",
"Jimin",
"ParkJimin",
"Park",
"Abcdefghi__lmnopqrsvuxyz",
"JM",
"UarMyHope",
"Rkrive",
"THV",
"KTH",
"SBT",
"BANGPD",
"projeto",
"army",
"armys ",
"info",
"projects",
"Pic",
"New",
"Babys",
].map((x) => x.toLowerCase())
================================================
FILE: app/layout.tsx
================================================
import { type Metadata, type Viewport } from "next"
import { fontSans } from "@/lib/fonts"
import { cn } from "@/lib/utils"
import { TailwindIndicator } from "@/components/tailwind-indicator"
import { ThemeProvider } from "@/components/theme-provider"
import "@/styles/globals.css"
export const metadata: Metadata = {
icons: {
icon: "/favicon.ico",
shortcut: "/favicon-16x16.png",
apple: "/apple-touch-icon.png",
},
}
export const viewport: Viewport = {
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "white" },
{ media: "(prefers-color-scheme: dark)", color: "black" },
],
}
interface RootLayoutProps {
children: React.ReactNode
}
export default function RootLayout({ children }: RootLayoutProps) {
return (
<>
{children}
>
)
}
================================================
FILE: components/avatar.tsx
================================================
/* eslint-disable @next/next/no-img-element */
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
export function Avatar({
src,
alt,
fallback,
className,
}: {
src?: string
alt: string
fallback?: string
className?: string
}) {
const [loaded, setLoaded] = React.useState(false)
return (
{src && (
setLoaded(true)}
/>
)}
{!loaded && (
{fallback}
)}
)
}
================================================
FILE: components/icons.tsx
================================================
import {
AtSign,
LucideProps,
Moon,
SunMedium,
type LucideIcon,
} from "lucide-react"
export type Icon = LucideIcon
export const Icons = {
sun: SunMedium,
moon: Moon,
logo: AtSign,
gitHub: (props: LucideProps) => (
),
}
================================================
FILE: components/layout.tsx
================================================
import { SiteHeader } from "@/components/site-header"
interface LayoutProps {
children: React.ReactNode
}
export function Layout({ children }: LayoutProps) {
return (
<>
{children}
>
)
}
================================================
FILE: components/link.tsx
================================================
"use client"
import NextLink, { type LinkProps } from "next/link"
import { getDomain } from "@/lib/utils"
interface Props
extends LinkProps,
Omit, keyof LinkProps> {}
export function Link({ href, ...props }: Props) {
if (typeof href === "string" && typeof window !== "undefined") {
const { subdomain, domain } = getDomain(window.location.hostname)
if (!!subdomain) {
return
} else {
return
}
} else {
return
}
}
================================================
FILE: components/load-more.tsx
================================================
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
interface Props {
children: React.ReactNode
domain: string
initialOffset: number | null
loadMoreAction: (
domain: string,
offset: number
) => Promise
className?: string
}
export function LoadMore({
children,
domain,
initialOffset,
loadMoreAction,
className,
}: Props) {
const ref = React.useRef(null)
const [loadMoreNodes, setLoadMoreNodes] = React.useState<
React.ReactElement[]
>([])
const [disabled, setDisabled] = React.useState(initialOffset === null)
const currentOffsetRef = React.useRef(initialOffset)
const [loading, setLoading] = React.useState(false)
const loadMore = React.useCallback(
async (abortController?: AbortController) => {
if (currentOffsetRef.current === null) {
setDisabled(true)
return
}
setLoading(true)
try {
const [nodes, next] = await loadMoreAction(
domain,
currentOffsetRef.current
)
if (abortController?.signal.aborted) return
currentOffsetRef.current = next
setLoadMoreNodes((prev) => [...prev, nodes])
if (next === null) {
setDisabled(true)
return
}
} finally {
setLoading(false)
}
},
[domain, loadMoreAction]
)
React.useEffect(() => {
const signal = new AbortController()
const element = ref.current
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting && element?.disabled === false) {
loadMore(signal)
}
})
if (element) {
observer.observe(element)
}
return () => {
signal.abort()
observer.disconnect()
}
}, [loadMore])
return (
<>
{children}
{loadMoreNodes}
loadMore()}
>
{loading ? "Loading..." : "Load More"}
>
)
}
================================================
FILE: components/main-nav.tsx
================================================
"use client"
import * as React from "react"
import { NavItem } from "@/types/nav"
import { cn } from "@/lib/utils"
import { Icons } from "@/components/icons"
import { Link } from "@/components/link"
interface MainNavProps {
title: string
items?: NavItem[]
}
export function MainNav({ title, items }: MainNavProps) {
const base = typeof window !== "undefined" ? window.location.host : ""
const isLocalhost = base.includes("localhost")
const prefix = isLocalhost ? "/swifties.social" : ""
return (
{title}
{items?.length ? (
{items?.map(
(item, index) =>
item.href && (
{item.title}
)
)}
) : null}
)
}
================================================
FILE: components/profile.tsx
================================================
/* eslint-disable @next/next/no-img-element */
import { AppBskyActorDefs } from "@atproto/api"
import { cn } from "@/lib/utils"
import { Avatar } from "./avatar"
interface Props {
profile: AppBskyActorDefs.ProfileViewDetailed
className?: string
}
export function Profile({ profile, className }: Props) {
return (
{profile.banner ? (
) : (
)}
{profile.displayName || profile.handle}
@{profile.handle}
)
}
================================================
FILE: components/site-header.tsx
================================================
"use client"
import { useState } from "react"
import { Menu, X } from "lucide-react"
import { type NavItem } from "@/types/nav"
import { siteConfig } from "@/config/site"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
import { Icons } from "@/components/icons"
import { Link } from "@/components/link"
import { ThemeToggle } from "@/components/theme-toggle"
interface Props {
children?: React.ReactNode
items?: NavItem[]
}
export function SiteHeader({ children }: Props) {
const [showMenu, setShowMenu] = useState(false)
const links = (
GitHub
)
const MenuIcon = showMenu ? X : Menu
return (
<>
{children}
setShowMenu((m) => !m)}
/>
{links}
{siteConfig.mainNav.map(
(item, index) =>
item.href && (
setShowMenu(false)}
>
{item.title}
)
)}
{links}
{/* Backdrop */}
setShowMenu(false)}
/>
>
)
}
================================================
FILE: components/stage.tsx
================================================
import { cn } from "@/lib/utils"
interface Props {
number: number
title: string
disabled?: boolean
last?: boolean
children?: React.ReactNode
}
export function Stage({ number, title, disabled, last, children }: Props) {
return (
)
}
================================================
FILE: components/tailwind-indicator.tsx
================================================
export function TailwindIndicator() {
if (process.env.NODE_ENV === "production") return null
return (
)
}
================================================
FILE: components/theme-provider.tsx
================================================
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { ThemeProviderProps } from "next-themes/dist/types"
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return
{children}
}
================================================
FILE: components/theme-toggle.tsx
================================================
"use client"
import * as React from "react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"
import { Icons } from "@/components/icons"
export function ThemeToggle() {
const { setTheme, theme } = useTheme()
return (
setTheme(theme === "light" ? "dark" : "light")}
>
Toggle theme
)
}
================================================
FILE: components/ui/button.tsx
================================================
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes
,
VariantProps {
asChild?: boolean
}
const Button = React.forwardRef(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
)
}
)
Button.displayName = "Button"
export { Button, buttonVariants }
================================================
FILE: components/ui/dialog.tsx
================================================
"use client"
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { cn } from "@/lib/utils"
const Dialog = DialogPrimitive.Root
const DialogTrigger = DialogPrimitive.Trigger
const DialogPortal = DialogPrimitive.Portal
const DialogClose = DialogPrimitive.Close
const DialogOverlay = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
const DialogContent = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, children, ...props }, ref) => (
{children}
Close
))
DialogContent.displayName = DialogPrimitive.Content.displayName
const DialogHeader = ({
className,
...props
}: React.HTMLAttributes) => (
)
DialogHeader.displayName = "DialogHeader"
const DialogFooter = ({
className,
...props
}: React.HTMLAttributes) => (
)
DialogFooter.displayName = "DialogFooter"
const DialogTitle = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
DialogTitle.displayName = DialogPrimitive.Title.displayName
const DialogDescription = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
DialogPortal,
DialogOverlay,
DialogClose,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}
================================================
FILE: components/ui/input.tsx
================================================
import * as React from "react"
import { cn } from "@/lib/utils"
export interface InputProps
extends React.InputHTMLAttributes {}
const Input = React.forwardRef(
({ className, type, ...props }, ref) => {
return (
)
}
)
Input.displayName = "Input"
export { Input }
================================================
FILE: components/ui/label.tsx
================================================
"use client"
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)
const Label = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef &
VariantProps
>(({ className, ...props }, ref) => (
))
Label.displayName = LabelPrimitive.Root.displayName
export { Label }
================================================
FILE: components/ui/tabs.tsx
================================================
"use client"
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
import { cn } from "@/lib/utils"
const Tabs = TabsPrimitive.Root
const TabsList = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
TabsList.displayName = TabsPrimitive.List.displayName
const TabsTrigger = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
const TabsContent = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => (
))
TabsContent.displayName = TabsPrimitive.Content.displayName
export { Tabs, TabsList, TabsTrigger, TabsContent }
================================================
FILE: config/site.ts
================================================
export type SiteConfig = typeof siteConfig
export const siteConfig = {
mainNav: [
{
title: "Join the community",
href: "/",
},
{
title: "Members",
href: "/community",
},
{
title: "Create your own community handle",
href: "/create-your-own",
},
],
links: {
github: "https://github.com/mozzius/community-handles",
},
}
================================================
FILE: lib/atproto.ts
================================================
import { BskyAgent, jsonToLex, stringifyLex } from "@atproto/api"
BskyAgent.configure({
fetch: async (reqUri, reqMethod, reqHeaders, reqBody) => {
const reqMimeType = reqHeaders["Content-Type"] || reqHeaders["content-type"]
if (reqMimeType && reqMimeType.startsWith("application/json")) {
reqBody = stringifyLex(reqBody)
}
const res = await fetch(reqUri, {
method: reqMethod,
headers: reqHeaders,
body: reqBody,
cache: "no-cache",
})
const resStatus = res.status
const resHeaders: Record = {}
res.headers.forEach((value: string, key: string) => {
resHeaders[key] = value
})
const resMimeType = resHeaders["Content-Type"] || resHeaders["content-type"]
let resBody
if (resMimeType) {
if (resMimeType.startsWith("application/json")) {
resBody = jsonToLex(await res.json())
} else if (resMimeType.startsWith("text/")) {
resBody = await res.text()
} else {
throw new Error("TODO: non-textual response body")
}
}
return {
status: resStatus,
headers: resHeaders,
body: resBody,
}
},
})
export const agent = new BskyAgent({
service: "https://public.api.bsky.app",
})
================================================
FILE: lib/db.ts
================================================
import { PrismaClient } from "@prisma/client"
const globalForPrisma = global as unknown as {
prisma: PrismaClient | undefined
}
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log: ["query"],
})
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
================================================
FILE: lib/fonts.ts
================================================
import { JetBrains_Mono as FontMono, Inter as FontSans } from "next/font/google"
export const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
})
export const fontMono = FontMono({
subsets: ["latin"],
variable: "--font-mono",
})
================================================
FILE: lib/slurs.ts
================================================
// RIPPED STRAIGHT OUT OF ATPROTO
// ALL CREDIT TO THEM ETC
// regexes taken from: https://github.com/Blank-Cheque/Slurs
/* eslint-disable no-misleading-character-class */
const explicitSlurRegexes = [
/\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][hĤĥȞȟḦḧḢḣḨḩḤḥḪḫH̱ẖĦħⱧⱨꞪɦꞕΗНн][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/,
/\b[cĆćĈĉČčĊċÇçḈḉȻȼꞒꞓꟄꞔƇƈɕ][ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0]{2}[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/,
/[fḞḟƑƒꞘꞙᵮᶂ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa@4][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{1,2}([ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeiÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ]{1,2}([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/,
/\b[kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLlyÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ][kḰḱǨǩĶķḲḳḴḵƘƙⱩⱪᶄꝀꝁꝂꝃꝄꝅꞢꞣ][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]([rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe])?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]*\b/,
/\b([sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ][a4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][dĎďḊḋḐḑD̦d̦ḌḍḒḓḎḏĐđÐðƉɖƊɗᵭᶁᶑȡ])?[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn][iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLloÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOoІіa4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]{1,2}(l[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]t|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEeaÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ]?|n[ÓóÒòŎŏÔôỐốỒồỖỗỔổǑǒÖöȪȫŐőÕõṌṍṎṏȬȭȮȯO͘o͘ȰȱØøǾǿǪǫǬǭŌōṒṓṐṑỎỏȌȍȎȏƠơỚớỜờỠỡỞởỢợỌọỘộO̩o̩Ò̩ò̩Ó̩ó̩ƟɵꝊꝋꝌꝍⱺOo0][gǴǵĞğĜĝǦǧĠġG̃g̃ĢģḠḡǤǥꞠꞡƓɠᶃꬶGgqꝖꝗꝘꝙɋʠ]|[a4ÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa]?)?[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/,
/\b[tŤťṪṫŢţṬṭȚțṰṱṮṯŦŧȾⱦƬƭƮʈT̈ẗᵵƫȶ][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ][aÁáÀàĂăẮắẰằẴẵẲẳÂâẤấẦầẪẫẨẩǍǎÅåǺǻÄäǞǟÃãȦȧǠǡĄąĄ́ą́Ą̃ą̃ĀāĀ̀ā̀ẢảȀȁA̋a̋ȂȃẠạẶặẬậḀḁȺⱥꞺꞻᶏẚAa4]+[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ƝɲŊŋꞐꞑꞤꞥᵰᶇɳȵꬻꬼИиПпNn]{1,2}([iÍíi̇́Ììi̇̀ĬĭÎîǏǐÏïḮḯĨĩi̇̃ĮįĮ́į̇́Į̃į̇̃ĪīĪ̀ī̀ỈỉȈȉI̋i̋ȊȋỊịꞼꞽḬḭƗɨᶖİiIıIi1lĺľļḷḹl̃ḽḻłŀƚꝉⱡɫɬꞎꬷꬸꬹᶅɭȴLl][e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe]|[yÝýỲỳŶŷY̊ẙŸÿỸỹẎẏȲȳỶỷỴỵɎɏƳƴỾỿ]|[e3ЄєЕеÉéÈèĔĕÊêẾếỀềỄễỂểÊ̄ê̄Ê̌ê̌ĚěËëẼẽĖėĖ́ė́Ė̃ė̃ȨȩḜḝĘęĘ́ę́Ę̃ę̃ĒēḖḗḔḕẺẻȄȅE̋e̋ȆȇẸẹỆệḘḙḚḛɆɇE̩e̩È̩è̩É̩é̩ᶒⱸꬴꬳEe][rŔŕŘřṘṙŖŗȐȑȒȓṚṛṜṝṞṟR̃r̃ɌɍꞦꞧⱤɽᵲᶉꭉ])[sŚśṤṥŜŝŠšṦṧṠṡŞşṢṣṨṩȘșS̩s̩ꞨꞩⱾȿꟅʂᶊᵴ]?\b/,
]
const indianSlurs = [
"Hijra",
"Bhangi",
"Kutta",
"Malech",
"Dhobi",
"Chamar",
"Chandaal",
"Pariah",
"Mahar",
"Kanjar",
"Bajaari",
"Avusaari",
"Avisaari",
"Thevadiya",
"Chappri",
"Bhand",
"Chinki",
"Kallu",
"Chuhra",
"Harijan",
"Dhedhgujari",
"Kasai",
"Jungli",
"Mala Mokam",
"Madiga Chestalu",
"Wadar",
"Poramboke",
"Kameena",
"Kameeni",
"Yanaadibuddulu",
"Budabukkaladana",
"Nakkalollapanulu",
"Lambadi",
"ChambarChoukashi",
"Yerukalollu",
"Kachra",
"Maharki",
"Ricebag",
]
export const hasExplicitSlur = (handle: string): boolean => {
const lowercaseHandle = handle.toLowerCase()
return (
explicitSlurRegexes.some((reg) => reg.test(lowercaseHandle)) ||
indianSlurs.map((x) => x.toLowerCase()).includes(lowercaseHandle)
)
}
================================================
FILE: lib/utils.ts
================================================
import { clsx, type ClassValue } from "clsx"
import psl from "psl"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
export function getDomain(host: string) {
const domain = psl.parse(host)
if (domain.error) throw new Error(domain.error.message)
return domain
}
================================================
FILE: middleware.ts
================================================
import { NextResponse, type NextRequest } from "next/server"
import { getDomain } from "./lib/utils"
export function middleware(request: NextRequest) {
const url = new URL(request.url)
const { domain, subdomain } = getDomain(url.hostname)
if (domain) {
if (subdomain && subdomain !== process.env.LANDING_SUBDOMAIN) {
return NextResponse.rewrite(
new URL(`/${domain}/${subdomain}${url.pathname}${url.search}`, url)
)
} else {
return NextResponse.rewrite(
new URL(`/${domain}${url.pathname}${url.search}`, url)
)
}
}
}
export const config = {
matcher: [
/*
* Match all paths except for:
* 1. /api routes
* 2. /_next (Next.js internals)
* 3. all root files inside /public (e.g. /favicon.ico)
* 4. opengraph images (e.g. /[a-z0-9-_.]/[a-z0-9-_]/opengraph-image)
* 5. Plausible analytics script
*/
"/((?!api/|_next/|_static/|js/|proxy/|[\\w-]+\\.\\w+|[a-zA-Z0-9-_.]+/[a-zA-Z0-9-_]+/opengraph-image).*)",
],
}
================================================
FILE: next-env.d.ts
================================================
///
///
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
================================================
FILE: next.config.mjs
================================================
import { withPlausibleProxy } from "next-plausible"
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
export default withPlausibleProxy({
customDomain: "https://plausible.mozzius.dev",
})(nextConfig)
================================================
FILE: package.json
================================================
{
"name": "next-template",
"version": "0.0.2",
"private": true,
"packageManager": "pnpm@10.25.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint:fix": "next lint --fix",
"preview": "next build && next start",
"typecheck": "tsc --noEmit",
"format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
"postinstall": "prisma generate",
"studio": "prisma studio",
"export": "tsx prisma/export.ts"
},
"dependencies": {
"@atproto/api": "^0.12.29",
"@prisma/client": "5.18.0",
"@radix-ui/react-avatar": "^1.1.0",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@types/psl": "^1.1.3",
"@vercel/kv": "^2.0.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"lucide-react": "0.427.0",
"next": "14.2.35",
"next-plausible": "^3.12.4",
"next-themes": "^0.3.0",
"prettier-plugin-tailwindcss": "^0.6.6",
"psl": "^1.9.0",
"react": "^18.3.1",
"react-day-picker": "^9.0.8",
"react-dom": "^18.3.1",
"sharp": "^0.33.4",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
"@types/node": "^22.2.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/parser": "^8.0.1",
"autoprefixer": "^10.4.20",
"eslint": "^8.57.0",
"eslint-config-next": "14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react": "^7.35.0",
"eslint-plugin-tailwindcss": "^3.17.4",
"postcss": "^8.4.41",
"prettier": "^3.3.3",
"prisma": "^5.18.0",
"tailwindcss": "^3.4.9",
"tsx": "^4.17.0",
"typescript": "^5.5.4"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
}
}
================================================
FILE: postcss.config.js
================================================
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
================================================
FILE: prettier.config.js
================================================
/** @type {import('prettier').Config} */
module.exports = {
endOfLine: "lf",
semi: false,
singleQuote: false,
tabWidth: 2,
trailingComma: "es5",
importOrder: [
"^(react/(.*)$)|^(react$)",
"^(next/(.*)$)|^(next$)",
"",
"",
"^types$",
"^@/types/(.*)$",
"^@/config/(.*)$",
"^@/lib/(.*)$",
"^@/hooks/(.*)$",
"^@/components/ui/(.*)$",
"^@/components/(.*)$",
"^@/styles/(.*)$",
"^@/app/(.*)$",
"",
"^[./]",
],
importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
plugins: [
"@ianvs/prettier-plugin-sort-imports",
"prettier-plugin-tailwindcss",
],
}
================================================
FILE: prisma/export.ts
================================================
import fs from "node:fs"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
async function main() {
if (!fs.existsSync("./export")) {
fs.mkdirSync("./export")
}
for (const domain of await prisma.domain.findMany()) {
console.log(domain.name)
let csv: string[][] = [["handle", "did", "createdAt"]]
const users = await prisma.user.findMany({
where: { domainId: domain.id },
})
for (const user of users) {
csv.push([user.handle, user.did, user.createdAt.toISOString()])
}
fs.writeFileSync(
`./export/${domain.name.replace(".", "_")}.csv`,
csv.map((row) => row.join(",")).join("\n")
)
}
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
================================================
FILE: prisma/schema.prisma
================================================
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Domain {
id String @id @default(uuid())
name String @unique
users User[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model User {
id String @id @default(uuid())
did String
handle String
domainId String
domain Domain @relation(fields: [domainId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([handle, domainId])
}
================================================
FILE: prisma/seed.ts
================================================
import { PrismaClient } from "@prisma/client"
import { kv } from "@vercel/kv"
const prisma = new PrismaClient()
async function main() {
const keys = await kv.keys("*")
for (const key of keys) {
const did = (await kv.get(key)) as string
const [handle, ...rest] = key.split(".")
const domain = rest.join(".")
await prisma.user.create({
data: {
did,
handle,
domain: {
connectOrCreate: {
where: {
name: domain,
},
create: {
name: domain,
},
},
},
},
})
console.log("Added", key, did)
}
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
================================================
FILE: styles/globals.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 47.4% 11.2%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--card: 0 0% 100%;
--card-foreground: 222.2 47.4% 11.2%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 100% 50%;
--destructive-foreground: 210 40% 98%;
--ring: 215 20.2% 65.1%;
--radius: 0.5rem;
}
.dark {
--background: 224 71% 4%;
--foreground: 213 31% 91%;
--muted: 223 47% 11%;
--muted-foreground: 215.4 16.3% 56.9%;
--accent: 216 34% 17%;
--accent-foreground: 210 40% 98%;
--popover: 224 71% 4%;
--popover-foreground: 215 20.2% 65.1%;
--border: 216 34% 17%;
--input: 216 34% 17%;
--card: 224 71% 4%;
--card-foreground: 213 31% 91%;
--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 1.2%;
--secondary: 222.2 47.4% 11.2%;
--secondary-foreground: 210 40% 98%;
--destructive: 0 63% 31%;
--destructive-foreground: 210 40% 98%;
--ring: 216 34% 17%;
--radius: 0.5rem;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
================================================
FILE: tailwind.config.js
================================================
const { fontFamily } = require("tailwindcss/defaultTheme")
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
},
borderRadius: {
lg: `var(--radius)`,
md: `calc(var(--radius) - 2px)`,
sm: "calc(var(--radius) - 4px)",
},
fontFamily: {
sans: ["var(--font-sans)", ...fontFamily.sans],
},
keyframes: {
"accordion-down": {
from: { height: 0 },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: 0 },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
}
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
},
"plugins": [
{
"name": "next"
}
],
"strictNullChecks": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
================================================
FILE: tsconfig.tsbuildinfo
================================================
{"program":{"fileNames":["../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@4.9.5/node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/styled-jsx/types/css.d.ts","../../node_modules/.pnpm/@types+react@18.0.22/node_modules/@types/react/global.d.ts","../../node_modules/.pnpm/csstype@3.1.2/node_modules/csstype/index.d.ts","../../node_modules/.pnpm/@types+prop-types@15.7.5/node_modules/@types/prop-types/index.d.ts","../../node_modules/.pnpm/@types+scheduler@0.16.3/node_modules/@types/scheduler/tracing.d.ts","../../node_modules/.pnpm/@types+react@18.0.22/node_modules/@types/react/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/styled-jsx/types/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/styled-jsx/types/macro.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/styled-jsx/types/style.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/styled-jsx/types/global.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/amp.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/amp.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/assert.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/assert/strict.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/globals.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/async_hooks.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/buffer.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/child_process.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/cluster.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/console.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/constants.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/crypto.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/dgram.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/dns.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/dns/promises.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/domain.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/events.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/fs.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/fs/promises.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/http.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/http2.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/https.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/inspector.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/module.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/net.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/os.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/path.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/perf_hooks.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/process.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/punycode.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/querystring.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/readline.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/repl.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/stream.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/stream/promises.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/stream/consumers.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/stream/web.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/string_decoder.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/timers.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/timers/promises.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/tls.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/trace_events.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/tty.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/url.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/util.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/v8.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/vm.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/wasi.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/worker_threads.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/zlib.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/globals.global.d.ts","../../node_modules/.pnpm/@types+node@17.0.12/node_modules/@types/node/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/get-page-files.d.ts","../../node_modules/.pnpm/@types+react-dom@18.0.7/node_modules/@types/react-dom/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/webpack/webpack.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/config.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/load-custom-routes.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/image-config.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/body-streams.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-kind.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-definitions/route-definition.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matches/route-match.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/request-meta.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/config-shared.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/base-http/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/api-utils/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/initialize-require-hook.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/node-polyfill-fetch.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/node-polyfill-web-streams.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matchers/route-matcher.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matcher-providers/route-matcher-provider.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/helpers/i18n-provider.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matcher-managers/route-matcher-manager.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/router.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/analysis/get-page-static-info.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/render-result.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/next-url.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/cookies.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/request.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/response.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/setup-exception-listeners.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/send-payload/revalidate-headers.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/send-payload/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/base-http/node.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/font-utils.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/load-components.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/render.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/response-cache/types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/response-cache/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/helpers/module-loader/module-loader.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-definitions/app-route-route-definition.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/coalesced-function.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/lib/incremental-cache/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/static-generation-async-storage.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/hooks-server-context.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/lib/patch-fetch.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/request-async-storage.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/headers.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/static-generation-bailout.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-modules/route-module.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/async-storage/async-storage-wrapper.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/async-storage/static-generation-async-storage-wrapper.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/http.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-modules/app-route/module.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-handler-managers/route-handler-manager.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/normalizers/normalizer.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/normalizers/locale-route-normalizer.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/base-server.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-definitions/locale-route-definition.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-definitions/pages-api-route-definition.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matches/pages-api-route-match.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/lib/render-server.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/image-optimizer.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/next-server.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matcher-managers/default-route-matcher-manager.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-matcher-managers/dev-route-matcher-manager.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/dev/static-paths-worker.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/dev/next-dev-server.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/next.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/extra-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/types/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/html-context.d.ts","../../node_modules/.pnpm/@next+env@13.3.0/node_modules/@next/env/types/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/mitt.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/with-router.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/router.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/route-loader.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/page-loader.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/bloom-filter/hashing.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/bloom-filter/base-filter.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/bloom-filter/bit-set.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/bloom-filter/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/router/router.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/constants.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/utils.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/pages/_app.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/app.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/runtime-config.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/config.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/pages/_document.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/document.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/dynamic.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dynamic.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/pages/_error.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/error.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/shared/lib/head.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/head.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/image.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/image.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/link.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/link.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/router.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/script.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/script.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@vercel/og/types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@vercel/og/index.node.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/web/spec-extension/image-response.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/server.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/types/global.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/image-types/global.d.ts","./next-env.d.ts","./config/site.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@next/font/dist/types.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","../../node_modules/.pnpm/next@13.3.0_@babel+core@7.20.7_react-dom@18.2.0_react@18.2.0/node_modules/next/font/google/index.d.ts","./lib/fonts.ts","../../node_modules/.pnpm/clsx@1.2.1/node_modules/clsx/clsx.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/tw-join.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/tw-merge.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/validators.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/types.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/default-config.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/extend-tailwind-merge.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/create-tailwind-merge.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/merge-configs.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/lib/from-theme.d.ts","../../node_modules/.pnpm/tailwind-merge@1.12.0/node_modules/tailwind-merge/dist/index.d.ts","./lib/utils.ts","./types/nav.ts","../../node_modules/.pnpm/class-variance-authority@0.4.0_typescript@4.9.5/node_modules/class-variance-authority/dist/types.d.ts","../../node_modules/.pnpm/class-variance-authority@0.4.0_typescript@4.9.5/node_modules/class-variance-authority/dist/index.d.ts","./components/ui/button.tsx","../../node_modules/.pnpm/lucide-react@0.105.0-alpha.4_react@18.2.0/node_modules/lucide-react/dist/lucide-react.d.ts","./components/icons.tsx","./components/main-nav.tsx","../../node_modules/.pnpm/next-themes@0.2.1_next@13.3.0_react-dom@18.2.0_react@18.2.0/node_modules/next-themes/dist/types.d.ts","../../node_modules/.pnpm/next-themes@0.2.1_next@13.3.0_react-dom@18.2.0_react@18.2.0/node_modules/next-themes/dist/index.d.ts","./components/theme-toggle.tsx","./components/site-header.tsx","./components/tailwind-indicator.tsx","./components/theme-provider.tsx","./app/layout.tsx","./app/page.tsx","./components/layout.tsx"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18","1fc5ab7a764205c68fa10d381b08417795fc73111d6dd16b5b1ed36badb743d9","746d62152361558ea6d6115cf0da4dd10ede041d14882ede3568bce5dc4b4f1f","d11a03592451da2d1065e09e61f4e2a9bf68f780f4f6623c18b57816a9679d17","aea179452def8a6152f98f63b191b84e7cbd69b0e248c91e61fb2e52328abe8c",{"version":"3aafcb693fe5b5c3bd277bd4c3a617b53db474fe498fc5df067c5603b1eebde7","affectsGlobalScope":true},{"version":"f3d4da15233e593eacb3965cde7960f3fddf5878528d882bcedd5cbaba0193c7","affectsGlobalScope":true},{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"d7f680a43f8cd12a6b6122c07c54ba40952b0c8aa140dcfcf32eb9e6cb028596","affectsGlobalScope":true},{"version":"3787b83e297de7c315d55d4a7c546ae28e5f6c0a361b7a1dcec1f1f50a54ef11","affectsGlobalScope":true},{"version":"e7e8e1d368290e9295ef18ca23f405cf40d5456fa9f20db6373a61ca45f75f40","affectsGlobalScope":true},{"version":"faf0221ae0465363c842ce6aa8a0cbda5d9296940a8e26c86e04cc4081eea21e","affectsGlobalScope":true},{"version":"06393d13ea207a1bfe08ec8d7be562549c5e2da8983f2ee074e00002629d1871","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"b248e32ca52e8f5571390a4142558ae4f203ae2f94d5bac38a3084d529ef4e58","affectsGlobalScope":true},{"version":"6c55633c733c8378db65ac3da7a767c3cf2cf3057f0565a9124a16a3a2019e87","affectsGlobalScope":true},{"version":"fb4416144c1bf0323ccbc9afb0ab289c07312214e8820ad17d709498c865a3fe","affectsGlobalScope":true},{"version":"5b0ca94ec819d68d33da516306c15297acec88efeb0ae9e2b39f71dbd9685ef7","affectsGlobalScope":true},{"version":"34c839eaaa6d78c8674ae2c37af2236dee6831b13db7b4ef4df3ec889a04d4f2","affectsGlobalScope":true},{"version":"34478567f8a80171f88f2f30808beb7da15eac0538ae91282dd33dce928d98ed","affectsGlobalScope":true},{"version":"ab7d58e6161a550ff92e5aff755dc37fe896245348332cd5f1e1203479fe0ed1","affectsGlobalScope":true},{"version":"6bda95ea27a59a276e46043b7065b55bd4b316c25e70e29b572958fa77565d43","affectsGlobalScope":true},{"version":"aedb8de1abb2ff1095c153854a6df7deae4a5709c37297f9d6e9948b6806fa66","affectsGlobalScope":true},{"version":"a4da0551fd39b90ca7ce5f68fb55d4dc0c1396d589b612e1902f68ee090aaada","affectsGlobalScope":true},{"version":"11ffe3c281f375fff9ffdde8bbec7669b4dd671905509079f866f2354a788064","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},"0990a7576222f248f0a3b888adcb7389f957928ce2afb1cd5128169086ff4d29",{"version":"bbdf156fea2fabed31a569445835aeedcc33643d404fcbaa54541f06c109df3f","affectsGlobalScope":true},"4c68749a564a6facdf675416d75789ee5a557afda8960e0803cf6711fa569288","6a386ff939f180ae8ef064699d8b7b6e62bc2731a62d7fbf5e02589383838dea","f5a8b384f182b3851cec3596ccc96cb7464f8d3469f48c74bf2befb782a19de5",{"version":"5917af4ff931b050dba49a1dedd9c00f15f7b3dc4345ad8491bfacd2ec68ed32","affectsGlobalScope":true},"cc69795d9954ee4ad57545b10c7bf1a7260d990231b1685c147ea71a6faa265c","8bc6c94ff4f2af1f4023b7bb2379b08d3d7dd80c698c9f0b07431ea16101f05f","1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","57194e1f007f3f2cbef26fa299d4c6b21f4623a2eddc63dfeef79e38e187a36e","0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","0cba3a5d7b81356222594442753cf90dd2892e5ccfe1d262aaca6896ba6c1380","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"c2ab70bbc7a24c42a790890739dd8a0ba9d2e15038b40dff8163a97a5d148c00","affectsGlobalScope":true},"422dbb183fdced59425ca072c8bd09efaa77ce4e2ab928ec0d8a1ce062d2a45a",{"version":"2a801b0322994c3dd7f0ef30265d19b3dd3bae6d793596879166ed6219c3da68","affectsGlobalScope":true},"1dab5ab6bcf11de47ab9db295df8c4f1d92ffa750e8f095e88c71ce4c3299628","f71f46ccd5a90566f0a37b25b23bc4684381ab2180bdf6733f4e6624474e1894",{"version":"54e65985a3ee3cec182e6a555e20974ea936fc8b8d1738c14e8ed8a42bd921d4","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","bcc8caf03ee65fe8610d258752f255fbdddbb2e4de7b6c5628956a5a0d859ec8","34e5de87d983bc6aefef8b17658556e3157003e8d9555d3cb098c6bef0b5fbc8","cc0b61316c4f37393f1f9595e93b673f4184e9d07f4c127165a490ec4a928668","f27371653aded82b2b160f7a7033fb4a5b1534b6f6081ef7be1468f0f15327d3","c762cd6754b13a461c54b59d0ae0ab7aeef3c292c6cf889873f786ee4d8e75c9","f4ea7d5df644785bd9fbf419930cbaec118f0d8b4160037d2339b8e23c059e79",{"version":"bfea28e6162ed21a0aeed181b623dcf250aa79abf49e24a6b7e012655af36d81","affectsGlobalScope":true},"7a5459efa09ea82088234e6533a203d528c594b01787fb90fba148885a36e8b6","ae97e20f2e10dbeec193d6a2f9cd9a367a1e293e7d6b33b68bacea166afd7792","10d4796a130577d57003a77b95d8723530bbec84718e364aa2129fa8ffba0378","ad41bb744149e92adb06eb953da195115620a3f2ad48e7d3ae04d10762dae197","bf73c576885408d4a176f44a9035d798827cc5020d58284cb18d7573430d9022","7ae078ca42a670445ae0c6a97c029cb83d143d62abd1730efb33f68f0b2c0e82",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"5d0a9ea09d990b5788f867f1c79d4878f86f7384cb7dab38eecbf22f9efd063d","12eea70b5e11e924bb0543aea5eadc16ced318aa26001b453b0d561c2fd0bd1e","08777cd9318d294646b121838574e1dd7acbb22c21a03df84e1f2c87b1ad47f2","08a90bcdc717df3d50a2ce178d966a8c353fd23e5c392fd3594a6e39d9bb6304",{"version":"8207e7e6db9aa5fc7e61c8f17ba74cf9c115d26f51f91ee93f790815a7ea9dfb","affectsGlobalScope":true},"2a12d2da5ac4c4979401a3f6eaafa874747a37c365e4bc18aa2b171ae134d21b","002b837927b53f3714308ecd96f72ee8a053b8aeb28213d8ec6de23ed1608b66","1dc9c847473bb47279e398b22c740c83ea37a5c88bf66629666e3cf4c5b9f99c","a9e4a5a24bf2c44de4c98274975a1a705a0abbaad04df3557c2d3cd8b1727949","00fa7ce8bc8acc560dc341bbfdf37840a8c59e6a67c9bfa3fa5f36254df35db2","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff",{"version":"806ef4cac3b3d9fa4a48d849c8e084d7c72fcd7b16d76e06049a9ed742ff79c0","affectsGlobalScope":true},"cfe724f7c694aab65a9bdd1acb05997848c504548c9d4c71645c187a091cfa2a","5f0ed51db151c2cdc4fa3bb0f44ce6066912ad001b607a34e65a96c52eb76248",{"version":"3345c276cab0e76dda86c0fb79104ff915a4580ba0f3e440870e183b1baec476","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","e383ff72aabf294913f8c346f5da1445ae6ad525836d28efd52cbadc01a361a6","f52fbf64c7e480271a9096763c4882d356b05cab05bf56a64e68a95313cd2ce2","59bdb65f28d7ce52ccfc906e9aaf422f8b8534b2d21c32a27d7819be5ad81df7","1835259a20b9fa6b1882931375b69ae5978195f2b139b4e0db51ec8319261649","28a2e7383fd898c386ffdcacedf0ec0845e5d1a86b5a43f25b86bc315f556b79","3aff9c8c36192e46a84afe7b926136d520487155154ab9ba982a8b544ea8fc95","a880cf8d85af2e4189c709b0fea613741649c0e40fffb4360ec70762563d5de0","85bbf436a15bbeda4db888be3062d47f99c66fd05d7c50f0f6473a9151b6a070","9f9c49c95ecd25e0cb2587751925976cf64fd184714cb11e213749c80cf0f927","f0c75c08a71f9212c93a719a25fb0320d53f2e50ca89a812640e08f8ad8c408c",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"0b3eba6dca8c6e534d16ef7b7d76cb546cd3cbab616c8f71daa0a151b5412b9e","30a1b56068b3820c91a055425a6af2294f8ef2bb10a59dcda413f6437093620d","e4dd91dd4789a109aab51d8a0569a282369fcda9ba6f2b2297bc61bacfb1a042","db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","5d97586646b92d2c7d8013e7078d7e06662db89d1155d2903e7ef893665dbd16","625e5d5e9e25017d53e65c62ff944d812d48ec1bbaaf7395c8f8cdf6c9218061","f307044185ce95a12cd54318863a9c56ed9271a4fc45df9e0c4d47db4285c3c2","39a3fc61a65aee8c90cd81bb2c9b508be6c5cc745cd40eaed95954a07c11bb82","6ceac05c32f579adbed2f1a9c98cd297de3c00a3caaffc423385d00e82bce4ce","973b59a17aaa817eb205baf6c132b83475a5c0a44e8294a472af7793b1817e89","ada39cbb2748ab2873b7835c90c8d4620723aedf323550e8489f08220e477c7f","fa5bbc7ab4130dd8cdc55ea294ec39f76f2bc507a0f75f4f873e38631a836ca7","f7c024ce0f73f3a0e56f35826bed34dd9743ad7daa19068acca653dd7d45f010","0b8c260ba3dce2d948222ddb53abb6d2de7692cca77ee8433507b0de0b8ff98d","d0a911a97b9eaf51bb8307ad2399e795790bb4fe2b247d7574bd5479fb5bd87e","43612765af269faa0548381af60886fdd78c507412bbcb3b676ba986b2e90bba","efc234c21b905df4553132cc604830f2aab1c0e492a6f7de5c0ea7fb22fbc2c1","c10a063aa725e3279752833d3661d6c5403b3dcddf339e82ac5aa36f104abc0d","8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","99549a6392ef52a5a1c5e8a9d3a449d9a518d25af22e5a4c31bdd11b61ded010","741c438ec079a077b08d37d9c0466924b68e98ed47224e83fcb125c5863eb355","649d4c4855a24d8f7cbe4977a0733c405b8ab00f87774359987e4648d0d9da1e","98435f5eaadf367fa5b29e886f6265456219dbbb05e075d135aa5938f7ffc46d","1b82026434e469addbcb287a1f2c6e81eab7e9c461714543ea37715763f45ef8","3fcd21b8633fd84dc57ba6e4a17d13f68946fb1702e1e68ca5b6412dcaa20275","9e588ebf03931ac4de811943fdecf605bea04e2060fafae0bf4529a4c9351607","403f280e4101791df0e67aaf1f52c23391390a9535aa597df533e6fe74c2bb75","aed65bf7421ea3b799066d0560878aa28f6728bd648a2cd33859eca4c1b8e3ac","ca1b882a105a1972f82cc58e3be491e7d750a1eb074ffd13b198269f57ed9e1b","c56cba491c0f32b78198af0ac7471c1cceca57db4e0a2c23c0b2659063bfae53","737d402374f91fad8f0928daf76e9ee9fd5912aeb35b351e44eb7ecea2dcb87c","fc7214ff37161bf1e89c52b11fc7dddceccab809e36ea0ee26353c7502b0b27b","58902668adae2e5eb67efbccb4048afa02308fa684f1a4e4c7d47668ecf58c1b","3d365237792d79384c1315ad7fba7505b4355ba88d2032349ab437bf7b22e2e8","ee9461f976caf518f336892f101a85109686d1fcfecee8d9079b81e9c68dc86e","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","c3624afffa46c8cd4c775a9578a627277e9b06cddfbc3fdb14cc0f4673f45ae7","cace786bf8078d7cb640d94f97c2f47e5c4f979c6a2e3c9168e54a0d79a6ac0a","17937316a2f7f362dd6375251a9ce9e4960cfdc0aa7ba6cbd00656f7ab92334b","575bc12d93a33c09e803375cd99a77f50c9272d01abe26d5de27af637c7427a3","7d7ce795ac82a239ce89b7088e6fcf8a406b1ebb6c4ff75ae3970beafba35585","e01ed711d76cfe84c7d099d75306323fa1ebc27ce02a742fab271e82a1da4dee","7d1b37284c9a4c58e2954aa21485d37881b5ab25937b29ebfb63c4d37fc3ae3d","1efe66d15fb19a2e8f3aff712fdfd1b9f7b19e7c3603ee188b13a9572ff9a7d8","f0e480e327dd94c30c7003c7ca188b401ab451396f40e4ec5ae2f9b3a944a7be","2a130020150086164f429b0ba507ad66a729f2cbaee14ed4348fdb2504bdd49e","6e5f5cee603d67ee1ba6120815497909b73399842254fc1e77a0d5cdc51d8c9c","f6404e7837b96da3ea4d38c4f1a3812c96c9dcdf264e93d5bdb199f983a3ef4b","4a3fb0f285c6bd13500366e3023d90b40bd2fbafcfe6e1ffaa8e6ab62bba4907","3cd0346fc79e262233785d9fe2cbad08fc3fe6339af3419791687152ddfe5596","9f3c4349b19905df8e6977106894cb01cbb5ebd6f2a8da64bddaae8b1b3e1c04","2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","1e7fb60ac7ae5365d12ec98b3efbcb9130c400ad3ccc07f2db6f26ff24d62ccf","0aef0a60e229dfeff49f68bf941d24b8338fc3d55aa7c64b1c9acbf9d3a67b46","c4277bc74428f8b8c3ffb5a3bc6684d6bda2ce66e7428e4a99df7ebaedf0f708","5b2e8cec02a40770a0c3f953d78dce6632f345638f85af4b24fd16fcfbaf0019","d23518a5f155f1a3e07214baf0295687507122ae2e6e9bd5e772551ebd4b3157","53a99fb41040b64c6bc8aa5b231547439d205e61f7f022a43a6a1da65657cbf6","3a083cc0c3bd0346304a0de0568a2cec000bed4cd7885bab3be70bfecef50e96","c8556b8716fc69ab436b340f8a5171d56cf9f03b3017f345fda4876174608080","c2299e6708a155e6c156ef9e92c83e074dbd32611fd84d6b07648d34cd35209a","fb480794b12bbe2cdce8a9e6759e3045208765278f248c6a6135c6993aa9683f","b0423e07b18195c4a276f95b30b464ee0816dc5e4fc59c262f60afe189930516","8317f1d2e04f181eca793161466a31d3082d3af6eb6516ba1fead9fe66037431","3ca193730b6d9fbb08cee1241b648297527dfa64a86853f7a1384e9943d76726","88961917ec908f9fde57b86b8038b8b30766ba14cfdcc214c7c5498d7c9f7924","6d8e12183e7baed15513970482d9cca86954bb7dfaef8ca862718ca144aadb3b","45e5c75f8ddf51eff85961cf1912a9a745809957f8b57a0a7d859e20b19ae260","5279f50f5711aaad3894a016eb905fa50d75bcba30bd652f8be73ab5f3037a73","1366638c25b6ce477f6394c584cc0e2364ff72ffaeec3ceb7dde1c7b939fade9","e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","1822b69406252b606dc1aec3231a7104ac1d456cfa2c0a9041e61061895ae348","0d05309199fe921b0b7dc131104f5dd2957a024072781a8393ea5357c8ce9a49","c1ac179620434b59c1569f2964a5c7354037ac91a212a1fb281673589965c893","9f891dc96f3e9343c4e823ba28195fd77e59c84199696a8bdfe7b67925732409","63f50c44294385846e5deed7d9d056b3b3bad04ebaa63e1fdca149e1627f5d40","7a5df736ff13c4981f10fe29ab73e61a6c3f8e4cfc30224e73566725b601d802","98b94a34fe1138e1d59d138dbf0d7b19592d6540393a1b4653d4ad7271d2f64d","b9de430616a42e94268dc62720d46bc80e04350efed18fc04be7a12974cfb84d","2c6f043430f24bde409ed1e70d197b3ef70607cd656817bfd6cf02e630bb7a39","495a5da35b04cd142d1301921ce8776c3bd8eab85bbf0ea694e631bc5cd35338","9d20a77883a17070169ea0f80ba2cd27575df30510f5bf4d6d292b3ea547f681","b0967cf27e8a3c05a82ca58cc96bb2e1443b03d400d5b19b85735cac81adb2ca","5cab8fa167ee711e4dfcd22ed632c60be36bd49dc6eea8cfdd3613c59d00c43d","6176b9f450623c979d65630c243971e4348b39f9c2b3052f4b1b2f2d558c13c7","06bcd1f53ae68951411b1649b45fdea22d87db52d2dbeeb8b0af44d47a186c3f","b65c4ff9cd4815c5f1855e8702740c8bbb4921140e3c415c5affe3e376e322dc","69b1a4767d6249cc8fa88110fbcee746684f9159c7c9d4f14f6ea3bf11ab8bd5","be90dde0efc4ce2544606fa5bd2cf15660f43175f49daae067c53a16d7cbf024","15e84dd6d50ef02f936e7bf8f32f71e7469d486df900955e6f8c152266e4b801","0efea28e99af48ea75df7cccb178ba8030aad78fdf04c884bde983a95b5b4545",{"version":"1fe4972a8ec31134aec90e9dba4073616d21464820c780774e156fa7ccb32bf7","affectsGlobalScope":true},"c31eabb9cbf9582fb62ceccaaae17d03768ec31b1dda9b9b258ee999500ce1ca","070187a9132cd795f971a1c22b75000c0a73bbdfc49c8d3091e763df8c80b002","2766dee26ea113e9b491b7842cb44df57c4d79b17057b42607e09fc174bd411d","cb4047ce260c2f4585b2d592d04a1d9a9c2a1ba32679a688523ec314a977989a","0511c61c22d677da1b6bab4d3844aead1d7e27028d2f0ed1ed315e0860ed5357",{"version":"b4610d904ab939109aa8bcee6f795de8da780b6b4a4d8ff2ff9d2e3b699f55b7","affectsGlobalScope":true},{"version":"6707b2ff066e782f676f90ba7abfca7d6f321eececbbecf3d42eebb7a8c28da2","affectsGlobalScope":true},"b87389fa915955221ff512128d9bad0b60fa922b6b29a358c032b3c5a1754ebd","7f9daeb92677b8461e7d64e05cb7a4fadcc4f1df15352fc41a7e9493fa9ae7ff","2ebe37d9476d15f0541dd5d79267db6e30d6491ed349254ee68a0de25620c577","2d3c25f508407607500045c74c69b5b6abe74838807f4dc2ef5c4bbf1cc642e6",{"version":"3cf72817794f1152e41b704c8f6072c099f0e676bcd704a967901220873fec94","affectsGlobalScope":true},"8e0579532322778ab89c3c61228588e08093aa2d698dcff9be3215e0dbc70be7","49d1d55994ac37a756bd332aad59ef68d89ae15a2b79c3c343f8432c468e09bc","06dfd2ebf571b3df2cc23a70f031417eb77f7702f0ce727cec99a296242d6929","65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","b7fff2d004c5879cae335db8f954eb1d61242d9f2d28515e67902032723caeab","8303df69e9d100e3df8f2d67ec77348cb6494dc406356fdd9b56e61aa7c3c758","8de50542d92f9ac659c30ead0a97e9c107dd3404a3b4fd4bf3504589a026221a","4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","a80e3207332979fcd48223790af48f61192c1d348162adb7e4f30f23085dc0e1","a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","c3a905a7fa93ca648349e934fb19356cf7b40e48d65658de3e0c77d67696fd40","a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","c2489c80994d62e5b51370a6f02f537db4c37af5f914fcb5b2755b81f1906cae","47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","da5f632f5f82f60322089dc4f73fde31ba4c51d599d920d1cad0eef686c71f7c","42c686ce08bf5576ed178f4a6a62d1b580d941334fb53bdff7054e0980f2dc75","605b66155b4f222c5f5a48bf19224815e4bceb2966dfb1c5704692ed07e5fa0a","cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","26a451bf3a5f87ebaaa7694c5b664c3d9cec296f3fa8b797b872aee0f302b3a0","5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","c0eeaaa67c85c3bb6c52b629ebbfd3b2292dc67e8c0ffda2fc6cd2f78dc471e6","4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","25c4bd23e828e865868722c7a1d01876ed891ddfbd92cb6f006e747f56eee0c9","c2008605e78208cfa9cd70bd29856b72dda7ad89df5dc895920f8e10bcb9cd0a","ec61ebac4d71c4698318673efbb5c481a6c4d374da8d285f6557541a5bd318d0","10ec84e648ffc7654868ca02c21a851bc211c8e4d50fd68131c1afa9afd96a33","b5934ca186f498c83e9a663d3df019d82290303fd86b1658cf27cf892b50aaf9",{"version":"90c89a318a59d6b3decbc0bc476210548eba1c3668037058b0a6e6cc363d47dd","affectsGlobalScope":true},{"version":"57ad3ef8cd87e876021acbcabcc6457f21a721cb0c5388de700bd57ea32030c1","affectsGlobalScope":true},"9c00f78ac4e60d1c34d0fb415df6b2fea5f6eea200076dff4d782256a4c2802d","79d056984a8964d3917c7587067447d7565d9da696fcf6ecaa5e8437a214f04e","9269d492817e359123ac64c8205e5d05dab63d71a3a7a229e68b5d9a0e8150bf","2bf8d68be6cfc43093d8e9961a77958ba6a406b2af4fbc04ae5c301fad5aef55","807535f4e95ebccc1eae3d675289b1be5c23e6aaa6fd624f2be485e3e1e6f23d","1d1872677306b44559ce09926b9eab6a34507d5f5dd465324d94f34cf7a36872","1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","f3c253f3833841eb9dd65d6b99a2f357debfdeef5f85c85c291a465bbf03bc6b","7a129438cedf12b5f1b5f773a3e96242b7569c95243432dcf12618f80fca5cdc","0165115e3c8788801fb59e9c3cca0c7ba573515a8b7ce010c7d75deba92b455f","0e000fd63bd08abc96dbd4746c371b8a0368f351629590ee7ba12c9787cdc8e6","463ed32d194c6bd58c35083d76af0170ad1b04f7b3ef91c9803593bd089c2864","84936ce43e5e01db3ee57c205d244181d85cd0e1fadbc6e1f94b3d9bd9a3aae5","802417aed26cb50faf8b7176fa00279bdb5acbb53bf4a63ae00d47d25d904516","bc1899efe6dcdce9c9c8bd9ce97d58b197facb7f4a516e5d13a804fa5f77cf4f","4d080c54c10ec25e6e84337dbaff7953066150baf94fd48db6c70a37cdd43a8a","3ad4660add51c3c3adf49524d61cc1e3ed57e16274c62c6cfb047b64aab973aa","22f25ec27fa1c1ca03010aa71b8077c742ab5bf6a08a44663a287a296be34481","74ac2c0b3fa70bb0cf47f80fabc73f6b868ba177ced233e294068fc099cf5a06","7c8c3dfc0cdd370d44932828eb067ef771c8fe7996693221d5d4b90af6d54f2d","fce3be25a64ca64c47d90887b7055580ad97976c00d1e3b9bac188cc381f05a6","951a918a753179bf5c018065e3302c8e2d899600ac1e7e5dfc1c2d9867a643c5","842454d0222fa151b62f4f18c893335993829311367f4502270d449bd32c1b72","ca8d9484968d464e3779ac344132494f8a41084d74ece61e5b19ec86e73bb0ad","894711d8c2e76012cc3258ab90fc6339b19a792349f94c16e1b4801709e0eb94","dc45760b1f08ebb5d24b69ddc2ea2a42b724e17c643cd73ef52128d992a62cc9","94caf997b590e006b84f927275ddddfb84bbf8539535b0888bd83eea867e88c4","ae0d70b4f8a3a43cb0a5a89859aca3611f2789a3bca6a387f9deab912b7605b0","966b0f7789547bb149ad553f5a8c0d7b4406eceac50991aaad8a12643f3aec71","8063cff815975c1dceb2f9cdba3cffa6afd97b084d71acc0264b7af00ef31d76","d78bd0f8ac7d8de2d80a0ca8818216f4f7d94abfea6c7f3a2581252ba110938d","3dbad0bac309b341e0f1a930e0a163b1bd041f5375975a0f9ecca9b4783ad8f0","de749e7f86ee33a1874c595c605a45746138ef46b7d35b1699043abb01f1e7c3","f7ff7b1534fec1cc87e8063745cb140dcfe2014c5e559994093d986b93274f69","29f43c6639fe1f2302cbc29a4362f15bb40fe1e5e88fb9d7cdf1e2ccb8102826","fa70bdc67035c981fcb92927c0964016a5d731937b51767e12b596dc53c2471d"],"options":{"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":false,"strictNullChecks":true},"fileIdsList":[[112],[69,112],[72,112],[73,78,112],[74,84,85,92,101,111,112],[74,75,84,92,112],[76,112],[77,78,85,93,112],[78,101,108,112],[79,81,84,92,112],[80,112],[81,82,112],[83,84,112],[84,112],[84,85,86,101,111,112],[84,85,86,101,112],[87,92,101,111,112],[84,85,87,88,92,101,108,111,112],[87,89,101,108,111,112],[69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118],[84,90,112],[91,111,112],[81,84,92,101,112],[93,112],[94,112],[72,95,112],[96,110,112,116],[97,112],[98,112],[84,99,112],[99,100,112,114],[84,101,102,103,112],[101,103,112],[101,102,112],[104,112],[105,112],[84,106,107,112],[106,107,112],[78,92,101,108,112],[109,112],[92,110,112],[73,87,98,111,112],[78,112],[101,112,113],[112,114],[112,115],[73,78,84,86,95,101,111,112,114,116],[101,112,117],[62,112],[58,59,60,61,112],[112,276],[62,112,282],[67,112],[112,227],[112,229],[112,124,134,146,212],[112,136],[98,112,119,120,124,134,147,173,174,175,178,212],[112,122,145],[112,122],[112,122,145,146],[112,180,181,212],[72,112,119,180,181,212],[72,112,119,175],[62,112,125],[62,111,112,119],[62,112,145,218],[62,112,145],[112,216,224],[62,112,217,226],[112,259],[62,101,112,119,250],[62,66,87,112,119,212,248,249],[112,123],[112,205,206,207,208,209,210],[112,207],[62,112,213,226],[62,112,226],[87,112,119,135,226],[72,112,119],[112,175,176,186],[87,112,119,134,136],[87,101,112,119,133,135,136,212],[87,98,111,112,119,123,124,125,129,133,134,135,136,142,143,144,145,148,157,158,160,162,163,164,165,166,168,170,175,190,192,212],[87,101,112,119],[112,122,124,125,126,133,212,226],[112,134],[98,111,112,119,124,129,132,133,134,135,136,142,143,144,155,158,161,164,167,175,190,193,199,201,202],[112,134,175],[112,133,134],[112,142,191],[112,130,131],[112,130,194],[112,130],[112,132,135,171,189],[112,130,131,132,140,141,143],[112,130,131,132,140,143,200],[112,132,141,142],[112,140],[112,129,131,132],[112,132,195],[112,129,131],[112,129,134,152,172,179,185,187,188],[112,129,131,152,176,177,182,183,184],[87,111,112,119,125,133,134,170],[112,157,170,226],[112,176,177],[112,120,163,212,226],[87,98,111,112,119,124,129,133,135,137,139,144,147,148,155,157,158,160,161,162,166,167,170,175,193,196,197,198,226],[87,112,119,133,199,203],[62,87,98,112,119,123,125,133,136,148,162,163,164,165,212],[87,98,111,112,119,127,132,135],[112,169],[87,112,119,148],[98,112,119,123,124,129,133,135,142,143],[87,112,119,148,159],[87,112,119,135,160],[87,112,119,134,142],[87,112,119],[112,151],[112,150],[112,152],[112,251],[112,134,149,151,155],[112,134,149,151],[87,112,119,127,134,152,153,154],[112,220],[112,220,221,222],[62,112,120,162,165,212,226],[62,98,111,112,119,123,215,217,219,223,226],[112,129,135,145],[98,112,119],[112,128],[62,87,98,112,119,123,212,213,214,224,225],[57,62,63,64,65,112,212,250],[112,231],[112,233],[112,235],[112,260],[112,237],[112,239],[66,68,112,212,228,230,232,234,236,238,240,242,243,245,253,254],[112,241],[112,217],[112,244],[72,112,152,153,154,155,246,247,252],[112,119],[62,66,87,98,112,119,121,123,136,204,211,226,250],[112,264,265,266,267,268,269,270,271,272],[112,264,267],[112,266,267],[112,267],[112,264],[112,255,258,262,274,285,286,287],[112,242,258,278],[112,279],[112,285],[62,112,242,258,274,275,280],[112,242,258,278,280,281,284],[62,112,282,283],[62,112,278,280,283],[62,112,274,277],[112,261],[112,263,273],[112,255,256]],"referencedMap":[[214,1],[69,2],[70,2],[72,3],[73,4],[74,5],[75,6],[76,7],[77,8],[78,9],[79,10],[80,11],[81,12],[82,12],[83,13],[84,14],[85,15],[86,16],[71,1],[118,1],[87,17],[88,18],[89,19],[119,20],[90,21],[91,22],[92,23],[93,24],[94,25],[95,26],[96,27],[97,28],[98,29],[99,30],[100,31],[101,32],[103,33],[102,34],[104,35],[105,36],[106,37],[107,38],[108,39],[109,40],[110,41],[111,42],[112,43],[113,44],[114,45],[115,46],[116,47],[117,48],[60,1],[121,49],[58,1],[62,50],[61,1],[277,51],[276,1],[263,1],[59,1],[279,49],[283,52],[282,49],[68,53],[228,54],[230,55],[145,56],[157,57],[179,58],[146,59],[173,1],[163,60],[147,61],[165,60],[158,60],[126,60],[183,62],[177,1],[182,63],[176,64],[184,1],[239,65],[241,66],[219,67],[218,68],[217,69],[244,49],[216,70],[150,1],[247,1],[260,71],[259,1],[249,1],[251,72],[248,49],[250,73],[122,1],[174,1],[124,74],[205,1],[206,1],[208,1],[211,75],[207,1],[209,76],[210,76],[156,1],[227,70],[231,77],[235,78],[136,79],[186,80],[187,81],[135,82],[161,83],[193,84],[127,85],[134,86],[123,87],[203,88],[202,89],[162,1],[142,90],[171,1],[192,91],[191,1],[172,92],[194,92],[195,93],[131,94],[190,95],[130,1],[200,96],[201,97],[143,98],[141,99],[140,100],[196,101],[132,102],[189,103],[185,104],[120,1],[198,105],[137,1],[175,106],[178,107],[197,1],[164,108],[199,109],[204,110],[138,1],[139,1],[148,85],[166,111],[133,112],[170,113],[169,114],[144,115],[160,116],[159,117],[188,1],[149,118],[180,119],[181,120],[151,121],[153,122],[252,123],[152,124],[154,125],[246,1],[155,126],[67,1],[221,127],[222,1],[220,1],[223,128],[225,1],[233,49],[237,49],[213,129],[125,1],[215,1],[224,130],[168,131],[167,132],[129,133],[128,1],[229,1],[226,134],[57,1],[66,135],[63,49],[64,1],[65,1],[232,136],[234,137],[236,138],[261,139],[238,140],[256,141],[240,141],[255,142],[242,143],[243,144],[245,145],[253,146],[254,147],[212,148],[273,149],[270,150],[268,151],[269,150],[272,152],[271,152],[264,1],[265,153],[267,1],[266,1],[11,1],[12,1],[14,1],[13,1],[2,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[3,1],[4,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[5,1],[30,1],[31,1],[32,1],[33,1],[6,1],[37,1],[34,1],[35,1],[36,1],[38,1],[7,1],[39,1],[44,1],[45,1],[40,1],[41,1],[42,1],[43,1],[8,1],[49,1],[46,1],[47,1],[48,1],[50,1],[9,1],[51,1],[52,1],[53,1],[54,1],[55,1],[1,1],[10,1],[56,1],[288,154],[289,155],[280,156],[290,157],[281,158],[285,159],[286,1],[287,160],[284,161],[278,162],[258,1],[262,163],[274,164],[257,165],[275,1]],"exportedModulesMap":[[214,1],[69,2],[70,2],[72,3],[73,4],[74,5],[75,6],[76,7],[77,8],[78,9],[79,10],[80,11],[81,12],[82,12],[83,13],[84,14],[85,15],[86,16],[71,1],[118,1],[87,17],[88,18],[89,19],[119,20],[90,21],[91,22],[92,23],[93,24],[94,25],[95,26],[96,27],[97,28],[98,29],[99,30],[100,31],[101,32],[103,33],[102,34],[104,35],[105,36],[106,37],[107,38],[108,39],[109,40],[110,41],[111,42],[112,43],[113,44],[114,45],[115,46],[116,47],[117,48],[60,1],[121,49],[58,1],[62,50],[61,1],[277,51],[276,1],[263,1],[59,1],[279,49],[283,52],[282,49],[68,53],[228,54],[230,55],[145,56],[157,57],[179,58],[146,59],[173,1],[163,60],[147,61],[165,60],[158,60],[126,60],[183,62],[177,1],[182,63],[176,64],[184,1],[239,65],[241,66],[219,67],[218,68],[217,69],[244,49],[216,70],[150,1],[247,1],[260,71],[259,1],[249,1],[251,72],[248,49],[250,73],[122,1],[174,1],[124,74],[205,1],[206,1],[208,1],[211,75],[207,1],[209,76],[210,76],[156,1],[227,70],[231,77],[235,78],[136,79],[186,80],[187,81],[135,82],[161,83],[193,84],[127,85],[134,86],[123,87],[203,88],[202,89],[162,1],[142,90],[171,1],[192,91],[191,1],[172,92],[194,92],[195,93],[131,94],[190,95],[130,1],[200,96],[201,97],[143,98],[141,99],[140,100],[196,101],[132,102],[189,103],[185,104],[120,1],[198,105],[137,1],[175,106],[178,107],[197,1],[164,108],[199,109],[204,110],[138,1],[139,1],[148,85],[166,111],[133,112],[170,113],[169,114],[144,115],[160,116],[159,117],[188,1],[149,118],[180,119],[181,120],[151,121],[153,122],[252,123],[152,124],[154,125],[246,1],[155,126],[67,1],[221,127],[222,1],[220,1],[223,128],[225,1],[233,49],[237,49],[213,129],[125,1],[215,1],[224,130],[168,131],[167,132],[129,133],[128,1],[229,1],[226,134],[57,1],[66,135],[63,49],[64,1],[65,1],[232,136],[234,137],[236,138],[261,139],[238,140],[256,141],[240,141],[255,142],[242,143],[243,144],[245,145],[253,146],[254,147],[212,148],[273,149],[270,150],[268,151],[269,150],[272,152],[271,152],[264,1],[265,153],[267,1],[266,1],[11,1],[12,1],[14,1],[13,1],[2,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[21,1],[22,1],[3,1],[4,1],[26,1],[23,1],[24,1],[25,1],[27,1],[28,1],[29,1],[5,1],[30,1],[31,1],[32,1],[33,1],[6,1],[37,1],[34,1],[35,1],[36,1],[38,1],[7,1],[39,1],[44,1],[45,1],[40,1],[41,1],[42,1],[43,1],[8,1],[49,1],[46,1],[47,1],[48,1],[50,1],[9,1],[51,1],[52,1],[53,1],[54,1],[55,1],[1,1],[10,1],[56,1],[288,154],[289,155],[280,156],[290,157],[281,158],[285,159],[286,1],[287,160],[284,161],[278,162],[258,1],[262,163],[274,164],[257,165],[275,1]],"semanticDiagnosticsPerFile":[214,69,70,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,71,118,87,88,89,119,90,91,92,93,94,95,96,97,98,99,100,101,103,102,104,105,106,107,108,109,110,111,112,113,114,115,116,117,60,121,58,62,61,277,276,263,59,279,283,282,68,228,230,145,157,179,146,173,163,147,165,158,126,183,177,182,176,184,239,241,219,218,217,244,216,150,247,260,259,249,251,248,250,122,174,124,205,206,208,211,207,209,210,156,227,231,235,136,186,187,135,161,193,127,134,123,203,202,162,142,171,192,191,172,194,195,131,190,130,200,201,143,141,140,196,132,189,185,120,198,137,175,178,197,164,199,204,138,139,148,166,133,170,169,144,160,159,188,149,180,181,151,153,252,152,154,246,155,67,221,222,220,223,225,233,237,213,125,215,224,168,167,129,128,229,226,57,66,63,64,65,232,234,236,261,238,256,240,255,242,243,245,253,254,212,273,270,268,269,272,271,264,265,267,266,11,12,14,13,2,15,16,17,18,19,20,21,22,3,4,26,23,24,25,27,28,29,5,30,31,32,33,6,37,34,35,36,38,7,39,44,45,40,41,42,43,8,49,46,47,48,50,9,51,52,53,54,55,1,10,56,288,289,280,290,281,285,286,287,284,278,258,262,274,257,275],"affectedFilesPendingEmit":[[214,1],[69,1],[70,1],[72,1],[73,1],[74,1],[75,1],[76,1],[77,1],[78,1],[79,1],[80,1],[81,1],[82,1],[83,1],[84,1],[85,1],[86,1],[71,1],[118,1],[87,1],[88,1],[89,1],[119,1],[90,1],[91,1],[92,1],[93,1],[94,1],[95,1],[96,1],[97,1],[98,1],[99,1],[100,1],[101,1],[103,1],[102,1],[104,1],[105,1],[106,1],[107,1],[108,1],[109,1],[110,1],[111,1],[112,1],[113,1],[114,1],[115,1],[116,1],[117,1],[60,1],[121,1],[58,1],[62,1],[61,1],[277,1],[276,1],[263,1],[59,1],[279,1],[283,1],[282,1],[68,1],[228,1],[230,1],[145,1],[157,1],[179,1],[146,1],[173,1],[163,1],[147,1],[165,1],[158,1],[126,1],[183,1],[177,1],[182,1],[176,1],[184,1],[239,1],[241,1],[219,1],[218,1],[217,1],[244,1],[216,1],[150,1],[247,1],[260,1],[259,1],[249,1],[251,1],[248,1],[250,1],[122,1],[174,1],[124,1],[205,1],[206,1],[208,1],[211,1],[207,1],[209,1],[210,1],[156,1],[227,1],[231,1],[235,1],[136,1],[186,1],[187,1],[135,1],[161,1],[193,1],[127,1],[134,1],[123,1],[203,1],[202,1],[162,1],[142,1],[171,1],[192,1],[191,1],[172,1],[194,1],[195,1],[131,1],[190,1],[130,1],[200,1],[201,1],[143,1],[141,1],[140,1],[196,1],[132,1],[189,1],[185,1],[120,1],[198,1],[137,1],[175,1],[178,1],[197,1],[164,1],[199,1],[204,1],[138,1],[139,1],[148,1],[166,1],[133,1],[170,1],[169,1],[144,1],[160,1],[159,1],[188,1],[149,1],[180,1],[181,1],[151,1],[153,1],[252,1],[152,1],[154,1],[246,1],[155,1],[67,1],[221,1],[222,1],[220,1],[223,1],[225,1],[233,1],[237,1],[213,1],[125,1],[215,1],[224,1],[168,1],[167,1],[129,1],[128,1],[229,1],[226,1],[57,1],[66,1],[63,1],[64,1],[65,1],[232,1],[234,1],[236,1],[261,1],[238,1],[256,1],[240,1],[255,1],[242,1],[243,1],[245,1],[253,1],[254,1],[212,1],[273,1],[270,1],[268,1],[269,1],[272,1],[271,1],[264,1],[265,1],[267,1],[266,1],[2,1],[3,1],[4,1],[5,1],[6,1],[7,1],[8,1],[9,1],[10,1],[288,1],[289,1],[280,1],[290,1],[281,1],[285,1],[286,1],[287,1],[284,1],[278,1],[258,1],[262,1],[274,1],[257,1],[275,1]]},"version":"4.9.5"}
================================================
FILE: types/nav.ts
================================================
export interface NavItem {
title: string
href?: string
disabled?: boolean
external?: boolean
}