diff --git a/apps/stage1-clk-transfer/package.json b/apps/stage1-clk-transfer/package.json
index 3ed36cd..3467469 100644
--- a/apps/stage1-clk-transfer/package.json
+++ b/apps/stage1-clk-transfer/package.json
@@ -11,30 +11,32 @@
},
"dependencies": {
"@clerk/nextjs": "^6.10.3",
+ "@fontsource/jetbrains-mono": "^5.2.5",
"@hookform/resolvers": "^3.10.0",
- "@radix-ui/react-aspect-ratio": "^1.1.1",
- "@radix-ui/react-avatar": "^1.1.1",
- "@radix-ui/react-collapsible": "^1.1.1",
- "@radix-ui/react-hover-card": "^1.1.1",
- "@radix-ui/react-icons": "^1.3.0",
- "@radix-ui/react-menubar": "^1.1.1",
- "@radix-ui/react-primitive": "^2.0.0",
- "@radix-ui/react-select": "^2.1.2",
- "@radix-ui/react-switch": "^1.1.0",
- "@radix-ui/react-checkbox": "^1.1.1",
- "@radix-ui/react-context-menu": "^2.1.5",
- "@radix-ui/react-dialog": "^1.1.2",
- "@radix-ui/react-dropdown-menu": "^2.1.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-navigation-menu": "^1.1.4",
- "@radix-ui/react-popover": "^1.0.7",
- "@radix-ui/react-radio-group": "^1.2.0",
- "@radix-ui/react-scroll-area": "^1.1.0",
- "@radix-ui/react-separator": "^1.1.0",
- "@radix-ui/react-slot": "^1.1.0",
- "@radix-ui/react-tabs": "^1.1.0",
- "@radix-ui/react-tooltip": "^1.1.3",
+ "@radix-ui/react-aspect-ratio": "^1.1.1",
+ "@radix-ui/react-avatar": "^1.1.1",
+ "@radix-ui/react-checkbox": "^1.1.1",
+ "@radix-ui/react-collapsible": "^1.1.1",
+ "@radix-ui/react-context-menu": "^2.1.5",
+ "@radix-ui/react-dialog": "^1.1.2",
+ "@radix-ui/react-dropdown-menu": "^2.1.2",
+ "@radix-ui/react-hover-card": "^1.1.1",
+ "@radix-ui/react-icons": "^1.3.0",
+ "@radix-ui/react-label": "^2.1.0",
+ "@radix-ui/react-menubar": "^1.1.1",
+ "@radix-ui/react-navigation-menu": "^1.1.4",
+ "@radix-ui/react-popover": "^1.0.7",
+ "@radix-ui/react-primitive": "^2.0.0",
+ "@radix-ui/react-radio-group": "^1.2.0",
+ "@radix-ui/react-scroll-area": "^1.1.0",
+ "@radix-ui/react-select": "^2.1.2",
+ "@radix-ui/react-separator": "^1.1.0",
+ "@radix-ui/react-slot": "^1.1.0",
+ "@radix-ui/react-switch": "^1.1.0",
+ "@radix-ui/react-tabs": "^1.1.0",
+ "@radix-ui/react-tooltip": "^1.1.3",
"@types/jsonwebtoken": "^9.0.8",
+ "@uiw/codemirror-theme-vscode": "^4.23.12",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "1.0.0",
diff --git a/apps/www/package.json b/apps/www/package.json
index d1ac4e7..e1c5cfe 100644
--- a/apps/www/package.json
+++ b/apps/www/package.json
@@ -56,6 +56,7 @@
"@unocss/postcss": "^0.61.5",
"@unocss/transformer-directives": "^0.61.5",
"@unocss/webpack": "^0.61.5",
+ "@uploadthing/react": "^7.3.1",
"@vercel/functions": "^2.0.0",
"@vercel/og": "^0.6.5",
"ag-grid-react": "^33.0.3",
@@ -108,6 +109,7 @@
"tailwindcss-patch": "^4.0.0",
"turbo": "^2.4.0",
"unplugin-tailwindcss-mangle": "^3.0.1",
+ "uploadthing": "^7.7.2",
"vaul": "^1.1.2",
"zod": "^3.24.2"
},
diff --git a/apps/www/public/sitemap-0.xml b/apps/www/public/sitemap-0.xml
index 0dc28c3..740e07d 100644
--- a/apps/www/public/sitemap-0.xml
+++ b/apps/www/public/sitemap-0.xml
@@ -1,12 +1,12 @@
-https://mhsf.app/waitlist2025-05-10T18:03:30.182Zdaily0.7
-https://mhsf.app/home2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/waitlist/oauth-need-discord2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/servers/embedded/sl-modification-frame/files2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/support2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/servers/embedded/sl-modification-frame2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/settings2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/waitlist/ref2025-05-10T18:03:30.186Zdaily0.7
-https://mhsf.app/servers2025-05-10T18:03:30.186Zdaily0.7
+https://mhsf.app/support2025-05-11T22:17:55.268Zdaily0.7
+https://mhsf.app/waitlist/oauth-need-discord2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/servers2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/waitlist/ref2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/settings2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/waitlist2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/servers/embedded/sl-modification-frame2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/servers/embedded/sl-modification-frame/files2025-05-11T22:17:55.272Zdaily0.7
+https://mhsf.app/home2025-05-11T22:17:55.272Zdaily0.7
\ No newline at end of file
diff --git a/apps/www/src/app/globals.css b/apps/www/src/app/globals.css
index 597ad3b..3668f2f 100644
--- a/apps/www/src/app/globals.css
+++ b/apps/www/src/app/globals.css
@@ -28,8 +28,9 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-@import "tailwindcss";
@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,100..900;1,100..900&display=swap');
+@import "tailwindcss";
+@import "../components/feat/server-page/server-editor/milkdown-additional-style.css";
@plugin 'tailwindcss-animate';
@config '../../tailwind-hero.config.ts';
@@ -38,19 +39,25 @@
@custom-variant dark (&:is(.dark *));
.milkdown {
+ @apply rounded-lg h-[400px] overflow-y-auto;
+
--crepe-font-title: "Inter Tight", "Roboto" !important;
.milkdown-slash-menu {
position: fixed !important;
+ }
+
+ .milkdown-code-block {
+ @apply rounded-lg
+ }
+}
- }
- .dark .milkdown-icon {
- fill: white !important;
- }
+.uploadthing-dropzone button {
+ @apply cursor-pointer
+}
- .dark {
- @import "@milkdown/crepe/theme/nord-dark.css";
- }
+.uploadthing-dropzone {
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.sr-only{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.relative{position:relative}.z-10{z-index:10}.z-50{z-index:50}.m-0{margin:0}.mx-auto{margin-left:auto;margin-right:auto}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.block{display:block}.flex{display:flex}.hidden{display:none}.size-4{height:1rem;width:1rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-5,.h-\[1\.25rem\]{height:1.25rem}.w-12{width:3rem}.w-36{width:9rem}.w-5{width:1.25rem}.w-64{width:16rem}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1{gap:.25rem}.gap-4{gap:1rem}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-gray-900\/25{border-color:rgba(17,24,39,.25)}.bg-blue-600\/10{background-color:rgba(37,99,235,.1)}.bg-transparent{background-color:transparent}.fill-none{fill:none}.stroke-current{stroke:currentColor}.stroke-2{stroke-width:2}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-10{padding-bottom:2.5rem;padding-top:2.5rem}.text-center{text-align:center}.align-middle{vertical-align:middle}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.blur{--tw-blur:blur(8px)}.blur,.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:left-0:after{content:var(--tw-content);left:0}.after\:h-full:after{content:var(--tw-content);height:100%}.after\:w-\[var\(--progress-width\)\]:after{content:var(--tw-content);width:var(--progress-width)}.after\:bg-blue-600:after{content:var(--tw-content);--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.after\:transition-\[width\]:after{content:var(--tw-content);transition-duration:.15s;transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1)}.after\:duration-500:after{content:var(--tw-content);transition-duration:.5s}.after\:content-\[\'\'\]:after{--tw-content:"";content:var(--tw-content)}.focus-within\:outline-none:focus-within{outline:2px solid transparent;outline-offset:2px}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-within\:ring-blue-600:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(37 99 235/var(--tw-ring-opacity,1))}.focus-within\:ring-offset-2:focus-within{--tw-ring-offset-width:2px}.hover\:bg-slate-200:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.hover\:text-blue-500:hover{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.disabled\:pointer-events-none:disabled{pointer-events:none}.group:hover .group-hover\:block{display:block}.group:hover .group-hover\:hidden{display:none}.data-\[state\=disabled\]\:cursor-not-allowed[data-state=disabled],.data-\[state\=readying\]\:cursor-not-allowed[data-state=readying]{cursor:not-allowed}.data-\[state\=disabled\]\:bg-blue-400[data-state=disabled]{--tw-bg-opacity:1;background-color:rgb(96 165 250/var(--tw-bg-opacity,1))}.data-\[state\=ready\]\:bg-blue-600[data-state=ready]{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.data-\[state\=readying\]\:bg-blue-400[data-state=readying],.data-\[state\=uploading\]\:bg-blue-400[data-state=uploading]{--tw-bg-opacity:1;background-color:rgb(96 165 250/var(--tw-bg-opacity,1))}.data-\[state\=uploading\]\:after\:bg-blue-600[data-state=uploading]:after{content:var(--tw-content);--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}
}
:root {
@@ -90,7 +97,41 @@
--sidebar-ring: 217.2 91.2% 59.8%;
--sidebar: hsl(0 0% 98%);
+ --crepe-color-background: #fdfcff;
+ --crepe-color-on-background: #1b1c1d;
+ --crepe-color-surface: #f8f9ff;
+ --crepe-color-surface-low: #f2f3fa;
+ --crepe-color-on-surface: #191c20;
+ --crepe-color-on-surface-variant: #43474e;
+ --crepe-color-outline: #73777f;
+ --crepe-color-primary: #37618e;
+ --crepe-color-secondary: #d7e3f8;
+ --crepe-color-on-secondary: #101c2b;
+ --crepe-color-inverse: #2e3135;
+ --crepe-color-on-inverse: #eff0f7;
+ --crepe-color-inline-code: #ba1a1a;
+ --crepe-color-error: #ba1a1a;
+ --crepe-color-hover: #eceef4;
+ --crepe-color-selected: #e1e2e8;
+ --crepe-color-inline-area: #d8dae0;
+
+ --crepe-font-title: Rubik, Cambria, 'Times New Roman', Times, serif;
+ --crepe-font-default: Inter, Arial, Helvetica, sans-serif;
+ --crepe-font-code:
+ 'JetBrains Mono', Menlo, Monaco, 'Courier New', Courier, monospace;
+
+ --crepe-shadow-1:
+ 0px 1px 3px 1px rgba(0, 0, 0, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.3);
+ --crepe-shadow-2:
+ 0px 2px 6px 2px rgba(0, 0, 0, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.3);
+.menu-groups .menu-group:nth-child(3n) li:nth-child(4n) {
+ @apply hidden;
+}
+.milkdown-toolbar button:nth-child(6n) {
+ @apply hidden;
+}
+
}
.dark {
@@ -138,11 +179,43 @@
--sidebar: hsl(240 5.9% 10%);
+ --crepe-color-background: #1b1c1d !important;
+ --crepe-color-on-background: #f8f9ff !important;
+ --crepe-color-surface: #111418 !important;
+ --crepe-color-surface-low: #191c20 !important;
+ --crepe-color-on-surface: #e1e2e8 !important;
+ --crepe-color-on-surface-variant: #c3c6cf !important;
+ --crepe-color-outline: #8d9199 !important;
+ --crepe-color-primary: #a1c9fd !important;
+ --crepe-color-secondary: #3c4858 !important;
+ --crepe-color-on-secondary: #d7e3f8 !important;
+ --crepe-color-inverse: #e1e2e8 !important;
+ --crepe-color-on-inverse: #2e3135 !important;
+ --crepe-color-inline-code: #ffb4ab !important;
+ --crepe-color-error: #ffb4ab !important;
+ --crepe-color-hover: #1d2024 !important;
+ --crepe-color-selected: #32353a !important;
+ --crepe-color-inline-area: #111418 !important;
+
+ --crepe-font-title: Rubik, Cambria, 'Times New Roman', Times, serif;
+ --crepe-font-default: Inter, Arial, Helvetica, sans-serif;
+ --crepe-font-code:
+ 'JetBrains Mono', Menlo, Monaco, 'Courier New', Courier, monospace;
+
+ --crepe-shadow-1:
+ 0px 1px 2px 0px rgba(255, 255, 255, 0.3),
+ 0px 1px 3px 1px rgba(255, 255, 255, 0.15) !important;
+ --crepe-shadow-2:
+ 0px 1px 2px 0px rgba(255, 255, 255, 0.3),
+ 0px 2px 6px 2px rgba(255, 255, 255, 0.15) !important;
*,
::before,
::after {
@apply border-zinc-800;
}
+ .milkdown-icon {
+ fill: white !important;
+ }
}
@theme {
diff --git a/apps/www/src/components/feat/server-page/server-editor/milkdown-additional-style.css b/apps/www/src/components/feat/server-page/server-editor/milkdown-additional-style.css
new file mode 100644
index 0000000..3c5fe25
--- /dev/null
+++ b/apps/www/src/components/feat/server-page/server-editor/milkdown-additional-style.css
@@ -0,0 +1,2812 @@
+/*!*****************************************************************************************************************************************************************************************************************************************************************************************************************!*\
+ !*** css ../../node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../node_modules/@milkdown/crepe/lib/theme/common/style.css ***!
+ \*****************************************************************************************************************************************************************************************************************************************************************************************************************/
+/*! tailwindcss v4.1.4 | MIT License | https://tailwindcss.com */
+.ProseMirror {
+ position: relative;
+}
+.ProseMirror {
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ white-space: break-spaces;
+ -webkit-font-variant-ligatures: none;
+ font-variant-ligatures: none;
+ font-feature-settings: "liga" 0;
+}
+.ProseMirror pre {
+ white-space: pre-wrap;
+}
+.ProseMirror li {
+ position: relative;
+}
+.ProseMirror-hideselection *::selection {
+ background: transparent;
+}
+.ProseMirror-hideselection *::-moz-selection {
+ background: transparent;
+}
+.ProseMirror-hideselection {
+ caret-color: transparent;
+}
+.ProseMirror [draggable][contenteditable="false"] {
+ user-select: text;
+}
+.ProseMirror-selectednode {
+ outline: 2px solid #8cf;
+}
+li.ProseMirror-selectednode {
+ outline: none;
+}
+li.ProseMirror-selectednode:after {
+ content: "";
+ position: absolute;
+ left: -32px;
+ right: -2px;
+ top: -2px;
+ bottom: -2px;
+ border: 2px solid #8cf;
+ pointer-events: none;
+}
+img.ProseMirror-separator {
+ display: inline !important;
+ border: none !important;
+ margin: 0 !important;
+}
+.milkdown .milkdown-block-handle[data-show="false"] {
+ opacity: 0;
+ pointer-events: none;
+}
+.milkdown .milkdown-block-handle {
+ transition: all 0.2s;
+ position: absolute;
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 2px;
+}
+.milkdown .milkdown-block-handle .operation-item {
+ border-radius: 4px;
+ width: 32px;
+ height: 32px;
+ padding: 4px;
+}
+.milkdown .milkdown-block-handle .operation-item svg {
+ width: 24px;
+ height: 24px;
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-block-handle .operation-item:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-block-handle .operation-item.active {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-slash-menu[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-slash-menu {
+ position: absolute;
+ display: block;
+ font-family: var(--crepe-font-default);
+ color: var(--crepe-color-on-surface);
+ background: var(--crepe-color-surface);
+ border-radius: 12px;
+ box-shadow: var(--crepe-shadow-1);
+}
+.milkdown .milkdown-slash-menu ul {
+ list-style-type: none;
+}
+.milkdown .milkdown-slash-menu ul li {
+ cursor: pointer;
+ border-radius: 8px;
+}
+.milkdown .milkdown-slash-menu .tab-group {
+ border-bottom: 1px solid var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ border-bottom: 1px solid
+ color-mix(in srgb, var(--crepe-color-outline), transparent 80%);
+ }
+ padding: 12px 12px 0;
+}
+.milkdown .milkdown-slash-menu .tab-group ul {
+ padding: 8px 10px;
+ display: flex;
+ gap: 10px;
+ flex-wrap: nowrap;
+}
+.milkdown .milkdown-slash-menu .tab-group ul li {
+ padding: 6px 10px;
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+}
+.milkdown .milkdown-slash-menu .tab-group ul li:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-slash-menu .tab-group ul li.selected {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-slash-menu .menu-groups {
+ padding: 0 12px 12px;
+ max-height: 420px;
+ overflow: auto;
+ overscroll-behavior: contain;
+ scroll-behavior: smooth;
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group h6 {
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+ padding: 14px 10px;
+ text-transform: uppercase;
+ color: var(--crepe-color-on-surface);
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in srgb, var(--crepe-color-on-surface), transparent 40%);
+ }
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group li {
+ min-width: 220px;
+ display: flex;
+ justify-content: flex-start;
+ align-items: center;
+ gap: 16px;
+ padding: 14px 10px;
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group li.hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group li.active {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group li > svg {
+ width: 24px;
+ height: 24px;
+ color: var(--crepe-color-outline);
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group li > span {
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+}
+.milkdown .milkdown-slash-menu .menu-groups .menu-group + .menu-group::before {
+ content: "";
+ display: block;
+ height: 1px;
+ background: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(in srgb, var(--crepe-color-outline), transparent 80%);
+ }
+ margin: 0 10px;
+}
+.milkdown .milkdown-code-block {
+ display: block;
+ position: relative;
+ padding: 8px 20px 20px;
+ background: var(--crepe-color-surface);
+ margin: 4px 0;
+}
+.milkdown .milkdown-code-block .language-picker {
+ padding-top: 10px;
+ width: -moz-max-content;
+ width: max-content;
+ position: absolute;
+ z-index: 1;
+}
+.milkdown .milkdown-code-block .hidden {
+ display: none !important;
+}
+.milkdown .milkdown-code-block.selected {
+ outline: 1px solid var(--crepe-color-primary);
+}
+.milkdown .milkdown-code-block .cm-editor {
+ outline: none !important;
+ background: var(--crepe-color-surface);
+}
+.milkdown .milkdown-code-block .cm-gutters {
+ border-right: none;
+ background: var(--crepe-color-surface);
+}
+.milkdown .milkdown-code-block .tools {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+.milkdown .milkdown-code-block .tools input {
+ caret-color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-code-block .tools .preview-toggle-button {
+ background: var(--crepe-color-secondary);
+ color: var(--crepe-color-on-surface-variant);
+ padding: 4px 10px;
+ opacity: 0;
+ cursor: pointer;
+ border-radius: 100px;
+ font-size: 12px;
+ line-height: 16px;
+ font-weight: 600;
+ font-family: var(--crepe-font-default);
+ transition: opacity 0.2s ease-in-out;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+}
+.milkdown .milkdown-code-block .tools .preview-toggle-button svg {
+ width: 14px;
+ height: 14px;
+ fill: var(--crepe-color-on-surface-variant);
+}
+.milkdown .milkdown-code-block .tools .language-button {
+ display: flex;
+ align-items: center;
+ font-family: var(--crepe-font-default);
+ gap: 6px;
+ padding: 2px 4px 2px 8px;
+ background: var(--crepe-color-surface-low);
+ color: var(--crepe-color-on-surface-variant);
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 600;
+ line-height: 16px;
+ margin-bottom: 8px;
+ opacity: 0;
+ cursor: pointer;
+ transition: opacity 0.2s ease-in-out;
+}
+.milkdown .milkdown-code-block .tools .language-button:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-code-block .tools .language-button .expand-icon {
+ transition: transform 0.2s ease-in-out;
+ width: 18px;
+ height: 18px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.milkdown .milkdown-code-block .tools .language-button .expand-icon svg {
+ width: 14px;
+ height: 14px;
+ color: var(--crepe-color-outline);
+}
+.milkdown
+ .milkdown-code-block
+ .tools
+ .language-button[data-expanded="true"]
+ .expand-icon {
+ transform: rotate(180deg);
+}
+.milkdown .milkdown-code-block .tools .language-button .expand-icon svg:focus,
+.milkdown
+ .milkdown-code-block
+ .tools
+ .language-button
+ .expand-icon:focus-visible {
+ outline: none;
+}
+.milkdown .milkdown-code-block:hover .language-button {
+ opacity: 1;
+}
+.milkdown .milkdown-code-block:hover .preview-toggle-button {
+ opacity: 1;
+}
+.milkdown .milkdown-code-block .list-wrapper {
+ background: var(--crepe-color-surface-low);
+ border-radius: 12px;
+ box-shadow: var(--crepe-shadow-1);
+ width: 240px;
+ padding-top: 12px;
+}
+.milkdown .milkdown-code-block .language-list {
+ height: 410px;
+ overflow-y: auto;
+ overscroll-behavior: contain;
+ margin: 0;
+ padding: 0;
+}
+.milkdown .milkdown-code-block .language-list-item {
+ cursor: pointer;
+ margin: 0;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 4px 22px;
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 20px;
+}
+.milkdown .milkdown-code-block .language-list-item:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-code-block .language-list-item:focus-visible {
+ outline: none;
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-code-block .language-list-item .leading,
+.milkdown .milkdown-code-block .language-list-item .leading svg {
+ width: 24px;
+ height: 24px;
+}
+.milkdown .milkdown-code-block .language-list-item.no-result {
+ cursor: default;
+ opacity: 0.6;
+}
+.milkdown .milkdown-code-block .language-list-item.no-result:hover {
+ background: transparent;
+}
+.milkdown .milkdown-code-block .search-box {
+ display: flex;
+ align-items: center;
+ margin: 0 12px 8px;
+ background: transparent;
+ border-radius: 4px;
+ outline: 1px solid var(--crepe-color-primary);
+ gap: 8px;
+ padding: 6px 10px;
+}
+.milkdown .milkdown-code-block .search-box:has(input:focus) {
+ outline: 2px solid var(--crepe-color-primary);
+}
+.milkdown .milkdown-code-block .search-box .search-input {
+ width: 100%;
+ color: var(--crepe-color-on-surface);
+}
+.milkdown .milkdown-code-block .search-box .search-icon {
+ display: none;
+}
+.milkdown .milkdown-code-block .search-box .clear-icon {
+ cursor: pointer;
+ width: 20px;
+ height: 20px;
+}
+.milkdown .milkdown-code-block .search-box .clear-icon svg {
+ width: 20px;
+ height: 20px;
+ color: var(--crepe-color-primary);
+ fill: var(--crepe-color-primary);
+}
+.milkdown .milkdown-code-block .search-box .clear-icon:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-code-block .search-box input {
+ font-family: var(--crepe-font-default);
+ font-size: 14px;
+ line-height: 20px;
+ background: transparent;
+}
+.milkdown .milkdown-code-block .search-box input:focus {
+ outline: none;
+}
+.milkdown .milkdown-code-block .preview-panel .preview-divider {
+ height: 1px;
+ opacity: 0.2;
+ background: var(--crepe-color-outline);
+ margin: 6px 0;
+}
+.milkdown .milkdown-code-block .preview-panel .preview-label {
+ margin: 6px 0;
+ font-size: 12px;
+ color: var(--crepe-color-on-surface);
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in srgb, var(--crepe-color-on-surface), transparent 40%);
+ }
+ font-weight: 600;
+ text-transform: uppercase;
+ font-family: var(--crepe-font-default);
+}
+.milkdown .milkdown-code-block .preview-panel .preview {
+ text-align: center;
+ overflow-x: auto;
+}
+.ProseMirror-gapcursor {
+ display: none;
+ pointer-events: none;
+ position: absolute;
+}
+.ProseMirror-gapcursor:after {
+ content: "";
+ display: block;
+ position: absolute;
+ top: -2px;
+ width: 20px;
+ border-top: 1px solid black;
+ animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
+}
+@keyframes ProseMirror-cursor-blink {
+ to {
+ visibility: hidden;
+ }
+}
+.ProseMirror-focused .ProseMirror-gapcursor {
+ display: block;
+}
+.ProseMirror.virtual-cursor-enabled {
+ caret-color: transparent;
+}
+.ProseMirror-focused {
+ --prosemirror-virtual-cursor-color: red;
+}
+.ProseMirror .prosemirror-virtual-cursor {
+ position: absolute;
+ cursor: text;
+ pointer-events: none;
+ transform: translate(-1px);
+ user-select: none;
+ -webkit-user-select: none;
+ border-left: 2px solid var(--prosemirror-virtual-cursor-color);
+}
+.ProseMirror .prosemirror-virtual-cursor-left {
+ width: 1ch;
+ transform: translate(calc(-1ch + -1px));
+ border-bottom: 2px solid var(--prosemirror-virtual-cursor-color);
+ border-right: 2px solid var(--prosemirror-virtual-cursor-color);
+ border-left: none;
+}
+.ProseMirror .prosemirror-virtual-cursor-right {
+ width: 1ch;
+ border-bottom: 2px solid var(--prosemirror-virtual-cursor-color);
+ border-left: 2px solid var(--prosemirror-virtual-cursor-color);
+ border-right: none;
+}
+.ProseMirror-focused .prosemirror-virtual-cursor-animation {
+ animation: prosemirror-virtual-cursor-blink 1s linear infinite;
+ animation-delay: 0.5s;
+}
+@keyframes prosemirror-virtual-cursor-blink {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+.milkdown .crepe-drop-cursor {
+ background-color: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background-color: color-mix(
+ in srgb,
+ var(--crepe-color-outline),
+ transparent 50%
+ );
+ }
+ opacity: 0.5;
+ transition: all 0.2s;
+ pointer-events: none;
+}
+.milkdown .ProseMirror-gapcursor:after {
+ box-sizing: border-box;
+ border-top: 1px solid var(--crepe-color-on-background);
+}
+.milkdown .ProseMirror-focused {
+ --prosemirror-virtual-cursor-color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-inline {
+ outline: none;
+ display: inline-flex;
+ vertical-align: text-bottom;
+}
+.milkdown .milkdown-image-inline input {
+ background: transparent;
+ outline: none;
+ border: 0;
+ caret-color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-inline > .empty-image-inline {
+ display: inline-flex;
+}
+.milkdown .milkdown-image-inline > .empty-image-inline .confirm {
+ cursor: pointer;
+}
+.milkdown .milkdown-image-inline > .empty-image-inline .link-importer {
+ position: relative;
+ flex: 1;
+}
+.milkdown
+ .milkdown-image-inline
+ > .empty-image-inline
+ .link-importer
+ > .link-input-area {
+ width: 208px;
+ color: var(--crepe-color-on-background);
+ display: flex;
+}
+.milkdown
+ .milkdown-image-inline
+ > .empty-image-inline
+ .link-importer
+ .placeholder {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ cursor: text;
+}
+.milkdown
+ .milkdown-image-inline
+ > .empty-image-inline
+ .link-importer
+ .placeholder
+ .uploader {
+ cursor: pointer;
+ display: flex;
+}
+.milkdown .milkdown-image-inline .hidden {
+ display: none !important;
+}
+.milkdown .milkdown-image-inline.empty.selected {
+ background: none;
+ outline: none;
+}
+.milkdown .milkdown-image-inline.empty.selected .empty-image-inline {
+ box-shadow: var(--crepe-shadow-1);
+}
+.milkdown .milkdown-image-inline.selected {
+ background: none;
+ outline: 1px solid var(--crepe-color-primary);
+}
+.milkdown .milkdown-image-inline.selected :not(input)::-moz-selection {
+ background: transparent;
+}
+.milkdown .milkdown-image-inline.selected :not(input)::selection {
+ background: transparent;
+}
+.milkdown .milkdown-image-inline .empty-image-inline {
+ align-items: center;
+ padding: 4px 10px;
+ gap: 10px;
+ background: var(--crepe-color-surface);
+ font-family: var(--crepe-font-default);
+ border-radius: 8px;
+ font-size: 16px;
+}
+.milkdown .milkdown-image-inline .empty-image-inline .image-icon svg {
+ width: 18px;
+ height: 18px;
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-inline .empty-image-inline .image-icon {
+ padding: 3px;
+ width: 24px;
+ height: 24px;
+}
+.milkdown .milkdown-image-inline .empty-image-inline .link-importer {
+ height: 24px;
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder {
+ color: var(--crepe-color-on-background);
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in srgb, var(--crepe-color-on-background), transparent 60%);
+ }
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder
+ :not(input)::-moz-selection {
+ background: transparent;
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder
+ :not(input)::selection {
+ background: transparent;
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .link-input-area {
+ line-height: 24px;
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder
+ .uploader {
+ gap: 8px;
+ color: var(--crepe-color-primary);
+ justify-content: center;
+ transition: color 0.2s;
+ font-family: var(--crepe-font-default);
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer.focus
+ .placeholder
+ .uploader {
+ color: unset;
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder
+ .uploader:hover {
+ color: var(--crepe-color-primary);
+}
+.milkdown
+ .milkdown-image-inline
+ .empty-image-inline
+ .link-importer
+ .placeholder
+ .text {
+ margin-left: 8px;
+}
+.milkdown .milkdown-image-inline .empty-image-inline .confirm svg {
+ width: 18px;
+ height: 18px;
+}
+.milkdown .milkdown-image-inline .empty-image-inline .confirm {
+ display: flex;
+ width: 24px;
+ height: 24px;
+ padding: 3px;
+ border-radius: 8px;
+ color: var(--crepe-color-primary);
+}
+.milkdown .milkdown-image-inline .empty-image-inline .confirm:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-image-block {
+ outline: none;
+ margin: 4px 0;
+ display: block;
+}
+.milkdown .milkdown-image-block > .image-wrapper {
+ position: relative;
+ width: -moz-fit-content;
+ width: fit-content;
+ margin: 0 auto;
+ min-width: 100px;
+}
+.milkdown .milkdown-image-block > .image-wrapper .operation {
+ position: absolute;
+ display: flex;
+}
+.milkdown .milkdown-image-block > .image-wrapper .operation > .operation-item {
+ cursor: pointer;
+}
+.milkdown .milkdown-image-block > .image-wrapper img {
+ max-width: 100%;
+ min-height: 100px;
+ display: block;
+ -o-object-fit: cover;
+ object-fit: cover;
+}
+.milkdown .milkdown-image-block > .image-wrapper > .image-resize-handle {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+}
+.milkdown .milkdown-image-block > .image-wrapper > .image-resize-handle:hover {
+ cursor: row-resize;
+}
+.milkdown .milkdown-image-block input {
+ background: transparent;
+ outline: none;
+ border: 0;
+ caret-color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-block > .caption-input {
+ display: block;
+ width: 100%;
+ text-align: center;
+ color: var(--crepe-color-on-background);
+}
+.milkdown .milkdown-image-block > .image-edit {
+ display: flex;
+}
+.milkdown .milkdown-image-block > .image-edit .confirm {
+ cursor: pointer;
+}
+.milkdown .milkdown-image-block > .image-edit .link-importer {
+ position: relative;
+ flex: 1;
+}
+.milkdown
+ .milkdown-image-block
+ > .image-edit
+ .link-importer
+ > .link-input-area {
+ width: 100%;
+}
+.milkdown .milkdown-image-block > .image-edit .link-importer .placeholder {
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ display: flex;
+ align-items: center;
+ cursor: text;
+}
+.milkdown
+ .milkdown-image-block
+ > .image-edit
+ .link-importer
+ .placeholder
+ .uploader {
+ cursor: pointer;
+ display: flex;
+}
+.milkdown .milkdown-image-block .hidden {
+ display: none !important;
+}
+.milkdown .milkdown-image-block.selected > .image-edit:not(:has(input:focus)) {
+ position: relative;
+}
+.milkdown
+ .milkdown-image-block.selected
+ > .image-edit:not(:has(input:focus))::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: var(--crepe-color-selected);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(in srgb, var(--crepe-color-selected), transparent 60%);
+ }
+ pointer-events: none;
+}
+.milkdown .milkdown-image-block.selected > .image-wrapper {
+ position: relative;
+}
+.milkdown .milkdown-image-block.selected > .image-wrapper::before {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: var(--crepe-color-selected);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(in srgb, var(--crepe-color-selected), transparent 60%);
+ }
+}
+.milkdown .milkdown-image-block.selected :not(input)::-moz-selection {
+ background: transparent;
+}
+.milkdown .milkdown-image-block.selected :not(input)::selection {
+ background: transparent;
+}
+.milkdown .milkdown-image-block .image-wrapper {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.milkdown .milkdown-image-block .image-wrapper .operation {
+ gap: 12px;
+ right: 12px;
+ top: 12px;
+ opacity: 0;
+ transition: all 0.2s;
+}
+.milkdown .milkdown-image-block:hover > .image-wrapper .operation {
+ opacity: 1;
+}
+.milkdown .milkdown-image-block .image-wrapper .operation > .operation-item {
+ color: var(--crepe-color-on-inverse);
+ padding: 4px;
+ background: var(--crepe-color-inverse);
+ opacity: 0.6;
+ border-radius: 50%;
+ width: 32px;
+ height: 32px;
+}
+.milkdown
+ .milkdown-image-block
+ .image-wrapper
+ .operation
+ > .operation-item
+ svg {
+ width: 24px;
+ height: 24px;
+}
+.milkdown .milkdown-image-block .image-wrapper .image-resize-handle {
+ height: 4px;
+ bottom: -2px;
+ max-width: 160px;
+ width: 100%;
+ background: var(--crepe-color-outline);
+ opacity: 0;
+ transition: all 0.2s;
+ border-radius: 4px;
+}
+.milkdown .milkdown-image-block:hover > .image-wrapper .image-resize-handle {
+ opacity: 1;
+}
+.milkdown .milkdown-image-block .caption-input {
+ margin: 4px auto;
+ font-family: var(--crepe-font-default);
+}
+.milkdown .milkdown-image-block .image-edit {
+ align-items: center;
+ padding: 16px 24px;
+ gap: 16px;
+ background: var(--crepe-color-surface);
+ height: 56px;
+}
+.milkdown .milkdown-image-block .image-edit .image-icon {
+ color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-block .image-edit .image-icon svg {
+ width: 24px;
+ height: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-image-block .image-edit .link-importer .placeholder {
+ color: var(--crepe-color-on-background);
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in srgb, var(--crepe-color-on-background), transparent 60%);
+ }
+}
+.milkdown
+ .milkdown-image-block
+ .image-edit
+ .link-importer
+ .placeholder
+ :not(input)::-moz-selection {
+ background: transparent;
+}
+.milkdown
+ .milkdown-image-block
+ .image-edit
+ .link-importer
+ .placeholder
+ :not(input)::selection {
+ background: transparent;
+}
+.milkdown .milkdown-image-block .image-edit .link-importer .link-input-area {
+ line-height: 24px;
+ color: var(--crepe-color-on-background);
+}
+.milkdown
+ .milkdown-image-block
+ .image-edit
+ .link-importer
+ .placeholder
+ .uploader {
+ gap: 8px;
+ color: var(--crepe-color-primary);
+ justify-content: center;
+ transition: color 0.2s;
+ font-weight: 600;
+}
+.milkdown
+ .milkdown-image-block
+ .image-edit
+ .link-importer.focus
+ .placeholder
+ .uploader {
+ color: unset;
+}
+.milkdown
+ .milkdown-image-block
+ .image-edit
+ .link-importer
+ .placeholder
+ .uploader:hover {
+ color: var(--crepe-color-primary);
+}
+.milkdown .milkdown-image-block .image-edit .link-importer .placeholder .text {
+ margin-left: 8px;
+}
+.milkdown .milkdown-image-block .image-edit .confirm {
+ background: var(--crepe-color-secondary);
+ color: var(--crepe-color-on-secondary);
+ line-height: 40px;
+ padding: 0 24px;
+ border-radius: 100px;
+ font-size: 14px;
+ font-weight: 600;
+}
+.milkdown .milkdown-image-block .image-edit .confirm:hover {
+ background: linear-gradient(
+ 0deg,
+ rgba(29, 25, 43, 0.08) 0%,
+ rgba(29, 25, 43, 0.08) 100%
+ ), var(--crepe-color-secondary);
+}
+.milkdown .milkdown-link-preview {
+ position: absolute;
+ z-index: 10;
+}
+.milkdown .milkdown-link-preview[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-link-preview > .link-preview {
+ height: 32px;
+ display: flex;
+ justify-content: center;
+ padding: 4px 10px;
+ background: var(--crepe-color-surface);
+ gap: 10px;
+ border-radius: 8px;
+ cursor: pointer;
+ box-shadow: var(--crepe-shadow-1);
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-display {
+ text-decoration: none;
+ color: unset;
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-display:hover:before {
+ display: block;
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-icon > svg {
+ width: 18px;
+ height: 18px;
+ color: var(--crepe-color-outline);
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-icon {
+ border-radius: 8px;
+ padding: 3px;
+ line-height: 24px;
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-icon:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-display {
+ width: 240px;
+ line-height: 24px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 14px;
+ white-space: nowrap;
+}
+.milkdown .milkdown-link-preview > .link-preview > .link-display:hover {
+ text-decoration: underline;
+}
+.milkdown .milkdown-link-preview > .link-preview > .button > svg {
+ width: 18px;
+ height: 18px;
+ color: var(--crepe-color-outline);
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-link-preview > .link-preview > .button {
+ padding: 3px;
+ border-radius: 8px;
+ line-height: 24px;
+}
+.milkdown .milkdown-link-preview > .link-preview > .button:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-link-edit {
+ position: absolute;
+ z-index: 10;
+}
+.milkdown .milkdown-link-edit[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-link-edit > .link-edit {
+ height: 32px;
+ display: flex;
+ justify-content: center;
+ padding: 4px 10px 4px 20px;
+ background: var(--crepe-color-surface);
+ gap: 8px;
+ border-radius: 8px;
+ box-shadow: var(--crepe-shadow-1);
+}
+.milkdown .milkdown-link-edit > .link-edit > .input-area {
+ outline: none;
+ background: transparent;
+ width: 200px;
+ font-size: 14px;
+ color: var(--crepe-color-on-background);
+}
+.milkdown .milkdown-link-edit > .link-edit > .button > svg {
+ width: 18px;
+ height: 18px;
+ color: var(--crepe-color-outline);
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-link-edit > .link-edit > .button {
+ padding: 3px;
+ cursor: pointer;
+ border-radius: 8px;
+ font-size: 12px;
+ line-height: 24px;
+}
+.milkdown .milkdown-link-edit > .link-edit > .button:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-link-edit > .link-edit > .button.hidden {
+ visibility: hidden;
+}
+.milkdown .milkdown-list-item-block {
+ display: block;
+ padding: 0;
+}
+.milkdown .milkdown-list-item-block > .list-item {
+ display: flex;
+ align-items: flex-start;
+}
+.milkdown .milkdown-list-item-block > .list-item > .children {
+ min-width: 0;
+ flex: 1;
+}
+.milkdown .milkdown-list-item-block li {
+ gap: 10px;
+}
+.milkdown .milkdown-list-item-block li .label-wrapper {
+ color: var(--crepe-color-outline);
+}
+.milkdown .milkdown-list-item-block li .label-wrapper svg {
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-list-item-block li .label-wrapper {
+ height: 32px;
+ width: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.milkdown .milkdown-list-item-block li .label-wrapper .label {
+ height: 32px;
+ padding: 4px 0;
+ width: 24px;
+ text-align: right;
+}
+.milkdown .milkdown-list-item-block li .label-wrapper .checked,
+.milkdown .milkdown-list-item-block li .label-wrapper .unchecked {
+ cursor: pointer;
+}
+.milkdown .milkdown-list-item-block li .label-wrapper .readonly {
+ cursor: not-allowed;
+}
+.milkdown .crepe-placeholder::before {
+ position: absolute;
+ color: var(--crepe-color-on-background);
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in srgb, var(--crepe-color-on-background), transparent 60%);
+ }
+ pointer-events: none;
+ height: 0;
+ content: attr(data-placeholder);
+}
+.milkdown .milkdown-toolbar[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-toolbar {
+ position: absolute;
+ display: flex;
+ background: var(--crepe-color-surface);
+ box-shadow: var(--crepe-shadow-1);
+ border-radius: 8px;
+ overflow: hidden;
+}
+.milkdown .milkdown-toolbar .divider {
+ width: 1px;
+ background: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(in srgb, var(--crepe-color-outline), transparent 80%);
+ }
+ height: 24px;
+ margin: 10px;
+}
+.milkdown .milkdown-toolbar .toolbar-item {
+ width: 32px;
+ height: 32px;
+ margin: 6px;
+ padding: 4px;
+ cursor: pointer;
+ border-radius: 4px;
+}
+.milkdown .milkdown-toolbar .toolbar-item:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-toolbar .toolbar-item:active {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-toolbar .toolbar-item svg {
+ height: 24px;
+ width: 24px;
+ color: var(--crepe-color-outline);
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-toolbar .toolbar-item.active svg {
+ color: var(--crepe-color-primary);
+ fill: var(--crepe-color-primary);
+}
+.ProseMirror .tableWrapper {
+ overflow-x: auto;
+}
+.ProseMirror table {
+ border-collapse: collapse;
+ table-layout: fixed;
+ width: 100%;
+ overflow: hidden;
+}
+.ProseMirror td,
+.ProseMirror th {
+ vertical-align: top;
+ box-sizing: border-box;
+ position: relative;
+}
+.ProseMirror td:not([data-colwidth]):not(.column-resize-dragging),
+.ProseMirror th:not([data-colwidth]):not(.column-resize-dragging) {
+ min-width: var(--default-cell-min-width);
+}
+.ProseMirror .column-resize-handle {
+ position: absolute;
+ right: -2px;
+ top: 0;
+ bottom: 0;
+ width: 4px;
+ z-index: 20;
+ background-color: #adf;
+ pointer-events: none;
+}
+.ProseMirror.resize-cursor {
+ cursor: ew-resize;
+ cursor: col-resize;
+}
+.ProseMirror .selectedCell:after {
+ z-index: 2;
+ position: absolute;
+ content: "";
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ background: rgba(200, 200, 255, 0.4);
+ pointer-events: none;
+}
+.milkdown .milkdown-table-block {
+ display: block;
+ margin: 4px 0;
+}
+.milkdown .milkdown-table-block th,
+.milkdown .milkdown-table-block td {
+ border: 1px solid var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ border: 1px solid
+ color-mix(in srgb, var(--crepe-color-outline), transparent 80%);
+ }
+ padding: 4px 16px;
+}
+.milkdown .milkdown-table-block th .ProseMirror-selectednode,
+.milkdown .milkdown-table-block td .ProseMirror-selectednode {
+ background-color: transparent !important;
+}
+.milkdown .milkdown-table-block th:has(.ProseMirror-selectednode),
+.milkdown .milkdown-table-block td:has(.ProseMirror-selectednode) {
+ outline: 1px solid var(--crepe-color-primary);
+ outline-offset: -1px;
+}
+.milkdown .milkdown-table-block .selectedCell::after {
+ background-color: var(--crepe-color-selected);
+ opacity: 0.4;
+}
+.milkdown .milkdown-table-block .selectedCell ::-moz-selection {
+ background: transparent;
+}
+.milkdown .milkdown-table-block .selectedCell ::selection {
+ background: transparent;
+}
+.milkdown .milkdown-table-block .drag-preview {
+ background-color: var(--crepe-color-surface);
+ opacity: 0.4;
+ position: absolute;
+ z-index: 100;
+ display: flex;
+ flex-direction: column;
+ outline: 1px solid var(--crepe-color-primary);
+ outline-offset: -1px;
+}
+.milkdown .milkdown-table-block .drag-preview[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-table-block .drag-preview th:has(.ProseMirror-selectednode),
+.milkdown
+ .milkdown-table-block
+ .drag-preview
+ td:has(.ProseMirror-selectednode) {
+ outline: none;
+}
+.milkdown .milkdown-table-block .handle {
+ position: absolute;
+ font-size: 14px;
+ transition: opacity ease-in-out 0.2s;
+}
+.milkdown .milkdown-table-block .handle[data-show="false"] {
+ opacity: 0;
+}
+.milkdown .milkdown-table-block svg {
+ fill: var(--crepe-color-outline);
+}
+.milkdown .milkdown-table-block .cell-handle {
+ z-index: 50;
+ left: -999px;
+ top: -999px;
+ cursor: grab;
+ background-color: var(--crepe-color-surface);
+ color: var(--crepe-color-outline);
+ border-radius: 100px;
+ box-shadow: var(--crepe-shadow-1);
+ transition: background-color 0.2s ease-in-out;
+}
+.milkdown .milkdown-table-block .cell-handle:hover {
+ background-color: var(--crepe-color-hover);
+}
+.milkdown .milkdown-table-block .cell-handle:has(.button-group:hover) {
+ background-color: var(--crepe-color-surface);
+}
+.milkdown .milkdown-table-block .cell-handle[data-role="col-drag-handle"] {
+ transform: translateY(50%);
+ padding: 0 6px;
+ width: 28px;
+ height: 16px;
+}
+.milkdown .milkdown-table-block .cell-handle[data-role="row-drag-handle"] {
+ transform: translateX(50%);
+ padding: 6px 0;
+ width: 16px;
+ height: 28px;
+}
+.milkdown .milkdown-table-block .cell-handle .button-group {
+ position: absolute;
+ transform: translateX(-50%);
+ left: 50%;
+ top: -52px;
+ display: flex;
+ background-color: var(--crepe-color-surface);
+ border-radius: 8px;
+ box-shadow: var(--crepe-shadow-1);
+}
+.milkdown .milkdown-table-block .cell-handle .button-group::after {
+ content: "";
+ position: absolute;
+ bottom: -8px;
+ height: 8px;
+ background-color: transparent;
+ width: 100%;
+}
+.milkdown .milkdown-table-block .cell-handle .button-group[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-table-block .cell-handle .button-group button {
+ cursor: pointer;
+ margin: 6px;
+ padding: 4px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 4px;
+}
+.milkdown .milkdown-table-block .cell-handle .button-group button svg {
+ width: 24px;
+ height: 24px;
+}
+.milkdown .milkdown-table-block .cell-handle .button-group button:hover {
+ border-radius: 8px;
+ background-color: var(--crepe-color-hover);
+}
+.milkdown .milkdown-table-block .cell-handle .button-group button:active {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-table-block .cell-handle:hover {
+ opacity: 1;
+}
+.milkdown .milkdown-table-block .line-handle {
+ z-index: 20;
+ background-color: var(--crepe-color-primary);
+}
+.milkdown .milkdown-table-block .line-handle:hover {
+ opacity: 1;
+}
+.milkdown .milkdown-table-block .line-handle .add-button {
+ cursor: pointer;
+ background-color: var(--crepe-color-surface);
+ color: var(--crepe-color-outline);
+ border-radius: 100px;
+ box-shadow: var(--crepe-shadow-1);
+ transition: background-color 0.2s ease-in-out;
+}
+.milkdown .milkdown-table-block .line-handle .add-button svg {
+ width: 16px;
+ height: 16px;
+}
+.milkdown .milkdown-table-block .line-handle .add-button:hover {
+ background-color: var(--crepe-color-hover);
+}
+.milkdown .milkdown-table-block .line-handle .add-button:active {
+ background: var(--crepe-color-selected);
+}
+.milkdown .milkdown-table-block .line-handle[data-role="x-line-drag-handle"] {
+ height: 1px;
+ z-index: 2;
+}
+.milkdown
+ .milkdown-table-block
+ .line-handle[data-role="x-line-drag-handle"]
+ .add-button {
+ position: absolute;
+ transform: translateX(-50%) translateY(-50%);
+ padding: 6px 0;
+ width: 16px;
+ height: 28px;
+}
+.milkdown .milkdown-table-block .line-handle[data-role="y-line-drag-handle"] {
+ width: 1px;
+ z-index: 1;
+}
+.milkdown
+ .milkdown-table-block
+ .line-handle[data-role="y-line-drag-handle"]
+ .add-button {
+ position: absolute;
+ transform: translateY(-50%) translateX(-50%);
+ padding: 0 6px;
+ width: 28px;
+ height: 16px;
+}
+.milkdown
+ .milkdown-table-block
+ .line-handle[data-display-type="indicator"]
+ .add-button {
+ display: none;
+}
+.milkdown .milkdown-table-block.readonly .handle {
+ display: none;
+}
+@font-face {
+ font-family: KaTeX_AMS;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_AMS-Regular.a79f1c31.woff2) format("woff2"),
+ url(/_next/static/media/KaTeX_AMS-Regular.1608a09b.woff) format("woff"),
+ url(/_next/static/media/KaTeX_AMS-Regular.4aafdb68.ttf) format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Caligraphic;
+ font-style: normal;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_Caligraphic-Bold.ec17d132.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Caligraphic-Bold.b6770918.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Caligraphic-Bold.cce5b8ec.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Caligraphic;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Caligraphic-Regular.55fac258.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Caligraphic-Regular.dad44a7f.woff)
+ format("woff"),
+ url(/_next/static/media/KaTeX_Caligraphic-Regular.07ef19e7.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Fraktur;
+ font-style: normal;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_Fraktur-Bold.d42a5579.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Fraktur-Bold.9f256b85.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Fraktur-Bold.b18f59e1.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Fraktur;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Fraktur-Regular.d3c882a6.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Fraktur-Regular.7c187121.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Fraktur-Regular.ed38e79f.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Main;
+ font-style: normal;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_Main-Bold.c3fb5ac2.woff2) format("woff2"),
+ url(/_next/static/media/KaTeX_Main-Bold.d181c465.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Main-Bold.b74a1a8b.ttf) format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Main;
+ font-style: italic;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_Main-BoldItalic.6f2bb1df.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Main-BoldItalic.e3f82f9d.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Main-BoldItalic.70d8b0a5.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Main;
+ font-style: italic;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Main-Italic.8916142b.woff2) format("woff2"),
+ url(/_next/static/media/KaTeX_Main-Italic.9024d815.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Main-Italic.47373d1e.ttf) format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Main;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Main-Regular.0462f03b.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Main-Regular.7f51fe03.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Main-Regular.b7f8fe9b.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Math;
+ font-style: italic;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_Math-BoldItalic.572d331f.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Math-BoldItalic.f1035d8d.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Math-BoldItalic.a879cf83.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Math;
+ font-style: italic;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Math-Italic.f28c23ac.woff2) format("woff2"),
+ url(/_next/static/media/KaTeX_Math-Italic.5295ba48.woff) format("woff"),
+ url(/_next/static/media/KaTeX_Math-Italic.939bc644.ttf) format("truetype");
+}
+@font-face {
+ font-family: "KaTeX_SansSerif";
+ font-style: normal;
+ font-weight: 700;
+ src: url(/_next/static/media/KaTeX_SansSerif-Bold.8c5b5494.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_SansSerif-Bold.bf59d231.woff)
+ format("woff"), url(/_next/static/media/KaTeX_SansSerif-Bold.94e1e8dc.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: "KaTeX_SansSerif";
+ font-style: italic;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_SansSerif-Italic.3b1e59b3.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_SansSerif-Italic.7c9bc82b.woff) format("woff"),
+ url(/_next/static/media/KaTeX_SansSerif-Italic.b4c20c84.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: "KaTeX_SansSerif";
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_SansSerif-Regular.ba21ed5f.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_SansSerif-Regular.74048478.woff)
+ format("woff"),
+ url(/_next/static/media/KaTeX_SansSerif-Regular.d4d7ba48.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Script;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Script-Regular.03e9641d.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Script-Regular.07505710.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Script-Regular.fe9cbbe1.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Size1;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Size1-Regular.eae34984.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Size1-Regular.e1e279cb.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Size1-Regular.fabc004a.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Size2;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Size2-Regular.5916a24f.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Size2-Regular.57727022.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Size2-Regular.d6b476ec.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Size3;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Size3-Regular.b4230e7e.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Size3-Regular.9acaf01c.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Size3-Regular.a144ef58.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Size4;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Size4-Regular.10d95fd3.woff2)
+ format("woff2"), url(/_next/static/media/KaTeX_Size4-Regular.7a996c9d.woff)
+ format("woff"), url(/_next/static/media/KaTeX_Size4-Regular.fbccdabe.ttf)
+ format("truetype");
+}
+@font-face {
+ font-family: KaTeX_Typewriter;
+ font-style: normal;
+ font-weight: 400;
+ src: url(/_next/static/media/KaTeX_Typewriter-Regular.a8709e36.woff2)
+ format("woff2"),
+ url(/_next/static/media/KaTeX_Typewriter-Regular.6258592b.woff)
+ format("woff"),
+ url(/_next/static/media/KaTeX_Typewriter-Regular.d97aaf4a.ttf)
+ format("truetype");
+}
+.katex {
+ font: normal 1.21em KaTeX_Main, Times New Roman, serif;
+ line-height: 1.2;
+ text-indent: 0;
+ text-rendering: auto;
+}
+.katex * {
+ -ms-high-contrast-adjust: none !important;
+ border-color: currentColor;
+}
+.katex .katex-version:after {
+ content: "0.16.22";
+}
+.katex .katex-mathml {
+ clip: rect(1px, 1px, 1px, 1px);
+ border: 0;
+ height: 1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+.katex .katex-html > .newline {
+ display: block;
+}
+.katex .base {
+ position: relative;
+ white-space: nowrap;
+ width: -webkit-min-content;
+ width: -moz-min-content;
+ width: min-content;
+}
+.katex .base,
+.katex .strut {
+ display: inline-block;
+}
+.katex .textbf {
+ font-weight: 700;
+}
+.katex .textit {
+ font-style: italic;
+}
+.katex .textrm {
+ font-family: KaTeX_Main;
+}
+.katex .textsf {
+ font-family: KaTeX_SansSerif;
+}
+.katex .texttt {
+ font-family: KaTeX_Typewriter;
+}
+.katex .mathnormal {
+ font-family: KaTeX_Math;
+ font-style: italic;
+}
+.katex .mathit {
+ font-family: KaTeX_Main;
+ font-style: italic;
+}
+.katex .mathrm {
+ font-style: normal;
+}
+.katex .mathbf {
+ font-family: KaTeX_Main;
+ font-weight: 700;
+}
+.katex .boldsymbol {
+ font-family: KaTeX_Math;
+ font-style: italic;
+ font-weight: 700;
+}
+.katex .amsrm,
+.katex .mathbb,
+.katex .textbb {
+ font-family: KaTeX_AMS;
+}
+.katex .mathcal {
+ font-family: KaTeX_Caligraphic;
+}
+.katex .mathfrak,
+.katex .textfrak {
+ font-family: KaTeX_Fraktur;
+}
+.katex .mathboldfrak,
+.katex .textboldfrak {
+ font-family: KaTeX_Fraktur;
+ font-weight: 700;
+}
+.katex .mathtt {
+ font-family: KaTeX_Typewriter;
+}
+.katex .mathscr,
+.katex .textscr {
+ font-family: KaTeX_Script;
+}
+.katex .mathsf,
+.katex .textsf {
+ font-family: KaTeX_SansSerif;
+}
+.katex .mathboldsf,
+.katex .textboldsf {
+ font-family: KaTeX_SansSerif;
+ font-weight: 700;
+}
+.katex .mathitsf,
+.katex .mathsfit,
+.katex .textitsf {
+ font-family: KaTeX_SansSerif;
+ font-style: italic;
+}
+.katex .mainrm {
+ font-family: KaTeX_Main;
+ font-style: normal;
+}
+.katex .vlist-t {
+ border-collapse: collapse;
+ display: inline-table;
+ table-layout: fixed;
+}
+.katex .vlist-r {
+ display: table-row;
+}
+.katex .vlist {
+ display: table-cell;
+ position: relative;
+ vertical-align: bottom;
+}
+.katex .vlist > span {
+ display: block;
+ height: 0;
+ position: relative;
+}
+.katex .vlist > span > span {
+ display: inline-block;
+}
+.katex .vlist > span > .pstrut {
+ overflow: hidden;
+ width: 0;
+}
+.katex .vlist-t2 {
+ margin-right: -2px;
+}
+.katex .vlist-s {
+ display: table-cell;
+ font-size: 1px;
+ min-width: 2px;
+ vertical-align: bottom;
+ width: 2px;
+}
+.katex .vbox {
+ align-items: baseline;
+ display: inline-flex;
+ flex-direction: column;
+}
+.katex .hbox {
+ width: 100%;
+}
+.katex .hbox,
+.katex .thinbox {
+ display: inline-flex;
+ flex-direction: row;
+}
+.katex .thinbox {
+ max-width: 0;
+ width: 0;
+}
+.katex .msupsub {
+ text-align: left;
+}
+.katex .mfrac > span > span {
+ text-align: center;
+}
+.katex .mfrac .frac-line {
+ border-bottom-style: solid;
+ display: inline-block;
+ width: 100%;
+}
+.katex .hdashline,
+.katex .hline,
+.katex .mfrac .frac-line,
+.katex .overline .overline-line,
+.katex .rule,
+.katex .underline .underline-line {
+ min-height: 1px;
+}
+.katex .mspace {
+ display: inline-block;
+}
+.katex .clap,
+.katex .llap,
+.katex .rlap {
+ position: relative;
+ width: 0;
+}
+.katex .clap > .inner,
+.katex .llap > .inner,
+.katex .rlap > .inner {
+ position: absolute;
+}
+.katex .clap > .fix,
+.katex .llap > .fix,
+.katex .rlap > .fix {
+ display: inline-block;
+}
+.katex .llap > .inner {
+ right: 0;
+}
+.katex .clap > .inner,
+.katex .rlap > .inner {
+ left: 0;
+}
+.katex .clap > .inner > span {
+ margin-left: -50%;
+ margin-right: 50%;
+}
+.katex .rule {
+ border: 0 solid;
+ display: inline-block;
+ position: relative;
+}
+.katex .hline,
+.katex .overline .overline-line,
+.katex .underline .underline-line {
+ border-bottom-style: solid;
+ display: inline-block;
+ width: 100%;
+}
+.katex .hdashline {
+ border-bottom-style: dashed;
+ display: inline-block;
+ width: 100%;
+}
+.katex .sqrt > .root {
+ margin-left: .2777777778em;
+ margin-right: -.5555555556em;
+}
+.katex .fontsize-ensurer.reset-size1.size1,
+.katex .sizing.reset-size1.size1 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size1.size2,
+.katex .sizing.reset-size1.size2 {
+ font-size: 1.2em;
+}
+.katex .fontsize-ensurer.reset-size1.size3,
+.katex .sizing.reset-size1.size3 {
+ font-size: 1.4em;
+}
+.katex .fontsize-ensurer.reset-size1.size4,
+.katex .sizing.reset-size1.size4 {
+ font-size: 1.6em;
+}
+.katex .fontsize-ensurer.reset-size1.size5,
+.katex .sizing.reset-size1.size5 {
+ font-size: 1.8em;
+}
+.katex .fontsize-ensurer.reset-size1.size6,
+.katex .sizing.reset-size1.size6 {
+ font-size: 2em;
+}
+.katex .fontsize-ensurer.reset-size1.size7,
+.katex .sizing.reset-size1.size7 {
+ font-size: 2.4em;
+}
+.katex .fontsize-ensurer.reset-size1.size8,
+.katex .sizing.reset-size1.size8 {
+ font-size: 2.88em;
+}
+.katex .fontsize-ensurer.reset-size1.size9,
+.katex .sizing.reset-size1.size9 {
+ font-size: 3.456em;
+}
+.katex .fontsize-ensurer.reset-size1.size10,
+.katex .sizing.reset-size1.size10 {
+ font-size: 4.148em;
+}
+.katex .fontsize-ensurer.reset-size1.size11,
+.katex .sizing.reset-size1.size11 {
+ font-size: 4.976em;
+}
+.katex .fontsize-ensurer.reset-size2.size1,
+.katex .sizing.reset-size2.size1 {
+ font-size: .8333333333em;
+}
+.katex .fontsize-ensurer.reset-size2.size2,
+.katex .sizing.reset-size2.size2 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size2.size3,
+.katex .sizing.reset-size2.size3 {
+ font-size: 1.1666666667em;
+}
+.katex .fontsize-ensurer.reset-size2.size4,
+.katex .sizing.reset-size2.size4 {
+ font-size: 1.3333333333em;
+}
+.katex .fontsize-ensurer.reset-size2.size5,
+.katex .sizing.reset-size2.size5 {
+ font-size: 1.5em;
+}
+.katex .fontsize-ensurer.reset-size2.size6,
+.katex .sizing.reset-size2.size6 {
+ font-size: 1.6666666667em;
+}
+.katex .fontsize-ensurer.reset-size2.size7,
+.katex .sizing.reset-size2.size7 {
+ font-size: 2em;
+}
+.katex .fontsize-ensurer.reset-size2.size8,
+.katex .sizing.reset-size2.size8 {
+ font-size: 2.4em;
+}
+.katex .fontsize-ensurer.reset-size2.size9,
+.katex .sizing.reset-size2.size9 {
+ font-size: 2.88em;
+}
+.katex .fontsize-ensurer.reset-size2.size10,
+.katex .sizing.reset-size2.size10 {
+ font-size: 3.4566666667em;
+}
+.katex .fontsize-ensurer.reset-size2.size11,
+.katex .sizing.reset-size2.size11 {
+ font-size: 4.1466666667em;
+}
+.katex .fontsize-ensurer.reset-size3.size1,
+.katex .sizing.reset-size3.size1 {
+ font-size: .7142857143em;
+}
+.katex .fontsize-ensurer.reset-size3.size2,
+.katex .sizing.reset-size3.size2 {
+ font-size: .8571428571em;
+}
+.katex .fontsize-ensurer.reset-size3.size3,
+.katex .sizing.reset-size3.size3 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size3.size4,
+.katex .sizing.reset-size3.size4 {
+ font-size: 1.1428571429em;
+}
+.katex .fontsize-ensurer.reset-size3.size5,
+.katex .sizing.reset-size3.size5 {
+ font-size: 1.2857142857em;
+}
+.katex .fontsize-ensurer.reset-size3.size6,
+.katex .sizing.reset-size3.size6 {
+ font-size: 1.4285714286em;
+}
+.katex .fontsize-ensurer.reset-size3.size7,
+.katex .sizing.reset-size3.size7 {
+ font-size: 1.7142857143em;
+}
+.katex .fontsize-ensurer.reset-size3.size8,
+.katex .sizing.reset-size3.size8 {
+ font-size: 2.0571428571em;
+}
+.katex .fontsize-ensurer.reset-size3.size9,
+.katex .sizing.reset-size3.size9 {
+ font-size: 2.4685714286em;
+}
+.katex .fontsize-ensurer.reset-size3.size10,
+.katex .sizing.reset-size3.size10 {
+ font-size: 2.9628571429em;
+}
+.katex .fontsize-ensurer.reset-size3.size11,
+.katex .sizing.reset-size3.size11 {
+ font-size: 3.5542857143em;
+}
+.katex .fontsize-ensurer.reset-size4.size1,
+.katex .sizing.reset-size4.size1 {
+ font-size: .625em;
+}
+.katex .fontsize-ensurer.reset-size4.size2,
+.katex .sizing.reset-size4.size2 {
+ font-size: .75em;
+}
+.katex .fontsize-ensurer.reset-size4.size3,
+.katex .sizing.reset-size4.size3 {
+ font-size: .875em;
+}
+.katex .fontsize-ensurer.reset-size4.size4,
+.katex .sizing.reset-size4.size4 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size4.size5,
+.katex .sizing.reset-size4.size5 {
+ font-size: 1.125em;
+}
+.katex .fontsize-ensurer.reset-size4.size6,
+.katex .sizing.reset-size4.size6 {
+ font-size: 1.25em;
+}
+.katex .fontsize-ensurer.reset-size4.size7,
+.katex .sizing.reset-size4.size7 {
+ font-size: 1.5em;
+}
+.katex .fontsize-ensurer.reset-size4.size8,
+.katex .sizing.reset-size4.size8 {
+ font-size: 1.8em;
+}
+.katex .fontsize-ensurer.reset-size4.size9,
+.katex .sizing.reset-size4.size9 {
+ font-size: 2.16em;
+}
+.katex .fontsize-ensurer.reset-size4.size10,
+.katex .sizing.reset-size4.size10 {
+ font-size: 2.5925em;
+}
+.katex .fontsize-ensurer.reset-size4.size11,
+.katex .sizing.reset-size4.size11 {
+ font-size: 3.11em;
+}
+.katex .fontsize-ensurer.reset-size5.size1,
+.katex .sizing.reset-size5.size1 {
+ font-size: .5555555556em;
+}
+.katex .fontsize-ensurer.reset-size5.size2,
+.katex .sizing.reset-size5.size2 {
+ font-size: .6666666667em;
+}
+.katex .fontsize-ensurer.reset-size5.size3,
+.katex .sizing.reset-size5.size3 {
+ font-size: .7777777778em;
+}
+.katex .fontsize-ensurer.reset-size5.size4,
+.katex .sizing.reset-size5.size4 {
+ font-size: .8888888889em;
+}
+.katex .fontsize-ensurer.reset-size5.size5,
+.katex .sizing.reset-size5.size5 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size5.size6,
+.katex .sizing.reset-size5.size6 {
+ font-size: 1.1111111111em;
+}
+.katex .fontsize-ensurer.reset-size5.size7,
+.katex .sizing.reset-size5.size7 {
+ font-size: 1.3333333333em;
+}
+.katex .fontsize-ensurer.reset-size5.size8,
+.katex .sizing.reset-size5.size8 {
+ font-size: 1.6em;
+}
+.katex .fontsize-ensurer.reset-size5.size9,
+.katex .sizing.reset-size5.size9 {
+ font-size: 1.92em;
+}
+.katex .fontsize-ensurer.reset-size5.size10,
+.katex .sizing.reset-size5.size10 {
+ font-size: 2.3044444444em;
+}
+.katex .fontsize-ensurer.reset-size5.size11,
+.katex .sizing.reset-size5.size11 {
+ font-size: 2.7644444444em;
+}
+.katex .fontsize-ensurer.reset-size6.size1,
+.katex .sizing.reset-size6.size1 {
+ font-size: .5em;
+}
+.katex .fontsize-ensurer.reset-size6.size2,
+.katex .sizing.reset-size6.size2 {
+ font-size: .6em;
+}
+.katex .fontsize-ensurer.reset-size6.size3,
+.katex .sizing.reset-size6.size3 {
+ font-size: .7em;
+}
+.katex .fontsize-ensurer.reset-size6.size4,
+.katex .sizing.reset-size6.size4 {
+ font-size: .8em;
+}
+.katex .fontsize-ensurer.reset-size6.size5,
+.katex .sizing.reset-size6.size5 {
+ font-size: .9em;
+}
+.katex .fontsize-ensurer.reset-size6.size6,
+.katex .sizing.reset-size6.size6 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size6.size7,
+.katex .sizing.reset-size6.size7 {
+ font-size: 1.2em;
+}
+.katex .fontsize-ensurer.reset-size6.size8,
+.katex .sizing.reset-size6.size8 {
+ font-size: 1.44em;
+}
+.katex .fontsize-ensurer.reset-size6.size9,
+.katex .sizing.reset-size6.size9 {
+ font-size: 1.728em;
+}
+.katex .fontsize-ensurer.reset-size6.size10,
+.katex .sizing.reset-size6.size10 {
+ font-size: 2.074em;
+}
+.katex .fontsize-ensurer.reset-size6.size11,
+.katex .sizing.reset-size6.size11 {
+ font-size: 2.488em;
+}
+.katex .fontsize-ensurer.reset-size7.size1,
+.katex .sizing.reset-size7.size1 {
+ font-size: .4166666667em;
+}
+.katex .fontsize-ensurer.reset-size7.size2,
+.katex .sizing.reset-size7.size2 {
+ font-size: .5em;
+}
+.katex .fontsize-ensurer.reset-size7.size3,
+.katex .sizing.reset-size7.size3 {
+ font-size: .5833333333em;
+}
+.katex .fontsize-ensurer.reset-size7.size4,
+.katex .sizing.reset-size7.size4 {
+ font-size: .6666666667em;
+}
+.katex .fontsize-ensurer.reset-size7.size5,
+.katex .sizing.reset-size7.size5 {
+ font-size: .75em;
+}
+.katex .fontsize-ensurer.reset-size7.size6,
+.katex .sizing.reset-size7.size6 {
+ font-size: .8333333333em;
+}
+.katex .fontsize-ensurer.reset-size7.size7,
+.katex .sizing.reset-size7.size7 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size7.size8,
+.katex .sizing.reset-size7.size8 {
+ font-size: 1.2em;
+}
+.katex .fontsize-ensurer.reset-size7.size9,
+.katex .sizing.reset-size7.size9 {
+ font-size: 1.44em;
+}
+.katex .fontsize-ensurer.reset-size7.size10,
+.katex .sizing.reset-size7.size10 {
+ font-size: 1.7283333333em;
+}
+.katex .fontsize-ensurer.reset-size7.size11,
+.katex .sizing.reset-size7.size11 {
+ font-size: 2.0733333333em;
+}
+.katex .fontsize-ensurer.reset-size8.size1,
+.katex .sizing.reset-size8.size1 {
+ font-size: .3472222222em;
+}
+.katex .fontsize-ensurer.reset-size8.size2,
+.katex .sizing.reset-size8.size2 {
+ font-size: .4166666667em;
+}
+.katex .fontsize-ensurer.reset-size8.size3,
+.katex .sizing.reset-size8.size3 {
+ font-size: .4861111111em;
+}
+.katex .fontsize-ensurer.reset-size8.size4,
+.katex .sizing.reset-size8.size4 {
+ font-size: .5555555556em;
+}
+.katex .fontsize-ensurer.reset-size8.size5,
+.katex .sizing.reset-size8.size5 {
+ font-size: .625em;
+}
+.katex .fontsize-ensurer.reset-size8.size6,
+.katex .sizing.reset-size8.size6 {
+ font-size: .6944444444em;
+}
+.katex .fontsize-ensurer.reset-size8.size7,
+.katex .sizing.reset-size8.size7 {
+ font-size: .8333333333em;
+}
+.katex .fontsize-ensurer.reset-size8.size8,
+.katex .sizing.reset-size8.size8 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size8.size9,
+.katex .sizing.reset-size8.size9 {
+ font-size: 1.2em;
+}
+.katex .fontsize-ensurer.reset-size8.size10,
+.katex .sizing.reset-size8.size10 {
+ font-size: 1.4402777778em;
+}
+.katex .fontsize-ensurer.reset-size8.size11,
+.katex .sizing.reset-size8.size11 {
+ font-size: 1.7277777778em;
+}
+.katex .fontsize-ensurer.reset-size9.size1,
+.katex .sizing.reset-size9.size1 {
+ font-size: .2893518519em;
+}
+.katex .fontsize-ensurer.reset-size9.size2,
+.katex .sizing.reset-size9.size2 {
+ font-size: .3472222222em;
+}
+.katex .fontsize-ensurer.reset-size9.size3,
+.katex .sizing.reset-size9.size3 {
+ font-size: .4050925926em;
+}
+.katex .fontsize-ensurer.reset-size9.size4,
+.katex .sizing.reset-size9.size4 {
+ font-size: .462962963em;
+}
+.katex .fontsize-ensurer.reset-size9.size5,
+.katex .sizing.reset-size9.size5 {
+ font-size: .5208333333em;
+}
+.katex .fontsize-ensurer.reset-size9.size6,
+.katex .sizing.reset-size9.size6 {
+ font-size: .5787037037em;
+}
+.katex .fontsize-ensurer.reset-size9.size7,
+.katex .sizing.reset-size9.size7 {
+ font-size: .6944444444em;
+}
+.katex .fontsize-ensurer.reset-size9.size8,
+.katex .sizing.reset-size9.size8 {
+ font-size: .8333333333em;
+}
+.katex .fontsize-ensurer.reset-size9.size9,
+.katex .sizing.reset-size9.size9 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size9.size10,
+.katex .sizing.reset-size9.size10 {
+ font-size: 1.2002314815em;
+}
+.katex .fontsize-ensurer.reset-size9.size11,
+.katex .sizing.reset-size9.size11 {
+ font-size: 1.4398148148em;
+}
+.katex .fontsize-ensurer.reset-size10.size1,
+.katex .sizing.reset-size10.size1 {
+ font-size: .2410800386em;
+}
+.katex .fontsize-ensurer.reset-size10.size2,
+.katex .sizing.reset-size10.size2 {
+ font-size: .2892960463em;
+}
+.katex .fontsize-ensurer.reset-size10.size3,
+.katex .sizing.reset-size10.size3 {
+ font-size: .337512054em;
+}
+.katex .fontsize-ensurer.reset-size10.size4,
+.katex .sizing.reset-size10.size4 {
+ font-size: .3857280617em;
+}
+.katex .fontsize-ensurer.reset-size10.size5,
+.katex .sizing.reset-size10.size5 {
+ font-size: .4339440694em;
+}
+.katex .fontsize-ensurer.reset-size10.size6,
+.katex .sizing.reset-size10.size6 {
+ font-size: .4821600771em;
+}
+.katex .fontsize-ensurer.reset-size10.size7,
+.katex .sizing.reset-size10.size7 {
+ font-size: .5785920926em;
+}
+.katex .fontsize-ensurer.reset-size10.size8,
+.katex .sizing.reset-size10.size8 {
+ font-size: .6943105111em;
+}
+.katex .fontsize-ensurer.reset-size10.size9,
+.katex .sizing.reset-size10.size9 {
+ font-size: .8331726133em;
+}
+.katex .fontsize-ensurer.reset-size10.size10,
+.katex .sizing.reset-size10.size10 {
+ font-size: 1em;
+}
+.katex .fontsize-ensurer.reset-size10.size11,
+.katex .sizing.reset-size10.size11 {
+ font-size: 1.1996142719em;
+}
+.katex .fontsize-ensurer.reset-size11.size1,
+.katex .sizing.reset-size11.size1 {
+ font-size: .2009646302em;
+}
+.katex .fontsize-ensurer.reset-size11.size2,
+.katex .sizing.reset-size11.size2 {
+ font-size: .2411575563em;
+}
+.katex .fontsize-ensurer.reset-size11.size3,
+.katex .sizing.reset-size11.size3 {
+ font-size: .2813504823em;
+}
+.katex .fontsize-ensurer.reset-size11.size4,
+.katex .sizing.reset-size11.size4 {
+ font-size: .3215434084em;
+}
+.katex .fontsize-ensurer.reset-size11.size5,
+.katex .sizing.reset-size11.size5 {
+ font-size: .3617363344em;
+}
+.katex .fontsize-ensurer.reset-size11.size6,
+.katex .sizing.reset-size11.size6 {
+ font-size: .4019292605em;
+}
+.katex .fontsize-ensurer.reset-size11.size7,
+.katex .sizing.reset-size11.size7 {
+ font-size: .4823151125em;
+}
+.katex .fontsize-ensurer.reset-size11.size8,
+.katex .sizing.reset-size11.size8 {
+ font-size: .578778135em;
+}
+.katex .fontsize-ensurer.reset-size11.size9,
+.katex .sizing.reset-size11.size9 {
+ font-size: .6945337621em;
+}
+.katex .fontsize-ensurer.reset-size11.size10,
+.katex .sizing.reset-size11.size10 {
+ font-size: .8336012862em;
+}
+.katex .fontsize-ensurer.reset-size11.size11,
+.katex .sizing.reset-size11.size11 {
+ font-size: 1em;
+}
+.katex .delimsizing.size1 {
+ font-family: KaTeX_Size1;
+}
+.katex .delimsizing.size2 {
+ font-family: KaTeX_Size2;
+}
+.katex .delimsizing.size3 {
+ font-family: KaTeX_Size3;
+}
+.katex .delimsizing.size4 {
+ font-family: KaTeX_Size4;
+}
+.katex .delimsizing.mult .delim-size1 > span {
+ font-family: KaTeX_Size1;
+}
+.katex .delimsizing.mult .delim-size4 > span {
+ font-family: KaTeX_Size4;
+}
+.katex .nulldelimiter {
+ display: inline-block;
+ width: .12em;
+}
+.katex .delimcenter,
+.katex .op-symbol {
+ position: relative;
+}
+.katex .op-symbol.small-op {
+ font-family: KaTeX_Size1;
+}
+.katex .op-symbol.large-op {
+ font-family: KaTeX_Size2;
+}
+.katex .accent > .vlist-t,
+.katex .op-limits > .vlist-t {
+ text-align: center;
+}
+.katex .accent .accent-body {
+ position: relative;
+}
+.katex .accent .accent-body:not(.accent-full) {
+ width: 0;
+}
+.katex .overlay {
+ display: block;
+}
+.katex .mtable .vertical-separator {
+ display: inline-block;
+ min-width: 1px;
+}
+.katex .mtable .arraycolsep {
+ display: inline-block;
+}
+.katex .mtable .col-align-c > .vlist-t {
+ text-align: center;
+}
+.katex .mtable .col-align-l > .vlist-t {
+ text-align: left;
+}
+.katex .mtable .col-align-r > .vlist-t {
+ text-align: right;
+}
+.katex .svg-align {
+ text-align: left;
+}
+.katex svg {
+ fill: currentColor;
+ stroke: currentColor;
+ fill-rule: nonzero;
+ fill-opacity: 1;
+ stroke-width: 1;
+ stroke-linecap: butt;
+ stroke-linejoin: miter;
+ stroke-miterlimit: 4;
+ stroke-dasharray: none;
+ stroke-dashoffset: 0;
+ stroke-opacity: 1;
+ display: block;
+ height: inherit;
+ position: absolute;
+ width: 100%;
+}
+.katex svg path {
+ stroke: none;
+}
+.katex img {
+ border-style: none;
+ max-height: none;
+ max-width: none;
+ min-height: 0;
+ min-width: 0;
+}
+.katex .stretchy {
+ display: block;
+ overflow: hidden;
+ position: relative;
+ width: 100%;
+}
+.katex .stretchy:after,
+.katex .stretchy:before {
+ content: "";
+}
+.katex .hide-tail {
+ overflow: hidden;
+ position: relative;
+ width: 100%;
+}
+.katex .halfarrow-left {
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ width: 50.2%;
+}
+.katex .halfarrow-right {
+ overflow: hidden;
+ position: absolute;
+ right: 0;
+ width: 50.2%;
+}
+.katex .brace-left {
+ left: 0;
+ overflow: hidden;
+ position: absolute;
+ width: 25.1%;
+}
+.katex .brace-center {
+ left: 25%;
+ overflow: hidden;
+ position: absolute;
+ width: 50%;
+}
+.katex .brace-right {
+ overflow: hidden;
+ position: absolute;
+ right: 0;
+ width: 25.1%;
+}
+.katex .x-arrow-pad {
+ padding: 0 .5em;
+}
+.katex .cd-arrow-pad {
+ padding: 0 .55556em 0 .27778em;
+}
+.katex .mover,
+.katex .munder,
+.katex .x-arrow {
+ text-align: center;
+}
+.katex .boxpad {
+ padding: 0 .3em;
+}
+.katex .fbox,
+.katex .fcolorbox {
+ border: .04em solid;
+ box-sizing: border-box;
+}
+.katex .cancel-pad {
+ padding: 0 .2em;
+}
+.katex .cancel-lap {
+ margin-left: -.2em;
+ margin-right: -.2em;
+}
+.katex .sout {
+ border-bottom-style: solid;
+ border-bottom-width: .08em;
+}
+.katex .angl {
+ border-right: .049em solid;
+ border-top: .049em solid;
+ box-sizing: border-box;
+ margin-right: .03889em;
+}
+.katex .anglpad {
+ padding: 0 .03889em;
+}
+.katex .eqn-num:before {
+ content: "(" counter(katexEqnNo) ")";
+ counter-increment: katexEqnNo;
+}
+.katex .mml-eqn-num:before {
+ content: "(" counter(mmlEqnNo) ")";
+ counter-increment: mmlEqnNo;
+}
+.katex .mtr-glue {
+ width: 50%;
+}
+.katex .cd-vert-arrow {
+ display: inline-block;
+ position: relative;
+}
+.katex .cd-label-left {
+ display: inline-block;
+ position: absolute;
+ right: calc(50% + .3em);
+ text-align: left;
+}
+.katex .cd-label-right {
+ display: inline-block;
+ left: calc(50% + .3em);
+ position: absolute;
+ text-align: right;
+}
+.katex-display {
+ display: block;
+ margin: 1em 0;
+ text-align: center;
+}
+.katex-display > .katex {
+ display: block;
+ text-align: center;
+ white-space: nowrap;
+}
+.katex-display > .katex > .katex-html {
+ display: block;
+ position: relative;
+}
+.katex-display > .katex > .katex-html > .tag {
+ position: absolute;
+ right: 0;
+}
+.katex-display.leqno > .katex > .katex-html > .tag {
+ left: 0;
+ right: auto;
+}
+.katex-display.fleqn > .katex {
+ padding-left: 2em;
+ text-align: left;
+}
+body {
+ counter-reset: katexEqnNo mmlEqnNo;
+}
+.milkdown span[data-type="math_inline"] {
+ padding: 0 4px;
+ display: inline-block;
+ vertical-align: bottom;
+ color: var(--crepe-color-primary);
+}
+.milkdown .milkdown-latex-inline-edit[data-show="false"] {
+ display: none;
+}
+.milkdown .milkdown-latex-inline-edit {
+ position: absolute;
+ background: var(--crepe-color-surface);
+ box-shadow: var(--crepe-shadow-1);
+ border-radius: 8px;
+ padding: 2px 6px 2px 12px;
+}
+.milkdown .milkdown-latex-inline-edit .container {
+ display: flex;
+ gap: 6px;
+ align-items: flex-start;
+}
+.milkdown .milkdown-latex-inline-edit .container button {
+ width: 24px;
+ height: 24px;
+ cursor: pointer;
+ border-radius: 8px;
+}
+.milkdown .milkdown-latex-inline-edit .container button:hover {
+ background: var(--crepe-color-hover);
+}
+.milkdown .milkdown-latex-inline-edit .ProseMirror {
+ padding: 0;
+ min-width: 174px;
+ max-width: 294px;
+ font-family: var(--crepe-font-code);
+}
+
+/*!***************************************************************************************************************************************************************************************************************************************************************************************************************!*\
+ !*** css ../../node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[2]!../../node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[13].oneOf[10].use[3]!../../node_modules/@milkdown/crepe/lib/theme/nord/style.css ***!
+ \***************************************************************************************************************************************************************************************************************************************************************************************************************/
+/*! tailwindcss v4.1.4 | MIT License | https://tailwindcss.com */
+.milkdown {
+ position: relative;
+}
+.milkdown * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+.milkdown button,
+.milkdown input {
+ border: none;
+ background: none;
+ box-shadow: none;
+}
+.milkdown button:focus,
+.milkdown input:focus {
+ outline: none;
+}
+.milkdown :focus-visible {
+ outline: none;
+}
+.milkdown {
+ font-family: var(--crepe-font-default);
+ color: var(--crepe-color-on-background);
+ background: var(--crepe-color-background);
+}
+.milkdown .milkdown-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+.milkdown .ProseMirror-focused {
+ outline: none;
+}
+.milkdown .ProseMirror {
+ padding: 60px 120px;
+}
+.milkdown .ProseMirror *::-moz-selection {
+ background: var(--crepe-color-selected);
+}
+.milkdown .ProseMirror *::selection {
+ background: var(--crepe-color-selected);
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode {
+ background: var(--crepe-color-selected);
+ outline: none;
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode ::-moz-selection {
+ background: transparent;
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode ::selection {
+ background: transparent;
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode::-moz-selection {
+ background: transparent;
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode::selection {
+ background: transparent;
+}
+.milkdown .ProseMirror li.ProseMirror-selectednode:after {
+ all: unset;
+}
+.milkdown .ProseMirror .ProseMirror-selectednode {
+ background: var(--crepe-color-selected);
+ outline: none;
+ background: var(--crepe-color-selected);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(in srgb, var(--crepe-color-selected), transparent 60%);
+ }
+}
+.milkdown .ProseMirror .ProseMirror-selectednode ::-moz-selection {
+ background: transparent;
+}
+.milkdown .ProseMirror .ProseMirror-selectednode ::selection {
+ background: transparent;
+}
+.milkdown .ProseMirror .ProseMirror-selectednode::-moz-selection {
+ background: transparent;
+}
+.milkdown .ProseMirror .ProseMirror-selectednode::selection {
+ background: transparent;
+}
+.milkdown .ProseMirror[data-dragging="true"]::-moz-selection,
+.milkdown .ProseMirror[data-dragging="true"] *::-moz-selection {
+ background: transparent;
+}
+.milkdown .ProseMirror[data-dragging="true"] .ProseMirror-selectednode,
+.milkdown .ProseMirror[data-dragging="true"]::selection,
+.milkdown .ProseMirror[data-dragging="true"] *::selection {
+ background: transparent;
+}
+.milkdown .ProseMirror[data-dragging="true"] input::-moz-selection {
+ background: var(--crepe-color-selected);
+}
+.milkdown .ProseMirror[data-dragging="true"] input::selection {
+ background: var(--crepe-color-selected);
+}
+.milkdown .ProseMirror img {
+ vertical-align: bottom;
+ max-width: 100%;
+}
+.milkdown .ProseMirror img.ProseMirror-selectednode {
+ background: none;
+ outline: 2px solid var(--crepe-color-primary);
+}
+.milkdown .ProseMirror h1,
+.milkdown .ProseMirror h2,
+.milkdown .ProseMirror h3,
+.milkdown .ProseMirror h4,
+.milkdown .ProseMirror h5,
+.milkdown .ProseMirror h6 {
+ font-family: var(--crepe-font-title);
+ font-weight: 400;
+ padding: 2px 0;
+}
+.milkdown .ProseMirror h1 {
+ font-size: 42px;
+ line-height: 50px;
+ margin-top: 32px;
+}
+.milkdown .ProseMirror h2 {
+ font-size: 36px;
+ line-height: 44px;
+ margin-top: 28px;
+}
+.milkdown .ProseMirror h3 {
+ font-size: 32px;
+ line-height: 40px;
+ margin-top: 24px;
+}
+.milkdown .ProseMirror h4 {
+ font-size: 28px;
+ line-height: 36px;
+ margin-top: 20px;
+}
+.milkdown .ProseMirror h5 {
+ font-size: 24px;
+ line-height: 32px;
+ margin-top: 16px;
+}
+.milkdown .ProseMirror h6 {
+ font-size: 18px;
+ font-weight: 700;
+ line-height: 28px;
+ margin-top: 16px;
+}
+.milkdown .ProseMirror p {
+ font-size: 16px;
+ line-height: 24px;
+ padding: 4px 0;
+}
+.milkdown .ProseMirror code {
+ color: var(--crepe-color-inline-code);
+ background: var(--crepe-color-inline-area);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(
+ in srgb,
+ var(--crepe-color-inline-area),
+ transparent 40%
+ );
+ }
+ font-family: var(--crepe-font-code);
+ padding: 0 2px;
+ border-radius: 4px;
+ font-size: 87.5%;
+ display: inline-block;
+ line-height: 1.4286;
+}
+.milkdown .ProseMirror a {
+ color: var(--crepe-color-primary);
+ text-decoration: underline;
+}
+.milkdown .ProseMirror pre {
+ background: var(--crepe-color-inline-area);
+ @supports (color: color-mix(in lab, red, red)) {
+ background: color-mix(
+ in srgb,
+ var(--crepe-color-inline-area),
+ transparent 40%
+ );
+ }
+ padding: 10px;
+ border-radius: 4px;
+}
+.milkdown .ProseMirror pre code {
+ padding: 0;
+ background: transparent;
+}
+.milkdown .ProseMirror blockquote {
+ position: relative;
+ padding-left: 40px;
+ padding-top: 0;
+ padding-bottom: 0;
+ box-sizing: content-box;
+ margin: 4px 0;
+}
+.milkdown .ProseMirror blockquote::before {
+ content: "";
+ width: 4px;
+ left: 0;
+ top: 4px;
+ bottom: 4px;
+ position: absolute;
+ background: var(--crepe-color-selected);
+ border-radius: 100px;
+}
+.milkdown .ProseMirror blockquote hr {
+ margin-bottom: 16px;
+}
+.milkdown .ProseMirror hr {
+ border: none;
+ background-color: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background-color: color-mix(
+ in srgb,
+ var(--crepe-color-outline),
+ transparent 80%
+ );
+ }
+ background-clip: content-box;
+ padding: 6px 0;
+ height: 13px;
+ position: relative;
+}
+.milkdown .ProseMirror hr.ProseMirror-selectednode {
+ outline: none;
+ background-color: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background-color: color-mix(
+ in srgb,
+ var(--crepe-color-outline),
+ transparent 20%
+ );
+ }
+ background-clip: content-box;
+}
+.milkdown .ProseMirror hr.ProseMirror-selectednode::before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ background-color: var(--crepe-color-outline);
+ @supports (color: color-mix(in lab, red, red)) {
+ background-color: color-mix(
+ in srgb,
+ var(--crepe-color-outline),
+ transparent 80%
+ );
+ }
+ pointer-events: none;
+}
+.milkdown .ProseMirror ul,
+.milkdown .ProseMirror ol {
+ padding: 0;
+}
diff --git a/apps/www/src/components/feat/server-page/server-editor/server-dark-provider.tsx b/apps/www/src/components/feat/server-page/server-editor/server-dark-provider.tsx
deleted file mode 100644
index d233ac3..0000000
--- a/apps/www/src/components/feat/server-page/server-editor/server-dark-provider.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * MHSF, Minehut Server List
- * All external content is rather licensed under the ECA Agreement
- * located here: https://mhsf.app/docs/legal/external-content-agreement
- *
- * All code under MHSF is licensed under the MIT License
- * by open source contributors
- *
- * Copyright (c) 2025 dvelo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-import '@milkdown/crepe/theme/nord-dark.css';
-import type { ReactNode } from 'react';
-
-export function ServerDescriptionDarkProvider({children}: {children: ReactNode}) {
- return children;
-}
\ No newline at end of file
diff --git a/apps/www/src/components/feat/server-page/server-editor/server-editor-description.tsx b/apps/www/src/components/feat/server-page/server-editor/server-editor-description.tsx
index dbeca36..48e0522 100644
--- a/apps/www/src/components/feat/server-page/server-editor/server-editor-description.tsx
+++ b/apps/www/src/components/feat/server-page/server-editor/server-editor-description.tsx
@@ -31,23 +31,26 @@
import { listenerCtx } from "@milkdown/kit/plugin/listener";
import { Crepe } from "@milkdown/crepe";
import { useEditor, type EditorInfoCtx, Milkdown } from "@milkdown/react";
-
+import { vscodeDark, vscodeDarkInit } from '@uiw/codemirror-theme-vscode';
import "@milkdown/crepe/theme/common/style.css";
+import "@fontsource/jetbrains-mono";
import { createContext } from "react";
import { Spinner } from "@/components/ui/spinner";
-import { ServerDescriptionLightProvider } from "./server-light-provider";
import { useTheme } from "@/lib/hooks/use-theme";
-import { ServerDescriptionDarkProvider } from "./server-dark-provider";
export function ServerEditorDescription({
defaultMarkdown,
onUpdate,
}: { defaultMarkdown: string; onUpdate?: (update: string) => void }) {
- const { resolvedTheme } = useTheme();
const { loading } = useEditor((root) => {
const crepe = new Crepe({
root,
defaultValue: defaultMarkdown,
+ featureConfigs: { [Crepe.Feature.Toolbar]: {
+ latexIcon: undefined
+ }, [Crepe.Feature.CodeMirror]: {
+ theme: vscodeDark
+ }}
});
crepe.editor.config(async (ctx) => {
ctx.get(listenerCtx).markdownUpdated((_, markdown) => {
@@ -58,7 +61,7 @@ export function ServerEditorDescription({
}, []);
return (
-
+
{loading && (
@@ -69,15 +72,7 @@ export function ServerEditorDescription({
)}
- {resolvedTheme === "dark" ? (
-
-
-
- ) : (
-
-
-
- )}
+
);
}
diff --git a/apps/www/src/components/feat/server-page/server-editor/server-editor-provider.tsx b/apps/www/src/components/feat/server-page/server-editor/server-editor-provider.tsx
index 10c93bc..619723b 100644
--- a/apps/www/src/components/feat/server-page/server-editor/server-editor-provider.tsx
+++ b/apps/www/src/components/feat/server-page/server-editor/server-editor-provider.tsx
@@ -20,6 +20,11 @@ import type { OnlineServer, ServerResponse } from "@/lib/types/mh-server";
import { useServers } from "@/lib/hooks/use-servers";
import { Alert } from "@/components/ui/alert";
import { toast } from "sonner";
+import { BannerUploaderRouter } from "@/pages/api/v1/server/get/[server]/settings/upload-banner";
+import {
+ generateUploadButton,
+ generateUploadDropzone,
+} from "@uploadthing/react";
const successClasses =
"bg-green-200 border-green-400 dark:bg-green-800 dark:border-green-600";
@@ -53,7 +58,7 @@ export function ServerEditorProvider({
setOnlineData(server);
}
}
- }, [open, loading]);
+ }, [open, loading, servers, minehutData.name]);
useEffect(() => {
(async () => {
@@ -68,13 +73,16 @@ export function ServerEditorProvider({
const requirementTwo = onlineData !== null;
const requirementThree = claimedUser === onlineData?.author;
const requirementFour = claimedUser !== null;
+ const UploadDropzone = generateUploadDropzone
({
+ url: `/api/v1/server/get/${minehutData._id}/settings/upload-banner`,
+ });
return (
<>
{children}
-
+
{!serverData.server?.customizationData.isOwned ? (
@@ -219,7 +227,7 @@ export function ServerEditorProvider({
) : (
<>
{serverData.server?.customizationData.isOwnedByUser ? (
-
+
Server Settings
@@ -235,13 +243,34 @@ export function ServerEditorProvider({
console.log(content)}
-
/>
)}
+
+ Server Banner
+
+ Pick out whatever represents your server best! Images
+ have a limit of 4.5MB, and the prefered aspect ratio for
+ the banner should be 10:4 to look the best on MHSF.
+
+ {
+ console.log("Upload complete response:", res);
+ // Refresh the server data
+ serverData.refresh();
+ toast.success("Banner uploaded successfully!");
+ }}
+ onUploadError={(error: Error) => {
+ console.error("Upload error:", error);
+ toast.error(`Upload failed: ${error.message}`);
+ }}
+ />
+
) : (
{
if (data.length === 0) {
window.dispatchEvent(new Event("update-modification-stack"));
} else setLoading(false);
- }, [data, filteredData.length]);
+ }, [data, filteredData, loading]);
const testModeInit = (type: "filter" | "sort") => {
window.dispatchEvent(new Event("test-mode.enabled"));
diff --git a/apps/www/src/lib/hooks/use-mhsf-server.tsx b/apps/www/src/lib/hooks/use-mhsf-server.tsx
index b11965d..db4322a 100644
--- a/apps/www/src/lib/hooks/use-mhsf-server.tsx
+++ b/apps/www/src/lib/hooks/use-mhsf-server.tsx
@@ -53,6 +53,12 @@ export function useMHSFServer(id: string) {
setServer(json.server);
},
+ refresh: async () => {
+ const response = await fetch("/api/v1/server/get/" + id);
+ const json = await response.json();
+
+ setServer(json.server);
+ },
favoriteServer: async () => {
if (!server)
throw new Error("Server hasn't initialized, cannot continue.");
diff --git a/apps/www/src/middleware.ts b/apps/www/src/middleware.ts
index 2f22131..c1a1189 100644
--- a/apps/www/src/middleware.ts
+++ b/apps/www/src/middleware.ts
@@ -47,6 +47,8 @@ const isWaitlistPage = createRouteMatcher(["/waitlist", "/waitlist(.*)"]);
const apiWaitlistPage = createRouteMatcher([
"/api/v1/user/waitlist(.*)",
"/api/v1/get-status",
+ // Required by UploadThing (okay fine Theo!)
+ "/api/v1/server/get/:serverId/settings/upload-banner"
]);
export default process.env.NEXT_PUBLIC_IS_AUTH === "true"
diff --git a/apps/www/src/pages/api/v1/server/get/[server]/index.ts b/apps/www/src/pages/api/v1/server/get/[server]/index.ts
index c585c8d..c158d89 100644
--- a/apps/www/src/pages/api/v1/server/get/[server]/index.ts
+++ b/apps/www/src/pages/api/v1/server/get/[server]/index.ts
@@ -275,7 +275,7 @@ async function fetchHistoryData(
return await cursor.toArray();
}
-async function findServerData(
+export async function findServerData(
server: string,
): Promise<{ exists: boolean; name: string }> {
try {
diff --git a/apps/www/src/pages/api/v1/server/get/[server]/settings/upload-banner.ts b/apps/www/src/pages/api/v1/server/get/[server]/settings/upload-banner.ts
new file mode 100644
index 0000000..ce5e094
--- /dev/null
+++ b/apps/www/src/pages/api/v1/server/get/[server]/settings/upload-banner.ts
@@ -0,0 +1,125 @@
+/*
+ * MHSF, Minehut Server List
+ * All external content is rather licensed under the ECA Agreement
+ * located here: https://mhsf.app/docs/legal/external-content-agreement
+ *
+ * All code under MHSF is licensed under the MIT License
+ * by open source contributors
+ *
+ * Copyright (c) 2025 dvelo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+import { getAuth } from "@clerk/nextjs/server";
+import {
+ createRouteHandler,
+ createUploadthing,
+ type FileRouter,
+} from "uploadthing/next-legacy";
+import { UploadThingError } from "uploadthing/server";
+import { findServerData } from "..";
+import { MongoClient } from "mongodb";
+import type { FileRoute } from "uploadthing/types";
+import type { Json } from "@uploadthing/shared";
+
+const f = createUploadthing();
+
+export default createRouteHandler({
+ router: {
+ imageUploader: f({
+ image: {
+ maxFileSize: "4MB",
+ maxFileCount: 1,
+ },
+ })
+ // Set permissions and file types for this FileRoute
+ .middleware(async ({ req, res }) => {
+ // Step 1: Check authentication
+ const { userId } = getAuth(req);
+
+ if (!userId) throw new UploadThingError("Unauthorized");
+
+ // Step 2: Check server
+ const { server } = req.query;
+ const serverData = await findServerData(server as string);
+ const mongoClient = new MongoClient(process.env.MONGO_DB as string);
+
+ try {
+ if (!serverData.exists) throw new UploadThingError("Server doesn't exist");
+ await mongoClient.connect();
+
+ const db = mongoClient.db(process.env.CUSTOM_MONGO_DB ?? "mhsf");
+ const ownedServer = await db.collection("owned-servers").findOne({ $or: [{ serverId: server }, { server: serverData.name }] });
+ if (!ownedServer) throw new UploadThingError("Server not linked");
+ if (ownedServer.author !== userId) throw new UploadThingError("You don't own this server.");
+
+ return {
+ userId,
+ ownedServer,
+ serverId: server,
+ serverName: serverData.name
+ };
+ } finally {
+ await mongoClient.close();
+ }
+ })
+ .onUploadComplete(async ({ metadata, file }) => {
+ // This code RUNS ON YOUR SERVER after upload
+ console.log("Upload complete for userId:", metadata.userId);
+ console.log("file url", file.ufsUrl);
+ console.log("metadata:", metadata);
+
+ // Update the server's customization data with the new banner URL
+ const mongoClient = new MongoClient(process.env.MONGO_DB as string);
+ try {
+ await mongoClient.connect();
+ const db = mongoClient.db(process.env.CUSTOM_MONGO_DB ?? "mhsf");
+
+ // Update or insert the customization data
+ const result = await db.collection("customization").updateOne(
+ { $or: [{ serverId: metadata.serverId }, { server: metadata.serverName }] },
+ { $set: { banner: file.ufsUrl } },
+ { upsert: true }
+ );
+
+ console.log("Database update result:", result);
+
+ // !!! Whatever is returned here is sent to the clientside `onClientUploadComplete` callback
+ return { uploadedBy: metadata.userId };
+ } catch (error) {
+ console.error("Error updating database:", error);
+ throw error;
+ } finally {
+ await mongoClient.close();
+ }
+ }),
+ },
+});
+
+export type BannerUploaderRouter = {
+ imageUploader: FileRoute<{
+ input: undefined;
+ output: {
+ uploadedBy: string;
+ };
+ errorShape: Json;
+ }>;
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 18c153f..3d239be 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -825,6 +825,15 @@
resolved "https://registry.yarnpkg.com/@effect-ts/system/-/system-0.57.5.tgz#921e9b39dcea2d1728e0f49a0af233472efdc6cb"
integrity sha512-/crHGujo0xnuHIYNc1VgP0HGJGFSoSqq88JFXe6FmFyXPpWt8Xu39LyLg7rchsxfXFeEdA9CrIZvLV5eswXV5g==
+"@effect/platform@0.81.0":
+ version "0.81.0"
+ resolved "https://registry.yarnpkg.com/@effect/platform/-/platform-0.81.0.tgz#da91e8ecaa157e02383dba9b97b1a592a7d3b485"
+ integrity sha512-RZ0pqpSUET0Ab3CBjOhJ12C2/vWLQsy+SLJbGNxjcOm9xZAwQowggWCs4S3ZXhdnNTR5WJHH02WlAWHJDaMKhA==
+ dependencies:
+ find-my-way-ts "^0.1.5"
+ msgpackr "^1.11.2"
+ multipasta "^0.2.5"
+
"@emnapi/core@^1.4.0":
version "1.4.3"
resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.4.3.tgz#9ac52d2d5aea958f67e52c40a065f51de59b77d6"
@@ -1357,6 +1366,11 @@
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429"
integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
+"@fontsource/jetbrains-mono@^5.2.5":
+ version "5.2.5"
+ resolved "https://registry.yarnpkg.com/@fontsource/jetbrains-mono/-/jetbrains-mono-5.2.5.tgz#c3e9931ae7ebd70b25b6aaf98caf5c2720aaffb3"
+ integrity sha512-TPZ9b/uq38RMdrlZZkl0RwN8Ju9JxuqMETrw76pUQFbGtE1QbwQaNsLlnUrACNNBNbd0NZRXiJJSkC8ajPgbew==
+
"@graphql-typed-document-node/core@^3.1.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861"
@@ -2704,6 +2718,36 @@
dependencies:
sparse-bitfield "^3.0.3"
+"@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz#9edec61b22c3082018a79f6d1c30289ddf3d9d11"
+ integrity sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==
+
+"@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz#33677a275204898ad8acbf62734fc4dc0b6a4855"
+ integrity sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==
+
+"@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz#19edf7cdc2e7063ee328403c1d895a86dd28f4bb"
+ integrity sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==
+
+"@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz#94fb0543ba2e28766c3fc439cabbe0440ae70159"
+ integrity sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==
+
+"@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz#4a0609ab5fe44d07c9c60a11e4484d3c38bbd6e3"
+ integrity sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==
+
+"@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz#0aa5502d547b57abfc4ac492de68e2006e417242"
+ integrity sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==
+
"@napi-rs/wasm-runtime@^0.2.8", "@napi-rs/wasm-runtime@^0.2.9":
version "0.2.9"
resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.9.tgz#7278122cf94f3b36d8170a8eee7d85356dfa6a96"
@@ -4280,6 +4324,16 @@
resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2"
integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==
+"@standard-schema/spec@1.0.0-beta.4":
+ version "1.0.0-beta.4"
+ resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0-beta.4.tgz#62f520109add3eb016004098363bfee0678dd1ec"
+ integrity sha512-d3IxtzLo7P1oZ8s8YNvxzBUXRXojSut8pbPrTYtzsc5sn4+53jVqbk66pQerSZbZSJZQux6LkclB/+8IDordHg==
+
+"@standard-schema/spec@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c"
+ integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==
+
"@stoplight/better-ajv-errors@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz#d74a5c4da5d786c17188d7f4edec505f089885fa"
@@ -5179,6 +5233,22 @@
"@typescript-eslint/types" "8.31.0"
eslint-visitor-keys "^4.2.0"
+"@uiw/codemirror-theme-vscode@^4.23.12":
+ version "4.23.12"
+ resolved "https://registry.yarnpkg.com/@uiw/codemirror-theme-vscode/-/codemirror-theme-vscode-4.23.12.tgz#564bd3d39743d370d0f0513b6e14e87bf48c724f"
+ integrity sha512-ePBaUQiixrpmSoZJWCGXUStKmcM8G0VBv3UqwPR+kNGBjqDife76Gbhv77izSeEI3zRPzL+683BOdclkvWnsMg==
+ dependencies:
+ "@uiw/codemirror-themes" "4.23.12"
+
+"@uiw/codemirror-themes@4.23.12":
+ version "4.23.12"
+ resolved "https://registry.yarnpkg.com/@uiw/codemirror-themes/-/codemirror-themes-4.23.12.tgz#9afbf8b3f7c403fa06cbd264762fd267f982548b"
+ integrity sha512-8etEByfS9yttFZW0rcWhdZc7/JXJKRWlU5lHmJCI3GydZNGCzydNA+HtK9nWKpJUndVc58Q2sqSC5OIcwq8y6A==
+ dependencies:
+ "@codemirror/language" "^6.0.0"
+ "@codemirror/state" "^6.0.0"
+ "@codemirror/view" "^6.0.0"
+
"@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8"
@@ -5384,6 +5454,28 @@
resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.6.3.tgz#841f71e6d01b4439f88178c0f571be46c0138620"
integrity sha512-n33drkd84G5Mu2BkUGawZXmm+IFPuRv7GpODfwEBs/CzZq2+BIZyAZmb03H9IgNbd7xaohZbtZ4/9Gb0xo5ssw==
+"@uploadthing/mime-types@0.3.5":
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/@uploadthing/mime-types/-/mime-types-0.3.5.tgz#6a4ed43ff9ac42d10203b15ea6d4090f0a87d413"
+ integrity sha512-iYOmod80XXOSe4NVvaUG9FsS91YGPUaJMTBj52Nwu0G2aTzEN6Xcl0mG1rWqXJ4NUH8MzjVqg+tQND5TPkJWhg==
+
+"@uploadthing/react@^7.3.1":
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/@uploadthing/react/-/react-7.3.1.tgz#c720dd1cb9210427fde9280d59456079e8fbfe3a"
+ integrity sha512-yIAFw46ZO/NPb74zpomwn6Hf2ZX/Ws+vNlR4oKNLJ7YtJ+/bqERclzC3xnRVi/pT47ctISlqXQFGiXUn85wg5Q==
+ dependencies:
+ "@uploadthing/shared" "7.1.8"
+ file-selector "0.6.0"
+
+"@uploadthing/shared@7.1.8":
+ version "7.1.8"
+ resolved "https://registry.yarnpkg.com/@uploadthing/shared/-/shared-7.1.8.tgz#5e34a270285badf6f53f4d9c033854eae2df0a18"
+ integrity sha512-OA9ZrTfILOCt1G93wOD7dZmS653z99Nr3isZpIxzBO3y4B2geKFmPjJUZClig2RrAWLKr2VUYToXKfd9D/wP9w==
+ dependencies:
+ "@uploadthing/mime-types" "0.3.5"
+ effect "3.14.21"
+ sqids "^0.3.0"
+
"@vercel/analytics@^1.3.1":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@vercel/analytics/-/analytics-1.5.0.tgz#073f93694897414b21a8495e2619bbf64447dcaa"
@@ -6831,6 +6923,11 @@ destroy@1.2.0:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
+detect-libc@^2.0.1:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8"
+ integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==
+
detect-libc@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
@@ -7018,6 +7115,14 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
+effect@3.14.21:
+ version "3.14.21"
+ resolved "https://registry.yarnpkg.com/effect/-/effect-3.14.21.tgz#140ebc4ee99aa14cefe11e3aadcff66a12d1692f"
+ integrity sha512-TKR7zfWcuZgEdWd+oIGA8LdREj/c+1Q0wz4pWqQtYT7VHnkW/QQEYCXgrDI5dT6lJgRTgyQAC1bAnpAf6MdjIA==
+ dependencies:
+ "@standard-schema/spec" "^1.0.0"
+ fast-check "^3.23.1"
+
embla-carousel-react@^8.5.2:
version "8.6.0"
resolved "https://registry.yarnpkg.com/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz#b737042a32761c38d6614593653b3ac619477bd1"
@@ -7896,6 +8001,13 @@ extract-zip@^2.0.1:
optionalDependencies:
"@types/yauzl" "^2.9.1"
+fast-check@^3.23.1:
+ version "3.23.2"
+ resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.23.2.tgz#0129f1eb7e4f500f58e8290edc83c670e4a574a2"
+ integrity sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==
+ dependencies:
+ pure-rand "^6.1.0"
+
fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -8020,6 +8132,13 @@ file-entry-cache@^8.0.0:
dependencies:
flat-cache "^4.0.0"
+file-selector@0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
+ integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
+ dependencies:
+ tslib "^2.4.0"
+
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
@@ -8040,6 +8159,11 @@ finalhandler@1.3.1:
statuses "2.0.1"
unpipe "~1.0.0"
+find-my-way-ts@^0.1.5:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/find-my-way-ts/-/find-my-way-ts-0.1.5.tgz#9de9494f19e0319d4f6366bb91d6bf7952af7874"
+ integrity sha512-4GOTMrpGQVzsCH2ruUn2vmwzV/02zF4q+ybhCIrw/Rkt3L8KWcycdC6aJMctJzwN4fXD4SD5F/4B9Sksh5rE0A==
+
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -11277,6 +11401,32 @@ ms@2.1.3, ms@^2.1.1, ms@^2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+msgpackr-extract@^3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz#e9d87023de39ce714872f9e9504e3c1996d61012"
+ integrity sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==
+ dependencies:
+ node-gyp-build-optional-packages "5.2.2"
+ optionalDependencies:
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64" "3.0.3"
+ "@msgpackr-extract/msgpackr-extract-darwin-x64" "3.0.3"
+ "@msgpackr-extract/msgpackr-extract-linux-arm" "3.0.3"
+ "@msgpackr-extract/msgpackr-extract-linux-arm64" "3.0.3"
+ "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.3"
+ "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.3"
+
+msgpackr@^1.11.2:
+ version "1.11.2"
+ resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.11.2.tgz#4463b7f7d68f2e24865c395664973562ad24473d"
+ integrity sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==
+ optionalDependencies:
+ msgpackr-extract "^3.0.2"
+
+multipasta@^0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/multipasta/-/multipasta-0.2.5.tgz#fb3564c4c619b73f98e72e2a4bbd4f7fba153edf"
+ integrity sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==
+
mute-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
@@ -11491,6 +11641,13 @@ node-fetch@^3.0.0:
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"
+node-gyp-build-optional-packages@5.2.2:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz#522f50c2d53134d7f3a76cd7255de4ab6c96a3a4"
+ integrity sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==
+ dependencies:
+ detect-libc "^2.0.1"
+
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@@ -12301,6 +12458,11 @@ puppeteer@^22.14.0:
devtools-protocol "0.0.1312386"
puppeteer-core "22.15.0"
+pure-rand@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2"
+ integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==
+
qr.js@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
@@ -13512,6 +13674,11 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
+sqids@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/sqids/-/sqids-0.3.0.tgz#969eabe54a362682e44cb73fce2bfea84e504dec"
+ integrity sha512-lOQK1ucVg+W6n3FhRwwSeUijxe93b51Bfz5PMRMihVf1iVkl82ePQG7V5vwrhzB11v0NtsR25PSZRGiSomJaJw==
+
stable-hash@^0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stable-hash/-/stable-hash-0.0.5.tgz#94e8837aaeac5b4d0f631d2972adef2924b40269"
@@ -14564,6 +14731,17 @@ unrs-resolver@^1.6.2:
"@unrs/resolver-binding-win32-ia32-msvc" "1.6.3"
"@unrs/resolver-binding-win32-x64-msvc" "1.6.3"
+uploadthing@^7.7.2:
+ version "7.7.2"
+ resolved "https://registry.yarnpkg.com/uploadthing/-/uploadthing-7.7.2.tgz#4a72ceb3eaa53564046e1831d626406fafb6a14c"
+ integrity sha512-Q8rp40vnh8g4+OHvocmf+YVoSi+6RWTKmemo5BgW7R8iFU2O2EYH/n+CIxPzxhYyH/QjhRF/pHoIMcUL/8OtSg==
+ dependencies:
+ "@effect/platform" "0.81.0"
+ "@standard-schema/spec" "1.0.0-beta.4"
+ "@uploadthing/mime-types" "0.3.5"
+ "@uploadthing/shared" "7.1.8"
+ effect "3.14.21"
+
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"