diff --git a/blocks/server-side/additional-materials/additional-materials.module.css b/blocks/server-side/additional-materials/additional-materials.module.css new file mode 100644 index 00000000000..99ae5aa186e --- /dev/null +++ b/blocks/server-side/additional-materials/additional-materials.module.css @@ -0,0 +1,3 @@ +.subtitle { + max-width: 740px; +} diff --git a/blocks/server-side/additional-materials/additional-materials.tsx b/blocks/server-side/additional-materials/additional-materials.tsx new file mode 100644 index 00000000000..f51e0815a5d --- /dev/null +++ b/blocks/server-side/additional-materials/additional-materials.tsx @@ -0,0 +1,41 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './additional-materials.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import YoutubePlayer from '@jetbrains/kotlin-web-site-ui/out/components/youtube-player'; + +export const AdditionalMaterials: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+
+ +

+ Additional materials +

+ +

+ Build better backends with Kotlin. Check out the Kotlin for Backend playlist for real-world use + cases, expert insights, and performance tips. +

+ +
+
+ +
+
+ + +
+
+ ); +}; diff --git a/blocks/server-side/card/card.module.css b/blocks/server-side/card/card.module.css new file mode 100644 index 00000000000..f54d53aa1e7 --- /dev/null +++ b/blocks/server-side/card/card.module.css @@ -0,0 +1,18 @@ +.card { + background: #3F2180; + border-radius: 16px; + backdrop-filter: blur(8px); + padding: 24px; + box-sizing: border-box; + height: 100%; +} + +.cardTitle { + padding: 0; + margin: 0 0 16px; +} + +.cardDescription { + margin: 0; + padding: 0; +} diff --git a/blocks/server-side/card/card.tsx b/blocks/server-side/card/card.tsx new file mode 100644 index 00000000000..3932baa4f44 --- /dev/null +++ b/blocks/server-side/card/card.tsx @@ -0,0 +1,25 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './card.module.css'; +import { useTextStyles } from '@rescui/typography'; + +interface CardProps { + title: string; + description: string; +} + +export const Card: FC = ({ title, description }) => { + + const textCn = useTextStyles(); + + return ( +
+

{title}

+

+ {description} +

+
+ ); +}; diff --git a/blocks/server-side/customer-logo-marquee/customer-logo-marquee-data.ts b/blocks/server-side/customer-logo-marquee/customer-logo-marquee-data.ts new file mode 100644 index 00000000000..e1bd84609b6 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/customer-logo-marquee-data.ts @@ -0,0 +1,110 @@ +import doordash from './logos/doordash-dark.svg' +import kingfisher from './logos/kingfisher-dark.svg' +import ing from './logos/ING.svg' +import n26 from './logos/N26.svg' +import adobe from './logos/adobe-logo.svg' +import allegro from './logos/allegro.svg' +import atlassian from './logos/atlassian.svg' +import aws from './logos/aws.svg' +import corda from './logos/c-rda.svg' +import expediaGroup from './logos/expedia grour.svg' +import faire from './logos/faire-dark.svg' +import flux from './logos/flux.svg' +import intuit from './logos/intuit.svg' +import ktor from './logos/ktor.svg' +import memobank from './logos/memobank.svg' +import mercedes from './logos/mercedes-io-dark.svg' +import novatec from './logos/novatec-dark.svg' +import olx from './logos/olx.svg' +import shazam from './logos/shazam.svg' +import spring from './logos/spring.svg' + +interface LogoItem { + id: ImgSrc; + link: string; +} + +const logos: LogoItem[] = [ + { + id: doordash, + link: 'https://kotlinlang.org/lp/server-side/case-studies/doordash/', + }, + { + id: kingfisher, + link: 'https://medium.com/kingfisher-technology/server-side-kotlin-our-new-default-2d15644f8ed0', + }, + { + id: ing, + link: 'https://medium.com/ing-blog/introducing-kotlin-at-ing-a-long-but-rewarding-story-1bfcd3dc8da0', + }, + { + id: n26, + link: 'https://medium.com/insiden26/5-reasons-why-n26-is-moving-to-kotlin-f920b184ab58', + }, + { + id: adobe, + link: 'https://medium.com/adobetech/streamlining-server-side-app-development-with-kotlin-be8cf9d8b61a', + }, + { + id: allegro, + link: 'https://open.spotify.com/episode/6gRiIJSWN515tAvZuMAwRR?si=vPsgW2jDShSG2_S8eLfjqA', + }, + { + id: atlassian, + link: 'https://www.youtube.com/watch?v=4GkoB4hZUnw', + }, + { + id: aws, + link: 'https://www.youtube.com/live/Ar73Axsz2YA?si=E2qlkuznF9B2MXou&t=2766', + }, + { + id: corda, + link: 'https://www.corda.net/blog/kotlin/', + }, + { + id: expediaGroup, + link: 'https://kotlinlang.org/lp/server-side/case-studies/expedia/', + }, + { + id: faire, + link: 'https://kotlinlang.org/lp/server-side/case-studies/faire/', + }, + { + id: flux, + link: 'https://open.spotify.com/episode/3VS5dSUfcsC4fSvzbm2OxV?si=yEcubDoeRAW7zwVdo3XFtw&nd=1&dlsi=5e0e4c8dba104719', + }, + { + id: intuit, + link: 'https://medium.com/intuit-engineering/what-the-f-p-is-kotlin-7c55e2643b07', + }, + { + id: ktor, + link: 'https://open.spotify.com/episode/7rcwW7gNFIOrDqy6tgA1HU?si=c8QerntfTUqUO9Ks3s3kKw', + }, + { + id: memobank, + link: 'https://medium.com/memobank/cuddling-with-kotlin-35f4f96931bb', + }, + { + id: mercedes, + link: 'https://www.mercedes-benz.io/blog/2024-11-22-transitioning-from-java-to-kotlin-in-backend-development', + }, + { + id: novatec, + link: 'https://kotlinlang.org/lp/server-side/case-studies/novatec/', + }, + { + id: olx, + link: 'https://open.spotify.com/episode/3XBlKY3x4vVojuay4oSh8g?si=qiiwg8vkSm2OIP6rvrwnkg', + }, + { + id: shazam, + link: 'https://open.spotify.com/episode/6oZdJE7XU1GF6Dlir6tP50?si=2h7YKDejSxGrlFaWqZE6Ng', + }, + { + id: spring, + link: 'https://youtu.be/QExksqeNWbY?si=KSy63mxDTh07DYPM', + }, +]; + +export default logos; diff --git a/blocks/server-side/customer-logo-marquee/index.module.css b/blocks/server-side/customer-logo-marquee/index.module.css new file mode 100644 index 00000000000..70c20ec1f3c --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/index.module.css @@ -0,0 +1,12 @@ +.section { + --marquee-gap: 64px; + padding: 48px 0; +} + +.list :global(.cmn-ui-marquee__group) { + align-items: center; +} + +.logo { + max-height: 64px; +} diff --git a/blocks/server-side/customer-logo-marquee/index.tsx b/blocks/server-side/customer-logo-marquee/index.tsx new file mode 100644 index 00000000000..5ebfd48c8a8 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/index.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import { Marquee } from '../marquee'; +import styles from './index.module.css'; + +import logos from './customer-logo-marquee-data'; + +const CustomerLogoMarqueeSection: React.FC = () => { + return ( +
+ + {logos.map((item, index) => ( + + {item.link} + + ))} + +
+ ); +}; + +export default CustomerLogoMarqueeSection; diff --git a/blocks/server-side/customer-logo-marquee/logos/ING.svg b/blocks/server-side/customer-logo-marquee/logos/ING.svg new file mode 100644 index 00000000000..aa0611d3a6a --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/ING.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/N26.svg b/blocks/server-side/customer-logo-marquee/logos/N26.svg new file mode 100644 index 00000000000..3e0817971d4 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/N26.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/adobe-logo.svg b/blocks/server-side/customer-logo-marquee/logos/adobe-logo.svg new file mode 100644 index 00000000000..564d2080985 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/adobe-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/allegro.svg b/blocks/server-side/customer-logo-marquee/logos/allegro.svg new file mode 100644 index 00000000000..110184d64fb --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/allegro.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/atlassian.svg b/blocks/server-side/customer-logo-marquee/logos/atlassian.svg new file mode 100644 index 00000000000..aafb00e827b --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/atlassian.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/aws.svg b/blocks/server-side/customer-logo-marquee/logos/aws.svg new file mode 100644 index 00000000000..fdba7b9c5ab --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/aws.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/c-rda.svg b/blocks/server-side/customer-logo-marquee/logos/c-rda.svg new file mode 100644 index 00000000000..2289887053a --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/c-rda.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/doordash-dark.svg b/blocks/server-side/customer-logo-marquee/logos/doordash-dark.svg new file mode 100644 index 00000000000..82d044680d4 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/doordash-dark.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/expedia grour.svg b/blocks/server-side/customer-logo-marquee/logos/expedia grour.svg new file mode 100644 index 00000000000..908100f3121 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/expedia grour.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/faire-dark.svg b/blocks/server-side/customer-logo-marquee/logos/faire-dark.svg new file mode 100644 index 00000000000..f3b9af35d7a --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/faire-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/flux.svg b/blocks/server-side/customer-logo-marquee/logos/flux.svg new file mode 100644 index 00000000000..b8217a3a7cf --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/flux.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/intuit.svg b/blocks/server-side/customer-logo-marquee/logos/intuit.svg new file mode 100644 index 00000000000..d080610f7b6 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/intuit.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/kingfisher-dark.svg b/blocks/server-side/customer-logo-marquee/logos/kingfisher-dark.svg new file mode 100644 index 00000000000..9328a292b69 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/kingfisher-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/ktor.svg b/blocks/server-side/customer-logo-marquee/logos/ktor.svg new file mode 100644 index 00000000000..845b4698950 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/ktor.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/logo-netflix.svg b/blocks/server-side/customer-logo-marquee/logos/logo-netflix.svg new file mode 100644 index 00000000000..110ce8525fb --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/logo-netflix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blocks/server-side/customer-logo-marquee/logos/memobank.svg b/blocks/server-side/customer-logo-marquee/logos/memobank.svg new file mode 100644 index 00000000000..b11c906e591 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/memobank.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/mercedes-io-dark.svg b/blocks/server-side/customer-logo-marquee/logos/mercedes-io-dark.svg new file mode 100644 index 00000000000..1d2b2f436d5 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/mercedes-io-dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/novatec-dark.svg b/blocks/server-side/customer-logo-marquee/logos/novatec-dark.svg new file mode 100644 index 00000000000..cfa5e660935 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/novatec-dark.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/olx.svg b/blocks/server-side/customer-logo-marquee/logos/olx.svg new file mode 100644 index 00000000000..4aabc2f7bac --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/olx.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/shazam.svg b/blocks/server-side/customer-logo-marquee/logos/shazam.svg new file mode 100644 index 00000000000..4715d67deb4 --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/shazam.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/customer-logo-marquee/logos/spring.svg b/blocks/server-side/customer-logo-marquee/logos/spring.svg new file mode 100644 index 00000000000..656e8ac838e --- /dev/null +++ b/blocks/server-side/customer-logo-marquee/logos/spring.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/ecosystem-data.ts b/blocks/server-side/ecosystem/ecosystem-data.ts new file mode 100644 index 00000000000..0d404d2624d --- /dev/null +++ b/blocks/server-side/ecosystem/ecosystem-data.ts @@ -0,0 +1,96 @@ +import spring from './images/spring.svg'; +import ktor from './images/ktor.svg'; +import micronaut from './images/micronaut-foundation.svg'; +import quarkus from './images/quarkus-dark.svg'; +import vaadin from './images/vaadin-dark.svg'; +import cubaPlatform from './images/cuba-platform-dark.svg'; +import vertx from './images/vertx-dark.svg'; +import http4k from './images/http4k-dark.svg'; +import javalin from './images/javalin.svg'; +import kafkaLogo from './images/kafka.svg'; + + +export const primaryCardsData = [ + { + title: 'Spring', + src: spring, + text: + 'With its versatile set of features, Spring is the world’s most popular Java framework. When it’s paired with Kotlin, and its concise syntax, the two make the ultimate combo for application development.', + linkHref: 'https://spring.io/guides/tutorials/spring-boot-kotlin/', + linkText: 'Read tutorial' + }, + { + title: 'Ktor', + src: ktor, + text: + 'Ktor is a multiplatform toolkit built by JetBrains for creating Web applications in Kotlin. It makes use of coroutines for high scalability and offers an easy-to-use API.', + linkHref: 'https://ktor.io/quickstart/', + linkText: 'How to start' + } +]; + +export const secondaryCardsData = [ + { + title: 'Micronaut', + src: micronaut, + text: + 'Build your next Kotlin microservice application with ease and test it, too.', + linkHref: + 'https://guides.micronaut.io/creating-your-first-micronaut-app-kotlin/guide/index.html', + linkText: 'Learn more' + }, + { + title: 'Quarkus', + src: quarkus, + text: + 'Looking to implement the next cloud-native service with Kotlin? Try Quarkus!', + linkHref: 'https://quarkus.io/guides/kotlin', + linkText: 'Learn more' + }, + { + title: 'Vaadin', + src: vaadin, + text: + 'Create web applications with great-looking UI using Java and Kotlin.', + linkHref: 'https://vaadin.com/kotlin', + linkText: 'Learn more' + }, + { + title: 'Cuba platform', + src: cubaPlatform, + text: + 'This full-stack framework with a wide range of add-ons is a great fit for business application development with Kotlin.', + linkHref: 'http://cuba-platform.com/kotlin', + linkText: 'Learn more' + }, + { + title: 'Vert.x', + src: vertx, + text: 'A tool-kit for building reactive applications on the JVM.', + linkHref: 'https://vertx.io/docs/vertx-core/kotlin/', + linkText: 'Learn more' + }, + { + title: 'HTTP4K', + src: http4k, + text: + 'The HTTP toolkit written in pure Kotlin. Enables the serving and consuming of HTTP services in a functional and consistent way.', + linkHref: 'https://www.http4k.org/', + linkText: 'Learn more' + }, + { + title: 'Javalin', + src: javalin, + text: 'A lightweight Java and Kotlin framework.', + linkHref: 'https://javalin.io/', + linkText: 'Learn more' + }, + { + title: 'Apache Kafka', + src: kafkaLogo, + text: + 'Build event-driven, scalable applications effortlessly in Kotlin using Apache Kafka, the industry-standard platform for real-time data streaming.', + linkHref: 'https://kafka.apache.org/', + linkText: 'Learn more' + } +]; diff --git a/blocks/server-side/ecosystem/ecosystem.module.css b/blocks/server-side/ecosystem/ecosystem.module.css new file mode 100644 index 00000000000..88043e94495 --- /dev/null +++ b/blocks/server-side/ecosystem/ecosystem.module.css @@ -0,0 +1,63 @@ +.ecosystemCard { + background: #19191C; + border-radius: 16px; + border: 1px solid rgba(255, 255, 255, 0.20); + padding: 32px; + height: 100%; + box-sizing: border-box; + display: block; + text-decoration: none; + &:hover { + border: 1px solid #7E42FF; + } +} + +.cards { + display: grid; + grid-gap: 16px; +} + +.bigCards { + display: grid; + grid-gap: 16px; +} + +.grid { + display: grid; + grid-template-columns: repeat(1, 1fr); + grid-gap: 16px; +} + +@media (min-width: 768px) { + + .bigCards { + grid-gap: 32px; + } + + .grid { + grid-gap: 32px; + } + +} + +@media (min-width: 1001px) { + .bigCards { + grid-template-columns: repeat(2, 1fr); + } + + .grid { + grid-template-columns: repeat(4, 1fr); + } + + .cards { + grid-template-columns: repeat(2, 1fr); + grid-gap: 32px; + } +} + +@media (min-width: 1191px) { + .cards { + grid-template-columns: repeat(4, 1fr); + grid-gap: 32px; + } +} diff --git a/blocks/server-side/ecosystem/ecosystem.tsx b/blocks/server-side/ecosystem/ecosystem.tsx new file mode 100644 index 00000000000..48cdb868c01 --- /dev/null +++ b/blocks/server-side/ecosystem/ecosystem.tsx @@ -0,0 +1,74 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './ecosystem.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import { Card } from '../card/card'; + +import { primaryCardsData, secondaryCardsData } from './ecosystem-data'; + +import Link from 'next/link' + +export const Ecosystem: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+
+ +

+ Rich JVM ecosystem for backend development +

+ +
+ + + + + + + +
+ + +
+ {primaryCardsData.map((card) => ( + + {`${card.title} +

{card.text}

+

+ {card.linkText} +

+ + ))} +
+ +
+ {secondaryCardsData.map((card) => ( +
+ + {`${card.title} +
{card.text}
+ +
+ ))} +
+
+
+ ); +}; diff --git a/blocks/server-side/ecosystem/images/cuba-platform-dark.svg b/blocks/server-side/ecosystem/images/cuba-platform-dark.svg new file mode 100644 index 00000000000..356e5f34043 --- /dev/null +++ b/blocks/server-side/ecosystem/images/cuba-platform-dark.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/http4k-dark.svg b/blocks/server-side/ecosystem/images/http4k-dark.svg new file mode 100644 index 00000000000..a8a37d3e99b --- /dev/null +++ b/blocks/server-side/ecosystem/images/http4k-dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/javalin.svg b/blocks/server-side/ecosystem/images/javalin.svg new file mode 100644 index 00000000000..1135a57ba7f --- /dev/null +++ b/blocks/server-side/ecosystem/images/javalin.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/kafka.svg b/blocks/server-side/ecosystem/images/kafka.svg new file mode 100644 index 00000000000..667c5432b1a --- /dev/null +++ b/blocks/server-side/ecosystem/images/kafka.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/ktor.svg b/blocks/server-side/ecosystem/images/ktor.svg new file mode 100644 index 00000000000..845b4698950 --- /dev/null +++ b/blocks/server-side/ecosystem/images/ktor.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/micronaut-foundation.svg b/blocks/server-side/ecosystem/images/micronaut-foundation.svg new file mode 100644 index 00000000000..266a5e5e899 --- /dev/null +++ b/blocks/server-side/ecosystem/images/micronaut-foundation.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/quarkus-dark.svg b/blocks/server-side/ecosystem/images/quarkus-dark.svg new file mode 100644 index 00000000000..cffb6bc9af2 --- /dev/null +++ b/blocks/server-side/ecosystem/images/quarkus-dark.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/spring.svg b/blocks/server-side/ecosystem/images/spring.svg new file mode 100644 index 00000000000..9ce4e1475ea --- /dev/null +++ b/blocks/server-side/ecosystem/images/spring.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/vaadin-dark.svg b/blocks/server-side/ecosystem/images/vaadin-dark.svg new file mode 100644 index 00000000000..15bcfdab4ba --- /dev/null +++ b/blocks/server-side/ecosystem/images/vaadin-dark.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/blocks/server-side/ecosystem/images/vertx-dark.svg b/blocks/server-side/ecosystem/images/vertx-dark.svg new file mode 100644 index 00000000000..e32df1a2704 --- /dev/null +++ b/blocks/server-side/ecosystem/images/vertx-dark.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/blocks/server-side/favorite-tools/favorite-tools.module.css b/blocks/server-side/favorite-tools/favorite-tools.module.css new file mode 100644 index 00000000000..e07f59d55b5 --- /dev/null +++ b/blocks/server-side/favorite-tools/favorite-tools.module.css @@ -0,0 +1,22 @@ +.image { + width: 100%; + height: auto; + border-radius: 4px; + overflow: hidden; +} + +.sectionTitle { + margin-top: 0; +} + +.logos { + display: flex; + flex-wrap: wrap; + grid-gap: 24px; + margin-top: 24px; + align-items: center; + + & > img { + max-height: max-content; + } +} diff --git a/blocks/server-side/favorite-tools/favorite-tools.tsx b/blocks/server-side/favorite-tools/favorite-tools.tsx new file mode 100644 index 00000000000..adc9621b36f --- /dev/null +++ b/blocks/server-side/favorite-tools/favorite-tools.tsx @@ -0,0 +1,96 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './favorite-tools.module.css'; +import { useTextStyles } from '@rescui/typography'; +import { Button } from '@rescui/button'; +import Image from 'next/image'; + +import { ArrowTopRightIcon } from '@rescui/icons'; + +import ToolsImage1 from './images/tools-screen-2.webp'; +import ToolsImage2 from './images/tools-screen-2.webp'; + +import IdeaLogo from './images/intellij-idea.svg' +import MavenLogo from './images/maven.svg'; +import GradleLogo from './images/gradle.svg'; +import AntLogo from './images/ant.svg'; +import BazelLogo from './images/bazel.svg'; + +export const FavoriteTools: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+
+ +

