> ParseFromFile(FileStream fileStream)
- {
- using var streamReader = new StreamReader(fileStream);
- var subject = await streamReader.ReadLineAsync();
- if (subject is null) throw new InvalidDataException("Subject is null");
-
- if (!FluidParser.TryParse(subject, out var subjectTemplate, out var errorSubject)) return errorSubject;
- var body = await streamReader.ReadToEndAsync();
- if (!FluidParser.TryParse(body, out var bodyTemplate, out var errorBody)) return errorBody;
-
- return new SmtpTemplate
- {
- Subject = subjectTemplate,
- Body = bodyTemplate
- };
- }
-}
\ No newline at end of file
diff --git a/API/SmtpTemplates/AccountActivation.liquid b/API/SmtpTemplates/AccountActivation.liquid
index 9dda4044..99322b53 100644
--- a/API/SmtpTemplates/AccountActivation.liquid
+++ b/API/SmtpTemplates/AccountActivation.liquid
@@ -1,55 +1,179 @@
-Hi! Activate your account
-
-
-
-
-
- Password Reset
-
-
-
-
-
Active your account!
-
Hello {{ To.Name }},
-
Thanks for signing up! Please verify your email address by clicking on the link below.
-
Activate Account
-
If you did not sign up, you can safely ignore this email.
-
Thank you, OpenShock Team
-
-
-
\ No newline at end of file
+Activate your OpenShock account
+
+
+
+
+
+
+
+
+
+ One last step: activate your new OpenShock account.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OpenShock
+
+
+
+
+
+
+
+
+
+
+ Activate your account
+
+
+ Hello
+ {{ To.Name }},
+
+
+ Thanks for signing up! Confirm this is your email
+ address to finish setting up your OpenShock
+ account.
+
+
+
+ If the button above doesn't work, copy and
+ paste this link into your browser:
+
+ {{ ActivationLink }}
+
+ If you did not sign up for OpenShock, you can
+ safely ignore this email. No account will be
+ created without confirmation.
+
+
+ Thank you, The OpenShock Team
+
+
+
+
+
+
+
+
+
+
+ OpenShock will never ask for your password, API
+ token, or any other credentials by email. If a
+ message appears to come from us and asks for
+ these, do not respond.
+
+
+ Need help? Visit
+ openshock.app .
+
+
+ © OpenShock. This is an automated message, please
+ do not reply.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/API/SmtpTemplates/EmailChangeNotice.liquid b/API/SmtpTemplates/EmailChangeNotice.liquid
index ac096b64..b88948d5 100644
--- a/API/SmtpTemplates/EmailChangeNotice.liquid
+++ b/API/SmtpTemplates/EmailChangeNotice.liquid
@@ -1,51 +1,161 @@
Your OpenShock email is being changed
-
-
-
-
-
- Email change requested
-
-
-
-
-
Email change requested
-
Hello {{ To.Name }},
-
Someone requested that the email address on your OpenShock account be changed to {{ NewEmail }} .
-
The change is not yet applied . It will only take effect once the new address is verified via the link sent to it.
-
If this was you, no action is needed.
-
If this was not you , sign in immediately and change your password — your account may be compromised.
-
Thank you, OpenShock Team
-
-
+
+
+
+
+
+
+
+
+
+ A change to your OpenShock account email was requested.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OpenShock
+
+
+
+
+
+
+
+
+
+
+ Email change requested
+
+
+ Hello
+ {{ To.Name }},
+
+
+ Someone requested that the email address on your
+ OpenShock account be changed to
+ {{ NewEmail }} .
+
+
+ The change is not yet applied . It
+ will only take effect once the new address is
+ verified via the link sent to it.
+
+
+ If this was you, no further action is needed.
+
+
+ If this was not you , sign in
+ immediately and change your password. Your account
+ may be compromised. You should also review active
+ sessions and API tokens.
+
+
+ Thank you, The OpenShock Team
+
+
+
+
+
+
+
+
+
+
+ OpenShock will never ask for your password, API
+ token, or any other credentials by email. If a
+ message appears to come from us and asks for
+ these, do not respond.
+
+
+ Need help? Visit
+ openshock.app .
+
+
+ © OpenShock. This is an automated message, please
+ do not reply.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/API/SmtpTemplates/EmailVerification.liquid b/API/SmtpTemplates/EmailVerification.liquid
index 4b8e0595..b5228aa1 100644
--- a/API/SmtpTemplates/EmailVerification.liquid
+++ b/API/SmtpTemplates/EmailVerification.liquid
@@ -1,55 +1,179 @@
-Hi! Verify your Email!
-
-
-
-
-
- Password Reset
-
-
-
-
-
Email verification
-
Hello {{ To.Name }},
-
Thanks for signing up! Please verify your email address by clicking on the link below.
-
Verify Email
-
If you did not sign up, you can safely ignore this email.
-
Thank you, OpenShock Team
-
-
-
\ No newline at end of file
+Verify your new OpenShock email address
+
+
+
+
+
+
+
+
+
+ Confirm this email address to apply the change on your OpenShock account.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OpenShock
+
+
+
+
+
+
+
+
+
+
+ Verify your email
+
+
+ Hello
+ {{ To.Name }},
+
+
+ Please confirm this is your email address by
+ clicking the button below. The change will only
+ take effect once this address has been verified.
+
+
+
+ If the button above doesn't work, copy and
+ paste this link into your browser:
+
+ {{ VerifyLink }}
+
+ If you did not request this change, you can safely
+ ignore this email. Your account email will not be
+ updated.
+
+
+ Thank you, The OpenShock Team
+
+
+
+
+
+
+
+
+
+
+ OpenShock will never ask for your password, API
+ token, or any other credentials by email. If a
+ message appears to come from us and asks for
+ these, do not respond.
+
+
+ Need help? Visit
+ openshock.app .
+
+
+ © OpenShock. This is an automated message, please
+ do not reply.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/API/SmtpTemplates/PasswordReset.liquid b/API/SmtpTemplates/PasswordReset.liquid
index 121ba441..f118c242 100644
--- a/API/SmtpTemplates/PasswordReset.liquid
+++ b/API/SmtpTemplates/PasswordReset.liquid
@@ -1,55 +1,182 @@
-Password reset request
-
-
-
-
-
- Password Reset
-
-
-
-
-
Password Reset
-
Hello {{ To.Name }},
-
We have received a request to reset the password for your account. Click the button below to reset your password:
-
Reset Password
-
If you did not request this change, you can safely ignore this email.
-
Thank you, OpenShock Team
+Reset your OpenShock password
+
+
+
+
+
+
+
+
+
+ Reset the password for your OpenShock account.
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OpenShock
+
+
+
+
+
+
+
+
+
+
+ Password reset
+
+
+ Hello
+ {{ To.Name }},
+
+
+ We received a request to reset the password for
+ your OpenShock account. Click the button below to
+ choose a new one.
+
+
+
+ If the button above doesn't work, copy and
+ paste this link into your browser:
+
+ {{ ResetLink }}
+
+ This link is single-use and will expire shortly.
+ If you did not request a password reset, you can
+ safely ignore this email. Your password will
+ remain unchanged. If you receive these messages
+ repeatedly, sign in and review your account's
+ recent activity.
+
+
+ Thank you, The OpenShock Team
+
+
+
+
+
+
+
+
+
+
+ OpenShock will never ask for your password, API
+ token, or any other credentials by email. If a
+ message appears to come from us and asks for
+ these, do not respond.
+
+
+ Need help? Visit
+ openshock.app .
+
+
+ © OpenShock. This is an automated message, please
+ do not reply.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/API/Utils/OneWayPolymorphicJsonConverter.cs b/API/Utils/OneWayPolymorphicJsonConverter.cs
deleted file mode 100644
index a2de0e31..00000000
--- a/API/Utils/OneWayPolymorphicJsonConverter.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace OpenShock.API.Utils;
-
-public sealed class OneWayPolymorphicJsonConverter
: JsonConverter
-{
- public override bool CanConvert(Type typeToConvert)
- {
- return typeof(T) == typeToConvert; //.IsAssignableFrom(typeToConvert);
- }
-
- public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
- throw new NotSupportedException();
-
- public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) =>
- JsonSerializer.Serialize(writer, value, value!.GetType());
-}
\ No newline at end of file
diff --git a/docker/API.Dockerfile b/docker/API.Dockerfile
index 2e67a470..038bc18a 100644
--- a/docker/API.Dockerfile
+++ b/docker/API.Dockerfile
@@ -20,4 +20,4 @@ RUN apk update && apk add --no-cache openssl
COPY --link --from=build-api /app .
COPY docker/appsettings.API.json /app/appsettings.Container.json
-ENTRYPOINT ["/bin/ash", "/entrypoint.sh", "OpenShock.API.dll"]
\ No newline at end of file
+ENTRYPOINT ["/bin/ash", "/entrypoint.sh", "OpenShock.API.dll"]
diff --git a/email-templates/.gitignore b/email-templates/.gitignore
new file mode 100644
index 00000000..f7786c25
--- /dev/null
+++ b/email-templates/.gitignore
@@ -0,0 +1,8 @@
+node_modules
+.react-email
+.next
+out
+.env
+.env.local
+*.log
+.DS_Store
diff --git a/email-templates/.prettierrc.json b/email-templates/.prettierrc.json
new file mode 100644
index 00000000..544138be
--- /dev/null
+++ b/email-templates/.prettierrc.json
@@ -0,0 +1,3 @@
+{
+ "singleQuote": true
+}
diff --git a/email-templates/README.md b/email-templates/README.md
new file mode 100644
index 00000000..9540f185
--- /dev/null
+++ b/email-templates/README.md
@@ -0,0 +1,70 @@
+# OpenShock Email Templates
+
+The API's transactional email templates, authored as React components via
+[`react-email`](https://react.email/) and exported to Liquid (`{{ name }}`
+variables) for the Fluid-based `SmtpTemplate` runtime loader.
+
+Rendered `.liquid` files live in `API/SmtpTemplates/` and are committed to the
+repo as static files — no Node/pnpm is needed during `dotnet build` or in
+CI/Docker.
+
+## Workflow
+
+When you edit a template source (`emails/*.tsx`), re-render and commit:
+
+```sh
+pnpm install # first time only
+pnpm dev # live preview at http://localhost:3000
+pnpm export # overwrites API/SmtpTemplates/*.liquid
+```
+
+Each exported file is a Fluid/Liquid template: line 1 is the subject, the rest
+is the HTML body — the format expected by
+`API/Services/Email/Smtp/SmtpTemplate.cs`.
+
+## Authoring a template
+
+Each `emails/*.tsx` file should export:
+
+- a **named** PascalCase React component (the parameterised template),
+- a `subject` string — emitted as the first line of the exported `.liquid` file (Fluid reads line 1 as the subject template),
+- a `sampleProps` object — keys define which props get placeholder-substituted on export; values are used by the live preview,
+- a **default** export wrapping the component with `sampleProps` so `email dev` can render it.
+
+Example:
+
+```tsx
+export interface VerifyEmailProps {
+ 'To.Name': string;
+ VerifyLink: string;
+}
+
+export const subject = 'Hi! Verify your Email!';
+
+export const sampleProps: VerifyEmailProps = {
+ 'To.Name': 'shockee',
+ VerifyLink: 'https://openshock.app/verify?token=preview',
+};
+
+export function EmailVerification(props: VerifyEmailProps) {
+ /* ... */
+}
+
+export default function Preview_EmailVerification() {
+ return ;
+}
+```
+
+On export, prop values become `{{ To.Name }}` / `{{ VerifyLink }}` etc. Prop
+names must match the variable names the API passes into Fluid at send time.
+
+## Layout
+
+- `emails/*.tsx` — templates (files starting with `_` are ignored by the exporter).
+- `emails/_lib/` — shared helpers.
+- `scripts/export-templates.ts` — Liquid exporter.
+- `../API/SmtpTemplates/*.liquid` — pre-rendered templates (committed, re-generated by `pnpm export`).
+
+## License
+
+AGPL-3.0
diff --git a/email-templates/emails/AccountActivation.tsx b/email-templates/emails/AccountActivation.tsx
new file mode 100644
index 00000000..ea2ec570
--- /dev/null
+++ b/email-templates/emails/AccountActivation.tsx
@@ -0,0 +1,47 @@
+import {
+ CtaButton,
+ Greeting,
+ Layout,
+ Paragraph,
+ RawLinkFallback,
+ SecurityNotice,
+ Signoff,
+} from './_lib/components.tsx';
+
+export interface AccountActivationProps {
+ 'To.Name': string;
+ ActivationLink: string;
+}
+
+export const subject = 'Activate your OpenShock account';
+
+export const sampleProps: AccountActivationProps = {
+ 'To.Name': 'shockee',
+ ActivationLink: 'https://openshock.app/activate?token=preview',
+};
+
+export function AccountActivation(props: AccountActivationProps) {
+ return (
+
+
+
+ Thanks for signing up! Confirm this is your email address to finish
+ setting up your OpenShock account.
+
+ Activate account
+
+
+ If you did not sign up for OpenShock, you can safely ignore this email.
+ No account will be created without confirmation.
+
+
+
+ );
+}
+
+export default function Preview_AccountActivation() {
+ return ;
+}
diff --git a/email-templates/emails/EmailChangeNotice.tsx b/email-templates/emails/EmailChangeNotice.tsx
new file mode 100644
index 00000000..5617eec3
--- /dev/null
+++ b/email-templates/emails/EmailChangeNotice.tsx
@@ -0,0 +1,50 @@
+import {
+ Greeting,
+ InlineCode,
+ Layout,
+ Paragraph,
+ SecurityNotice,
+ Signoff,
+} from './_lib/components.tsx';
+
+export interface EmailChangeNoticeProps {
+ 'To.Name': string;
+ NewEmail: string;
+}
+
+export const subject = 'Your OpenShock email is being changed';
+
+export const sampleProps: EmailChangeNoticeProps = {
+ 'To.Name': 'shockee',
+ NewEmail: 'new-address@example.com',
+};
+
+export function EmailChangeNotice(props: EmailChangeNoticeProps) {
+ return (
+
+
+
+ Someone requested that the email address on your OpenShock account be
+ changed to {props.NewEmail} .
+
+
+ The change is not yet applied . It will only take effect
+ once the new address is verified via the link sent to it.
+
+ If this was you, no further action is needed.
+
+ If this was not you , sign in immediately and change
+ your password. Your account may be compromised. You should also review
+ active sessions and API tokens.
+
+
+
+ );
+}
+
+export default function Preview_EmailChangeNotice() {
+ return ;
+}
diff --git a/email-templates/emails/EmailVerification.tsx b/email-templates/emails/EmailVerification.tsx
new file mode 100644
index 00000000..9d490192
--- /dev/null
+++ b/email-templates/emails/EmailVerification.tsx
@@ -0,0 +1,47 @@
+import {
+ CtaButton,
+ Greeting,
+ Layout,
+ Paragraph,
+ RawLinkFallback,
+ SecurityNotice,
+ Signoff,
+} from './_lib/components.tsx';
+
+export interface EmailVerificationProps {
+ 'To.Name': string;
+ VerifyLink: string;
+}
+
+export const subject = 'Verify your new OpenShock email address';
+
+export const sampleProps: EmailVerificationProps = {
+ 'To.Name': 'shockee',
+ VerifyLink: 'https://openshock.app/verify?token=preview',
+};
+
+export function EmailVerification(props: EmailVerificationProps) {
+ return (
+
+
+
+ Please confirm this is your email address by clicking the button below.
+ The change will only take effect once this address has been verified.
+
+ Verify email
+
+
+ If you did not request this change, you can safely ignore this email.
+ Your account email will not be updated.
+
+
+
+ );
+}
+
+export default function Preview_EmailVerification() {
+ return ;
+}
diff --git a/email-templates/emails/PasswordReset.tsx b/email-templates/emails/PasswordReset.tsx
new file mode 100644
index 00000000..06881045
--- /dev/null
+++ b/email-templates/emails/PasswordReset.tsx
@@ -0,0 +1,49 @@
+import {
+ CtaButton,
+ Greeting,
+ Layout,
+ Paragraph,
+ RawLinkFallback,
+ SecurityNotice,
+ Signoff,
+} from './_lib/components.tsx';
+
+export interface PasswordResetProps {
+ 'To.Name': string;
+ ResetLink: string;
+}
+
+export const subject = 'Reset your OpenShock password';
+
+export const sampleProps: PasswordResetProps = {
+ 'To.Name': 'shockee',
+ ResetLink: 'https://openshock.app/reset?token=preview',
+};
+
+export function PasswordReset(props: PasswordResetProps) {
+ return (
+
+
+
+ We received a request to reset the password for your OpenShock account.
+ Click the button below to choose a new one.
+
+ Reset password
+
+
+ This link is single-use and will expire shortly. If you did not request
+ a password reset, you can safely ignore this email. Your password will
+ remain unchanged. If you receive these messages repeatedly, sign in and
+ review your account's recent activity.
+
+
+
+ );
+}
+
+export default function Preview_PasswordReset() {
+ return ;
+}
diff --git a/email-templates/emails/_lib/components.tsx b/email-templates/emails/_lib/components.tsx
new file mode 100644
index 00000000..6907f03a
--- /dev/null
+++ b/email-templates/emails/_lib/components.tsx
@@ -0,0 +1,135 @@
+import type { ReactNode } from 'react';
+import {
+ Body,
+ Container,
+ Head,
+ Heading,
+ Hr,
+ Html,
+ Link,
+ Preview,
+ Section,
+ Text,
+} from '@react-email/components';
+import { styles } from './styles.ts';
+
+export function Layout({
+ heading,
+ preview,
+ children,
+}: {
+ heading: string;
+ preview: string;
+ children: ReactNode;
+}) {
+ return (
+
+
+ {preview}
+
+
+
+
+ {heading}
+ {children}
+
+
+
+
+
+ );
+}
+
+function Header() {
+ return (
+
+ );
+}
+
+function Footer() {
+ return (
+
+
+ OpenShock will never ask for your password, API token, or any other
+ credentials by email. If a message appears to come from us and asks for
+ these, do not respond.
+
+
+ Need help? Visit{' '}
+
+ openshock.app
+
+ .
+
+
+ © OpenShock. This is an automated message, please do not reply.
+
+
+ );
+}
+
+export function Paragraph({ children }: { children: ReactNode }) {
+ return {children} ;
+}
+
+export function MutedParagraph({ children }: { children: ReactNode }) {
+ return {children} ;
+}
+
+export function Greeting({ name }: { name: string }) {
+ return Hello {name}, ;
+}
+
+export function Signoff() {
+ return (
+
+ Thank you,
+
+ The OpenShock Team
+
+ );
+}
+
+export function CtaButton({
+ href,
+ children,
+}: {
+ href: string;
+ children: ReactNode;
+}) {
+ return (
+
+ );
+}
+
+export function RawLinkFallback({ href }: { href: string }) {
+ return (
+ <>
+
+ If the button above doesn't work, copy and paste this link into your
+ browser:
+
+
+ {href}
+
+ >
+ );
+}
+
+export function SecurityNotice({ children }: { children: ReactNode }) {
+ return {children} ;
+}
+
+export function Divider() {
+ return ;
+}
+
+export function InlineCode({ children }: { children: ReactNode }) {
+ return {children} ;
+}
diff --git a/email-templates/emails/_lib/placeholders.ts b/email-templates/emails/_lib/placeholders.ts
new file mode 100644
index 00000000..a0d4daf7
--- /dev/null
+++ b/email-templates/emails/_lib/placeholders.ts
@@ -0,0 +1,13 @@
+export type TemplateFormat = 'liquid';
+
+/**
+ * Build a concrete props object whose values are Liquid placeholder strings.
+ * Uses the keys of `sampleProps` as the source of truth.
+ */
+export function build_placeholders>(
+ sample: T,
+): T {
+ const out: Record = {};
+ for (const key of Object.keys(sample)) out[key] = `{{ ${key} }}`;
+ return out as unknown as T;
+}
diff --git a/email-templates/emails/_lib/styles.ts b/email-templates/emails/_lib/styles.ts
new file mode 100644
index 00000000..b48150bc
--- /dev/null
+++ b/email-templates/emails/_lib/styles.ts
@@ -0,0 +1,132 @@
+import type { CSSProperties } from 'react';
+
+const fontStack =
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';
+
+const colors = {
+ pageBg: '#f4f5f7',
+ cardBg: '#ffffff',
+ border: '#e4e7eb',
+ text: '#1f2329',
+ textMuted: '#5a6473',
+ textFaint: '#8a93a3',
+ accent: '#111827',
+ accentText: '#ffffff',
+ noticeBg: '#fff8e1',
+ noticeBorder: '#f0c419',
+ noticeText: '#5a4500',
+ codeBg: '#f1f3f5',
+ link: '#1f6feb',
+} as const;
+
+export const styles = {
+ body: {
+ fontFamily: fontStack,
+ lineHeight: '1.6',
+ backgroundColor: colors.pageBg,
+ color: colors.text,
+ margin: '0',
+ padding: '0',
+ WebkitFontSmoothing: 'antialiased',
+ },
+ container: {
+ maxWidth: '560px',
+ margin: '32px auto',
+ backgroundColor: colors.cardBg,
+ border: `1px solid ${colors.border}`,
+ borderRadius: '8px',
+ overflow: 'hidden',
+ },
+ header: {
+ padding: '20px 32px',
+ backgroundColor: colors.accent,
+ color: colors.accentText,
+ },
+ brand: {
+ margin: '0',
+ fontSize: '18px',
+ fontWeight: '700',
+ letterSpacing: '0.5px',
+ color: colors.accentText,
+ },
+ content: {
+ padding: '28px 32px 8px',
+ },
+ heading: {
+ color: colors.text,
+ fontSize: '22px',
+ fontWeight: '600',
+ margin: '0 0 16px',
+ lineHeight: '1.3',
+ },
+ text: {
+ fontSize: '15px',
+ color: colors.text,
+ margin: '0 0 16px',
+ },
+ muted: {
+ fontSize: '13px',
+ color: colors.textMuted,
+ margin: '0 0 12px',
+ },
+ buttonSection: {
+ padding: '8px 0 20px',
+ },
+ button: {
+ display: 'inline-block',
+ padding: '12px 24px',
+ backgroundColor: colors.accent,
+ color: colors.accentText,
+ fontSize: '15px',
+ fontWeight: '600',
+ textDecoration: 'none',
+ borderRadius: '6px',
+ },
+ rawLinkLabel: {
+ fontSize: '13px',
+ color: colors.textMuted,
+ margin: '0 0 6px',
+ },
+ rawLink: {
+ fontFamily:
+ 'ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',
+ fontSize: '12px',
+ color: colors.link,
+ wordBreak: 'break-all',
+ margin: '0 0 20px',
+ display: 'block',
+ },
+ inlineCode: {
+ fontFamily:
+ 'ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',
+ backgroundColor: colors.codeBg,
+ padding: '2px 6px',
+ borderRadius: '4px',
+ fontSize: '13px',
+ },
+ notice: {
+ backgroundColor: colors.noticeBg,
+ border: `1px solid ${colors.noticeBorder}`,
+ borderRadius: '6px',
+ padding: '12px 16px',
+ margin: '0 0 20px',
+ fontSize: '14px',
+ color: colors.noticeText,
+ },
+ divider: {
+ border: 'none',
+ borderTop: `1px solid ${colors.border}`,
+ margin: '24px 0',
+ },
+ footer: {
+ padding: '20px 32px 24px',
+ backgroundColor: '#fafbfc',
+ borderTop: `1px solid ${colors.border}`,
+ },
+ footerText: {
+ fontSize: '12px',
+ color: colors.textFaint,
+ margin: '0 0 6px',
+ lineHeight: '1.5',
+ },
+} satisfies Record;
diff --git a/email-templates/package.json b/email-templates/package.json
new file mode 100644
index 00000000..1b7af171
--- /dev/null
+++ b/email-templates/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "openshock-email-templates",
+ "version": "0.1.0",
+ "private": true,
+ "license": "AGPL-3.0",
+ "type": "module",
+ "packageManager": "pnpm@11.3.0",
+ "engines": {
+ "node": ">=20"
+ },
+ "scripts": {
+ "dev": "email dev",
+ "build": "email build",
+ "export": "tsx scripts/export-templates.ts",
+ "format": "prettier --write \"emails/**/*.{ts,tsx}\" \"scripts/**/*.ts\"",
+ "lint": "prettier --check \"emails/**/*.{ts,tsx}\" \"scripts/**/*.ts\""
+ },
+ "dependencies": {
+ "@react-email/components": "1.0.12",
+ "@react-email/render": "2.0.8",
+ "react": "19.2.6",
+ "react-dom": "19.2.6",
+ "react-email": "6.3.2"
+ },
+ "devDependencies": {
+ "@react-email/ui": "6.3.2",
+ "@types/node": "^25.9.1",
+ "@types/react": "19.2.15",
+ "@types/react-dom": "19.2.3",
+ "prettier": "3.8.3",
+ "tsx": "4.21.0",
+ "typescript": "6.0.3"
+ }
+}
diff --git a/email-templates/pnpm-lock.yaml b/email-templates/pnpm-lock.yaml
new file mode 100644
index 00000000..542c7e28
--- /dev/null
+++ b/email-templates/pnpm-lock.yaml
@@ -0,0 +1,2356 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@react-email/components':
+ specifier: 1.0.12
+ version: 1.0.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@react-email/render':
+ specifier: 2.0.8
+ version: 2.0.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ react:
+ specifier: 19.2.6
+ version: 19.2.6
+ react-dom:
+ specifier: 19.2.6
+ version: 19.2.6(react@19.2.6)
+ react-email:
+ specifier: 6.3.2
+ version: 6.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ devDependencies:
+ '@react-email/ui':
+ specifier: 6.3.2
+ version: 6.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@types/node':
+ specifier: ^25.9.1
+ version: 25.9.1
+ '@types/react':
+ specifier: 19.2.15
+ version: 19.2.15
+ '@types/react-dom':
+ specifier: 19.2.3
+ version: 19.2.3(@types/react@19.2.15)
+ prettier:
+ specifier: 3.8.3
+ version: 3.8.3
+ tsx:
+ specifier: 4.21.0
+ version: 4.21.0
+ typescript:
+ specifier: 6.0.3
+ version: 6.0.3
+
+packages:
+
+ '@babel/code-frame@7.29.0':
+ resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.29.1':
+ resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.27.0':
+ resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/parser@7.29.3':
+ resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/template@7.28.6':
+ resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.27.0':
+ resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
+
+ '@esbuild/aix-ppc64@0.27.7':
+ resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/aix-ppc64@0.28.0':
+ resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.7':
+ resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm64@0.28.0':
+ resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.7':
+ resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.0':
+ resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.7':
+ resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.0':
+ resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.7':
+ resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-arm64@0.28.0':
+ resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.7':
+ resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.0':
+ resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-arm64@0.28.0':
+ resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.7':
+ resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.0':
+ resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.7':
+ resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm64@0.28.0':
+ resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.7':
+ resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.0':
+ resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.7':
+ resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.0':
+ resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.7':
+ resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.0':
+ resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.7':
+ resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.0':
+ resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.7':
+ resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.0':
+ resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.7':
+ resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.0':
+ resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.7':
+ resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.0':
+ resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.7':
+ resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.0':
+ resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-arm64@0.28.0':
+ resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.7':
+ resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.0':
+ resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-arm64@0.28.0':
+ resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.7':
+ resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.0':
+ resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/openharmony-arm64@0.28.0':
+ resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.7':
+ resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/sunos-x64@0.28.0':
+ resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.7':
+ resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-arm64@0.28.0':
+ resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.7':
+ resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.0':
+ resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.7':
+ resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.0':
+ resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@next/env@16.2.6':
+ resolution: {integrity: sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==}
+
+ '@next/swc-darwin-arm64@16.2.6':
+ resolution: {integrity: sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@16.2.6':
+ resolution: {integrity: sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@16.2.6':
+ resolution: {integrity: sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-arm64-musl@16.2.6':
+ resolution: {integrity: sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-linux-x64-gnu@16.2.6':
+ resolution: {integrity: sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@next/swc-linux-x64-musl@16.2.6':
+ resolution: {integrity: sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@next/swc-win32-arm64-msvc@16.2.6':
+ resolution: {integrity: sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@16.2.6':
+ resolution: {integrity: sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@react-email/body@0.3.0':
+ resolution: {integrity: sha512-uGo0BOOzjbMUo3lu+BIDWayvn5o6Xyfmnlla5VGf05n8gHMvO1ll7U4FtzWe3hxMLwt53pmc4iE0M+B5slG+Ug==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/button@0.2.1':
+ resolution: {integrity: sha512-qXyj7RZLE7POy9BMKSoqQ00tOXThjOZSUnI2Yu9i29IHngPlmrNayIWBoVKtElES7OWwypUcpiajwi1mUWx6/A==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/code-block@0.2.1':
+ resolution: {integrity: sha512-M3B7JpVH4ytgn83/ujRR1k1DQHvTeABiDM61OvAbjLRPhC/5KLHU5KkzIbbuGIrjWwxAbL1kSQzU8MhLEtSxyw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/code-inline@0.0.6':
+ resolution: {integrity: sha512-jfhebvv3dVsp3OdPgKXnk8+e2pBiDVZejDOBFzBa/IblrAJ9cQDkN6rBD5IyEg8hTOxwbw3iaI/yZFmDmIguIA==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/column@0.0.14':
+ resolution: {integrity: sha512-f+W+Bk2AjNO77zynE33rHuQhyqVICx4RYtGX9NKsGUg0wWjdGP0qAuIkhx9Rnmk4/hFMo1fUrtYNqca9fwJdHg==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/components@1.0.12':
+ resolution: {integrity: sha512-tH18JhPDWgE+3jnYkzyB6ZrZdfNnEsFe4PwmuXmlOw4NGIysP8wPY5aXZg++pTG9qUabXg1nzX/FGHGkObH8xQ==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/container@0.0.16':
+ resolution: {integrity: sha512-QWBB56RkkU0AJ9h+qy33gfT5iuZknPC7Un/IjZv9B0QmMIK+WWacc0cH6y2SV5Cv/b99hU94fjEMOOO4enpkbQ==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/font@0.0.10':
+ resolution: {integrity: sha512-0urVSgCmQIfx5r7Xc586miBnQUVnGp3OTYUm8m5pwtQRdTRO5XrTtEfNJ3JhYhSOruV0nD8fd+dXtKXobum6tA==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/head@0.0.13':
+ resolution: {integrity: sha512-AJg6le/08Gz4tm+6MtKXqtNNyKHzmooOCdmtqmWxD7FxoAdU1eVcizhtQ0gcnVaY6ethEyE/hnEzQxt1zu5Kog==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/heading@0.0.16':
+ resolution: {integrity: sha512-jmsKnQm1ykpBzw4hCYHwBkt5pW2jScXffPeEH5ZRF5tZeF5b1pvlFTO9han7C0pCkZYo1kEvWiRtx69yfCIwuw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/hr@0.0.12':
+ resolution: {integrity: sha512-TwmOmBDibavUQpXBxpmZYi2Iks/yeZOzFYh+di9EltMSnEabH8dMZXrl+pxNXzCgZ2XE8HY7VmUL65Lenfu5PA==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/html@0.0.12':
+ resolution: {integrity: sha512-KTShZesan+UsreU7PDUV90afrZwU5TLwYlALuCSU0OT+/U8lULNNbAUekg+tGwCnOfIKYtpDPKkAMRdYlqUznw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/img@0.0.12':
+ resolution: {integrity: sha512-sRCpEARNVTf3FQhZOC+JTvu5r6ubiYWkT0ucYXg8ctkyi4G8QG+jgYPiNUqVeTLA2STOfmPM/nrk1nb84y6CPQ==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/link@0.0.13':
+ resolution: {integrity: sha512-lkWc/NjOcefRZMkQoSDDbuKBEBDES9aXnFEOuPH845wD3TxPwh+QTf0fStuzjoRLUZWpHnio4z7qGGRYusn/sw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/markdown@0.0.18':
+ resolution: {integrity: sha512-gSuYK5fsMbGk87jDebqQ6fa2fKcWlkf2Dkva8kMONqLgGCq8/0d+ZQYMEJsdidIeBo3kmsnHZPrwdFB4HgjUXg==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/preview@0.0.14':
+ resolution: {integrity: sha512-aYK8q0IPkBXyMsbpMXgxazwHxYJxTrXrV95GFuu2HbEiIToMwSyUgb8HDFYwPqqfV03/jbwqlsXmFxsOd+VNaw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/render@2.0.6':
+ resolution: {integrity: sha512-xOzaYkH3jLZKqN5MqrTXYnmqBYUnZSVbkxdb5PGGmDcK6sKDVMliaDiSwfXajRC9JtSHTcGc2tmGLHWuCgVpog==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/render@2.0.8':
+ resolution: {integrity: sha512-5udvVr3U/WuGJZfLdLBOhkzrqRWd2Q5ZYmF7ppcy7FzWcwgshdqLMNqJOXcVzAXJXg/2bm7D+WGJzTtZOZMQnQ==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/row@0.0.13':
+ resolution: {integrity: sha512-bYnOac40vIKCId7IkwuLAAsa3fKfSfqCvv6epJKmPE0JBuu5qI4FHFCl9o9dVpIIS08s/ub+Y/txoMt0dYziGw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/section@0.0.17':
+ resolution: {integrity: sha512-qNl65ye3W0Rd5udhdORzTV9ezjb+GFqQQSae03NDzXtmJq6sqVXNWNiVolAjvJNypim+zGXmv6J9TcV5aNtE/w==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/tailwind@2.0.7':
+ resolution: {integrity: sha512-kGw80weVFXikcnCXbigTGXGWQ0MRCSYNCudcdkWxebkWYd0FG6/NPoN3V1p/u68/4+NxZwYPVi2fhnp0x23HdA==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ '@react-email/body': '>=0'
+ '@react-email/button': '>=0'
+ '@react-email/code-block': '>=0'
+ '@react-email/code-inline': '>=0'
+ '@react-email/container': '>=0'
+ '@react-email/heading': '>=0'
+ '@react-email/hr': '>=0'
+ '@react-email/img': '>=0'
+ '@react-email/link': '>=0'
+ '@react-email/preview': '>=0'
+ '@react-email/text': '>=0'
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@react-email/body':
+ optional: true
+ '@react-email/button':
+ optional: true
+ '@react-email/code-block':
+ optional: true
+ '@react-email/code-inline':
+ optional: true
+ '@react-email/container':
+ optional: true
+ '@react-email/heading':
+ optional: true
+ '@react-email/hr':
+ optional: true
+ '@react-email/img':
+ optional: true
+ '@react-email/link':
+ optional: true
+ '@react-email/preview':
+ optional: true
+
+ '@react-email/text@0.1.6':
+ resolution: {integrity: sha512-TYqkioRS45wTR5il3dYk/SbUjjEdhSwh9BtRNB99qNH1pXAwA45H7rAuxehiu8iJQJH0IyIr+6n62gBz9ezmsw==}
+ engines: {node: '>=20.0.0'}
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ '@react-email/ui@6.3.2':
+ resolution: {integrity: sha512-wjwbl6/I8S1Ictt0G3VflvJi5PyTI05jSRqC7LbHkivAoIpymEe/WJwxtGbKXoMlX4II7aYBpilsc2o5Lbo2pw==}
+
+ '@selderee/plugin-htmlparser2@0.11.0':
+ resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==}
+
+ '@socket.io/component-emitter@3.1.2':
+ resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==}
+
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
+ '@types/cors@2.8.19':
+ resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==}
+
+ '@types/node@25.9.1':
+ resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==}
+
+ '@types/react-dom@19.2.3':
+ resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
+ peerDependencies:
+ '@types/react': ^19.2.0
+
+ '@types/react@19.2.15':
+ resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==}
+
+ '@types/ws@8.18.1':
+ resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
+
+ accepts@1.3.8:
+ resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
+ engines: {node: '>= 0.6'}
+
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
+ atomically@2.1.1:
+ resolution: {integrity: sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ base64id@2.0.0:
+ resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
+ engines: {node: ^4.5.0 || >= 5.9}
+
+ baseline-browser-mapping@2.10.32:
+ resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ brace-expansion@5.0.6:
+ resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+ engines: {node: 18 || 20 || >=22}
+
+ caniuse-lite@1.0.30001793:
+ resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ citty@0.2.2:
+ resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==}
+
+ client-only@0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+
+ commander@13.1.0:
+ resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==}
+ engines: {node: '>=18'}
+
+ conf@15.1.0:
+ resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==}
+ engines: {node: '>=20'}
+
+ cookie@0.7.2:
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ engines: {node: '>= 0.6'}
+
+ cors@2.8.6:
+ resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
+ engines: {node: '>= 0.10'}
+
+ css-tree@3.2.1:
+ resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ debounce-fn@6.0.0:
+ resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==}
+ engines: {node: '>=18'}
+
+ debounce@2.2.0:
+ resolution: {integrity: sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw==}
+ engines: {node: '>=18'}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deepmerge@4.3.1:
+ resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
+ engines: {node: '>=0.10.0'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
+ dot-prop@10.1.0:
+ resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==}
+ engines: {node: '>=20'}
+
+ engine.io-parser@5.2.3:
+ resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==}
+ engines: {node: '>=10.0.0'}
+
+ engine.io@6.6.8:
+ resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==}
+ engines: {node: '>=10.2.0'}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ env-paths@3.0.0:
+ resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ esbuild@0.27.7:
+ resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ esbuild@0.28.0:
+ resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-uri@3.1.2:
+ resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ get-tsconfig@4.14.0:
+ resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
+
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ engines: {node: 18 || 20 || >=22}
+
+ globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ html-to-text@9.0.5:
+ resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
+ engines: {node: '>=14'}
+
+ htmlparser2@8.0.2:
+ resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
+
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ jsesc@3.1.0:
+ resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-schema-typed@8.0.2:
+ resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ kleur@3.0.3:
+ resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
+ engines: {node: '>=6'}
+
+ leac@0.6.0:
+ resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==}
+
+ log-symbols@7.0.1:
+ resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==}
+ engines: {node: '>=18'}
+
+ lru-cache@11.5.0:
+ resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==}
+ engines: {node: 20 || >=22}
+
+ marked@15.0.12:
+ resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
+ engines: {node: '>= 18'}
+ hasBin: true
+
+ mdn-data@2.27.1:
+ resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
+
+ mimic-function@5.0.1:
+ resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
+ engines: {node: '>=18'}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.12:
+ resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ negotiator@0.6.3:
+ resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
+ engines: {node: '>= 0.6'}
+
+ next@16.2.6:
+ resolution: {integrity: sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ nypm@0.6.6:
+ resolution: {integrity: sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ parseley@0.12.1:
+ resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
+
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ peberminta@0.9.0:
+ resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picospinner@3.0.0:
+ resolution: {integrity: sha512-lGA1TNsmy2bxvRsTI2cV01kfTwKzZjnZSDmF9llYNyMHMrU4sP87lQ5taiIKm88L3cbswjl008nwyGc3WpNvzg==}
+ engines: {node: '>=18.0.0'}
+
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prettier@3.8.3:
+ resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ prismjs@1.30.0:
+ resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
+ engines: {node: '>=6'}
+
+ prompts@2.4.2:
+ resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
+ engines: {node: '>= 6'}
+
+ react-dom@19.2.6:
+ resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==}
+ peerDependencies:
+ react: ^19.2.6
+
+ react-email@6.3.2:
+ resolution: {integrity: sha512-ZzmrwM+QLzfs/EZBnFZRMZwT3Kfvp46zIMCLsGn/rtRBh9ocRJDKHcnV0JWJyc0AVJTdPDHeFNBWap6N/3Dnhg==}
+ engines: {node: '>=20.0.0'}
+ hasBin: true
+ peerDependencies:
+ react: ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^18.0 || ^19.0 || ^19.0.0-rc
+
+ react@19.2.6:
+ resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==}
+ engines: {node: '>=0.10.0'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-pkg-maps@1.0.0:
+ resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ selderee@0.11.0:
+ resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
+
+ semver@7.8.1:
+ resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ sisteransi@1.0.5:
+ resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
+
+ socket.io-adapter@2.5.7:
+ resolution: {integrity: sha512-e0LyK91f3cUxTmv95/KzoLg47+zF+s/sbxRGDNsyG4dmIP8ZSX8ax6byOxfJXeNNtS/8AZlfD+uP7gBeR7DLlg==}
+
+ socket.io-parser@4.2.6:
+ resolution: {integrity: sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==}
+ engines: {node: '>=10.0.0'}
+
+ socket.io@4.8.3:
+ resolution: {integrity: sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==}
+ engines: {node: '>=10.2.0'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ stubborn-fs@2.0.0:
+ resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==}
+
+ stubborn-utils@1.0.2:
+ resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==}
+
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
+ tagged-tag@1.0.0:
+ resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
+ engines: {node: '>=20'}
+
+ tailwindcss@4.3.0:
+ resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==}
+
+ tinyexec@1.2.2:
+ resolution: {integrity: sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==}
+ engines: {node: '>=18'}
+
+ tsconfig-paths@4.2.0:
+ resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==}
+ engines: {node: '>=6'}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsx@4.21.0:
+ resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
+ engines: {node: '>=18.0.0'}
+ hasBin: true
+
+ type-fest@5.6.0:
+ resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==}
+ engines: {node: '>=20'}
+
+ typescript@6.0.3:
+ resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ uint8array-extras@1.5.0:
+ resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
+ engines: {node: '>=18'}
+
+ undici-types@7.24.6:
+ resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
+ when-exit@2.1.5:
+ resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==}
+
+ ws@8.20.1:
+ resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ yoctocolors@2.1.2:
+ resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==}
+ engines: {node: '>=18'}
+
+snapshots:
+
+ '@babel/code-frame@7.29.0':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.28.5
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/generator@7.29.1':
+ dependencies:
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+ jsesc: 3.1.0
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/parser@7.27.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/parser@7.29.3':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/template@7.28.6':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/parser': 7.29.3
+ '@babel/types': 7.29.0
+
+ '@babel/traverse@7.27.0':
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ '@babel/generator': 7.29.1
+ '@babel/parser': 7.27.0
+ '@babel/template': 7.28.6
+ '@babel/types': 7.29.0
+ debug: 4.4.3
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@emnapi/runtime@1.10.0':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@esbuild/aix-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/aix-ppc64@0.28.0':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/android-arm@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm@0.28.0':
+ optional: true
+
+ '@esbuild/android-x64@0.27.7':
+ optional: true
+
+ '@esbuild/android-x64@0.28.0':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.0':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.0':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.0':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-loong64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.7':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.28.0':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.28.0':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.7':
+ optional: true
+
+ '@esbuild/linux-s390x@0.28.0':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-x64@0.28.0':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.28.0':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.7':
+ optional: true
+
+ '@esbuild/sunos-x64@0.28.0':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-arm64@0.28.0':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/win32-ia32@0.28.0':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-x64@0.28.0':
+ optional: true
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.10.0
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@next/env@16.2.6': {}
+
+ '@next/swc-darwin-arm64@16.2.6':
+ optional: true
+
+ '@next/swc-darwin-x64@16.2.6':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@16.2.6':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@16.2.6':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@16.2.6':
+ optional: true
+
+ '@next/swc-linux-x64-musl@16.2.6':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@16.2.6':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@16.2.6':
+ optional: true
+
+ '@react-email/body@0.3.0(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/button@0.2.1(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/code-block@0.2.1(react@19.2.6)':
+ dependencies:
+ prismjs: 1.30.0
+ react: 19.2.6
+
+ '@react-email/code-inline@0.0.6(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/column@0.0.14(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/components@1.0.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
+ dependencies:
+ '@react-email/body': 0.3.0(react@19.2.6)
+ '@react-email/button': 0.2.1(react@19.2.6)
+ '@react-email/code-block': 0.2.1(react@19.2.6)
+ '@react-email/code-inline': 0.0.6(react@19.2.6)
+ '@react-email/column': 0.0.14(react@19.2.6)
+ '@react-email/container': 0.0.16(react@19.2.6)
+ '@react-email/font': 0.0.10(react@19.2.6)
+ '@react-email/head': 0.0.13(react@19.2.6)
+ '@react-email/heading': 0.0.16(react@19.2.6)
+ '@react-email/hr': 0.0.12(react@19.2.6)
+ '@react-email/html': 0.0.12(react@19.2.6)
+ '@react-email/img': 0.0.12(react@19.2.6)
+ '@react-email/link': 0.0.13(react@19.2.6)
+ '@react-email/markdown': 0.0.18(react@19.2.6)
+ '@react-email/preview': 0.0.14(react@19.2.6)
+ '@react-email/render': 2.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ '@react-email/row': 0.0.13(react@19.2.6)
+ '@react-email/section': 0.0.17(react@19.2.6)
+ '@react-email/tailwind': 2.0.7(@react-email/body@0.3.0(react@19.2.6))(@react-email/button@0.2.1(react@19.2.6))(@react-email/code-block@0.2.1(react@19.2.6))(@react-email/code-inline@0.0.6(react@19.2.6))(@react-email/container@0.0.16(react@19.2.6))(@react-email/heading@0.0.16(react@19.2.6))(@react-email/hr@0.0.12(react@19.2.6))(@react-email/img@0.0.12(react@19.2.6))(@react-email/link@0.0.13(react@19.2.6))(@react-email/preview@0.0.14(react@19.2.6))(@react-email/text@0.1.6(react@19.2.6))(react@19.2.6)
+ '@react-email/text': 0.1.6(react@19.2.6)
+ react: 19.2.6
+ transitivePeerDependencies:
+ - react-dom
+
+ '@react-email/container@0.0.16(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/font@0.0.10(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/head@0.0.13(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/heading@0.0.16(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/hr@0.0.12(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/html@0.0.12(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/img@0.0.12(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/link@0.0.13(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/markdown@0.0.18(react@19.2.6)':
+ dependencies:
+ marked: 15.0.12
+ react: 19.2.6
+
+ '@react-email/preview@0.0.14(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/render@2.0.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
+ dependencies:
+ html-to-text: 9.0.5
+ prettier: 3.8.3
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+
+ '@react-email/render@2.0.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
+ dependencies:
+ html-to-text: 9.0.5
+ prettier: 3.8.3
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+
+ '@react-email/row@0.0.13(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/section@0.0.17(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/tailwind@2.0.7(@react-email/body@0.3.0(react@19.2.6))(@react-email/button@0.2.1(react@19.2.6))(@react-email/code-block@0.2.1(react@19.2.6))(@react-email/code-inline@0.0.6(react@19.2.6))(@react-email/container@0.0.16(react@19.2.6))(@react-email/heading@0.0.16(react@19.2.6))(@react-email/hr@0.0.12(react@19.2.6))(@react-email/img@0.0.12(react@19.2.6))(@react-email/link@0.0.13(react@19.2.6))(@react-email/preview@0.0.14(react@19.2.6))(@react-email/text@0.1.6(react@19.2.6))(react@19.2.6)':
+ dependencies:
+ '@react-email/text': 0.1.6(react@19.2.6)
+ react: 19.2.6
+ tailwindcss: 4.3.0
+ optionalDependencies:
+ '@react-email/body': 0.3.0(react@19.2.6)
+ '@react-email/button': 0.2.1(react@19.2.6)
+ '@react-email/code-block': 0.2.1(react@19.2.6)
+ '@react-email/code-inline': 0.0.6(react@19.2.6)
+ '@react-email/container': 0.0.16(react@19.2.6)
+ '@react-email/heading': 0.0.16(react@19.2.6)
+ '@react-email/hr': 0.0.12(react@19.2.6)
+ '@react-email/img': 0.0.12(react@19.2.6)
+ '@react-email/link': 0.0.13(react@19.2.6)
+ '@react-email/preview': 0.0.14(react@19.2.6)
+
+ '@react-email/text@0.1.6(react@19.2.6)':
+ dependencies:
+ react: 19.2.6
+
+ '@react-email/ui@6.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
+ dependencies:
+ esbuild: 0.28.0
+ next: 16.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ transitivePeerDependencies:
+ - '@babel/core'
+ - '@opentelemetry/api'
+ - '@playwright/test'
+ - babel-plugin-macros
+ - babel-plugin-react-compiler
+ - react
+ - react-dom
+ - sass
+
+ '@selderee/plugin-htmlparser2@0.11.0':
+ dependencies:
+ domhandler: 5.0.3
+ selderee: 0.11.0
+
+ '@socket.io/component-emitter@3.1.2': {}
+
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
+ '@types/cors@2.8.19':
+ dependencies:
+ '@types/node': 25.9.1
+
+ '@types/node@25.9.1':
+ dependencies:
+ undici-types: 7.24.6
+
+ '@types/react-dom@19.2.3(@types/react@19.2.15)':
+ dependencies:
+ '@types/react': 19.2.15
+
+ '@types/react@19.2.15':
+ dependencies:
+ csstype: 3.2.3
+
+ '@types/ws@8.18.1':
+ dependencies:
+ '@types/node': 25.9.1
+
+ accepts@1.3.8:
+ dependencies:
+ mime-types: 2.1.35
+ negotiator: 0.6.3
+
+ ajv-formats@3.0.1(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.2
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ atomically@2.1.1:
+ dependencies:
+ stubborn-fs: 2.0.0
+ when-exit: 2.1.5
+
+ balanced-match@4.0.4: {}
+
+ base64id@2.0.0: {}
+
+ baseline-browser-mapping@2.10.32: {}
+
+ brace-expansion@5.0.6:
+ dependencies:
+ balanced-match: 4.0.4
+
+ caniuse-lite@1.0.30001793: {}
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ citty@0.2.2: {}
+
+ client-only@0.0.1: {}
+
+ commander@13.1.0: {}
+
+ conf@15.1.0:
+ dependencies:
+ ajv: 8.20.0
+ ajv-formats: 3.0.1(ajv@8.20.0)
+ atomically: 2.1.1
+ debounce-fn: 6.0.0
+ dot-prop: 10.1.0
+ env-paths: 3.0.0
+ json-schema-typed: 8.0.2
+ semver: 7.8.1
+ uint8array-extras: 1.5.0
+
+ cookie@0.7.2: {}
+
+ cors@2.8.6:
+ dependencies:
+ object-assign: 4.1.1
+ vary: 1.1.2
+
+ css-tree@3.2.1:
+ dependencies:
+ mdn-data: 2.27.1
+ source-map-js: 1.2.1
+
+ csstype@3.2.3: {}
+
+ debounce-fn@6.0.0:
+ dependencies:
+ mimic-function: 5.0.1
+
+ debounce@2.2.0: {}
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ deepmerge@4.3.1: {}
+
+ detect-libc@2.1.2:
+ optional: true
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dot-prop@10.1.0:
+ dependencies:
+ type-fest: 5.6.0
+
+ engine.io-parser@5.2.3: {}
+
+ engine.io@6.6.8:
+ dependencies:
+ '@types/cors': 2.8.19
+ '@types/node': 25.9.1
+ '@types/ws': 8.18.1
+ accepts: 1.3.8
+ base64id: 2.0.0
+ cookie: 0.7.2
+ cors: 2.8.6
+ debug: 4.4.3
+ engine.io-parser: 5.2.3
+ ws: 8.20.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ entities@4.5.0: {}
+
+ env-paths@3.0.0: {}
+
+ esbuild@0.27.7:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.7
+ '@esbuild/android-arm': 0.27.7
+ '@esbuild/android-arm64': 0.27.7
+ '@esbuild/android-x64': 0.27.7
+ '@esbuild/darwin-arm64': 0.27.7
+ '@esbuild/darwin-x64': 0.27.7
+ '@esbuild/freebsd-arm64': 0.27.7
+ '@esbuild/freebsd-x64': 0.27.7
+ '@esbuild/linux-arm': 0.27.7
+ '@esbuild/linux-arm64': 0.27.7
+ '@esbuild/linux-ia32': 0.27.7
+ '@esbuild/linux-loong64': 0.27.7
+ '@esbuild/linux-mips64el': 0.27.7
+ '@esbuild/linux-ppc64': 0.27.7
+ '@esbuild/linux-riscv64': 0.27.7
+ '@esbuild/linux-s390x': 0.27.7
+ '@esbuild/linux-x64': 0.27.7
+ '@esbuild/netbsd-arm64': 0.27.7
+ '@esbuild/netbsd-x64': 0.27.7
+ '@esbuild/openbsd-arm64': 0.27.7
+ '@esbuild/openbsd-x64': 0.27.7
+ '@esbuild/openharmony-arm64': 0.27.7
+ '@esbuild/sunos-x64': 0.27.7
+ '@esbuild/win32-arm64': 0.27.7
+ '@esbuild/win32-ia32': 0.27.7
+ '@esbuild/win32-x64': 0.27.7
+
+ esbuild@0.28.0:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.28.0
+ '@esbuild/android-arm': 0.28.0
+ '@esbuild/android-arm64': 0.28.0
+ '@esbuild/android-x64': 0.28.0
+ '@esbuild/darwin-arm64': 0.28.0
+ '@esbuild/darwin-x64': 0.28.0
+ '@esbuild/freebsd-arm64': 0.28.0
+ '@esbuild/freebsd-x64': 0.28.0
+ '@esbuild/linux-arm': 0.28.0
+ '@esbuild/linux-arm64': 0.28.0
+ '@esbuild/linux-ia32': 0.28.0
+ '@esbuild/linux-loong64': 0.28.0
+ '@esbuild/linux-mips64el': 0.28.0
+ '@esbuild/linux-ppc64': 0.28.0
+ '@esbuild/linux-riscv64': 0.28.0
+ '@esbuild/linux-s390x': 0.28.0
+ '@esbuild/linux-x64': 0.28.0
+ '@esbuild/netbsd-arm64': 0.28.0
+ '@esbuild/netbsd-x64': 0.28.0
+ '@esbuild/openbsd-arm64': 0.28.0
+ '@esbuild/openbsd-x64': 0.28.0
+ '@esbuild/openharmony-arm64': 0.28.0
+ '@esbuild/sunos-x64': 0.28.0
+ '@esbuild/win32-arm64': 0.28.0
+ '@esbuild/win32-ia32': 0.28.0
+ '@esbuild/win32-x64': 0.28.0
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-uri@3.1.2: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ get-tsconfig@4.14.0:
+ dependencies:
+ resolve-pkg-maps: 1.0.0
+
+ glob@13.0.6:
+ dependencies:
+ minimatch: 10.2.5
+ minipass: 7.1.3
+ path-scurry: 2.0.2
+
+ globals@11.12.0: {}
+
+ html-to-text@9.0.5:
+ dependencies:
+ '@selderee/plugin-htmlparser2': 0.11.0
+ deepmerge: 4.3.1
+ dom-serializer: 2.0.0
+ htmlparser2: 8.0.2
+ selderee: 0.11.0
+
+ htmlparser2@8.0.2:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ entities: 4.5.0
+
+ is-unicode-supported@2.1.0: {}
+
+ jiti@2.4.2: {}
+
+ js-tokens@4.0.0: {}
+
+ jsesc@3.1.0: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ json-schema-typed@8.0.2: {}
+
+ json5@2.2.3: {}
+
+ kleur@3.0.3: {}
+
+ leac@0.6.0: {}
+
+ log-symbols@7.0.1:
+ dependencies:
+ is-unicode-supported: 2.1.0
+ yoctocolors: 2.1.2
+
+ lru-cache@11.5.0: {}
+
+ marked@15.0.12: {}
+
+ mdn-data@2.27.1: {}
+
+ mime-db@1.52.0: {}
+
+ mime-db@1.54.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mime-types@3.0.2:
+ dependencies:
+ mime-db: 1.54.0
+
+ mimic-function@5.0.1: {}
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.6
+
+ minimist@1.2.8: {}
+
+ minipass@7.1.3: {}
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.12: {}
+
+ negotiator@0.6.3: {}
+
+ next@16.2.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
+ dependencies:
+ '@next/env': 16.2.6
+ '@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.10.32
+ caniuse-lite: 1.0.30001793
+ postcss: 8.4.31
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+ styled-jsx: 5.1.6(react@19.2.6)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.2.6
+ '@next/swc-darwin-x64': 16.2.6
+ '@next/swc-linux-arm64-gnu': 16.2.6
+ '@next/swc-linux-arm64-musl': 16.2.6
+ '@next/swc-linux-x64-gnu': 16.2.6
+ '@next/swc-linux-x64-musl': 16.2.6
+ '@next/swc-win32-arm64-msvc': 16.2.6
+ '@next/swc-win32-x64-msvc': 16.2.6
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ normalize-path@3.0.0: {}
+
+ nypm@0.6.6:
+ dependencies:
+ citty: 0.2.2
+ pathe: 2.0.3
+ tinyexec: 1.2.2
+
+ object-assign@4.1.1: {}
+
+ parseley@0.12.1:
+ dependencies:
+ leac: 0.6.0
+ peberminta: 0.9.0
+
+ path-scurry@2.0.2:
+ dependencies:
+ lru-cache: 11.5.0
+ minipass: 7.1.3
+
+ pathe@2.0.3: {}
+
+ peberminta@0.9.0: {}
+
+ picocolors@1.1.1: {}
+
+ picospinner@3.0.0: {}
+
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prettier@3.8.3: {}
+
+ prismjs@1.30.0: {}
+
+ prompts@2.4.2:
+ dependencies:
+ kleur: 3.0.3
+ sisteransi: 1.0.5
+
+ react-dom@19.2.6(react@19.2.6):
+ dependencies:
+ react: 19.2.6
+ scheduler: 0.27.0
+
+ react-email@6.3.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
+ dependencies:
+ '@babel/parser': 7.27.0
+ '@babel/traverse': 7.27.0
+ '@react-email/render': 2.0.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
+ chokidar: 4.0.3
+ commander: 13.1.0
+ conf: 15.1.0
+ css-tree: 3.2.1
+ debounce: 2.2.0
+ esbuild: 0.28.0
+ glob: 13.0.6
+ jiti: 2.4.2
+ log-symbols: 7.0.1
+ marked: 15.0.12
+ mime-types: 3.0.2
+ normalize-path: 3.0.0
+ nypm: 0.6.6
+ picospinner: 3.0.0
+ prismjs: 1.30.0
+ prompts: 2.4.2
+ react: 19.2.6
+ react-dom: 19.2.6(react@19.2.6)
+ socket.io: 4.8.3
+ tailwindcss: 4.3.0
+ tsconfig-paths: 4.2.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ react@19.2.6: {}
+
+ readdirp@4.1.2: {}
+
+ require-from-string@2.0.2: {}
+
+ resolve-pkg-maps@1.0.0: {}
+
+ scheduler@0.27.0: {}
+
+ selderee@0.11.0:
+ dependencies:
+ parseley: 0.12.1
+
+ semver@7.8.1: {}
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.8.1
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ sisteransi@1.0.5: {}
+
+ socket.io-adapter@2.5.7:
+ dependencies:
+ debug: 4.4.3
+ ws: 8.20.1
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ socket.io-parser@4.2.6:
+ dependencies:
+ '@socket.io/component-emitter': 3.1.2
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ socket.io@4.8.3:
+ dependencies:
+ accepts: 1.3.8
+ base64id: 2.0.0
+ cors: 2.8.6
+ debug: 4.4.3
+ engine.io: 6.6.8
+ socket.io-adapter: 2.5.7
+ socket.io-parser: 4.2.6
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ source-map-js@1.2.1: {}
+
+ strip-bom@3.0.0: {}
+
+ stubborn-fs@2.0.0:
+ dependencies:
+ stubborn-utils: 1.0.2
+
+ stubborn-utils@1.0.2: {}
+
+ styled-jsx@5.1.6(react@19.2.6):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.6
+
+ tagged-tag@1.0.0: {}
+
+ tailwindcss@4.3.0: {}
+
+ tinyexec@1.2.2: {}
+
+ tsconfig-paths@4.2.0:
+ dependencies:
+ json5: 2.2.3
+ minimist: 1.2.8
+ strip-bom: 3.0.0
+
+ tslib@2.8.1: {}
+
+ tsx@4.21.0:
+ dependencies:
+ esbuild: 0.27.7
+ get-tsconfig: 4.14.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ type-fest@5.6.0:
+ dependencies:
+ tagged-tag: 1.0.0
+
+ typescript@6.0.3: {}
+
+ uint8array-extras@1.5.0: {}
+
+ undici-types@7.24.6: {}
+
+ vary@1.1.2: {}
+
+ when-exit@2.1.5: {}
+
+ ws@8.20.1: {}
+
+ yoctocolors@2.1.2: {}
diff --git a/email-templates/pnpm-workspace.yaml b/email-templates/pnpm-workspace.yaml
new file mode 100644
index 00000000..dbb26c82
--- /dev/null
+++ b/email-templates/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+allowBuilds:
+ esbuild: true
+ sharp: true
diff --git a/email-templates/scripts/export-templates.ts b/email-templates/scripts/export-templates.ts
new file mode 100644
index 00000000..3e5c837b
--- /dev/null
+++ b/email-templates/scripts/export-templates.ts
@@ -0,0 +1,75 @@
+import { render } from '@react-email/render';
+import { readdir, writeFile } from 'node:fs/promises';
+import { dirname, join, resolve } from 'node:path';
+import { fileURLToPath, pathToFileURL } from 'node:url';
+import { createElement } from 'react';
+import { build_placeholders } from '../emails/_lib/placeholders.ts';
+
+const __dirname = dirname(fileURLToPath(import.meta.url));
+const root = resolve(__dirname, '..');
+const emails_dir = join(root, 'emails');
+const out_dir = resolve(root, '..', 'API', 'SmtpTemplates');
+
+import type { ComponentType } from 'react';
+
+type TemplateModule = {
+ default?: unknown;
+ sampleProps?: Record;
+ subject?: string;
+ [key: string]: unknown;
+};
+
+function pick_component(
+ mod: TemplateModule,
+ file: string,
+): ComponentType {
+ for (const [name, value] of Object.entries(mod)) {
+ if (name === 'default' || name === 'sampleProps' || name === 'subject')
+ continue;
+ if (typeof value === 'function' && /^[A-Z]/.test(name)) {
+ return value as ComponentType;
+ }
+ }
+ throw new Error(`No named PascalCase component export found in ${file}`);
+}
+
+async function list_templates(): Promise {
+ const entries = await readdir(emails_dir, { withFileTypes: true });
+ return entries
+ .filter(
+ (e: { isFile(): boolean; name: string }) =>
+ e.isFile() && e.name.endsWith('.tsx') && !e.name.startsWith('_'),
+ )
+ .map((e: { name: string }) => e.name);
+}
+
+async function export_liquid() {
+ const files = await list_templates();
+ let rendered = 0;
+ for (const file of files) {
+ const mod = (await import(
+ pathToFileURL(join(emails_dir, file)).href
+ )) as TemplateModule;
+ if (!mod.sampleProps) {
+ console.log(` skip ${file} (no sampleProps export)`);
+ continue;
+ }
+ if (!mod.subject) {
+ console.log(` skip ${file} (no subject export)`);
+ continue;
+ }
+ const Component = pick_component(mod, file);
+ const props = build_placeholders(mod.sampleProps);
+ const body = await render(createElement(Component, props), {
+ pretty: true,
+ });
+ const out_name = file.replace(/\.tsx$/, '.liquid');
+ await writeFile(join(out_dir, out_name), `${mod.subject}\n${body}`, 'utf8');
+ console.log(` ${out_name}`);
+ rendered++;
+ }
+ console.log(` ${rendered} template(s) rendered\n`);
+}
+
+console.log('Exporting liquid...');
+await export_liquid();
diff --git a/email-templates/tsconfig.json b/email-templates/tsconfig.json
new file mode 100644
index 00000000..a5a98367
--- /dev/null
+++ b/email-templates/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "compilerOptions": {
+ "composite": false,
+ "target": "ES2022",
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "jsx": "react-jsx",
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "strictNullChecks": true,
+ "esModuleInterop": true,
+ "allowImportingTsExtensions": true,
+ "types": ["node"]
+ },
+ "include": ["**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules", ".react-email", "out"]
+}