1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-26 07:05:21 -04:00

a bunch of cleanup, mostly of my messy css hacks over the years

This commit is contained in:
Jake Jarvis 2025-04-18 12:11:16 -04:00
parent eec8f5e1c2
commit 98ea88dae9
Signed by: jake
SSH Key Fingerprint: SHA256:nCkvAjYA6XaSPUqc4TfbBQTpzr8Xj7ritg/sGInCdkc
25 changed files with 221 additions and 184 deletions

View File

@ -15,6 +15,14 @@ export const metadata = addMetadata({
alternates: {
canonical: "/birthday",
},
openGraph: {
videos: [
{
url: `${env.NEXT_PUBLIC_BASE_URL}${webm}`,
type: "video/webm",
},
],
},
});
const Page = () => {

View File

@ -37,7 +37,8 @@
}
.submitButton {
flex-shrink: 0;
display: flex;
align-items: center;
height: 3.25em;
padding: 1em 1.25em;
margin-right: 1.5em;
@ -56,9 +57,16 @@
background-color: var(--colors-link);
}
.submitIcon {
width: 1.3em;
height: 1.3em;
margin-right: 0.5em;
}
.result {
display: flex;
align-items: center;
font-weight: 600;
line-height: 1.5;
}
.result.success {
@ -70,8 +78,7 @@
}
.resultIcon {
display: inline;
width: 1.3em;
height: 1.3em;
vertical-align: -0.3em;
margin-right: 0.25em;
}

View File

