diff --git a/surfsense_web/app/(home)/page.tsx b/surfsense_web/app/(home)/page.tsx index 825c647c1..26e227fda 100644 --- a/surfsense_web/app/(home)/page.tsx +++ b/surfsense_web/app/(home)/page.tsx @@ -4,19 +4,17 @@ import { CompareTable } from "@/components/homepage/compare-table"; import { ConnectorGrid } from "@/components/homepage/connector-grid"; import { HeroSection } from "@/components/homepage/hero-section"; import { HomeFaq } from "@/components/homepage/home-faq"; -import { HowItWorks } from "@/components/homepage/how-it-works"; -import { PersonaPaths } from "@/components/homepage/persona-paths"; -import { UseCasesRow } from "@/components/homepage/use-cases"; +import { LogoCloud } from "@/components/homepage/logo-cloud"; +import { SocialProof } from "@/components/homepage/social-proof"; export default function HomePage() { return (
- + + - - diff --git a/surfsense_web/components/homepage/footer-new.tsx b/surfsense_web/components/homepage/footer-new.tsx index 17e8c2848..4d021afee 100644 --- a/surfsense_web/components/homepage/footer-new.tsx +++ b/surfsense_web/components/homepage/footer-new.tsx @@ -106,7 +106,7 @@ export function FooterNew() { ]; return (
-
+
diff --git a/surfsense_web/components/homepage/hero-chat-demo.tsx b/surfsense_web/components/homepage/hero-chat-demo.tsx index 3e7d6c23e..e04398053 100644 --- a/surfsense_web/components/homepage/hero-chat-demo.tsx +++ b/surfsense_web/components/homepage/hero-chat-demo.tsx @@ -77,6 +77,7 @@ function DemoTimeline({ @@ -869,9 +870,9 @@ const UseCasePane = memo(function UseCasePane({
-

+

{useCase.title} -

+

{useCase.description}

diff --git a/surfsense_web/components/homepage/logo-cloud.tsx b/surfsense_web/components/homepage/logo-cloud.tsx new file mode 100644 index 000000000..607deef0a --- /dev/null +++ b/surfsense_web/components/homepage/logo-cloud.tsx @@ -0,0 +1,111 @@ +"use client"; + +import { AnimatePresence, motion } from "motion/react"; +import { useEffect, useState } from "react"; +import { Reveal } from "@/components/connectors-marketing/reveal"; +import { MarketingSection } from "@/components/marketing/section"; + +/** + * Real signups pulled from prod (Google-auth), curated to the most recognizable + * names. These are self-serve users, not signed enterprise accounts, so the + * heading stays honest ("Used by people at") rather than implying contracts. + * + * Logos live in `public/logos/` — official marks from Wikimedia Commons / + * Wikipedia (universities use their seals). Bosta, Devoteam, and Leverage Edu + * have no clean Wikimedia logo, so they fall back to a brand favicon. Each item + * also falls back to a text wordmark on image error. + */ +const COMPANIES: { title: string; file: string }[] = [ + { title: "UC Berkeley", file: "berkeley.svg" }, + { title: "USC", file: "usc.svg" }, + { title: "Texas A&M", file: "tamu.svg" }, + { title: "UW–Madison", file: "wisc.svg" }, + { title: "Pitt", file: "pitt.svg" }, + { title: "Korean Air", file: "koreanair.svg" }, + { title: "Iron Mountain", file: "ironmountain.svg" }, + { title: "Globant", file: "globant.svg" }, + { title: "Devoteam", file: "devoteam.png" }, + { title: "VNG", file: "vng.svg" }, + { title: "TPBank", file: "tpbank.svg" }, + { title: "OpenGov", file: "opengov.png" }, + { title: "WeLab", file: "welab.png" }, + { title: "Leverage Edu", file: "leverageedu.png" }, + { title: "Zopper", file: "zopper.png" }, + { title: "Tec de Monterrey", file: "tec.svg" }, + { title: "Chulalongkorn", file: "chula.svg" }, + { title: "Univ. of Bristol", file: "bristol.svg" }, + { title: "Nutresa", file: "nutresa.svg" }, + { title: "Bosta", file: "bosta.png" }, +]; + +const LOGOS_PER_SET = 10; +const TOTAL_SETS = Math.ceil(COMPANIES.length / LOGOS_PER_SET); + +function LogoItem({ title, file }: { title: string; file: string }) { + const [failed, setFailed] = useState(false); + + if (failed) { + return ( + {title} + ); + } + + return ( + // biome-ignore lint/performance/noImgElement: swapped in/out by the cycling animation, next/image adds no value here + {title} setFailed(true)} + // dark mode: dark-on-transparent marks would vanish, so render every logo as a + // uniform light silhouette (brightness-0 + invert) instead of relying on its own color + className="h-10 w-auto max-w-[130px] object-contain opacity-60 grayscale transition duration-300 hover:opacity-100 hover:grayscale-0 dark:opacity-70 dark:brightness-0 dark:invert dark:hover:opacity-100" + /> + ); +} + +export function LogoCloud() { + const [currentSet, setCurrentSet] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentSet((prev) => (prev + 1) % TOTAL_SETS); + }, 3000); + return () => clearInterval(interval); + }, []); + + const startIndex = currentSet * LOGOS_PER_SET; + const currentLogos = Array.from( + { length: LOGOS_PER_SET }, + (_, i) => COMPANIES[(startIndex + i) % COMPANIES.length] + ); + + return ( + + +

+ Used by people at +

+
+
+ + {currentLogos.map((logo, index) => ( + + + + ))} + +
+
+ ); +} diff --git a/surfsense_web/components/homepage/navbar.tsx b/surfsense_web/components/homepage/navbar.tsx index 4cce7ff82..da71f8be0 100644 --- a/surfsense_web/components/homepage/navbar.tsx +++ b/surfsense_web/components/homepage/navbar.tsx @@ -250,17 +250,22 @@ const DesktopNav = ({ navItems, isScrolled, scrolledBgClassName }: DesktopNavPro href="https://discord.gg/ejRNvftDp9" target="_blank" rel="noopener noreferrer" + aria-label="SurfSense on Discord" className="hidden rounded-full p-2 hover:bg-gray-100 dark:hover:bg-neutral-800 transition-colors md:flex items-center justify-center" > - + - + @@ -362,17 +367,25 @@ const MobileNav = ({ navItems, isScrolled, scrolledBgClassName }: MobileNavProps href="https://discord.gg/ejRNvftDp9" target="_blank" rel="noopener noreferrer" + aria-label="SurfSense on Discord" className="flex items-center justify-center rounded-lg p-2 hover:bg-gray-100 dark:hover:bg-neutral-800 transition-colors touch-manipulation" > - + - + diff --git a/surfsense_web/components/homepage/social-proof.tsx b/surfsense_web/components/homepage/social-proof.tsx new file mode 100644 index 000000000..35c464e3c --- /dev/null +++ b/surfsense_web/components/homepage/social-proof.tsx @@ -0,0 +1,298 @@ +"use client"; + +import { + IconBrandLinkedin, + IconBrandTiktok, + IconBrandX, + IconBrandYoutube, +} from "@tabler/icons-react"; +import { Component, type ReactNode, useEffect, useRef, useState } from "react"; +import { LinkedInEmbed, TikTokEmbed, XEmbed, YouTubeEmbed } from "react-social-media-embed"; +import { Reveal } from "@/components/connectors-marketing/reveal"; + +type Post = + | { kind: "youtube"; url: string; title: string; channel: string } + | { kind: "x"; url: string } + | { kind: "linkedin"; url: string; postUrl: string } + | { kind: "tiktok"; url: string }; + +/** + * Organic SurfSense coverage — real posts embedded live with react-social-media-embed, + * grouped into three platform-uniform marquee rows (heights match within a row). + * + * Note: LinkedIn only renders when the author enabled embedding on the post; if + * disabled, the EmbedBoundary swaps in a link card to the original. + * + * ponytail: three rows, each list duplicated once for a seamless CSS loop. Ceiling: + * heavy third-party embeds. Mitigated by lazy-mounting the whole section on scroll + * (IntersectionObserver). Upgrade path: per-card virtualization, or swap YouTube + * players for thumbnail links. + */ +const YOUTUBE: Post[] = [ + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=i9AJ7PHGSGg", + title: "SurfSense vs NotebookLM", + channel: "rezasaad plus", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=VBOwuD6xVK0", + title: "NotebookLM Is Great… Until You See SurfSense", + channel: "Thomas AI", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=UaekqjhUiJM", + title: "NotebookLM vs SurfSense en 6 pruebas reales (sorprendente)", + channel: "NextGen IA Hub", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=QGjKpZJJ9aw", + title: "Gana DINERO configurando “Cerebros de IA” privados con SurfSense", + channel: "Creando Con La IA", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=cfNAIQtNbKY", + title: "¿Adiós NotebookLM? Probé SurfSense y es BRUTAL (IA Gratis)", + channel: "NextGen IA Hub", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=pIWOKSHhf38", + title: "¿Superaron a NotebookLM? SurfSense es Open Source, privada y GRATIS", + channel: "academIArtificial", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=K5xx-J_mQZ8", + title: "¿Mejor que NotebookLM? IA GRATIS con modo local", + channel: "Migue Baena IA", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=AKxM3RUBFsc", + title: "¿Nueva IA GRATIS destroza a NotebookLM de Google? (OPEN SOURCE)", + channel: "Inteligencia Artificial Top", + }, + { + kind: "youtube", + url: "https://www.youtube.com/watch?v=jCAgeaVgPDA", + title: "¿Nueva Herramienta IA GRATIS Destroza a NotebookLM? (OPEN SOURCE)", + channel: "Joaquín Barberá", + }, +]; + +const TWEETS: Post[] = [ + { kind: "x", url: "https://x.com/LangChain/status/1853133037019562434" }, + { kind: "x", url: "https://x.com/MoureDev/status/1976279289780740448" }, + { kind: "x", url: "https://x.com/GithubProjects/status/2004892541590929490" }, + { kind: "x", url: "https://x.com/GitHub_Daily/status/1920418408736436438" }, + { kind: "x", url: "https://x.com/tom_doerr/status/2066062170173977088" }, + { kind: "x", url: "https://x.com/itsharmanjot/status/2066118517905354816" }, + { kind: "x", url: "https://x.com/JulianGoldieSEO/status/2011085275133604095" }, + { kind: "x", url: "https://x.com/L_go_mrk/status/2066482853232115847" }, + { kind: "x", url: "https://x.com/semihdev/status/2006275500952736028" }, + { kind: "x", url: "https://x.com/shao__meng/status/1919912860957999494" }, + { kind: "x", url: "https://x.com/LangChain/status/1840406184316342561" }, +]; + +const SOCIAL: Post[] = [ + { + kind: "linkedin", + url: "https://www.linkedin.com/embed/feed/update/urn:li:ugcPost:7448203908834938881", + postUrl: + "https://www.linkedin.com/posts/vikas-singh-546643206_most-ai-tools-live-in-your-browser-and-ugcPost-7448203908834938881-gR6y", + }, + { + kind: "linkedin", + url: "https://www.linkedin.com/embed/feed/update/urn:li:share:7448351685409701889", + postUrl: + "https://www.linkedin.com/posts/neha-jain-279b80118_ive-been-using-a-lot-of-ai-tools-daily-share-7448351685409701889-JvFP", + }, + { + kind: "tiktok", + url: "https://www.tiktok.com/@alejavirivera/video/7603064928114625814", + }, +]; + +const CARD = "mr-4 shrink-0 overflow-hidden rounded-xl border bg-card"; + +const SIZE: Record = { + youtube: "h-[262px] w-[340px]", + x: "h-[440px] w-[340px]", + linkedin: "h-[540px] w-[340px]", + tiktok: "h-[540px] w-[340px]", +}; + +const META: Record = { + youtube: { Icon: IconBrandYoutube, label: "YouTube" }, + x: { Icon: IconBrandX, label: "X" }, + linkedin: { Icon: IconBrandLinkedin, label: "LinkedIn" }, + tiktok: { Icon: IconBrandTiktok, label: "TikTok" }, +}; + +/** + * Some embeds (notably Facebook, and LinkedIn when the author disabled embedding) + * throw at render/mount instead of degrading gracefully. This boundary stops one + * bad embed from taking down the whole marquee — it swaps in a link card instead. + */ +class EmbedBoundary extends Component< + { fallback: ReactNode; children: ReactNode }, + { failed: boolean } +> { + state = { failed: false }; + static getDerivedStateFromError() { + return { failed: true }; + } + render() { + return this.state.failed ? this.props.fallback : this.props.children; + } +} + +function FallbackCard({ post }: { post: Post }) { + const { Icon, label } = META[post.kind]; + const href = post.kind === "linkedin" ? post.postUrl : post.url; + return ( + + ); +} + +function Card({ post }: { post: Post }) { + switch (post.kind) { + case "youtube": + return ( +
+ +
+
+ + {post.channel} +
+ + {post.title} + +
+
+ ); + case "x": + return ( +
+ +
+ ); + case "linkedin": + return ( +
+ +
+ ); + case "tiktok": + return ( +
+ +
+ ); + } +} + +function Row({ + posts, + animation, + duration, +}: { + posts: Post[]; + animation: "ss-marquee-l" | "ss-marquee-r"; + duration: number; +}) { + return ( +
+ {/* Track holds the list twice; the -50% shift wraps seamlessly (margins, not gap). */} +
+ {[...posts, ...posts].map((post, i) => ( + } + > + + + ))} +
+
+ ); +} + +export function SocialProof() { + // Third-party embeds are heavy; only mount them once the section scrolls near view. + const ref = useRef(null); + const [visible, setVisible] = useState(false); + useEffect(() => { + const el = ref.current; + if (!el) return; + const io = new IntersectionObserver( + (entries) => { + if (entries[0]?.isIntersecting) { + setVisible(true); + io.disconnect(); + } + }, + { rootMargin: "300px" } + ); + io.observe(el); + return () => io.disconnect(); + }, []); + + return ( +
+ +
+

+ Loved across the internet +

+
+
+
+ {visible ? ( + <> + + + {/* Only 3 social cards — pre-double so one set spans wide viewports (no loop gap). */} + + + ) : null} +
+ +
+ ); +} diff --git a/surfsense_web/package.json b/surfsense_web/package.json index 82e4144f0..4de9077bb 100644 --- a/surfsense_web/package.json +++ b/surfsense_web/package.json @@ -138,6 +138,7 @@ "react-dom": "^19.2.3", "react-dropzone": "^14.3.8", "react-hook-form": "^7.61.1", + "react-social-media-embed": "^2.5.18", "react-syntax-highlighter": "^15.6.1", "react-wrap-balancer": "^1.1.1", "rehype-katex": "^7.0.1", diff --git a/surfsense_web/pnpm-lock.yaml b/surfsense_web/pnpm-lock.yaml index d93ad580d..29719c759 100644 --- a/surfsense_web/pnpm-lock.yaml +++ b/surfsense_web/pnpm-lock.yaml @@ -335,6 +335,9 @@ importers: react-hook-form: specifier: ^7.61.1 version: 7.71.2(react@19.2.4) + react-social-media-embed: + specifier: ^2.5.18 + version: 2.5.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4) react-syntax-highlighter: specifier: ^15.6.1 version: 15.6.6(react@19.2.4) @@ -1155,28 +1158,24 @@ packages: engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [musl] '@biomejs/cli-linux-arm64@2.4.6': resolution: {integrity: sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - libc: [glibc] '@biomejs/cli-linux-x64-musl@2.4.6': resolution: {integrity: sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [musl] '@biomejs/cli-linux-x64@2.4.6': resolution: {integrity: sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - libc: [glibc] '@biomejs/cli-win32-arm64@2.4.6': resolution: {integrity: sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg==} @@ -1864,105 +1863,89 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] - libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] - libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] - libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] - libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] - libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] - libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] - libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] - libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] - libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -2082,35 +2065,30 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-arm64-musl@0.1.97': resolution: {integrity: sha512-kKmSkQVnWeqg7qdsiXvYxKhAFuHz3tkBjW/zyQv5YKUPhotpaVhpBGv5LqCngzyuRV85SXoe+OFj+Tv0a0QXkQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] '@napi-rs/canvas-linux-riscv64-gnu@0.1.97': resolution: {integrity: sha512-Jc7I3A51jnEOIAXeLsN/M/+Z28LUeakcsXs07FLq9prXc0eYOtVwsDEv913Gr+06IRo34gJJVgT0TXvmz+N2VA==} engines: {node: '>= 10'} cpu: [riscv64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-x64-gnu@0.1.97': resolution: {integrity: sha512-iDUBe7AilfuBSRbSa8/IGX38Mf+iCSBqoVKLSQ5XaY2JLOaqz1TVyPFEyIck7wT6mRQhQt5sN6ogfjIDfi74tg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] '@napi-rs/canvas-linux-x64-musl@0.1.97': resolution: {integrity: sha512-AKLFd/v0Z5fvgqBDqhvqtAdx+fHMJ5t9JcUNKq4FIZ5WH+iegGm8HPdj00NFlCSnm83Fp3Ln8I2f7uq1aIiWaA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] '@napi-rs/canvas-win32-arm64-msvc@0.1.97': resolution: {integrity: sha512-u883Yr6A6fO7Vpsy9YE4FVCIxzzo5sO+7pIUjjoDLjS3vQaNMkVzx5bdIpEL+ob+gU88WDK4VcxYMZ6nmnoX9A==} @@ -2154,28 +2132,24 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [glibc] '@next/swc-linux-arm64-musl@16.1.6': resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - libc: [musl] '@next/swc-linux-x64-gnu@16.1.6': resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [glibc] '@next/swc-linux-x64-musl@16.1.6': resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - libc: [musl] '@next/swc-win32-arm64-msvc@16.1.6': resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==} @@ -2827,56 +2801,48 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [glibc] '@oxfmt/binding-linux-arm64-musl@0.45.0': resolution: {integrity: sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - libc: [musl] '@oxfmt/binding-linux-ppc64-gnu@0.45.0': resolution: {integrity: sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] - libc: [glibc] '@oxfmt/binding-linux-riscv64-gnu@0.45.0': resolution: {integrity: sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - libc: [glibc] '@oxfmt/binding-linux-riscv64-musl@0.45.0': resolution: {integrity: sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] - libc: [musl] '@oxfmt/binding-linux-s390x-gnu@0.45.0': resolution: {integrity: sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] - libc: [glibc] '@oxfmt/binding-linux-x64-gnu@0.45.0': resolution: {integrity: sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [glibc] '@oxfmt/binding-linux-x64-musl@0.45.0': resolution: {integrity: sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - libc: [musl] '@oxfmt/binding-openharmony-arm64@0.45.0': resolution: {integrity: sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg==} @@ -2931,42 +2897,36 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.6': resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] - libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.6': resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.6': resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] - libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.6': resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.6': resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] - libc: [musl] '@parcel/watcher-win32-arm64@2.5.6': resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} @@ -4287,79 +4247,66 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} @@ -4550,28 +4497,24 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [glibc] '@swc/core-linux-arm64-musl@1.15.13': resolution: {integrity: sha512-SmZ9m+XqCB35NddHCctvHFLqPZDAs5j8IgD36GoutufDJmeq2VNfgk5rQoqNqKmAK3Y7iFdEmI76QoHIWiCLyw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - libc: [musl] '@swc/core-linux-x64-gnu@1.15.13': resolution: {integrity: sha512-5rij+vB9a29aNkHq72EXI2ihDZPszJb4zlApJY4aCC/q6utgqFA6CkrfTfIb+O8hxtG3zP5KERETz8mfFK6A0A==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [glibc] '@swc/core-linux-x64-musl@1.15.13': resolution: {integrity: sha512-OlSlaOK9JplQ5qn07WiBLibkOw7iml2++ojEXhhR3rbWrNEKCD7sd8+6wSavsInyFdw4PhLA+Hy6YyDBIE23Yw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - libc: [musl] '@swc/core-win32-arm64-msvc@1.15.13': resolution: {integrity: sha512-zwQii5YVdsfG8Ti9gIKgBKZg8qMkRZxl+OlYWUT5D93Jl4NuNBRausP20tfEkQdAPSRrMCSUZBM6FhW7izAZRg==} @@ -4655,28 +4598,24 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.2.1': resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] - libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.2.1': resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.2.1': resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] - libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.2.1': resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} @@ -4976,6 +4915,9 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/youtube-player@5.5.11': + resolution: {integrity: sha512-pM41CDBqJqBmTeJWnF7NOGz82IQoYOhqzMYXv5vKCXBqGiYSLldxMtpCk6KAEtADTy49S45AriYaCaZyeUX38Q==} + '@typescript-eslint/eslint-plugin@8.56.0': resolution: {integrity: sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5100,49 +5042,41 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] - libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] - libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] - libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] - libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -5830,6 +5764,14 @@ packages: dayjs@1.11.21: resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -7255,28 +7197,24 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [glibc] lightningcss-linux-arm64-musl@1.31.1: resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - libc: [musl] lightningcss-linux-x64-gnu@1.31.1: resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [glibc] lightningcss-linux-x64-musl@1.31.1: resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - libc: [musl] lightningcss-win32-arm64-msvc@1.31.1: resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} @@ -7297,6 +7235,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + load-script@1.0.0: + resolution: {integrity: sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -7617,6 +7558,9 @@ packages: react-dom: optional: true + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -8169,6 +8113,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 + react-html-props@2.1.1: + resolution: {integrity: sha512-tM+YCYlr90m3JontKUAa+gNVU2zkyprlCS7OQ9aa3z2MfyJjAioJzrSmi1Vef/+UCTE6CQlPqLX4ebdLIJDKxw==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -8227,6 +8177,12 @@ packages: '@types/react': optional: true + react-social-media-embed@2.5.18: + resolution: {integrity: sha512-+PkzLRGAwnySkxKajaiK5VD+EjOhlFsh/vjNxgHsDfKBTseDpFxPrMXXQWkk6BRCwFBNVWX+V1HZ9AU0y54Wgw==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-style-singleton@2.2.3: resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} engines: {node: '>=10'} @@ -8237,6 +8193,12 @@ packages: '@types/react': optional: true + react-sub-unsub@2.2.8: + resolution: {integrity: sha512-o3tmiOOZPdQUCmRhkdCHXRFLOHnCwdz/N3QZ1JQ14fQGA2HysKMF0kWu56ERnQUCK7wYVCQzI8pFbnivAYNQ+A==} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0 + react-syntax-highlighter@15.6.6: resolution: {integrity: sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==} peerDependencies: @@ -8261,11 +8223,24 @@ packages: react-native: optional: true + react-twitter-embed@4.0.4: + resolution: {integrity: sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA==} + engines: {node: '>=10'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-wrap-balancer@1.1.1: resolution: {integrity: sha512-AB+l7FPRWl6uZ28VcJ8skkwLn2+UC62bjiw8tQUrZPlEWDVnR9MG0lghyn7EyxuJSsFEpht4G+yh2WikEqQ/5Q==} peerDependencies: react: '>=16.8.0 || ^17.0.0 || ^18' + react-youtube@10.1.0: + resolution: {integrity: sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg==} + engines: {node: '>= 14.x'} + peerDependencies: + react: '>=0.14.1' + react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -8489,6 +8464,9 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + scriptjs@2.5.9: + resolution: {integrity: sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg==} + scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} @@ -8574,6 +8552,9 @@ packages: simple-swizzle@0.2.4: resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + sister@3.0.2: + resolution: {integrity: sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA==} + slate-dom@0.119.0: resolution: {integrity: sha512-foc8a2NkE+1SldDIYaoqjhVKupt8RSuvHI868rfYOcypD4we5TT7qunjRKJ852EIRh/Ql8sSTepXgXKOUJnt1w==} peerDependencies: @@ -9240,6 +9221,9 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + youtube-player@5.5.2: + resolution: {integrity: sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ==} + zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -13989,6 +13973,8 @@ snapshots: dependencies: '@types/node': 20.19.33 + '@types/youtube-player@5.5.11': {} + '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.3(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -14881,6 +14867,10 @@ snapshots: dayjs@1.11.21: {} + debug@2.6.9: + dependencies: + ms: 2.0.0 + debug@3.2.7: dependencies: ms: 2.1.3 @@ -16535,6 +16525,8 @@ snapshots: lines-and-columns@1.2.4: {} + load-script@1.0.0: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -17136,6 +17128,8 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + ms@2.0.0: {} + ms@2.1.3: {} mutative@1.1.0: {} @@ -17802,6 +17796,11 @@ snapshots: dependencies: react: 19.2.4 + react-html-props@2.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-is@16.13.1: {} react-lifecycles-compat@3.0.4: {} @@ -17870,6 +17869,19 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 + react-social-media-embed@2.5.18(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@types/youtube-player': 5.5.11 + classnames: 2.5.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-html-props: 2.1.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-sub-unsub: 2.2.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-twitter-embed: 4.0.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-youtube: 10.1.0(react@19.2.4) + transitivePeerDependencies: + - supports-color + react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4): dependencies: get-nonce: 1.0.1 @@ -17878,6 +17890,11 @@ snapshots: optionalDependencies: '@types/react': 19.2.14 + react-sub-unsub@2.2.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-syntax-highlighter@15.6.6(react@19.2.4): dependencies: '@babel/runtime': 7.29.2 @@ -17906,10 +17923,25 @@ snapshots: optionalDependencies: react-dom: 19.2.4(react@19.2.4) + react-twitter-embed@4.0.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + scriptjs: 2.5.9 + react-wrap-balancer@1.1.1(react@19.2.4): dependencies: react: 19.2.4 + react-youtube@10.1.0(react@19.2.4): + dependencies: + fast-deep-equal: 3.1.3 + prop-types: 15.8.1 + react: 19.2.4 + youtube-player: 5.5.2 + transitivePeerDependencies: + - supports-color + react@19.2.4: {} readable-stream@2.3.8: @@ -18250,6 +18282,8 @@ snapshots: scheduler@0.27.0: {} + scriptjs@2.5.9: {} + scroll-into-view-if-needed@3.1.0: dependencies: compute-scroll-into-view: 3.1.1 @@ -18383,6 +18417,8 @@ snapshots: dependencies: is-arrayish: 0.3.4 + sister@3.0.2: {} + slate-dom@0.119.0(slate@0.120.0): dependencies: '@juggle/resize-observer': 3.4.0 @@ -19095,6 +19131,14 @@ snapshots: yoctocolors@2.1.2: {} + youtube-player@5.5.2: + dependencies: + debug: 2.6.9 + load-script: 1.0.0 + sister: 3.0.2 + transitivePeerDependencies: + - supports-color + zod-to-json-schema@3.25.1(zod@4.3.6): dependencies: zod: 4.3.6 diff --git a/surfsense_web/public/logos/berkeley.svg b/surfsense_web/public/logos/berkeley.svg new file mode 100644 index 000000000..97700a05e --- /dev/null +++ b/surfsense_web/public/logos/berkeley.svg @@ -0,0 +1,874 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/surfsense_web/public/logos/bosta.png b/surfsense_web/public/logos/bosta.png new file mode 100644 index 000000000..12b579129 Binary files /dev/null and b/surfsense_web/public/logos/bosta.png differ diff --git a/surfsense_web/public/logos/bristol.svg b/surfsense_web/public/logos/bristol.svg new file mode 100644 index 000000000..dc0e18921 --- /dev/null +++ b/surfsense_web/public/logos/bristol.svg @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/surfsense_web/public/logos/chula.svg b/surfsense_web/public/logos/chula.svg new file mode 100644 index 000000000..01ec9298a --- /dev/null +++ b/surfsense_web/public/logos/chula.svg @@ -0,0 +1,578 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/surfsense_web/public/logos/devoteam.png b/surfsense_web/public/logos/devoteam.png new file mode 100644 index 000000000..71b1f29d2 Binary files /dev/null and b/surfsense_web/public/logos/devoteam.png differ diff --git a/surfsense_web/public/logos/globant.svg b/surfsense_web/public/logos/globant.svg new file mode 100644 index 000000000..cd3e6b96d --- /dev/null +++ b/surfsense_web/public/logos/globant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/surfsense_web/public/logos/ironmountain.svg b/surfsense_web/public/logos/ironmountain.svg new file mode 100644 index 000000000..bbfa907de --- /dev/null +++ b/surfsense_web/public/logos/ironmountain.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/surfsense_web/public/logos/koreanair.svg b/surfsense_web/public/logos/koreanair.svg new file mode 100644 index 000000000..9bb9df295 --- /dev/null +++ b/surfsense_web/public/logos/koreanair.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/surfsense_web/public/logos/leverageedu.png b/surfsense_web/public/logos/leverageedu.png new file mode 100644 index 000000000..ff9ecad31 Binary files /dev/null and b/surfsense_web/public/logos/leverageedu.png differ diff --git a/surfsense_web/public/logos/nutresa.svg b/surfsense_web/public/logos/nutresa.svg new file mode 100644 index 000000000..0b8a1db80 --- /dev/null +++ b/surfsense_web/public/logos/nutresa.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/surfsense_web/public/logos/opengov.png b/surfsense_web/public/logos/opengov.png new file mode 100644 index 000000000..042a50b29 Binary files /dev/null and b/surfsense_web/public/logos/opengov.png differ diff --git a/surfsense_web/public/logos/pitt.svg b/surfsense_web/public/logos/pitt.svg new file mode 100644 index 000000000..101f7e7b5 --- /dev/null +++ b/surfsense_web/public/logos/pitt.svg @@ -0,0 +1 @@ +University-of-Pittsburgh-Seal-2020 \ No newline at end of file diff --git a/surfsense_web/public/logos/tamu.svg b/surfsense_web/public/logos/tamu.svg new file mode 100644 index 000000000..9bb086c67 --- /dev/null +++ b/surfsense_web/public/logos/tamu.svg @@ -0,0 +1,810 @@ + + + + + diff --git a/surfsense_web/public/logos/tec.svg b/surfsense_web/public/logos/tec.svg new file mode 100644 index 000000000..3e68ed5ca --- /dev/null +++ b/surfsense_web/public/logos/tec.svg @@ -0,0 +1,569 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/surfsense_web/public/logos/tpbank.svg b/surfsense_web/public/logos/tpbank.svg new file mode 100644 index 000000000..4874bb42c --- /dev/null +++ b/surfsense_web/public/logos/tpbank.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/surfsense_web/public/logos/usc.svg b/surfsense_web/public/logos/usc.svg new file mode 100644 index 000000000..6176e5d61 --- /dev/null +++ b/surfsense_web/public/logos/usc.svg @@ -0,0 +1,1335 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/surfsense_web/public/logos/vng.svg b/surfsense_web/public/logos/vng.svg new file mode 100644 index 000000000..33c9392e6 --- /dev/null +++ b/surfsense_web/public/logos/vng.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/surfsense_web/public/logos/welab.png b/surfsense_web/public/logos/welab.png new file mode 100644 index 000000000..d8c283428 Binary files /dev/null and b/surfsense_web/public/logos/welab.png differ diff --git a/surfsense_web/public/logos/wisc.svg b/surfsense_web/public/logos/wisc.svg new file mode 100644 index 000000000..59f4a1290 --- /dev/null +++ b/surfsense_web/public/logos/wisc.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/surfsense_web/public/logos/zopper.png b/surfsense_web/public/logos/zopper.png new file mode 100644 index 000000000..7d01bc672 Binary files /dev/null and b/surfsense_web/public/logos/zopper.png differ