+ Use your favorite tools +

+ +
+
+ {'IDE +
+
+

+ IDE support +

+ +

+ For a Java developer, getting started with Kotlin is very easy. Kotlin is natively supported + in IntelliJ IDEA, and the automated Java-to-Kotlin converter is there to help you with your + first steps. The powerful refactoring, navigation, and static code analysis features make + programming in Kotlin a pleasure! +

+ + + +
+ IntelliJ IDEA logo +
+
+
+ +
+
+

+ Build tools +

+ +

+ Use your favorite build tool for building Kotlin programs. Plugins are available for Gradle, Maven, Ant, and  + Bazel + ↗ +

+ +
+ Maven logo + Gradle logo + Ant logo + Bazel logo +
+
+
+ {'Build +
+
+ +
+
+ ); +}; diff --git a/blocks/server-side/favorite-tools/images/ant.svg b/blocks/server-side/favorite-tools/images/ant.svg new file mode 100644 index 00000000000..85d2641816c --- /dev/null +++ b/blocks/server-side/favorite-tools/images/ant.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blocks/server-side/favorite-tools/images/bazel.svg b/blocks/server-side/favorite-tools/images/bazel.svg new file mode 100644 index 00000000000..02e89b4f4a4 --- /dev/null +++ b/blocks/server-side/favorite-tools/images/bazel.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blocks/server-side/favorite-tools/images/gradle.svg b/blocks/server-side/favorite-tools/images/gradle.svg new file mode 100644 index 00000000000..0fc0ef4608f --- /dev/null +++ b/blocks/server-side/favorite-tools/images/gradle.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/blocks/server-side/favorite-tools/images/intellij-idea.svg b/blocks/server-side/favorite-tools/images/intellij-idea.svg new file mode 100644 index 00000000000..af095d34727 --- /dev/null +++ b/blocks/server-side/favorite-tools/images/intellij-idea.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/blocks/server-side/favorite-tools/images/maven.svg b/blocks/server-side/favorite-tools/images/maven.svg new file mode 100644 index 00000000000..2dd2328807d --- /dev/null +++ b/blocks/server-side/favorite-tools/images/maven.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/blocks/server-side/favorite-tools/images/tools-screen-1.webp b/blocks/server-side/favorite-tools/images/tools-screen-1.webp new file mode 100644 index 00000000000..d199d65191c Binary files /dev/null and b/blocks/server-side/favorite-tools/images/tools-screen-1.webp differ diff --git a/blocks/server-side/favorite-tools/images/tools-screen-2.webp b/blocks/server-side/favorite-tools/images/tools-screen-2.webp new file mode 100644 index 00000000000..e73f8d0d9c7 Binary files /dev/null and b/blocks/server-side/favorite-tools/images/tools-screen-2.webp differ diff --git a/blocks/server-side/features-carousel/index.module.css b/blocks/server-side/features-carousel/index.module.css new file mode 100644 index 00000000000..cb86178472c --- /dev/null +++ b/blocks/server-side/features-carousel/index.module.css @@ -0,0 +1,104 @@ +.carouselContainer { + display: flex; + flex-direction: column; + width: 100%; +} + +.carousel { + /* Styles for the carousel container */ + width: 100%; +} + +.slide { + /*width: calc(100vw - 44px - 78px);*/ +} + +.featureCard { + border-radius: 24px 24px 16px 16px; + display: flex; + flex-direction: column; + background: var(--rs-color-white-t5); + &:hover { + outline: 1px solid #7E42FF; + } +} + +.content { + padding: 24px; + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: space-between; + background: rgba(126, 66, 255, 0.8); + border-radius: 16px; +} + +@media (max-width: 768px) { + .content { + padding: 16px; + } +} + +.contentIcon { + width: 48px; +} + +.contentIcon svg { + width: 100%; +} + +.imageWrapper { + position: relative; + width: 100%; +} + +.image { + width: 100%; + border-radius: 16px; +} + +.copyButton { + position: absolute; + bottom: 16px; + right: 16px; + z-index: 2; +} + +.codeBlock { + width: 100%; + padding: 16px 16px 66px; + border-radius: 16px; + margin-top: 32px; + box-sizing: border-box; + overflow: auto; + background-color: #282a36; /* Dracula theme background */ +} + +.codeBlock :global(pre) { + margin: 0; + font-family: 'JetBrains Mono', monospace; + font-size: 14px; + line-height: 1.5; +} + +.controls { + display: flex; + justify-content: center; + align-items: center; + margin-top: 24px; + gap: 16px; +} + +.navButton { + min-width: 80px; +} + +.indicator { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-size: 14px; + font-weight: 500; + color: #6f7276; + padding: 0 8px; + min-width: 40px; + text-align: center; +} diff --git a/blocks/server-side/features-carousel/index.tsx b/blocks/server-side/features-carousel/index.tsx new file mode 100644 index 00000000000..48c38f6837e --- /dev/null +++ b/blocks/server-side/features-carousel/index.tsx @@ -0,0 +1,122 @@ +import React, { FC, useState } from 'react'; +import classNames from 'classnames'; +import { useTextStyles } from '@rescui/typography'; +import SwipeableViews from 'react-swipeable-views'; +import { Button } from '@rescui/button'; +import { CodeHighlight } from '../../../components/code-highlight/code-highlight'; + +import { ArrowLeftIcon, ArrowRightIcon } from '@rescui/icons'; + +import styles from './index.module.css'; +import { SnapCarousel } from '../../../components/snap-carousel/snap-carousel'; + +interface FeatureSlideItem { + id: string; + icon: ImgSrc; + title: React.ReactNode; + description: React.ReactNode; + codeSample: string; +} + +interface CopyCodeButtonProps { + codeSample: string; +} + +const CopyCodeButton: FC = ({ codeSample }) => { + const handleCopy = () => { + navigator.clipboard.writeText(codeSample); + }; + + return ( + + ); +}; + +interface FeatureCardProps { + icon: ImgSrc; + title: React.ReactNode; + description: React.ReactNode; + codeSample: string; + className?: string; +} + +const FeatureCard: FC = ({ + icon, + title, + description, + codeSample, + className + }) => { + const textCn = useTextStyles(); + + return ( +
+
+
+
+ 404 +
+

{title}

+

+ {description} +

+
+
+
+ + +
+
+ ); +}; + +interface FeaturesCarouselProps { + featuresData: FeatureSlideItem[]; + className?: string; +} + +export const FeaturesCarousel: FC = ({ featuresData, className }) => { + const [activeIndex, setActiveIndex] = useState(0); + + const handleChangeIndex = (index: number) => { + setActiveIndex(index); + }; + + const handlePrev = () => { + setActiveIndex((prevIndex) => (prevIndex > 0 ? prevIndex - 1 : prevIndex)); + }; + + const handleNext = () => { + setActiveIndex((prevIndex) => (prevIndex < featuresData.length - 1 ? prevIndex + 1 : prevIndex)); + }; + + return ( +
+ + + {featuresData.map(feature => ( + + ))} + +
+ ); +}; + +export default FeaturesCarousel; diff --git a/blocks/server-side/features-section/diamond.svg b/blocks/server-side/features-section/diamond.svg new file mode 100644 index 00000000000..ab3c7ac220e --- /dev/null +++ b/blocks/server-side/features-section/diamond.svg @@ -0,0 +1,3 @@ + + + diff --git a/blocks/server-side/features-section/index.module.css b/blocks/server-side/features-section/index.module.css new file mode 100644 index 00000000000..71f3e3129e6 --- /dev/null +++ b/blocks/server-side/features-section/index.module.css @@ -0,0 +1,13 @@ +.exposedFeatureCard { + padding: 24px; + border-radius: 16px; + background: rgba(107, 87, 255, 0.20); + backdrop-filter: blur(8px); + box-sizing: border-box; +} + +.exposedFeatureCardIcon svg { + width: 48px; + height: 48px; +} + diff --git a/blocks/server-side/features-section/index.tsx b/blocks/server-side/features-section/index.tsx new file mode 100644 index 00000000000..31f7b3a2ce1 --- /dev/null +++ b/blocks/server-side/features-section/index.tsx @@ -0,0 +1,31 @@ +import React, { FC } from 'react'; +import classNames from 'classnames'; +import { useTextStyles } from '@rescui/typography'; +import { useTL } from '@jetbrains/kotlin-web-site-ui/out/components/breakpoints'; + +import { featureSlideshowItems } from './items'; +import { FeaturesCarousel } from '../features-carousel'; +import { FeaturesSwitcher } from '../features-switcher'; + +const FeaturesSection: FC = () => { + const textCn = useTextStyles(); + const isTL = useTL(); + + return ( +
+
+

+ Safety: fewer production bugs and crashes +

+ + {isTL ? ( + + ) : ( + + )} +
+
+ ); +}; + +export default FeaturesSection; diff --git a/blocks/server-side/features-section/items.tsx b/blocks/server-side/features-section/items.tsx new file mode 100644 index 00000000000..4c8324b994c --- /dev/null +++ b/blocks/server-side/features-section/items.tsx @@ -0,0 +1,84 @@ +import React, { ReactNode } from 'react'; + +import DiamondIcon from './diamond.svg'; + +interface FeatureItem { + id: string; + icon: ImgSrc; + title: string; + description: ReactNode; +} + +interface FeatureSlideItem extends FeatureItem { + codeSample: string; +} + +export const featureSlideshowItems: FeatureSlideItem[] = [ + { + id: 'null-safety', + icon: DiamondIcon, + title: 'Null-safety', + description: 'Switching backend development to Kotlin significantly reduces crashes at runtime.', + codeSample: `val b: String? = "Kotlin" +// reduction of null-pointer exceptions is achieved by +// explicit nullable types (String?) and enforced compile-time checks (?.) + +val length: Int? = b?.length +// b.length <-- won't compile, as the length can only be accessed safely + +if (b != null && b.length > 0) { + print("String of length \${b.length}") +} else { + print("Empty string") +} +// Kotlin smart-casts b to a non-null value after an != null check. +// It makes code clearer and easier tofor debugging and maintainenance. +`, + }, + { + id: 'immutability', + icon: DiamondIcon, + title: 'Immutability', + description: `Immutable data by default:\n +- Immutable collections reduce concurrency issues +- Easier reasoning about application state +- Improved predictability +`, + codeSample: `data class Config(val host: String, val port: Int) + +val config = Config(host = "localhost", port = 8080) + +// config.port = 8081 <-- won't compile, val cannot be changed + +val updatedConfig = config.copy(port = 8081) +// Kotlin's data classes, immutability, and the built-in .copy() function +// simplify safe object updates and state management, directly enhancing code stability. + +println(config) //Config(host = "localhost", port = 8080) +println(updatedConfig) //Config(host = "localhost", port = 8081) +`, + }, + { + id: 'type-safety', + icon: DiamondIcon, + title: 'Type-safety', + description: `An explicit and expressive type system helps developers catch errors early:\n +- Strong type system clarifies intent, eases refactoring, and safeguards code evolution at scale. +- Reified generics keep type parameters at runtime, eliminating type erasure. +`, + codeSample: `// Features like sealed classes, smart casts, and inline value classes +// enforce exhaustive, compile-time checking of code paths. + +@JvmInline value class UserId(val id: String) // explicit type-safety for primitive types + +sealed class Result +data class Found(val userId: UserId): Result() +data object NotFound: Result() + +fun handle(res: Result): String = when(res) { // exhaustive compile-time check + is Found -> "User: \${res.userId.id}" // smart-cast 'res' automatically + NotFound -> "User not found" +} +`, + }, +]; diff --git a/blocks/server-side/features-switcher/index.module.css b/blocks/server-side/features-switcher/index.module.css new file mode 100644 index 00000000000..30f5bd8eae5 --- /dev/null +++ b/blocks/server-side/features-switcher/index.module.css @@ -0,0 +1,192 @@ +.slideshow { + position: relative; + display: flex; + --slideshow-tab-width: 360px; + --slideshow-tab-lg-width: 264px; +} + +.offsettop12 { + margin-top: 12px; +} + +@media (max-width: 992px) { + .slideshow { + padding: 16px; + } +} + +.slides { + position: relative; + flex: 1 1 auto; + width: calc(100% - var(--slideshow-tab-width)); +} + +@media (max-width: 1200px) { + .slides { + width: calc(100% - var(--slideshow-tab-lg-width)); + } +} + +@media (max-width: 768px) { + .slides { + width: 100%; + } +} + +.slide { + top: 0; + right: 0; + /*bottom: 0;*/ + left: 0; + width: 100%; + /*height: 100%;*/ + border-radius: 16px; + overflow: hidden; +} + +.slideVisible { + position: relative; + opacity: 1; + visibility: visible; + transition: opacity 0.5s linear 0s, visibility 0s linear 0s; +} + +.slideHidden { + position: absolute; + opacity: 0; + visibility: hidden; + transition: opacity 0.5s linear 0s, visibility 0s linear 0.5s; +} + +.slidesPanel { + display: flex; + flex-direction: column; + align-items: stretch; + width: var(--slideshow-tab-width); + min-height: fit-content; +} + +@media (max-width: 1200px) { + .slidesPanel { + width: var(--slideshow-tab-lg-width); + } +} + +.slidesSwitcher { + list-style: none; + position: relative; + overflow-y: auto; + flex-shrink: 1; + flex-grow: 1; + box-sizing: border-box; + width: 100%; + padding-right: 32px; + margin-top: 0; + margin-left: 0; + padding-left: 0; +} + +@media (max-width: 992px) { + .slidesSwitcher { + padding-right: 16px; + } +} + +.tab { + position: relative; + overflow: hidden; + flex: 0 0 auto; + width: 100%; + padding: 16px; + border-radius: 16px; + border: 1px solid transparent; + cursor: pointer; + text-align: left; + background-color: rgba(107, 87, 255, 0.20); +} + +@media (max-width: 992px) { + .tab { + padding: 16px; + border-radius: 16px; + } +} + +.tab:focus { + outline: none; +} + +.tab:focus[data-focus-method='key'] { + box-shadow: rgba(107, 87, 255, 0.80) 0 0 0 4px; +} + +.tab:hover { + border: 1px solid rgba(107, 87, 255, 0.80); +} + +.tabActive { + background-color: rgba(107, 87, 255, 0.80); +} + +.tabTitle { + position: relative; + margin: 0; +} + +.tabDescription { + position: relative; + margin: 8px 0 0; +} + +.tabIcon svg { + width: 48px; + height: 48px; +} + +.imageContainer { + height: 100%; + max-height: 476px; + background-color: #000000; +} + +@media (max-width: 1200px) { + .imageContainer { + max-height: unset; + } +} + +.image { + width: 100%; + height: 100%; + object-fit: contain; + object-position: top left; +} + +.copyButton { + position: absolute; + bottom: 16px; + right: 16px; + z-index: 2; +} + +.tag { + position: absolute; + top: 16px; + right: 16px; + z-index: 2; +} + +.codeBlock { + width: 100%; + padding: 32px 32px 92px; + border-radius: 16px; + overflow: auto; + background-color: #282a36; /* Dracula theme background */ +} + +.codeBlock :global(pre) { + margin: 0; + font-family: 'JetBrains Mono', monospace; + font-size: 14px; + line-height: 2; +} diff --git a/blocks/server-side/features-switcher/index.tsx b/blocks/server-side/features-switcher/index.tsx new file mode 100644 index 00000000000..d9590e6f655 --- /dev/null +++ b/blocks/server-side/features-switcher/index.tsx @@ -0,0 +1,105 @@ +import React, { FC, useState } from 'react'; +import classNames from 'classnames'; +import { useTextStyles } from '@rescui/typography'; +import { Button } from '@rescui/button'; +import { CodeHighlight } from '../../../components/code-highlight/code-highlight'; + +import styles from './index.module.css'; + +interface CopyCodeButtonProps { + codeSample: string; +} + +const CopyCodeButton: FC = ({ codeSample }) => { + const handleCopy = () => { + navigator.clipboard.writeText(codeSample); + }; + + return ( + + ); +}; + +interface CustomSlideProps { + codeSample: string; +} + +const CustomSlide: FC = ({ codeSample }) => ( +
+ + +
+); + +interface FeatureSlideItem { + id: string; + icon: ImgSrc; + title: React.ReactNode; + description: React.ReactNode; + codeSample: string; +} + +interface FeaturesSwitcherProps { + slides: FeatureSlideItem[]; + className?: string; +} + +export const FeaturesSwitcher: FC = ({ slides, className }) => { + const textCn = useTextStyles(); + const [currentSlideIndex, setCurrentSlideIndex] = useState(0); + + return ( +
+
+
    + {slides.map((slide, i) => ( +
  • + +
  • + ))} +
+
+ +
+ {slides.map((slide, i) => ( +
+ +
+ ))} +
+
+ ); +}; + +export default FeaturesSwitcher; diff --git a/blocks/server-side/get-started/get-started.module.css b/blocks/server-side/get-started/get-started.module.css new file mode 100644 index 00000000000..331b174b90a --- /dev/null +++ b/blocks/server-side/get-started/get-started.module.css @@ -0,0 +1,46 @@ +.wrapper { + position: relative; + overflow: hidden; + padding: 96px 0; +} + +.content { + position: relative; + z-index: 2; +} + +.backgroundImage { + position: absolute; + bottom: 0; + right: 50%; + transform: translateX(50%); + margin-right: -150px; + z-index: 1; + max-width: none; +} + +.card { + background: #000000; + border: 1px solid rgba(255, 255, 255, 0.20); + padding: 32px 32px 40px 32px; + box-sizing: border-box; + border-radius: 16px; + height: 100%; + display: block; + text-decoration: none; + &:hover { + outline: 1px solid #7E42FF; + } +} + +@media (max-width: 1024px) { + .mobileSpacer { + margin-top: 32px; + } +} + +@media (max-width: 768px) { + .mobileSpacer { + margin-top: 16px; + } +} diff --git a/blocks/server-side/get-started/get-started.tsx b/blocks/server-side/get-started/get-started.tsx new file mode 100644 index 00000000000..66461718408 --- /dev/null +++ b/blocks/server-side/get-started/get-started.tsx @@ -0,0 +1,81 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './get-started.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import ktorLogo from './images/ktor.svg'; +import springLogo from './images/spring.svg'; + +import Img from 'next/image'; +import getStartedGraphics from './images/get-started-graphics-cut.webp'; + +import Link from 'next/link'; + +export const GetStarted: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+ +
+ + {'Get + +
+ +

+ Get started +

+ +
+
+ +
+ Ktor Logo +
+
+

+ Ktor quick start +

+
+
+

+ Ktor is a multiplatform toolkit built by JetBrains for creating Web applications + in + Kotlin. It makes use of coroutines for high scalability and offers an + easy-to-use + API. +

+
+ +
+ +
+ +
+ Spring Logo +
+
+

+ Go server-side with Spring +

+
+
+

+ Use Kotlin with the familiar Spring framework to build powerful enterprise + applications. +

+
+ +
+
+ +
+ +
+
+ ); +}; diff --git a/blocks/server-side/get-started/images/get-started-graphics-cut.webp b/blocks/server-side/get-started/images/get-started-graphics-cut.webp new file mode 100644 index 00000000000..668ba007514 Binary files /dev/null and b/blocks/server-side/get-started/images/get-started-graphics-cut.webp differ diff --git a/blocks/server-side/get-started/images/ktor.svg b/blocks/server-side/get-started/images/ktor.svg new file mode 100644 index 00000000000..bbd9d98b342 --- /dev/null +++ b/blocks/server-side/get-started/images/ktor.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/blocks/server-side/get-started/images/spring.svg b/blocks/server-side/get-started/images/spring.svg new file mode 100644 index 00000000000..760d25605e3 --- /dev/null +++ b/blocks/server-side/get-started/images/spring.svg @@ -0,0 +1,4 @@ + + + + diff --git a/blocks/server-side/hero/hero.module.css b/blocks/server-side/hero/hero.module.css new file mode 100644 index 00000000000..0f0e9b69a79 --- /dev/null +++ b/blocks/server-side/hero/hero.module.css @@ -0,0 +1,80 @@ +.wrapper { + background: #000000; + padding: 96px 0 72px 0; + color: #fff; + position: relative; + overflow: hidden; +} + +.content { + max-width: 816px; + position: relative; + z-index: 2; +} + +.heroImage { + position: absolute; + top: -140px; + right: 50%; + transform: translateX(50%); + margin-right: -200px; + z-index: 1; + max-width: none; +} + +.heroTitle { + margin: 0; +} + +.heroSubtitle { + margin: 56px 0 0; +} + +.featuresList { + display: grid; + grid-template-columns: repeat(1, 1fr); + grid-gap: 16px; + margin-top: 32px; +} + +.feature { + background: rgba(126, 66, 255, 0.20); + backdrop-filter: blur(40px); + border-radius: 16px; + display: flex; + align-items: center; + padding: 24px 32px; + text-decoration: none; + &:hover { + outline: 1px solid #7E42FF; + } +} + +.featureTitle { + margin: 0; + padding: 0; +} + +.buttons { + margin-top: 32px; + display: flex; + flex-direction: column; + gap: 16px; +} + +@media (min-width: 768px) { + .heroImage { + margin-right: -390px; + } + + .featuresList { + grid-template-columns: repeat(2, 1fr); + grid-gap: 24px; + } + + .buttons { + margin-top: 56px; + flex-direction: row; + gap: 24px; + } +} diff --git a/blocks/server-side/hero/hero.tsx b/blocks/server-side/hero/hero.tsx new file mode 100644 index 00000000000..2d3ecdd7440 --- /dev/null +++ b/blocks/server-side/hero/hero.tsx @@ -0,0 +1,62 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './hero.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import '@jetbrains/kotlin-web-site-ui/out/components/layout'; + +import { Button } from '@rescui/button'; + +import Img from 'next/image'; +import Link from 'next/link'; + +import heroImg from './images/hero-graphics.webp' + +export const ServerSideHero: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+ + {'Server-side + +
+
+

+ Modern backend
development
with Kotlin +

+ +

+ Kotlin is a perfect fit for building backends on JVM. It's trusted by major tech companies to build scalable and reliable server-side applications +

+ +
+ + +

Safety

+ + +

Runtime performance

+ + +

Access to the rich JVM ecosystem

+ + +

Great developer experience

+ + +
+ +
+ + +
+
+ +
+
+ ); +}; diff --git a/blocks/server-side/hero/images/hero-graphics.webp b/blocks/server-side/hero/images/hero-graphics.webp new file mode 100644 index 00000000000..10cafa72c9e Binary files /dev/null and b/blocks/server-side/hero/images/hero-graphics.webp differ diff --git a/blocks/server-side/how-to-start/how-to-start.module.css b/blocks/server-side/how-to-start/how-to-start.module.css new file mode 100644 index 00000000000..6785a8a57a2 --- /dev/null +++ b/blocks/server-side/how-to-start/how-to-start.module.css @@ -0,0 +1,64 @@ +.item { + border-radius: 16px; + background: rgba(126, 66, 255, 0.30); + backdrop-filter: blur(8px); + display: flex; + align-items: center; + padding: 16px; + min-height: 80px; + box-sizing: border-box; + &:not(:last-child) { + margin-bottom: 16px; + } + + &:nth-child(2) { + background: rgba(126, 66, 255, 0.50); + margin-left: 32px; + } + + &:nth-child(3) { + background: rgba(126, 66, 255, 0.70); + margin-left: 64px; + } + + &:nth-child(4) { + background: rgba(126, 66, 255, 0.90); + margin-left: 96px; + } +} + +.icon { + flex-shrink: 0; + margin-right: 16px; +} + +.title { + padding: 0; + margin: 0; +} + +.codeBlock { + width: 100%; + padding: 32px 32px 66px; + border-radius: 16px; + box-sizing: border-box; + overflow: auto; + background-color: #282a36; /* Dracula theme background */ +} + +.codeBlock :global(pre) { + margin: 0; + font-family: 'JetBrains Mono', monospace; + font-size: 14px; + line-height: 2; +} + +@media (max-width: 1000px) { + .codeSample { + margin-top: 32px; + } + + .codeBlock { + padding: 16px 16px 66px; + } +} diff --git a/blocks/server-side/how-to-start/how-to-start.tsx b/blocks/server-side/how-to-start/how-to-start.tsx new file mode 100644 index 00000000000..2be0160f7b4 --- /dev/null +++ b/blocks/server-side/how-to-start/how-to-start.tsx @@ -0,0 +1,80 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './how-to-start.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import {ArrowRightIcon} from '@rescui/icons'; + +import { CodeHighlight } from '../../../components/code-highlight/code-highlight'; + +const codeSample = `data class User(val name: String, val age: Int) + +@Test fun \`should return valid user when input correct\`() { + val repo = mockk() + every { repo.findById(any()) } returns User("John", 30) + val service = UserService(repo) + assertEquals(User("John", 30), service.getUser("test-id")) +}`; + + +export const HowToStart: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+
+ +

+ How to start – incremental adoption in Java projects +

+ +

+ Because of Kotlin’s full interoperability with Java,
+ teams can introduce it gradually +

+ +
+
+ +
+
+ +

+ Start using Kotlin for your tests. +

+
+
+ +

+ Implement new services from scratch in Kotlin using your existing framework (Spring, Quarkus, JEE, etc.). +

+
+
+ +

+ Develop new features in Kotlin within existing Java projects. +

+
+
+ +

+ Gradually convert your existing Java codebase to Kotlin. +

+
+
+ +
+ +
+ +
+ +
+ +
+
+ ); +}; diff --git a/blocks/server-side/layout/server-side-layout.module.css b/blocks/server-side/layout/server-side-layout.module.css new file mode 100644 index 00000000000..b48092aa4ec --- /dev/null +++ b/blocks/server-side/layout/server-side-layout.module.css @@ -0,0 +1,3 @@ +.contentWrapper { + background: #000000; +} diff --git a/blocks/server-side/layout/server-side-layout.tsx b/blocks/server-side/layout/server-side-layout.tsx new file mode 100644 index 00000000000..2652cd54dbe --- /dev/null +++ b/blocks/server-side/layout/server-side-layout.tsx @@ -0,0 +1,123 @@ +import React, { FC, useCallback, useMemo } from 'react'; + +import Head from 'next/head'; + +import GlobalHeader, { SERVER_SIDE_TITLE, SERVER_SIDE_URL } from '@jetbrains/kotlin-web-site-ui/out/components/header'; +import GlobalFooter from '@jetbrains/kotlin-web-site-ui/out/components/footer'; +import TopMenu from '@jetbrains/kotlin-web-site-ui/out/components/top-menu'; +import { ThemeProvider } from '@rescui/ui-contexts'; +import { useRouter } from 'next/router'; +import { StickyHeader } from '../../../components/sticky-header/sticky-header'; +import styles from './server-side-layout.module.css'; +import releasesDataRaw from '../../../data/releases.yml'; +import searchConfig from '../../../search-config.json'; +import { Button } from '@rescui/button'; + + +const releasesData: ReleasesData = releasesDataRaw as ReleasesData; + +const TOP_MENU_ITEMS = [ + { + url: '/lp/server-side/case-studies/', + title: 'Case Studies' + }, +]; + +interface CommunityLayoutProps { + title: string; + description?: string; + ogImageName?: string; + children: React.ReactNode; +} + +export const ServerSideLayout: FC = ({ title, ogImageName, description, children }) => { + const theme = 'dark'; + const router = useRouter(); + const pathname = addTrailingSlash(router.pathname); + + let items = TOP_MENU_ITEMS; + + let activeIndex = useMemo( + () => items.map((item) => item.url).indexOf(pathname), + [pathname, items] + ); + + const linkHandler = useCallback( + (event, url) => { + event.preventDefault(); + router.push(url); + }, + [router] + ); + + const ogImagePath = useMemo( + () => `https://kotlinlang.org/assets/images/open-graph/${ogImageName ? ogImageName : 'general.png'}`, + [ogImageName] + ); + + const ogImageTwitterPath = useMemo( + () => (ogImageName ? ogImagePath : 'https://kotlinlang.org/assets/images/twitter/general.png'), + [ogImageName, ogImagePath] + ); + + return ( + <> + + {title} + + + + + + + + {description && } + + + + + + {description && } + + + + + + + + +
+ + + +
+
+ +
+ {children} +
+ + +
+ + ); +}; + +function addTrailingSlash(path: string): string { + return path.endsWith('/') ? path : `${path}/`; +} diff --git a/blocks/server-side/marquee/index.module.css b/blocks/server-side/marquee/index.module.css new file mode 100644 index 00000000000..c2999569227 --- /dev/null +++ b/blocks/server-side/marquee/index.module.css @@ -0,0 +1,44 @@ +.marquee { + position: relative; + width: 100%; + overflow: hidden; + display: flex; + --marquee-gap: 80px; +} + +.fadingEdges { + mask-image: linear-gradient( + to right, + hsl(0 0% 0% / 0), + hsl(0 0% 0% / 1) 20%, + hsl(0 0% 0% / 1) 80%, + hsl(0 0% 0% / 0) + ); +} + +.group { + display: flex; + align-items: center; + justify-content: space-around; + min-width: 100%; + animation: scroll 60s linear infinite; + gap: var(--marquee-gap); + flex-shrink: 0; +} + +.group:nth-child(1) { + margin-right: var(--marquee-gap); +} + +.paused { + animation-play-state: paused; +} + +@keyframes scroll { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(-100%); + } +} diff --git a/blocks/server-side/marquee/index.tsx b/blocks/server-side/marquee/index.tsx new file mode 100644 index 00000000000..75f5396fefb --- /dev/null +++ b/blocks/server-side/marquee/index.tsx @@ -0,0 +1,43 @@ +import React, { ReactNode, useRef, useState } from 'react'; +import styles from './index.module.css'; + +interface MarqueeProps { + children: ReactNode; + className?: string; + pauseOnHover?: boolean; + hasFadingEdges?: boolean; +} + +export const Marquee: React.FC = ({ + children, + className = '', + pauseOnHover = false, + hasFadingEdges = true, +}) => { + const containerRef = useRef(null); + const [isPaused, setIsPaused] = useState(false); + + const handleMouseEnter = () => { + if (pauseOnHover) { + setIsPaused(true); + } + }; + + const handleMouseLeave = () => { + if (pauseOnHover) { + setIsPaused(false); + } + }; + + return ( +
+
{children}
+
{children}
+
+ ); +}; diff --git a/blocks/server-side/performance/performance.module.css b/blocks/server-side/performance/performance.module.css new file mode 100644 index 00000000000..4ba53ba9a3c --- /dev/null +++ b/blocks/server-side/performance/performance.module.css @@ -0,0 +1,38 @@ +.cards { + display: grid; + grid-gap: 16px; +} + +.videos { + display: grid; + grid-gap: 16px; +} + +.videoCard { + border-radius: 16px; + overflow: hidden; + background: #19191C; + border: 1px solid rgba(255, 255, 255, 0.20) +} + +.videoCardDescription { + padding: 32px; + margin: 0; +} + +@media (min-width: 809px) { + .cards { + grid-template-columns: repeat(2, 1fr); + } +} + + +@media (min-width: 1001px) { + .cards { + grid-template-columns: repeat(4, 1fr); + } + + .videos { + grid-template-columns: repeat(2, 1fr); + } +} diff --git a/blocks/server-side/performance/performance.tsx b/blocks/server-side/performance/performance.tsx new file mode 100644 index 00000000000..4366dab6d78 --- /dev/null +++ b/blocks/server-side/performance/performance.tsx @@ -0,0 +1,85 @@ +import React, { FC } from 'react'; + +import cn from 'classnames'; + +import styles from './performance.module.css'; +import { useTextStyles } from '@rescui/typography'; + +import YoutubePlayer from '@jetbrains/kotlin-web-site-ui/out/components/youtube-player'; + +import { Card } from '../card/card'; + + +export const ServerSidePerformance: FC = ({}) => { + + const textCn = useTextStyles(); + + return ( +
+
+

+ Performance: optimized for high-load +

+ +

+ From lightweight concurrency to efficient memory use,
+ Kotlin and JVM combo brings serious advantage +

+ +
+ + + + + + + +
+ +
+ +
+
+ +
+

+ Watch the full story on Kotlin coroutines from their creator, Roman Elizarov. +

+
+ +
+
+ +
+

+ Watch the full story on Kotlin coroutines from their creator, Roman Elizarov. +

+
+ + +
+ +
+
+ ); +}; diff --git a/components/code-highlight/code-highlight.tsx b/components/code-highlight/code-highlight.tsx new file mode 100644 index 00000000000..8a2ce107cc6 --- /dev/null +++ b/components/code-highlight/code-highlight.tsx @@ -0,0 +1,27 @@ +import React, { FC } from 'react'; +import { codeToHtml } from 'shiki'; + +interface CodeHighlightProps { + code: string; + className?: string; + language?: string; +} + +export const CodeHighlight: FC = ({ code, className = '', language = 'kotlin' }) => { + const [highlightedCode, setHighlightedCode] = React.useState(''); + + React.useEffect(() => { + const highlight = async () => { + const html = await codeToHtml(code, { + theme: 'dracula', + lang: language, + }); + setHighlightedCode(html); + }; + + highlight(); + }, [code]); + + return
; +}; + diff --git a/components/snap-carousel/snap-carousel.module.css b/components/snap-carousel/snap-carousel.module.css new file mode 100644 index 00000000000..30f0a8e1db6 --- /dev/null +++ b/components/snap-carousel/snap-carousel.module.css @@ -0,0 +1,41 @@ +.block { + display: flex; + width: 100%; +} + +.carousel { + --slides-gap: 32px; + width: 100%; + box-sizing: border-box; +} + +.wrapper { + overflow-x: scroll; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + + scrollbar-width: thin; + scrollbar-color: transparent transparent; + + position: relative; + display: flex; + gap: 32px; + + &::-webkit-scrollbar { + display: none; /* for Chrome, Safari, and Opera */ + } +} + +.slide { + flex: 0 0 auto; + width: 100%; + scroll-snap-align: center; +} + +.navigation { + display: flex; + align-items: center; + justify-content: center; + gap: 16px; + margin-top: 24px; +} diff --git a/components/snap-carousel/snap-carousel.tsx b/components/snap-carousel/snap-carousel.tsx new file mode 100644 index 00000000000..3929ab6a43f --- /dev/null +++ b/components/snap-carousel/snap-carousel.tsx @@ -0,0 +1,58 @@ +import React, { useMemo, ReactNode } from 'react'; +import cn from 'classnames'; +import { useSnapCarousel } from 'react-snap-carousel'; + +import styles from './snap-carousel.module.css'; +import { useTextStyles } from '@rescui/typography'; +import { Button } from '@rescui/button'; +import { ArrowLeftIcon, ArrowRightIcon } from '@rescui/icons'; + +interface SnapCarouselProps { + children: ReactNode; +} + +export const SnapCarousel = ({ children }: SnapCarouselProps) => { + const { scrollRef, activePageIndex, prev, next, pages } = useSnapCarousel(); + const textCn = useTextStyles(); + + const childrenWithProps = useMemo( + () => + React.Children.map(children, (child, index) => { + if (React.isValidElement(child)) { + const isChildFunction = typeof child.type === 'function'; + return React.cloneElement(child, { + ...(isChildFunction && { isActive: activePageIndex === index }), + className: cn(styles.slide, child.props.className) + }); + } + return child; + }), + [children, activePageIndex] + ); + + return ( +
+
+
+
+ {childrenWithProps} +
+
+
+ +
+
+
+ + ); +}; diff --git a/package.json b/package.json index f98c0aa5eff..f1d1c95ced5 100644 --- a/package.json +++ b/package.json @@ -68,10 +68,12 @@ "react-outside-click-handler": "1.3.0", "react-remove-scroll-bar": "2.3.4", "react-scrollbar-size": "5.0.0", + "react-snap-carousel": "0.5.1", "react-swipeable-views": "0.14.0", "resolve-url-loader": "4.0.0", "rollup": "2.47.0", "sha.js": "^2.4.11", + "shiki": "3.6.0", "svgo": "2.7.0", "svgo-loader": "3.0.0", "tslib": "2.2.0", diff --git a/pages/global.css b/pages/global.css index 0f81945714e..8e934022422 100644 --- a/pages/global.css +++ b/pages/global.css @@ -8,6 +8,7 @@ html { min-width: 320px; + scroll-behavior: smooth; } img { diff --git a/pages/server-side/index.tsx b/pages/server-side/index.tsx new file mode 100644 index 00000000000..ab60a6252bd --- /dev/null +++ b/pages/server-side/index.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { ServerSideLayout } from '../../blocks/server-side/layout/server-side-layout'; +import { ServerSideHero } from '../../blocks/server-side/hero/hero'; +import { ServerSidePerformance } from '../../blocks/server-side/performance/performance'; +import FeaturesSection from '../../blocks/server-side/features-section'; +import CustomerLogoMarqueeSection from '../../blocks/server-side/customer-logo-marquee'; +import { Ecosystem } from '../../blocks/server-side/ecosystem/ecosystem'; +import { HowToStart } from '../../blocks/server-side/how-to-start/how-to-start'; +import { FavoriteTools } from '../../blocks/server-side/favorite-tools/favorite-tools'; +import { AdditionalMaterials } from '../../blocks/server-side/additional-materials/additional-materials'; +import { GetStarted } from '../../blocks/server-side/get-started/get-started'; + +import './styles.css'; + +function Index() { + return ( + + + + + + + + + + + + ); +} + +export default Index; diff --git a/pages/server-side/styles.css b/pages/server-side/styles.css new file mode 100644 index 00000000000..30e2dd3b49f --- /dev/null +++ b/pages/server-side/styles.css @@ -0,0 +1,28 @@ +/*Spacer*/ + +@media (max-width: 1024px) { + .spacer-md { + margin-top: 32px; + } +} + +@media (max-width: 768px) { + .spacer-md { + margin-top: 16px; + } +} + + +.section-offset { + margin-top: 72px; + padding-bottom: 72px; + position: relative; + + &:before { + content: ''; + display: block; + height: 72px; + margin-top: -72px; + visibility: hidden; + } +} diff --git a/yarn.lock b/yarn.lock index 3d0eb7addc8..ed8e8746b34 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1991,6 +1991,60 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.3.0.tgz#f5635b36fc0dad96ef1e542a302cd914230188c0" integrity sha512-IthPJsJR85GhOkp3Hvp8zFOPK5ynKn6STyHa/WZpioK7E1aYDiBzpqQPrngc14DszIUkIrdd3k9Iu0XSzlP/1w== +"@shikijs/core@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-3.6.0.tgz#11048ab2bd9af1bde34eb3c77af1a638a5ae2737" + integrity sha512-9By7Xb3olEX0o6UeJyPLI1PE1scC4d3wcVepvtv2xbuN9/IThYN4Wcwh24rcFeASzPam11MCq8yQpwwzCgSBRw== + dependencies: + "@shikijs/types" "3.6.0" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.5" + +"@shikijs/engine-javascript@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-3.6.0.tgz#8d3d6725e43240650e8aa110520b15e8b39df3d5" + integrity sha512-7YnLhZG/TU05IHMG14QaLvTW/9WiK8SEYafceccHUSXs2Qr5vJibUwsDfXDLmRi0zHdzsxrGKpSX6hnqe0k8nA== + dependencies: + "@shikijs/types" "3.6.0" + "@shikijs/vscode-textmate" "^10.0.2" + oniguruma-to-es "^4.3.3" + +"@shikijs/engine-oniguruma@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.6.0.tgz#dce6074a258f1b349ff043eddba9779e76984769" + integrity sha512-nmOhIZ9yT3Grd+2plmW/d8+vZ2pcQmo/UnVwXMUXAKTXdi+LK0S08Ancrz5tQQPkxvjBalpMW2aKvwXfelauvA== + dependencies: + "@shikijs/types" "3.6.0" + "@shikijs/vscode-textmate" "^10.0.2" + +"@shikijs/langs@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-3.6.0.tgz#e3faea60e12c9bcdbebeeac14975c71f927bc7cb" + integrity sha512-IdZkQJaLBu1LCYCwkr30hNuSDfllOT8RWYVZK1tD2J03DkiagYKRxj/pDSl8Didml3xxuyzUjgtioInwEQM/TA== + dependencies: + "@shikijs/types" "3.6.0" + +"@shikijs/themes@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-3.6.0.tgz#6003780e033f9fec6b1336395a8994be17959e81" + integrity sha512-Fq2j4nWr1DF4drvmhqKq8x5vVQ27VncF8XZMBuHuQMZvUSS3NBgpqfwz/FoGe36+W6PvniZ1yDlg2d4kmYDU6w== + dependencies: + "@shikijs/types" "3.6.0" + +"@shikijs/types@3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-3.6.0.tgz#0a4944724320eaa6f151d26d8f982a7f4a0b53ff" + integrity sha512-cLWFiToxYu0aAzJqhXTQsFiJRTFDAGl93IrMSBNaGSzs7ixkLfdG6pH11HipuWFGW5vyx4X47W8HDQ7eSrmBUg== + dependencies: + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz#a90ab31d0cc1dfb54c66a69e515bf624fa7b2224" + integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -2167,6 +2221,13 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/hast@^3.0.0", "@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + "@types/http-errors@*": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" @@ -2189,6 +2250,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + "@types/mime@^1": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" @@ -2286,6 +2354,11 @@ dependencies: "@types/node" "*" +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== + "@types/ws@^8.5.5": version "8.5.12" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.12.tgz#619475fe98f35ccca2a2f6c137702d85ec247b7e" @@ -2337,6 +2410,11 @@ "@typescript-eslint/types" "5.59.7" eslint-visitor-keys "^3.3.0" +"@ungap/structured-clone@^1.0.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + "@wasm-codecs/gifsicle@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@wasm-codecs/gifsicle/-/gifsicle-1.0.0.tgz#6d14c97a52cc01d1dd344b6e722509a007e4feb2" @@ -3223,6 +3301,11 @@ caniuse-lite@^1.0.30001251, caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.300016 resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz" integrity sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw== +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -3251,6 +3334,16 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + check-more-types@2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" @@ -3386,6 +3479,11 @@ colorette@^2.0.10, colorette@^2.0.14: resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + commander@^10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" @@ -3777,6 +3875,11 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -3804,6 +3907,13 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -4953,6 +5063,30 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +hast-util-to-html@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz#ccc673a55bb8e85775b08ac28380f72d47167005" + integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + hoist-non-react-statics@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -4983,6 +5117,11 @@ html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -5694,6 +5833,21 @@ map-stream@~0.1.0: resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g== +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" @@ -5736,6 +5890,38 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromark-util-character@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" + integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" + integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" + integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-symbol@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" + integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== + +micromark-util-types@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" + integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== + micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" @@ -6120,6 +6306,20 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +oniguruma-parser@^0.12.1: + version "0.12.1" + resolved "https://registry.yarnpkg.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz#82ba2208d7a2b69ee344b7efe0ae930c627dcc4a" + integrity sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w== + +oniguruma-to-es@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz#50db2c1e28ec365e102c1863dfd3d1d1ad18613e" + integrity sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg== + dependencies: + oniguruma-parser "^0.12.1" + regex "^6.0.1" + regex-recursion "^6.0.2" + open@^8.0.9: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" @@ -6514,6 +6714,11 @@ prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, object-assign "^4.1.1" react-is "^16.13.1" +property-information@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" + integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -6724,6 +6929,11 @@ react-scrollbar-size@5.0.0: resolved "https://registry.yarnpkg.com/react-scrollbar-size/-/react-scrollbar-size-5.0.0.tgz#29892779dfcb9077ce18e2483d1dba6400c58fb0" integrity sha512-Ly3OuRMz4yDFViTh+ANH6TrG8EqrgjC1uxxm2a/95+2Ijy3XT+bWtzm4QmgZUcUVg+8BCKzmPMM7z39ZtucDIQ== +react-snap-carousel@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/react-snap-carousel/-/react-snap-carousel-0.5.1.tgz#7cc274796cf19f6217d3e4c8f001264c30171a48" + integrity sha512-t8FMtBUUIi65ie2B1ton1ew3LxONMNBeJXOZUCmg9lGZnT25H8vEj8Z0+UeWVmT9mgSdEKTnySWVWWeCzE90KA== + react-style-singleton@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" @@ -6883,6 +7093,25 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== +regex-recursion@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/regex-recursion/-/regex-recursion-6.0.2.tgz#a0b1977a74c87f073377b938dbedfab2ea582b33" + integrity sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg== + dependencies: + regex-utilities "^2.3.0" + +regex-utilities@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-utilities/-/regex-utilities-2.3.0.tgz#87163512a15dce2908cf079c8960d5158ff43280" + integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng== + +regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/regex/-/regex-6.0.1.tgz#282fa4435d0c700b09c0eb0982b602e05ab6a34f" + integrity sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA== + dependencies: + regex-utilities "^2.3.0" + regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" @@ -7321,6 +7550,20 @@ shell-quote@^1.8.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== +shiki@3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-3.6.0.tgz#217309a83345ca3e77da87a93fa1720bda1b8790" + integrity sha512-tKn/Y0MGBTffQoklaATXmTqDU02zx8NYBGQ+F6gy87/YjKbizcLd+Cybh/0ZtOBX9r1NEnAy/GTRDKtOsc1L9w== + dependencies: + "@shikijs/core" "3.6.0" + "@shikijs/engine-javascript" "3.6.0" + "@shikijs/engine-oniguruma" "3.6.0" + "@shikijs/langs" "3.6.0" + "@shikijs/themes" "3.6.0" + "@shikijs/types" "3.6.0" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -7440,6 +7683,11 @@ sourcemap-codec@^1.4.8: resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + spdy-transport@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" @@ -7605,6 +7853,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -7836,6 +8092,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -7992,6 +8253,44 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -8086,6 +8385,22 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +vfile-message@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" + integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== + dependencies: + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" + wait-on@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7" @@ -8357,3 +8672,8 @@ yaml@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== + +zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==