@ -5,7 +5,7 @@ import { useActionState, useState } from "react";
import TextareaAutosize from "react-textarea-autosize";
import Turnstile from "react-turnstile";
import clsx from "clsx";
import { CheckIcon, XIcon } from "lucide-react";
import { SendIcon, LoaderIcon, CheckIcon, XIcon } from "lucide-react";
import Link from "../../components/Link";
import { send, type ContactState, type ContactInput } from "./action";
@ -80,13 +80,12 @@ const ContactForm = () => {
stroke="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
height="1.25em"
width="1.25em"
height="1.25em"
style={{
display: "inline",
width: "1.25em",
height: "1.25em",
verticalAlign: "-0.25em",
verticalAlign: "text-top",
marginRight: "0.25em",
}}
xmlns="http://www.w3.org/2000/svg"
@ -115,19 +114,12 @@ const ContactForm = () => {
{!formState.success && (
<button type="submit" disabled={pending} className={styles.submitButton}>
{pending ? (
<span>Sending...</span>
<>
<LoaderIcon size="1.3em" className={styles.submitIcon} /> <span>Sending...</span>
</>
) : (
<>
<span
style={{
fontSize: "1.3em",
marginRight: "0.3em",
lineHeight: "1",
}}
>
📤
</span>{" "}
<span>Send</span>
<SendIcon size="1.3em" className={styles.submitIcon} /> <span>Send</span>
</>
)}
</button>

View File

@ -1,3 +1,4 @@
import { LockIcon } from "lucide-react";
import PageTitle from "../../components/PageTitle";
import Link from "../../components/Link";
import { addMetadata } from "../../lib/helpers/metadata";
@ -28,7 +29,15 @@ const Page = () => {
<Link href="https://fediverse.jarv.is/@jake">direct message on Mastodon</Link>.
</p>
<p>
🔐 You can grab my public key here:{" "}
<LockIcon
size="0.975em"
style={{
marginRight: "0.15em",
stroke: "var(--colors-warning)",
verticalAlign: "middle",
}}
/>{" "}
You can grab my public key here:{" "}
<Link href="https://jrvs.io/pgp" title="My Public Key">
<code
style={{

View File

@ -17,6 +17,14 @@ export const metadata = addMetadata({
alternates: {
canonical: "/hillary",
},
openGraph: {
videos: [
{
url: `${env.NEXT_PUBLIC_BASE_URL}${webm}`,
type: "video/webm",
},
],
},
});
const Page = () => {

View File

@ -13,7 +13,6 @@
}
.container {
display: block;
width: 100%;
max-width: var(--max-width);
margin: 0 auto;

View File

@ -17,6 +17,14 @@ export const metadata = addMetadata({
alternates: {
canonical: "/leo",
},
openGraph: {
videos: [
{
url: `${env.NEXT_PUBLIC_BASE_URL}${webm}`,
type: "video/webm",
},
],
},
});
const Page = () => {

View File

@ -1,5 +1,6 @@
.meta {
display: inline-flex;
display: flex;
justify-items: flex-start;
flex-wrap: wrap;
font-size: 0.925em;
line-height: 2.3;
@ -8,6 +9,8 @@
}
.meta .metaItem {
display: inline-flex;
align-items: center;
margin-right: 1.6em;
white-space: nowrap;
}
@ -17,17 +20,16 @@
}
.meta .metaIcon {
display: inline-block;
width: 1.2em;
height: 1.2em;
vertical-align: -0.225em;
width: 1.25em;
height: 1.25em;
margin-right: 0.6em;
flex-shrink: 0;
}
.meta .metaTags {
white-space: normal;
display: inline-flex;
flex-wrap: wrap;
white-space: normal;
}
.meta .metaTag {

View File

@ -1,7 +1,8 @@
import { env } from "../../../lib/env";
import { Suspense } from "react";
import { JsonLd } from "react-schemaorg";
import { CalendarIcon, TagIcon, SquarePenIcon, EyeIcon } from "lucide-react";
import clsx from "clsx";
import { CalendarDaysIcon, TagIcon, SquarePenIcon, EyeIcon } from "lucide-react";
import Link from "../../../components/Link";
import Time from "../../../components/Time";
import Comments from "../../../components/Comments";
@ -89,16 +90,14 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
/>
<div className={styles.meta}>
<div className={styles.metaItem}>
<Link href={`/${POSTS_DIR}/${frontmatter!.slug}`} plain className={styles.metaLink}>
<CalendarIcon size="1.2em" className={styles.metaIcon} />
<Time date={frontmatter!.date} format="MMMM d, y" />
</Link>
</div>
<Link href={`/${POSTS_DIR}/${frontmatter!.slug}`} plain className={clsx(styles.metaItem, styles.metaLink)}>
<CalendarDaysIcon size="1.25em" className={styles.metaIcon} />
<Time date={frontmatter!.date} format="MMMM d, y" />
</Link>
{frontmatter!.tags && (
<div className={styles.metaItem}>
<TagIcon size="1.2em" className={styles.metaIcon} />
<TagIcon size="1.25em" className={styles.metaIcon} />
<span className={styles.metaTags}>
{frontmatter!.tags.map((tag) => (
<span key={tag} title={tag} className={styles.metaTag} aria-label={`Tagged with ${tag}`}>
@ -109,17 +108,15 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
</div>
)}
<div className={styles.metaItem}>
<Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}/blob/main/${POSTS_DIR}/${frontmatter!.slug}/index.mdx`}
title={`Edit "${frontmatter!.title}" on GitHub`}
plain
className={styles.metaLink}
>
<SquarePenIcon size="1.2em" className={styles.metaIcon} />
<span>Improve This Post</span>
</Link>
</div>
<Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}/blob/main/${POSTS_DIR}/${frontmatter!.slug}/index.mdx`}
title={`Edit "${frontmatter!.title}" on GitHub`}
plain
className={clsx(styles.metaItem, styles.metaLink)}
>
<SquarePenIcon size="1.25em" className={styles.metaIcon} />
<span>Improve This Post</span>
</Link>
<div
className={styles.metaItem}
@ -129,7 +126,7 @@ const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
marginRight: 0,
}}
>
<EyeIcon size="1.2em" className={styles.metaIcon} />
<EyeIcon size="1.25em" className={styles.metaIcon} />
<Suspense
// when this loads, the component will count up from zero to the actual number of hits, so we can simply
// show a zero here as a "loading indicator"

View File

@ -28,7 +28,6 @@
}
.wave {
display: inline-block;
margin-left: 0.1em;
font-size: 1.2em;
}

View File

@ -275,7 +275,7 @@ const Page = () => {
darkColor="#959595"
plain
>
<LockIcon size="1.25em" style={{ verticalAlign: "-0.25em" }} />{" "}
<LockIcon size="1.25em" style={{ verticalAlign: "text-top" }} />{" "}
<code
style={{
margin: "0 0.15em",

View File

@ -58,13 +58,12 @@ export const WindowsLogo = () => (
stroke="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
height="1.2em"
width="1.2em"
width="1.25em"
height="1.25em"
style={{
display: "inline",
width: "1.2em",
height: "1.2em",
verticalAlign: "-0.15em",
width: "1.25em",
height: "1.25em",
verticalAlign: "text-bottom",
marginRight: "0.1em",
}}
>

View File

@ -174,20 +174,19 @@ const Page = async () => {
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
height="1.2em"
width="1.2em"
height="1.2em"
style={{
display: "inline",
width: "1.2em",
height: "1.2em",
verticalAlign: "-0.2em",
margin: "0 0.15em",
verticalAlign: "text-top",
margin: "0 0.1em 0 0.25em",
fill: "var(--colors-text)",
}}
>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>{" "}
GitHub...
GitHub.
</Link>
</p>
</>

View File

@ -37,15 +37,13 @@
}
.icon {
display: inline;
width: 1.25em;
height: 1.25em;
vertical-align: -0.25em;
margin: 0 0.1em;
vertical-align: text-top;
}
.heart {
display: inline-block;
color: var(--colors-error);
}

View File

@ -26,11 +26,7 @@ const Footer = ({ className, ...rest }: FooterProps) => {
</div>
<div>
Made with{" "}
<span className={styles.heart} title="Love">
<HeartIcon size="1.25em" fill="currentColor" className={styles.icon} />
</span>{" "}
and{" "}
Made with <HeartIcon size="1.25em" fill="currentColor" className={clsx(styles.icon, styles.heart)} /> and{" "}
<Link
href="https://nextjs.org/"
title="Powered by Next.js"
@ -44,8 +40,8 @@ const Footer = ({ className, ...rest }: FooterProps) => {
stroke="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
height="1.25em"
width="1.25em"
height="1.25em"
className={styles.icon}
>
<path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z" />

View File

@ -22,7 +22,7 @@
}
.home {
display: inline-flex;
display: flex;
flex-shrink: 0;
align-items: center;
color: var(--colors-medium-dark) !important;

View File

@ -1,11 +1,13 @@
.menu {
display: inline-flex;
display: flex;
flex-direction: row;
align-items: center;
padding: 0;
margin: 0;
}
.item {
display: inline-block;
display: block;
margin-left: 1em;
list-style: none;
}

View File

@ -27,7 +27,13 @@ const Menu = ({ className, ...rest }: MenuProps) => {
);
})}
<li className={styles.item}>
<li
className={styles.item}
style={{
// manually align the theme toggle with the rest of the menu icons
paddingTop: "0.2em",
}}
>
<MenuItem
// @ts-expect-error
icon={ThemeToggle}

View File

@ -1,6 +1,8 @@
.link {
display: inline-block;
display: inline-flex;
align-items: center;
padding: 0.6em;
margin-top: 0.2em;
color: var(--colors-medium-dark) !important;
}
@ -17,17 +19,16 @@
}
.icon {
display: inline-block;
display: block;
width: 1.25em;
height: 1.25em;
vertical-align: -0.3em;
}
.label {
margin-left: 0.7em;
font-size: 0.925em;
font-weight: 500;
letter-spacing: 0.025em;
margin-left: 0.7em;
}
@media (max-width: 768px) {

View File

@ -1,4 +1,5 @@
.toggle {
display: block;
border: 0;
padding: 0.6em;
margin-right: -0.6em;
@ -15,7 +16,7 @@
/* hacky way to avoid flashing icon for a few milliseconds on initial render */
.toggle > .sun,
[data-theme="dark"] .toggle > .moon {
display: inline-block;
display: inherit;
}
/* stylelint-disable-next-line no-descending-specificity */

View File

@ -1,4 +1,5 @@
import { env } from "../../lib/env";
import { cache } from "react";
import path from "path";
import fs from "fs/promises";
import glob from "fast-glob";
@ -20,7 +21,7 @@ export type FrontMatter = {
};
/** Use filesystem to get a simple list of all post slugs */
export const getSlugs = async (): Promise<string[]> => {
export const getSlugs = cache(async (): Promise<string[]> => {
// list all .mdx files in POSTS_DIR
const mdxFiles = await glob("*/index.mdx", {
cwd: path.join(process.cwd(), POSTS_DIR),
@ -31,7 +32,7 @@ export const getSlugs = async (): Promise<string[]> => {
const slugs = mdxFiles.map((fileName) => fileName.replace(/\/index\.mdx$/, ""));
return slugs;
};
});
// overloaded to return either the front matter of a single post or ALL posts
export const getFrontMatter: {
@ -43,65 +44,67 @@ export const getFrontMatter: {
* Parses and returns the front matter of a given slug, or undefined if the slug does not exist
*/
(slug: string): Promise<FrontMatter | undefined>;
} = async (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
slug?: any
): // eslint-disable-next-line @typescript-eslint/no-explicit-any
Promise<any> => {
if (typeof slug === "string") {
try {
const { frontmatter } = await import(`../../${POSTS_DIR}/${slug}/index.mdx`);
} = cache(
async (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
slug?: any
): // eslint-disable-next-line @typescript-eslint/no-explicit-any
Promise<any> => {
if (typeof slug === "string") {
try {
const { frontmatter } = await import(`../../${POSTS_DIR}/${slug}/index.mdx`);
// process markdown title to html...
const htmlTitle = await unified()
.use(remarkParse)
.use(remarkSmartypants)
.use(remarkHtml, {
sanitize: {
// allow *very* limited markdown to be used in post titles
tagNames: ["code", "em", "strong"],
},
})
.process(frontmatter.title)
.then((result) => result.toString().trim());
// process markdown title to html...
const htmlTitle = await unified()
.use(remarkParse)
.use(remarkSmartypants)
.use(remarkHtml, {
sanitize: {
// allow *very* limited markdown to be used in post titles
tagNames: ["code", "em", "strong"],
},
})
.process(frontmatter.title)
.then((result) => result.toString().trim());
// ...and then (sketchily) remove said html for a plaintext version:
// https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
const title = decode(htmlTitle.replace(/<[^>]*>/g, ""));
// ...and then (sketchily) remove said html for a plaintext version:
// https://css-tricks.com/snippets/javascript/strip-html-tags-in-javascript/
const title = decode(htmlTitle.replace(/<[^>]*>/g, ""));
return {
...(frontmatter as Partial<FrontMatter>),
// plain title without html or markdown syntax:
title,
// stylized title with limited html tags:
htmlTitle,
slug,
// validate/normalize the date string provided from front matter
date: new Date(frontmatter.date).toISOString(),
permalink: `${env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${slug}`,
} as FrontMatter;
} catch (error) {
console.error(`Failed to load front matter for post with slug "${slug}":`, error);
return undefined;
return {
...(frontmatter as Partial<FrontMatter>),
// plain title without html or markdown syntax:
title,
// stylized title with limited html tags:
htmlTitle,
slug,
// validate/normalize the date string provided from front matter
date: new Date(frontmatter.date).toISOString(),
permalink: `${env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${slug}`,
} as FrontMatter;
} catch (error) {
console.error(`Failed to load front matter for post with slug "${slug}":`, error);
return undefined;
}
}
if (!slug) {
// concurrently fetch the front matter of each post
const slugs = await getSlugs();
const posts = await Promise.all(slugs.map(getFrontMatter));
// sort the results reverse chronologically and return
return posts.sort(
(post1, post2) => new Date(post2!.date).getTime() - new Date(post1!.date).getTime()
) as FrontMatter[];
}
throw new Error("getFrontMatter() called with invalid argument.");
}
if (!slug) {
// concurrently fetch the front matter of each post
const slugs = await getSlugs();
const posts = await Promise.all(slugs.map(getFrontMatter));
// sort the results reverse chronologically and return
return posts.sort(
(post1, post2) => new Date(post2!.date).getTime() - new Date(post1!.date).getTime()
) as FrontMatter[];
}
throw new Error("getFrontMatter() called with invalid argument.");
};
);
/** Returns the content of a post with very limited processing to include in RSS feeds */
export const getContent = async (slug: string): Promise<string | undefined> => {
export const getContent = cache(async (slug: string): Promise<string | undefined> => {
try {
// TODO: also remove MDX-related syntax (e.g. import/export statements)
const content = await unified()
@ -139,4 +142,4 @@ export const getContent = async (slug: string): Promise<string | undefined> => {
console.error(`Failed to load/parse content for post with slug "${slug}":`, error);
return undefined;
}
};
});

View File

@ -11,8 +11,13 @@ import "./lib/env";
const nextConfig: NextConfig = {
reactStrictMode: true,
productionBrowserSourceMaps: true,
pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"],
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
outputFileTracingIncludes: {
"/notes/[slug]/opengraph-image": [
"./notes/**/*",
@ -24,6 +29,7 @@ const nextConfig: NextConfig = {
outputFileTracingExcludes: {
"*": ["./public/**/*", "**/*.mp4", "**/*.webm", "**/*.vtt"],
},
productionBrowserSourceMaps: true,
webpack: (config) => {
config.module.rules.push({
test: /\.(mp4|webm|vtt)$/i,
@ -50,9 +56,6 @@ const nextConfig: NextConfig = {
],
},
},
eslint: {
dirs: ["app", "components", "contexts", "hooks", "lib", "notes"],
},
headers: async () => [
{
// matches any path

View File

@ -22,13 +22,12 @@ export const OctocatLink = ({ repo }) => {
xmlns="http://www.w3.org/2000/svg"
strokeWidth="0"
viewBox="0 0 24 24"
height="1.2em"
width="1.2em"
height="1.2em"
style={{
display: "inline",
height: "1.2em",
width: "1.2em",
verticalAlign: "-0.2em",
height: "1.2em",
verticalAlign: "text-top",
fill: "var(--colors-text)",
}}
>

View File

@ -13,8 +13,9 @@
"dev": "next dev -H 0.0.0.0",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prepare": "husky"
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"prepare": "test -d node_modules/husky && husky || echo \"skipping husky\""
},
"dependencies": {
"@date-fns/tz": "^1.2.0",
@ -37,7 +38,7 @@
"feed": "^4.2.2",
"geist": "^1.3.1",
"html-entities": "^2.6.0",
"lucide-react": "0.488.0",
"lucide-react": "0.501.0",
"next": "15.3.1-canary.13",
"polished": "^4.3.1",
"prop-types": "^15.8.1",

80
pnpm-lock.yaml generated
View File

@ -40,7 +40,7 @@ importers:
version: 15.26.0
'@t3-oss/env-nextjs':
specifier: ^0.12.0
version: 0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.2)
version: 0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.3)
'@upstash/redis':
specifier: ^1.34.8
version: 1.34.8
@ -69,8 +69,8 @@ importers:
specifier: ^2.6.0
version: 2.6.0
lucide-react:
specifier: 0.488.0
version: 0.488.0(react@19.1.0)
specifier: 0.501.0
version: 0.501.0(react@19.1.0)
next:
specifier: 15.3.1-canary.13
version: 15.3.1-canary.13(@babel/core@7.26.10)(babel-plugin-react-compiler@19.0.0-beta-ebf51a3-20250411)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@ -417,8 +417,8 @@ packages:
'@emotion/hash@0.9.2':
resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==}
'@eslint-community/eslint-utils@4.6.0':
resolution: {integrity: sha512-WhCn7Z7TauhBtmzhvKpoQs0Wwb/kBcy4CwpuI0/eEIr2Lx2auxmulAzLr91wVZJaz47iUZdkXOK7WlAfxGKCnA==}
'@eslint-community/eslint-utils@4.6.1':
resolution: {integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
@ -648,8 +648,8 @@ packages:
'@types/react': '>=16'
react: '>=16'
'@napi-rs/wasm-runtime@0.2.8':
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
'@napi-rs/wasm-runtime@0.2.9':
resolution: {integrity: sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==}
'@next/bundle-analyzer@15.3.1-canary.13':
resolution: {integrity: sha512-dyobhAPSrAistAAW9eilkwrqv6Ie4RTDtZhvgD0MZQTpW6ftuV93c3LqEHMrxVgmCG6eMPe3dRd1DJYZF0faog==}
@ -1272,8 +1272,8 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
caniuse-lite@1.0.30001713:
resolution: {integrity: sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==}
caniuse-lite@1.0.30001714:
resolution: {integrity: sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg==}
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@ -1506,8 +1506,8 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
electron-to-chromium@1.5.137:
resolution: {integrity: sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==}
electron-to-chromium@1.5.138:
resolution: {integrity: sha512-FWlQc52z1dXqm+9cCJ2uyFgJkESd+16j6dBEjsgDNuHjBpuIzL8/lRc0uvh1k8RNI6waGo6tcy2DvwkTBJOLDg==}
emoji-regex-xs@1.0.0:
resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
@ -2440,8 +2440,8 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
lucide-react@0.488.0:
resolution: {integrity: sha512-ronlL0MyKut4CEzBY/ai2ZpKPxyWO4jUqdAkm2GNK5Zn3Rj+swDz+3lvyAUXN0PNqPKIX6XM9Xadwz/skLs/pQ==}
lucide-react@0.501.0:
resolution: {integrity: sha512-E2KoyhW59fCb/yUbR3rbDer83fqn7a8NG91ZhIot2yWaPHjPyGzzsNKh40N//GezYShAuycf3TcQksRQznIsRw==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@ -2780,8 +2780,8 @@ packages:
resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
engines: {node: '>=18'}
oniguruma-parser@0.11.1:
resolution: {integrity: sha512-fX6SirDOsTUNqSUOnL3fDtD3R7PCXNWGA3WWPvv9egEfTWkNXzRLO/9CC1WkDusP6HyWRZig06kHeYPcw3mlqQ==}
oniguruma-parser@0.11.2:
resolution: {integrity: sha512-F7Ld4oDZJCI5/wCZ8AOffQbqjSzIRpKH7I/iuSs1SkhZeCj0wS6PMZ4W6VA16TWHrAo0Y9bBKEJOe7tvwcTXnw==}
oniguruma-to-es@4.2.0:
resolution: {integrity: sha512-MDPs6KSOLS0tKQ7joqg44dRIRZUyotfTy0r+7oEEs6VwWWP0+E2PPDYWMFN0aqOjRyWHBYq7RfKw9GQk2S2z5g==}
@ -3760,8 +3760,8 @@ packages:
peerDependencies:
zod: ^3.18.0
zod@3.24.2:
resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==}
zod@3.24.3:
resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==}
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@ -3970,7 +3970,7 @@ snapshots:
'@emotion/hash@0.9.2': {}
'@eslint-community/eslint-utils@4.6.0(eslint@9.24.0)':
'@eslint-community/eslint-utils@4.6.1(eslint@9.24.0)':
dependencies:
eslint: 9.24.0
eslint-visitor-keys: 3.4.3
@ -4199,7 +4199,7 @@ snapshots:
'@types/react': 19.1.2
react: 19.1.0
'@napi-rs/wasm-runtime@0.2.8':
'@napi-rs/wasm-runtime@0.2.9':
dependencies:
'@emnapi/core': 1.4.3
'@emnapi/runtime': 1.4.3
@ -4417,19 +4417,19 @@ snapshots:
dependencies:
tslib: 2.8.1
'@t3-oss/env-core@0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.2)':
'@t3-oss/env-core@0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.3)':
optionalDependencies:
typescript: 5.8.3
valibot: 1.0.0(typescript@5.8.3)
zod: 3.24.2
zod: 3.24.3
'@t3-oss/env-nextjs@0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.2)':
'@t3-oss/env-nextjs@0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.3)':
dependencies:
'@t3-oss/env-core': 0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.2)
'@t3-oss/env-core': 0.12.0(typescript@5.8.3)(valibot@1.0.0(typescript@5.8.3))(zod@3.24.3)
optionalDependencies:
typescript: 5.8.3
valibot: 1.0.0(typescript@5.8.3)
zod: 3.24.2
zod: 3.24.3
'@tybys/wasm-util@0.9.0':
dependencies:
@ -4561,7 +4561,7 @@ snapshots:
'@typescript-eslint/utils@8.30.1(eslint@9.24.0)(typescript@5.8.3)':
dependencies:
'@eslint-community/eslint-utils': 4.6.0(eslint@9.24.0)
'@eslint-community/eslint-utils': 4.6.1(eslint@9.24.0)
'@typescript-eslint/scope-manager': 8.30.1
'@typescript-eslint/types': 8.30.1
'@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3)
@ -4615,7 +4615,7 @@ snapshots:
'@unrs/resolver-binding-wasm32-wasi@1.5.0':
dependencies:
'@napi-rs/wasm-runtime': 0.2.8
'@napi-rs/wasm-runtime': 0.2.9
optional: true
'@unrs/resolver-binding-win32-arm64-msvc@1.5.0':
@ -4792,8 +4792,8 @@ snapshots:
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001713
electron-to-chromium: 1.5.137
caniuse-lite: 1.0.30001714
electron-to-chromium: 1.5.138
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.24.4)
@ -4832,7 +4832,7 @@ snapshots:
callsites@3.1.0: {}
caniuse-lite@1.0.30001713: {}
caniuse-lite@1.0.30001714: {}
ccount@2.0.1: {}
@ -5044,7 +5044,7 @@ snapshots:
eastasianwidth@0.2.0: {}
electron-to-chromium@1.5.137: {}
electron-to-chromium@1.5.138: {}
emoji-regex-xs@1.0.0: {}
@ -5352,8 +5352,8 @@ snapshots:
'@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.26.10)
eslint: 9.24.0
hermes-parser: 0.25.1
zod: 3.24.2
zod-validation-error: 3.4.0(zod@3.24.2)
zod: 3.24.3
zod-validation-error: 3.4.0(zod@3.24.3)
transitivePeerDependencies:
- supports-color
@ -5394,7 +5394,7 @@ snapshots:
eslint@9.24.0:
dependencies:
'@eslint-community/eslint-utils': 4.6.0(eslint@9.24.0)
'@eslint-community/eslint-utils': 4.6.1(eslint@9.24.0)
'@eslint-community/regexpp': 4.12.1
'@eslint/config-array': 0.20.0
'@eslint/config-helpers': 0.2.1
@ -6239,7 +6239,7 @@ snapshots:
dependencies:
yallist: 3.1.1
lucide-react@0.488.0(react@19.1.0):
lucide-react@0.501.0(react@19.1.0):
dependencies:
react: 19.1.0
@ -6744,7 +6744,7 @@ snapshots:
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
caniuse-lite: 1.0.30001713
caniuse-lite: 1.0.30001714
postcss: 8.4.31
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
@ -6856,12 +6856,12 @@ snapshots:
dependencies:
mimic-function: 5.0.1
oniguruma-parser@0.11.1: {}
oniguruma-parser@0.11.2: {}
oniguruma-to-es@4.2.0:
dependencies:
emoji-regex-xs: 1.0.0
oniguruma-parser: 0.11.1
oniguruma-parser: 0.11.2
regex: 6.0.1
regex-recursion: 6.0.2
@ -8165,10 +8165,10 @@ snapshots:
yocto-queue@0.1.0: {}
zod-validation-error@3.4.0(zod@3.24.2):
zod-validation-error@3.4.0(zod@3.24.3):
dependencies:
zod: 3.24.2
zod: 3.24.3
zod@3.24.2: {}
zod@3.24.3: {}
zwitch@2.0.4: {}