feat: revamp homepage (#2332)

feat: revamp homepage
This commit is contained in:
Henry 2024-03-19 15:03:13 +09:00 committed by GitHub
commit a1c16fa6f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 2441 additions and 887 deletions

View File

@ -3,4 +3,5 @@ UMAMI_PROJECT_API_KEY=xxxx
UMAMI_APP_URL=xxxx UMAMI_APP_URL=xxxx
ALGOLIA_API_KEY=xxxx ALGOLIA_API_KEY=xxxx
ALGOLIA_APP_ID=xxxx ALGOLIA_APP_ID=xxxx
GITHUB_ACCESS_TOKEN=xxxx GITHUB_ACCESS_TOKEN=xxxx
API_KEY_BREVO=xxxx

View File

@ -16,7 +16,7 @@ tags: [Postmortem]
<meta property="og:description" content="Comprehensive postmortem on the Jan AI v0.4.4 Bitdefender false positive incident on January 10, 2024. Learn about the investigation, solutions, and preventive measures." /> <meta property="og:description" content="Comprehensive postmortem on the Jan AI v0.4.4 Bitdefender false positive incident on January 10, 2024. Learn about the investigation, solutions, and preventive measures." />
<meta property="og:url" content="https://jan.ai/blog/postmortems/january-10-2024-bitdefender-false-positive-flag/" /> <meta property="og:url" content="https://jan.ai/blog/postmortems/january-10-2024-bitdefender-false-positive-flag/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>

View File

@ -26,7 +26,7 @@ keywords:
<meta property="og:description" content="Discover the modular architecture of Jan, a ChatGPT alternative that runs on your own computer. Learn about Jan's local API server, Desktop UI, and the Nitro inference engine." /> <meta property="og:description" content="Discover the modular architecture of Jan, a ChatGPT alternative that runs on your own computer. Learn about Jan's local API server, Desktop UI, and the Nitro inference engine." />
<meta property="og:url" content="https://jan.ai/developer/architecture/" /> <meta property="og:url" content="https://jan.ai/developer/architecture/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
:::warning :::warning

View File

@ -26,7 +26,7 @@ keywords:
<meta property="og:description" content="Learn how Jan, a ChatGPT alternative, leverages a local filesystem for data persistence, promoting composability and tinkerability similar to VSCode." /> <meta property="og:description" content="Learn how Jan, a ChatGPT alternative, leverages a local filesystem for data persistence, promoting composability and tinkerability similar to VSCode." />
<meta property="og:url" content="https://jan.ai/developer/file-based/" /> <meta property="og:url" content="https://jan.ai/developer/file-based/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
:::warning :::warning

View File

@ -26,7 +26,7 @@ keywords:
<meta property="og:description" content="Explore Jan's UI Kit for customizing the user interface to fit your brand and style. Learn how to personalize your application with Jan's flexible UI components." /> <meta property="og:description" content="Explore Jan's UI Kit for customizing the user interface to fit your brand and style. Learn how to personalize your application with Jan's flexible UI components." />
<meta property="og:url" content="https://jan.ai/developer/ui/" /> <meta property="og:url" content="https://jan.ai/developer/ui/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
:::warning :::warning

View File

@ -29,7 +29,7 @@ keywords:
<meta property="og:description" content="Comprehensive guide to installing and setting up Jan for development. Covers hardware, system requirements, and step-by-step instructions for developers." /> <meta property="og:description" content="Comprehensive guide to installing and setting up Jan for development. Covers hardware, system requirements, and step-by-step instructions for developers." />
<meta property="og:url" content="https://jan.ai/developer/prereq/" /> <meta property="og:url" content="https://jan.ai/developer/prereq/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
## Requirements ## Requirements

View File

@ -26,7 +26,7 @@ keywords:
<meta property="og:description" content="Guide for developers on building extensions on top of the Jan Framework. Learn about Jan's extensible framework for AI applications, available on all platforms." /> <meta property="og:description" content="Guide for developers on building extensions on top of the Jan Framework. Learn about Jan's extensible framework for AI applications, available on all platforms." />
<meta property="og:url" content="https://jan.ai/developer/" /> <meta property="og:url" content="https://jan.ai/developer/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
The following docs are aimed at developers who want to build extensions on top of the Jan Framework. The following docs are aimed at developers who want to build extensions on top of the Jan Framework.

View File

@ -28,7 +28,7 @@ keywords:
<meta property="og:description" content="Step-by-step guide on how to build your first extension for Jan AI. Learn how to use the extension template and integrate your custom functionality into Jan." /> <meta property="og:description" content="Step-by-step guide on how to build your first extension for Jan AI. Learn how to use the extension template and integrate your custom functionality into Jan." />
<meta property="og:url" content="https://jan.ai/developer/build-extension/your-first-extension/" /> <meta property="og:url" content="https://jan.ai/developer/build-extension/your-first-extension/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
:::caution :::caution

View File

@ -28,7 +28,7 @@ keywords:
<meta property="og:description" content="Learn how to resolve the 'Permission Denied' error encountered while running Jan AI by changing ownership of the `~/.npm` directory to the current user." /> <meta property="og:description" content="Learn how to resolve the 'Permission Denied' error encountered while running Jan AI by changing ownership of the `~/.npm` directory to the current user." />
<meta property="og:url" content="https://jan.ai/troubleshooting/permission-denied" /> <meta property="og:url" content="https://jan.ai/troubleshooting/permission-denied" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
When you run Jan, you may encounter the following error: When you run Jan, you may encounter the following error:

View File

@ -27,7 +27,7 @@ keywords:
<meta property="og:description" content="Learn how to configure settings for default extensions in Jan AI, including how to enable/disable extensions and modify their configurations." /> <meta property="og:description" content="Learn how to configure settings for default extensions in Jan AI, including how to enable/disable extensions and modify their configurations." />
<meta property="og:url" content="https://jan.ai/guides/using-extensions/extension-settings/" /> <meta property="og:url" content="https://jan.ai/guides/using-extensions/extension-settings/" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
The current Jan Desktop Client has some default extensions built on top of this framework to enhance the user experience. In this guide, we will show you the list of default extensions and how to configure extension settings. The current Jan Desktop Client has some default extensions built on top of this framework to enhance the user experience. In this guide, we will show you the list of default extensions and how to configure extension settings.

View File

@ -13,7 +13,7 @@ title: GPUs and VRAM
<meta property="og:description" content="Explore the world of GPUs and VRAM, learn their importance in gaming, AI, machine learning, and more. Understand how to connect a GPU to a motherboard and choose the right graphics card for your needs." /> <meta property="og:description" content="Explore the world of GPUs and VRAM, learn their importance in gaming, AI, machine learning, and more. Understand how to connect a GPU to a motherboard and choose the right graphics card for your needs." />
<meta property="og:url" content="https://jan.ai/guides/gpus-and-vram" /> <meta property="og:url" content="https://jan.ai/guides/gpus-and-vram" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
## What Is a GPU? ## What Is a GPU?

View File

@ -13,7 +13,7 @@ title: Recommended AI Hardware by Budget
<meta property="og:description" content="Explore recommended AI hardware builds for entry-level, mid-range, and high-end budgets. Find the perfect balance of performance and cost for your AI and machine learning projects." /> <meta property="og:description" content="Explore recommended AI hardware builds for entry-level, mid-range, and high-end budgets. Find the perfect balance of performance and cost for your AI and machine learning projects." />
<meta property="og:url" content="https://jan.ai/guides/recommended-ai-hardware-by-budget" /> <meta property="og:url" content="https://jan.ai/guides/recommended-ai-hardware-by-budget" />
<meta property="og:type" content="article" /> <meta property="og:type" content="article" />
<meta property="og:image" content="https://jan.ai/img/og-image.png" /> <meta property="og:image" content="https://jan.ai/img/og-image.svg" />
</head> </head>
> :warning: **Warning:** Do your own research before any purchase. Jan is not liable for compatibility, performance or other issues. Products can become outdated quickly. > :warning: **Warning:** Do your own research before any purchase. Jan is not liable for compatibility, performance or other issues. Products can become outdated quickly.

View File

@ -199,7 +199,7 @@ const config = {
// Docs: https://docusaurus.io/docs/api/themes/configuration // Docs: https://docusaurus.io/docs/api/themes/configuration
themeConfig: { themeConfig: {
image: 'img/og-image.png', image: 'img/og-image.svg',
// Only for react live // Only for react live
liveCodeBlock: { liveCodeBlock: {
playgroundPosition: 'bottom', playgroundPosition: 'bottom',
@ -222,8 +222,7 @@ const config = {
metadata: [ metadata: [
{ {
name: 'description', name: 'description',
content: content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
}, },
{ {
name: 'keywords', name: 'keywords',
@ -233,32 +232,30 @@ const config = {
{ name: 'robots', content: 'index, follow' }, { name: 'robots', content: 'index, follow' },
{ {
property: 'og:title', property: 'og:title',
content: 'Jan | Open-source ChatGPT Alternative', content: 'Jan AI | Rethink the Computer',
}, },
{ {
property: 'og:description', property: 'og:description',
content: content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
}, },
{ {
property: 'og:image', property: 'og:image',
content: 'https://jan.ai/img/og-image.png', content: 'https://jan.ai/img/og-image.svg',
}, },
{ property: 'og:type', content: 'website' }, { property: 'og:type', content: 'website' },
{ property: 'twitter:card', content: 'summary_large_image' }, { property: 'twitter:card', content: 'summary_large_image' },
{ property: 'twitter:site', content: '@janframework' }, { property: 'twitter:site', content: '@janframework' },
{ {
property: 'twitter:title', property: 'twitter:title',
content: 'Jan | Open-source ChatGPT Alternative', content: 'Jan AI | Rethink the Computer',
}, },
{ {
property: 'twitter:description', property: 'twitter:description',
content: content: `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
}, },
{ {
property: 'twitter:image', property: 'twitter:image',
content: 'https://jan.ai/img/og-image.png', content: 'https://jan.ai/img/og-image.svg',
}, },
], ],
headTags: [ headTags: [
@ -280,8 +277,7 @@ const config = {
'@context': 'https://schema.org/', '@context': 'https://schema.org/',
'@type': 'localAI', '@type': 'localAI',
'name': 'Jan', 'name': 'Jan',
'description': 'description': `Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution.`,
'Jan runs 100% offline on your computer, utilizes open-source AI models, prioritizes privacy, and is highly customizable.',
'keywords': 'keywords':
'Jan AI, Jan, ChatGPT alternative, local AI, private AI, conversational AI, no-subscription fee, large language model ', 'Jan AI, Jan, ChatGPT alternative, local AI, private AI, conversational AI, no-subscription fee, large language model ',
'applicationCategory': 'BusinessApplication', 'applicationCategory': 'BusinessApplication',
@ -338,10 +334,15 @@ const config = {
position: 'left', position: 'left',
label: 'Ecosystem', label: 'Ecosystem',
}, },
{
to: 'download',
position: 'left',
label: 'Download',
},
// { // {
// type: "docSidebar", // type: "docSidebar",
// sidebarId: "pricingSidebar", // sidebarId: "pricingSidebar",
// positionL: "left", // positionl: "left",
// label: "Pricing", // label: "Pricing",
// }, // },
// Navbar right // Navbar right
@ -403,6 +404,11 @@ const config = {
}, },
}, },
// Put your custom environment here
customFields: {
apiKeyBrevo: process.env.API_KEY_BREVO,
},
themes: ['@docusaurus/theme-live-codeblock', '@docusaurus/theme-mermaid'], themes: ['@docusaurus/theme-live-codeblock', '@docusaurus/theme-mermaid'],
} }

View File

@ -37,9 +37,12 @@
"postcss": "^8.4.30", "postcss": "^8.4.30",
"posthog-docusaurus": "^2.0.0", "posthog-docusaurus": "^2.0.0",
"prism-react-renderer": "^1.3.5", "prism-react-renderer": "^1.3.5",
"lucide-react": "^0.291.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hook-form": "^7.47.0",
"react-icons": "^4.11.0", "react-icons": "^4.11.0",
"react-tweet": "^3.2.0",
"redocusaurus": "^2.0.0", "redocusaurus": "^2.0.0",
"sass": "^1.69.3", "sass": "^1.69.3",
"tailwind-merge": "^2.1.0", "tailwind-merge": "^2.1.0",
@ -47,7 +50,7 @@
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "^3.0.0", "@docusaurus/module-type-aliases": "^3.0.0",
"dotenv": "^16.3.1", "dotenv": "^16.4.5",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7"
}, },
"browserslist": { "browserslist": {

View File

@ -15,77 +15,76 @@
const sidebars = { const sidebars = {
aboutSidebar: [ aboutSidebar: [
{ {
type: "category", type: 'category',
label: "What is Jan?", label: 'What is Jan?',
link: { type: "doc", id: "about/about" }, link: { type: 'doc', id: 'about/about' },
items: [ items: [
//"about/roadmap", //"about/roadmap",
"community/community", 'community/community',
], ],
}, },
{ {
type: "category", type: 'category',
label: "Who we are", label: 'Who we are',
link: { type: "doc", id: "team/team" }, link: { type: 'doc', id: 'team/team' },
items: ["team/join-us", "team/contributor-program"], items: ['team/join-us', 'team/contributor-program'],
}, },
"wall-of-love", 'wall-of-love',
{ {
type: "category", type: 'category',
label: "How We Work", label: 'How We Work',
link: { type: "doc", id: "how-we-work" }, link: { type: 'doc', id: 'how-we-work' },
items: [ items: [
"how-we-work/strategy/strategy", 'how-we-work/strategy/strategy',
"how-we-work/project-management/project-management", 'how-we-work/project-management/project-management',
{ {
type: "category", type: 'category',
label: "Engineering", label: 'Engineering',
link: { type: "doc", id: "how-we-work/engineering/engineering" }, link: { type: 'doc', id: 'how-we-work/engineering/engineering' },
items: [ items: [
"how-we-work/engineering/ci-cd", 'how-we-work/engineering/ci-cd',
"how-we-work/engineering/qa", 'how-we-work/engineering/qa',
], ],
}, },
"how-we-work/product-design/product-design", 'how-we-work/product-design/product-design',
"how-we-work/analytics/analytics", 'how-we-work/analytics/analytics',
"how-we-work/website-docs/website-docs", 'how-we-work/website-docs/website-docs',
], ],
}, },
"acknowledgements", 'acknowledgements',
{ {
type: "category", type: 'category',
label: "FAQ", label: 'FAQ',
link: { type: "doc", id: "about/faq" }, link: { type: 'doc', id: 'about/faq' },
items: items: [],
[],
}, },
], ],
productSidebar: [ productSidebar: [
{ {
type: "category", type: 'category',
label: "Platforms", label: 'Platforms',
collapsible: false, collapsible: false,
items: [ items: [
"platforms/desktop", 'platforms/desktop',
"server-suite/home-server", 'server-suite/home-server',
// "server-suite/enterprise", // "server-suite/enterprise",
// "platforms/mobile", // "platforms/mobile",
// "platforms/hub", // "platforms/hub",
], ],
}, },
{ {
type: "category", type: 'category',
collapsible: true, collapsible: true,
collapsed: false, collapsed: false,
label: "Features", label: 'Features',
link: { type: "doc", id: "features/features" }, link: { type: 'doc', id: 'features/features' },
items: [ items: [
"features/local", 'features/local',
"features/remote", 'features/remote',
"features/api-server", 'features/api-server',
"features/extensions-framework", 'features/extensions-framework',
"features/agents-framework", 'features/agents-framework',
"features/data-security", 'features/data-security',
], ],
}, },
// NOTE: Jan Server Suite will be torn out into it's own section in the future // NOTE: Jan Server Suite will be torn out into it's own section in the future
@ -103,56 +102,56 @@ const sidebars = {
], ],
solutionSidebar: [ solutionSidebar: [
{ {
type: "category", type: 'category',
label: "Use Cases", label: 'Use Cases',
collapsed: true, collapsed: true,
collapsible: true, collapsible: true,
items: ["solutions/ai-pc", "solutions/chatgpt-alternative"], items: ['solutions/ai-pc', 'solutions/chatgpt-alternative'],
}, },
{ {
type: "category", type: 'category',
label: "Sectors", label: 'Sectors',
collapsed: true, collapsed: true,
collapsible: true, collapsible: true,
items: [ items: [
"solutions/finance", 'solutions/finance',
"solutions/healthcare", 'solutions/healthcare',
"solutions/legal", 'solutions/legal',
"solutions/government", 'solutions/government',
], ],
}, },
{ {
type: "category", type: 'category',
label: "Organization Type", label: 'Organization Type',
collapsed: true, collapsed: true,
collapsible: true, collapsible: true,
items: [ items: [
"solutions/developers", 'solutions/developers',
"solutions/consultants", 'solutions/consultants',
"solutions/startups", 'solutions/startups',
"solutions/enterprises", 'solutions/enterprises',
], ],
}, },
], ],
pricingSidebar: ["pricing/pricing"], pricingSidebar: ['pricing/pricing'],
ecosystemSidebar: [ ecosystemSidebar: [
"ecosystem/ecosystem", 'ecosystem/ecosystem',
{ {
type: "category", type: 'category',
label: "Partners", label: 'Partners',
link: { type: "doc", id: "partners/partners" }, link: { type: 'doc', id: 'partners/partners' },
collapsible: true, collapsible: true,
items: ["partners/become-a-partner"], items: ['partners/become-a-partner'],
}, },
{ {
type: "category", type: 'category',
label: "Integrations", label: 'Integrations',
link: { type: "doc", id: "integrations" }, link: { type: 'doc', id: 'integrations' },
items: [ items: [
{ {
type: "autogenerated", type: 'autogenerated',
dirName: "integrations", dirName: 'integrations',
}, },
], ],
}, },
@ -165,159 +164,154 @@ const sidebars = {
// ], // ],
guidesSidebar: [ guidesSidebar: [
{ {
type: "category", type: 'category',
label: "Get Started", label: 'Get Started',
collapsible: false, collapsible: false,
className: "head_Menu", className: 'head_Menu',
items: [ items: [
"guides/quickstart", 'guides/quickstart',
"guides/install", 'guides/install',
"guides/start-server", 'guides/start-server',
"guides/models-list" 'guides/models-list',
] ],
}, },
{ {
type: "category", type: 'category',
label: "Guides", label: 'Guides',
collapsible: false, collapsible: false,
className: "head_Menu", className: 'head_Menu',
items: [ items: ['guides/best-practices', 'guides/thread'],
"guides/best-practices",
"guides/thread",
]
}, },
{ {
type: "category", type: 'category',
label: "Advanced Features", label: 'Advanced Features',
collapsible: false, collapsible: false,
className: "head_Menu", className: 'head_Menu',
items: [ items: [
{ {
type: "category", type: 'category',
label: "Advanced Settings", label: 'Advanced Settings',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/advanced-settings/advanced-settings", id: 'guides/advanced-settings/advanced-settings',
}, },
items: [ items: ['guides/advanced-settings/http-proxy'],
"guides/advanced-settings/http-proxy",
]
}, },
{ {
type: "category", type: 'category',
label: "Advanced Model Setup", label: 'Advanced Model Setup',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/models/README", id: 'guides/models/README',
}, },
items: [ items: [
"guides/models/customize-engine", 'guides/models/customize-engine',
"guides/models/import-models", 'guides/models/import-models',
"guides/models/integrate-remote", 'guides/models/integrate-remote',
] ],
}, },
{ {
type: "category", type: 'category',
label: "Inference Providers", label: 'Inference Providers',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/providers/README", id: 'guides/providers/README',
}, },
items: [ items: [
"guides/providers/llama-cpp", 'guides/providers/llama-cpp',
"guides/providers/tensorrt-llm", 'guides/providers/tensorrt-llm',
] ],
}, },
{ {
type: "category", type: 'category',
label: "Extensions", label: 'Extensions',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/extensions/README", id: 'guides/extensions/README',
}, },
items: [ items: [
"guides/extensions/import-ext", 'guides/extensions/import-ext',
"guides/extensions/setup-ext", 'guides/extensions/setup-ext',
] ],
}, },
{ {
type: "category", type: 'category',
label: "Integrations", label: 'Integrations',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/integration/README", id: 'guides/integration/README',
}, },
items: [ items: [
"guides/integration/azure", 'guides/integration/azure',
"guides/integration/discord", 'guides/integration/discord',
"guides/integration/groq", 'guides/integration/groq',
"guides/integration/lmstudio", 'guides/integration/lmstudio',
"guides/integration/mistral", 'guides/integration/mistral',
"guides/integration/ollama", 'guides/integration/ollama',
"guides/integration/openinterpreter", 'guides/integration/openinterpreter',
"guides/integration/openrouter", 'guides/integration/openrouter',
"guides/integration/raycast", 'guides/integration/raycast',
"guides/integration/vscode", 'guides/integration/vscode',
] ],
}, },
] ],
}, },
{ {
type: "category", type: 'category',
label: "Troubleshooting", label: 'Troubleshooting',
collapsible: false, collapsible: false,
className: "head_Menu", className: 'head_Menu',
items: [ items: [
{ {
type: "category", type: 'category',
label: "Error Codes", label: 'Error Codes',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/error-codes/README", id: 'guides/error-codes/README',
}, },
items: [ items: [
"guides/error-codes/how-to-get-error-logs", 'guides/error-codes/how-to-get-error-logs',
"guides/error-codes/permission-denied", 'guides/error-codes/permission-denied',
"guides/error-codes/something-amiss", 'guides/error-codes/something-amiss',
"guides/error-codes/undefined-issue", 'guides/error-codes/undefined-issue',
"guides/error-codes/unexpected-token", 'guides/error-codes/unexpected-token',
] ],
}, },
{ {
type: "category", type: 'category',
label: "Common Error", label: 'Common Error',
className: "head_SubMenu", className: 'head_SubMenu',
link: { link: {
type: 'doc', type: 'doc',
id: "guides/common-error/README", id: 'guides/common-error/README',
}, },
items: [ items: [
"guides/common-error/broken-build", 'guides/common-error/broken-build',
"guides/common-error/not-using-gpu", 'guides/common-error/not-using-gpu',
] ],
}, },
"guides/faq" 'guides/faq',
] ],
}, },
], ],
developerSidebar: [ developerSidebar: [
{ {
type: "autogenerated", type: 'autogenerated',
dirName: "developer", dirName: 'developer',
}, },
], ],
releasesSidebar: [ releasesSidebar: [
{ {
type: "autogenerated", type: 'autogenerated',
dirName: "releases", dirName: 'releases',
}, },
] ],
}; }
module.exports = sidebars; module.exports = sidebars

View File

@ -1,32 +1,43 @@
import React from "react"; import React from 'react'
import { useAppStars } from "@site/src/hooks/useAppStars"; import { useAppStars } from '@site/src/hooks/useAppStars'
import { useAppRelease } from "@site/src/hooks/useAppRelease"; import { useAppRelease } from '@site/src/hooks/useAppRelease'
import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai'
import { BiLogoDiscordAlt } from "react-icons/bi"; import { BiLogoDiscordAlt } from 'react-icons/bi'
import { FaLinkedin } from 'react-icons/fa'
const socials = [ const socials = [
{ {
icon: <AiOutlineTwitter className="text-xl text-white" />, icon: <AiOutlineTwitter className="text-xl text-white" />,
href: "https://twitter.com/janframework", href: 'https://twitter.com/janframework',
}, },
{ {
icon: <BiLogoDiscordAlt className="text-xl text-white" />, icon: <BiLogoDiscordAlt className="text-xl text-white" />,
href: "https://discord.com/invite/FTk2MvZwJH", href: 'https://discord.com/invite/FTk2MvZwJH',
}, },
{ {
icon: <AiOutlineGithub className="text-lg text-white" />, icon: <AiOutlineGithub className="text-lg text-white" />,
href: "https://github.com/janhq/jan", href: 'https://github.com/janhq/jan',
}, },
]; {
icon: <FaLinkedin className="text-lg text-white" />,
href: 'https://www.linkedin.com/company/janframework/',
},
]
export default function AnnoncementBanner() { export default function AnnoncementBanner() {
const { stargazers } = useAppStars(); const { stargazers } = useAppStars()
const { release } = useAppRelease(); const { release } = useAppRelease()
return ( return (
<div className="h-10 w-full flex-shrink-0 bg-blue-600"> <div
className="h-10 w-full flex-shrink-0"
style={{
background:
'radial-gradient(58.83% 95.12% at 62.37% 97.91%, rgba(238, 203, 255, 0.59) 0%, rgba(255, 255, 255, 0.00) 100%), linear-gradient(249deg, rgba(67, 119, 233, 0.80) 79.81%, rgba(67, 119, 233, 0.80) 93.59%, rgba(194, 226, 255, 0.80) 110.85%)',
}}
>
<div className="px-4 lg:px-10 flex h-full items-center justify-between py-0.5"> <div className="px-4 lg:px-10 flex h-full items-center justify-between py-0.5">
<div className="flex h-6 items-center shadow-sm"> <div className="flex h-6 items-center shadow-sm">
<a <a
@ -75,10 +86,10 @@ export default function AnnoncementBanner() {
> >
{social.icon} {social.icon}
</a> </a>
); )
})} })}
</div> </div>
</div> </div>
</div> </div>
); )
} }

View File

@ -1,135 +1,161 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from 'react'
import axios from "axios"; import axios from 'axios'
import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; import { FaWindows, FaApple, FaLinux } from 'react-icons/fa'
import { twMerge } from "tailwind-merge"; import { twMerge } from 'tailwind-merge'
import { DownloadIcon } from 'lucide-react'
const systemsTemplate = [ const systemsTemplate = [
{ {
name: "Mac M1, M2, M3", name: 'Mac M1, M2, M3',
label: 'Apple Silicon',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-arm64-{tag}.dmg", fileFormat: '{appname}-mac-arm64-{tag}.dmg',
comingSoon: false,
}, },
{ {
name: "Mac (Intel)", name: 'Mac (Intel)',
label: 'Apple Intel',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-x64-{tag}.dmg", fileFormat: '{appname}-mac-x64-{tag}.dmg',
comingSoon: false,
}, },
{ {
name: "Windows", name: 'Windows',
label: 'Standard (64-bit)',
logo: FaWindows, logo: FaWindows,
fileFormat: "{appname}-win-x64-{tag}.exe", fileFormat: '{appname}-win-x64-{tag}.exe',
}, },
{ {
name: "Linux (AppImage)", name: 'Linux (AppImage)',
label: 'AppImage',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-x86_64-{tag}.AppImage", fileFormat: '{appname}-linux-x86_64-{tag}.AppImage',
}, },
{ {
name: "Linux (deb)", name: 'Linux (deb)',
label: 'Deb',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-amd64-{tag}.deb", fileFormat: '{appname}-linux-amd64-{tag}.deb',
}, },
]; ]
const groupTemnplate = [
{ label: 'MacOS', name: 'mac', logo: FaApple },
{ label: 'Windows', name: 'windows', logo: FaWindows },
{ label: 'Linux', name: 'linux', logo: FaLinux },
]
export default function DownloadApp() { export default function DownloadApp() {
const [systems, setSystems] = useState(systemsTemplate); const [systems, setSystems] = useState(systemsTemplate)
const getLatestReleaseInfo = async (repoOwner, repoName) => { const getLatestReleaseInfo = async (repoOwner, repoName) => {
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`; const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`
try { try {
const response = await axios.get(url); const response = await axios.get(url)
return response.data; return response.data
} catch (error) { } catch (error) {
console.error(error); console.error(error)
return null; return null
} }
}; }
const extractAppName = (fileName) => { const extractAppName = (fileName) => {
// Extract appname using a regex that matches the provided file formats // Extract appname using a regex that matches the provided file formats
const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|amd64|x86_64)-.*$/; const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|amd64|x86_64)-.*$/
const match = fileName.match(regex); const match = fileName.match(regex)
return match ? match[1] : null; return match ? match[1] : null
}; }
useEffect(() => { useEffect(() => {
const updateDownloadLinks = async () => { const updateDownloadLinks = async () => {
try { try {
const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); const releaseInfo = await getLatestReleaseInfo('janhq', 'jan')
// Extract appname from the first asset name // Extract appname from the first asset name
const firstAssetName = releaseInfo.assets[0].name; const firstAssetName = releaseInfo.assets[0].name
const appname = extractAppName(firstAssetName); const appname = extractAppName(firstAssetName)
if (!appname) { if (!appname) {
console.error( console.error(
"Failed to extract appname from file name:", 'Failed to extract appname from file name:',
firstAssetName firstAssetName
); )
return; return
} }
// Remove 'v' at the start of the tag_name // Remove 'v' at the start of the tag_name
const tag = releaseInfo.tag_name.startsWith("v") const tag = releaseInfo.tag_name.startsWith('v')
? releaseInfo.tag_name.substring(1) ? releaseInfo.tag_name.substring(1)
: releaseInfo.tag_name; : releaseInfo.tag_name
const updatedSystems = systems.map((system) => { const updatedSystems = systems.map((system) => {
const downloadUrl = system.fileFormat const downloadUrl = system.fileFormat
.replace("{appname}", appname) .replace('{appname}', appname)
.replace("{tag}", tag); .replace('{tag}', tag)
return { return {
...system, ...system,
href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`,
}; }
}); })
setSystems(updatedSystems); setSystems(updatedSystems)
} catch (error) { } catch (error) {
console.error("Failed to update download links:", error); console.error('Failed to update download links:', error)
} }
}; }
updateDownloadLinks(); updateDownloadLinks()
}, []); }, [])
const renderDownloadLink = (group) => {
return (
<>
{systems
.filter((x) => x.name.toLowerCase().includes(group))
.map((system, i) => (
<div
key={i}
className="border-b border-[#F0F0F0] dark:border-gray-800 last:border-none pb-2 pt-2"
>
<a
href={system.href || ''}
className={twMerge(
'inline-flex text-lg my-2 font-semibold cursor-pointer justify-center items-center space-x-2] text-blue-500 hover:text-blue-500 gap-2',
system.comingSoon && 'pointer-events-none'
)}
>
<span className="text-sm">{system.label}</span>
<DownloadIcon size={16} />
</a>
</div>
))}
</>
)
}
return ( return (
<div> <div className="w-full lg:w-3/5 mx-auto px-4">
<div className="flex flex-col lg:flex-row items-center justify-center gap-4 mb-4"> <div className="grid grid-cols-1 lg:grid-cols-3 py-10 gap-8">
<span className="text-zinc-500 text-lg font-medium inline-block"> {groupTemnplate.map((item, i) => {
Download for PC return (
</span> <div
<div className="bg-yellow-50 text-yellow-700 space-x-2 px-4 py-2 border border-yellow-400 rounded-lg text-base"> className="border border-[#F0F0F0] dark:border-gray-800 rounded-xl text-center"
<span>🚧</span> key={i}
<span className="font-semibold">Warning:</span> >
<span className="font-medium"> <div className="text-center">
Jan is in the process of being built. Expect bugs! <div className="flex gap-2 p-4 border-b border-[#F0F0F0] dark:border-gray-800 items-center justify-center">
</span> <div className="text-2xl">
</div> <item.logo />
</div> </div>
<div className="mx-auto text-center"> <h6>{item.label}</h6>
{systems.map((system, i) => ( </div>
<a <div className="mx-auto text-center py-2">
key={i} {renderDownloadLink(item.name)}
href={system.href || ""} </div>
className={twMerge( </div>
"btn-shadow inline-flex m-2 px-4 rounded-lg text-lg font-semibold cursor-pointer justify-center items-center space-x-2 border border-zinc-200 dark:border-gray-700 text-black dark:text-white bg-zinc-50 min-w-[150px] dark:bg-[#18181B] h-[36px]", </div>
system.comingSoon && "pointer-events-none" )
)} })}
>
<system.logo />
<span className="text-sm">{system.name}</span>
{system.comingSoon && (
<span className="bg-zinc-200 py-0.5 px-2 inline-block ml-2 rounded-md text-xs h-[20px] dark:text-black">
Coming Soon
</span>
)}
</a>
))}
</div> </div>
</div> </div>
); )
} }

View File

@ -1,134 +1,134 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from 'react'
import { Fragment } from "react"; import { Fragment } from 'react'
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from '@headlessui/react'
import { ChevronDownIcon } from "@heroicons/react/20/solid"; import { ChevronDownIcon } from '@heroicons/react/20/solid'
import axios from "axios"; import axios from 'axios'
import { FaWindows, FaApple, FaLinux } from "react-icons/fa"; import { FaWindows, FaApple, FaLinux } from 'react-icons/fa'
const systemsTemplate = [ const systemsTemplate = [
{ {
name: "Download for Mac (M1/M2/M3)", name: 'Download for Mac (M1/M2/M3)',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-arm64-{tag}.dmg", fileFormat: '{appname}-mac-arm64-{tag}.dmg',
}, },
{ {
name: "Download for Mac (Intel)", name: 'Download for Mac (Intel)',
logo: FaApple, logo: FaApple,
fileFormat: "{appname}-mac-x64-{tag}.dmg", fileFormat: '{appname}-mac-x64-{tag}.dmg',
}, },
{ {
name: "Download for Windows", name: 'Download for Windows',
logo: FaWindows, logo: FaWindows,
fileFormat: "{appname}-win-x64-{tag}.exe", fileFormat: '{appname}-win-x64-{tag}.exe',
}, },
{ {
name: "Download for Linux (AppImage)", name: 'Download for Linux (AppImage)',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-x86_64-{tag}.AppImage", fileFormat: '{appname}-linux-x86_64-{tag}.AppImage',
}, },
{ {
name: "Download for Linux (deb)", name: 'Download for Linux (deb)',
logo: FaLinux, logo: FaLinux,
fileFormat: "{appname}-linux-amd64-{tag}.deb", fileFormat: '{appname}-linux-amd64-{tag}.deb',
} },
]; ]
function classNames(...classes) { function classNames(...classes) {
return classes.filter(Boolean).join(" "); return classes.filter(Boolean).join(' ')
} }
export default function Dropdown() { export default function Dropdown() {
const [systems, setSystems] = useState(systemsTemplate); const [systems, setSystems] = useState(systemsTemplate)
const [defaultSystem, setDefaultSystem] = useState(systems[0]); const [defaultSystem, setDefaultSystem] = useState(systems[0])
const getLatestReleaseInfo = async (repoOwner, repoName) => { const getLatestReleaseInfo = async (repoOwner, repoName) => {
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`; const url = `https://api.github.com/repos/${repoOwner}/${repoName}/releases/latest`
try { try {
const response = await axios.get(url); const response = await axios.get(url)
return response.data; return response.data
} catch (error) { } catch (error) {
console.error(error); console.error(error)
return null; return null
} }
}; }
const extractAppName = (fileName) => { const extractAppName = (fileName) => {
// Extract appname using a regex that matches the provided file formats // Extract appname using a regex that matches the provided file formats
const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/; const regex = /^(.*?)-(?:mac|win|linux)-(?:arm64|x64|x86_64|amd64)-.*$/
const match = fileName.match(regex); const match = fileName.match(regex)
return match ? match[1] : null; return match ? match[1] : null
}; }
const changeDefaultSystem = async (systems) => { const changeDefaultSystem = async (systems) => {
const userAgent = navigator.userAgent; const userAgent = navigator.userAgent
if (userAgent.includes("Windows")) { if (userAgent.includes('Windows')) {
// windows user // windows user
setDefaultSystem(systems[2]); setDefaultSystem(systems[2])
} else if (userAgent.includes("Linux")) { } else if (userAgent.includes('Linux')) {
// linux user // linux user
setDefaultSystem(systems[3]); setDefaultSystem(systems[3])
} else if (userAgent.includes("Mac OS")) { } else if (userAgent.includes('Mac OS')) {
setDefaultSystem(systems[0]); setDefaultSystem(systems[0])
} else { } else {
setDefaultSystem(systems[1]); setDefaultSystem(systems[1])
} }
}; }
useEffect(() => { useEffect(() => {
const updateDownloadLinks = async () => { const updateDownloadLinks = async () => {
try { try {
const releaseInfo = await getLatestReleaseInfo("janhq", "jan"); const releaseInfo = await getLatestReleaseInfo('janhq', 'jan')
// Extract appname from the first asset name // Extract appname from the first asset name
const firstAssetName = releaseInfo.assets[0].name; const firstAssetName = releaseInfo.assets[0].name
const appname = extractAppName(firstAssetName); const appname = extractAppName(firstAssetName)
if (!appname) { if (!appname) {
console.error( console.error(
"Failed to extract appname from file name:", 'Failed to extract appname from file name:',
firstAssetName firstAssetName
); )
changeDefaultSystem(systems); changeDefaultSystem(systems)
return; return
} }
// Remove 'v' at the start of the tag_name // Remove 'v' at the start of the tag_name
const tag = releaseInfo.tag_name.startsWith("v") const tag = releaseInfo.tag_name.startsWith('v')
? releaseInfo.tag_name.substring(1) ? releaseInfo.tag_name.substring(1)
: releaseInfo.tag_name; : releaseInfo.tag_name
const updatedSystems = systems.map((system) => { const updatedSystems = systems.map((system) => {
const downloadUrl = system.fileFormat const downloadUrl = system.fileFormat
.replace("{appname}", appname) .replace('{appname}', appname)
.replace("{tag}", tag); .replace('{tag}', tag)
return { return {
...system, ...system,
href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`, href: `https://github.com/janhq/jan/releases/download/${releaseInfo.tag_name}/${downloadUrl}`,
}; }
}); })
setSystems(updatedSystems); setSystems(updatedSystems)
changeDefaultSystem(updatedSystems); changeDefaultSystem(updatedSystems)
} catch (error) { } catch (error) {
console.error("Failed to update download links:", error); console.error('Failed to update download links:', error)
} }
}; }
updateDownloadLinks(); updateDownloadLinks()
}, []); }, [])
return ( return (
<div className="inline-flex align-items-stretch"> <div className="inline-flex align-items-stretch">
<a <a
href={defaultSystem.href || ""} href={defaultSystem.href || ''}
className="cursor-pointer relative inline-flex items-center rounded-l-md border-0 px-4 py-3 text-base font-semibold dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white" className="cursor-pointer relative inline-flex items-center rounded-l-xl border-0 px-4 py-4 text-base font-semibold dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white dark:border dark:border-[#B2B2B3]"
> >
<defaultSystem.logo className="h-5 mr-3 -mt-1" /> <defaultSystem.logo className="h-5 mr-3 -mt-1" />
{defaultSystem.name} {defaultSystem.name}
</a> </a>
<Menu as="div" className="relative -ml-px block"> <Menu as="div" className="relative -ml-px block">
<Menu.Button className="cursor-pointer relative inline-flex items-center rounded-r-md border-l border-gray-600 h-full dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white w-8 justify-center"> <Menu.Button className="cursor-pointer relative inline-flex items-center rounded-r-xl border-l border-gray-600 h-full dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white w-8 justify-center dark:border dark:border-[#B2B2B3]">
<span className="sr-only">Open OS options</span> <span className="sr-only">Open OS options</span>
<ChevronDownIcon className="h-6 w-6" aria-hidden="true" /> <ChevronDownIcon className="h-6 w-6" aria-hidden="true" />
</Menu.Button> </Menu.Button>
@ -141,7 +141,7 @@ export default function Dropdown() {
leaveFrom="transform opacity-100 scale-100" leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95" leaveTo="transform opacity-0 scale-95"
> >
<Menu.Items className="absolute right-0 z-10 mt-1 w-80 text-left origin-top-right rounded-md dark:bg-white dark:text-black bg-black text-white dark:hover:text-black hover:text-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none overflow-hidden"> <Menu.Items className="absolute right-0 z-10 mt-1 w-80 text-left origin-top-right rounded-xl dark:bg-[#343435] dark:text-white bg-black text-white hover:text-white shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none overflow-hidden">
<div className="overflow-hidden"> <div className="overflow-hidden">
{systems.map((system) => ( {systems.map((system) => (
<Menu.Item <Menu.Item
@ -150,16 +150,16 @@ export default function Dropdown() {
> >
{({ active }) => ( {({ active }) => (
<a <a
href={system.href || ""} href={system.href || ''}
className={classNames( className={classNames(
active active
? "dark:bg-blue-100 bg-gray-900 hover:text-white dark:text-black" ? 'dark:bg-black/20 bg-gray-900 hover:text-white'
: "text-white dark:text-black", : 'text-white ',
"flex px-4 py-3 items-center text-white hover:text-white dark:text-black" 'flex px-4 py-3 items-center text-white hover:text-white'
)} )}
> >
<system.logo className="w-3 mr-3 -mt-1 flex-shrink-0" /> <system.logo className="w-3 mr-3 -mt-1 flex-shrink-0" />
<span className="text-white dark:text-black font-medium"> <span className="text-white font-medium">
{system.name} {system.name}
</span> </span>
</a> </a>
@ -171,5 +171,5 @@ export default function Dropdown() {
</Transition> </Transition>
</Menu> </Menu>
</div> </div>
); )
} }

View File

@ -1,134 +1,208 @@
import React from "react"; import React from 'react'
import { AiOutlineGithub, AiOutlineTwitter } from "react-icons/ai"; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import { BiLogoDiscordAlt, BiLogoLinkedin } from "react-icons/bi"; import { AiOutlineGithub, AiOutlineTwitter } from 'react-icons/ai'
import { BiLogoDiscordAlt, BiLogoLinkedin } from 'react-icons/bi'
import { useForm } from 'react-hook-form'
const socials = [ const socials = [
{ {
icon: <AiOutlineTwitter className="text-xl text-black dark:text-white" />, icon: (
href: "https://twitter.com/janframework", <AiOutlineTwitter className="text-xl text-black/60 dark:text-white/60" />
),
href: 'https://twitter.com/janframework',
}, },
{ {
icon: <BiLogoDiscordAlt className="text-xl text-black dark:text-white" />, icon: (
href: "https://discord.com/invite/FTk2MvZwJH", <BiLogoDiscordAlt className="text-xl text-black/60 dark:text-white/60" />
),
href: 'https://discord.com/invite/FTk2MvZwJH',
}, },
{ {
icon: <AiOutlineGithub className="text-lg text-black dark:text-white" />, icon: (
href: "https://github.com/janhq/jan", <AiOutlineGithub className="text-lg text-black/60 dark:text-white/60" />
),
href: 'https://github.com/janhq/jan',
}, },
{ {
icon: <BiLogoLinkedin className="text-xl text-black dark:text-white" />, icon: (
href: "https://www.linkedin.com/company/janframework/", <BiLogoLinkedin className="text-xl text-black/60 dark:text-white/60" />
} ),
]; href: 'https://www.linkedin.com/company/janframework/',
},
]
const menus = [ const menus = [
{ {
name: "For Developers", name: 'Product',
child: [ child: [
{ {
menu: "Documentation", menu: 'Download',
path: "/developer", path: '/download',
}, },
{ {
menu: "Hardware", menu: 'Documentation',
path: "/hardware", path: '/developer',
}, },
{ {
menu: "API Reference", menu: 'Changelog',
path: "/api-reference", path: 'https://github.com/janhq/jan/releases',
},
{
menu: "Changelog",
path: "https://github.com/janhq/jan/releases",
external: true, external: true,
}, },
], ],
}, },
{ {
name: "Community", name: 'For Developers',
child: [ child: [
{ {
menu: "Github", menu: 'Guides',
path: "https://github.com/janhq/jan", path: '/guides',
external: true,
}, },
{ {
menu: "Discord", menu: 'Developer',
path: "https://discord.gg/FTk2MvZwJH", path: '/developer',
external: true,
}, },
{ {
menu: "Twitter", menu: 'API Reference',
path: "https://twitter.com/janframework", path: '/api-reference',
external: true,
}, },
{
menu: "LinkedIn",
path: "https://www.linkedin.com/company/janframework/",
external: true,
}
], ],
}, },
{ {
name: "Company", name: 'Community',
child: [ child: [
{ {
menu: "About", menu: 'Github',
path: "/about", path: 'https://github.com/janhq/jan',
},
{
menu: "Blog",
path: "/blog",
},
{
menu: "Careers",
path: "https://janai.bamboohr.com/careers",
external: true, external: true,
}, },
{ {
menu: "Newsletter", menu: 'Discord',
path: "/community#newsletter", path: 'https://discord.gg/FTk2MvZwJH',
} external: true,
},
{
menu: 'Twitter',
path: 'https://twitter.com/janframework',
external: true,
},
{
menu: 'LinkedIn',
path: 'https://www.linkedin.com/company/janframework/',
external: true,
},
], ],
}, },
]; {
name: 'Company',
child: [
{
menu: 'About',
path: '/about',
},
{
menu: 'Blog',
path: '/blog',
},
{
menu: 'Careers',
path: 'https://janai.bamboohr.com/careers',
external: true,
},
{
menu: 'Newsletter',
path: '/community#newsletter',
},
],
},
]
const getCurrentYear = new Date().getFullYear(); const getCurrentYear = new Date().getFullYear()
export default function Footer() { export default function Footer() {
const { register, handleSubmit, reset } = useForm({
defaultValues: {
email: '',
},
})
const {
siteConfig: { customFields },
} = useDocusaurusContext()
const onSubmit = (data) => {
const { email } = data
const options = {
method: 'POST',
headers: {
'accept': 'application/json',
'content-type': 'application/json',
'api-key': customFields.apiKeyBrevo,
},
body: JSON.stringify({
updateEnabled: false,
email,
listIds: [13],
}),
}
if (email) {
fetch('https://api.brevo.com/v3/contacts', options)
.then((response) => response.json())
.then((response) => {
if (response.id) {
reset()
}
})
.catch((err) => console.error(err))
}
}
return ( return (
<footer className="flex-shrink-0 dark:bg-[#09090B]/10 bg-[#D4D4D8]/10 relative overflow-hidden py-10"> <footer className="flex-shrink-0 relative overflow-hidden py-10">
<div className="container"> <div className="container">
<div className="grid grid-cols-2 gap-8 md:grid-cols-2 lg:grid-cols-6"> <div className="grid grid-cols-2 gap-8 md:grid-cols-2 lg:grid-cols-6">
<div className="lg:col-span-3 col-span-2"> <div className="col-span-2">
<div className="flex items-center space-x-2 mb-3"> <div className="flex items-center space-x-2 mb-3">
<img alt="Jan Logo" src="/img/logo.svg" /> <img alt="Jan Logo" src="/img/logo.svg" />
<h2 className="h6">Jan</h2> <h2 className="h5">Jan</h2>
</div> </div>
<div className="w-full lg:w-1/2"> <div className="w-full lg:w-3/4 mt-2">
<p className="dark:text-gray-400 text-gray-600"> <h6>The Soul of a New Machine</h6>
Jan is the open-source, self-hosted&nbsp; <p className="dark:text-gray-400 text-gray-600 mt-2">
Subscribe to our newsletter on AI{' '}
<br className="hidden lg:block" /> <br className="hidden lg:block" />
&nbsp;alternative to ChatGPT. research and building Jan:
</p> </p>
<div className="mt-4"> <div className="mt-4">
<div className="flex items-center gap-x-3"> <form className="relative" onSubmit={handleSubmit(onSubmit)}>
{socials.map((social, i) => { <input
return ( type="email"
<a className="w-full h-12 p-4 pr-14 rounded-xl border dark:border-gray-600 dark:bg-[#252525] border-[#F0F0F0]"
aria-label={`social-${i}`} placeholder="Enter your email"
key={i} {...register('email')}
href={social.href} />
target="_blank" <button
rel="noopener" type="submit"
> className="absolute flex p-2 bg-black dark:bg-[#3B3B3C] w-8 h-8 border dark:border-gray-600 rounded-lg top-1/2 right-3 -translate-y-1/2"
{social.icon} >
</a> <svg
); width="16"
})} height="16"
</div> viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.09026 8.41933L3.72077 7.62985C1.24061 6.80348 0 6.3903 0 5.63033C0 4.87142 1.24061 4.45718 3.72077 3.63081L12.6938 0.639442C14.4393 0.0576106 15.3121 -0.233305 15.7727 0.227312C16.2333 0.687928 15.9424 1.56068 15.3616 3.30512L12.3692 12.2792C11.5428 14.7594 11.1296 16 10.3697 16C9.61076 16 9.19652 14.7594 8.37015 12.2792L7.57962 9.9108L12.1689 5.3215C12.3609 5.1227 12.4672 4.85645 12.4648 4.58008C12.4624 4.30372 12.3515 4.03935 12.1561 3.84392C11.9607 3.64849 11.6963 3.53764 11.4199 3.53524C11.1435 3.53284 10.8773 3.63908 10.6785 3.83108L6.09026 8.41933Z"
fill="white"
/>
</svg>
</button>
</form>
</div> </div>
</div> </div>
</div> </div>
@ -142,25 +216,42 @@ export default function Footer() {
<li key={i}> <li key={i}>
<a <a
href={child.path} href={child.path}
target={child.external ? "_blank" : "_self"} target={child.external ? '_blank' : '_self'}
className="inline-block py-1 dark:text-gray-400 text-gray-600" className="inline-block py-1 dark:text-gray-400 text-gray-600"
> >
{child.menu} {child.menu}
</a> </a>
</li> </li>
); )
})} })}
</ul> </ul>
</div> </div>
); )
})} })}
</div> </div>
</div> </div>
<div className="container mt-6"> <div className="container mt-8">
<span className="dark:text-gray-300 text-gray-700"> <div className="flex w-full justify-between items-center">
&copy;{getCurrentYear}&nbsp;Jan AI Pte Ltd. <span className="dark:text-gray-300 text-gray-700">
</span> &copy;{getCurrentYear}&nbsp;Jan AI Pte Ltd.
</span>
<div className="flex items-center gap-x-3">
{socials.map((social, i) => {
return (
<a
aria-label={`social-${i}`}
key={i}
href={social.href}
target="_blank"
rel="noopener"
>
{social.icon}
</a>
)
})}
</div>
</div>
</div> </div>
</footer> </footer>
); )
} }

View File

@ -1,47 +0,0 @@
import React from "react";
import { FaGithub, FaDiscord } from "react-icons/fa";
import { RiStarSFill } from "react-icons/ri";
import { useAppStars } from "@site/src/hooks/useAppStars";
import { useDiscordWidget } from "@site/src/hooks/useDiscordWidget";
export default function SocialButton() {
const { stargazers } = useAppStars();
const { data } = useDiscordWidget();
return (
<div className="flex items-center space-x-2 justify-start">
<a
href="https://github.com/janhq/jan"
target="_blank"
className="inline-flex px-4 py-3 rounded-lg font-semibold cursor-pointer justify-center items-center space-x-4 border border-gray-400 dark:border-gray-700 text-white bg-black hover:text-white"
>
<span>
<FaGithub className="text-3xl" />
</span>
<div className="flex-col">
<p className="text-base">Github</p>
<p className="text-sm text-white flex items-center space-x-1">
<RiStarSFill className="text-lg text-[#FEC928]" />
<span>{stargazers.count} stars</span>
</p>
</div>
</a>
<a
href="https://discord.gg/FTk2MvZwJH"
target="_blank"
className="text-white bg-[#5765F2] hover:bg-[#5765F2] hover:text-white inline-flex px-4 py-3 rounded-lg font-semibold cursor-pointer justify-center items-center space-x-4"
>
<span>
<FaDiscord className="text-3xl" />
</span>
<div className="flex-col">
<p className="text-base">Discord</p>
<div className="text-sm text-white flex items-center space-x-1">
<div className="w-2 h-2 bg-green-500 rounded-full" />
<span>{data.presence_count} online</span>
</div>
</div>
</a>
</div>
);
}

View File

@ -0,0 +1,370 @@
import { useColorMode } from '@docusaurus/theme-common'
import { Tweet } from 'react-tweet'
const firstColumn = [
{
type: 'tweet',
id: '1742843063938994469',
},
{
type: 'youtube',
id: 'ZCiEQVOjH5U',
},
{
type: 'youtube',
id: '7JpzE-_cKo4',
},
{
type: 'tweet',
id: '1744729548074459310',
},
]
const secondColumn = [
{
type: 'youtube',
id: 'QpMQgJL4AZA',
},
{
type: 'tweet',
id: '1750801065132384302',
},
{
type: 'youtube',
id: '9ta2S425Zu8',
},
{
type: 'tweet',
id: '1757504717519749292',
},
]
const thirdColumn = [
{
type: 'tweet',
id: '1745560583548670250',
},
{
type: 'youtube',
id: 'zkafOIyQM8s',
},
{
type: 'tweet',
id: '1757500111629025788',
},
]
const fourthColumn = [
{
type: 'tweet',
id: '1742993414986068423',
},
{
type: 'youtube',
id: '9ta2S425Zu8',
},
{
type: 'youtube',
id: 'ES021_sY6WQ',
},
{
type: 'youtube',
id: 'CbJGxNmdWws',
},
]
const Testimonial = () => {
const { colorMode } = useColorMode()
return (
<div className="bg-[#F0F0F0] dark:bg-[#242424] p-8 mt-10 pb-20">
<div className="w-full xl:w-3/5 mx-auto relative py-8 text-center">
<h1 className="text-5xl !font-normal leading-tight lg:leading-tight mt-2 font-serif">
People say nice things
</h1>
<p className="leading-relaxed mt-2 text-black/60 dark:text-white/60 flex gap-x-2 justify-center">
...despite our bugs and fast moving releases{' '}
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_1810_7276)">
<path
d="M24.0001 11.4301H22.8601V19.4326H24.0001V11.4301Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M22.8599 19.4325H21.7124V20.5725H22.8599V19.4325Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M22.8599 9.14246H21.7124V11.43H22.8599V9.14246Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M21.7125 20.5725H20.5725V21.72H21.7125V20.5725Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M21.7125 6.86255H20.5725V9.14255H21.7125V6.86255Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M20.5726 21.72H19.4326V22.86H20.5726V21.72Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M20.5726 5.71497H19.4326V6.86247H20.5726V5.71497Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M19.4324 2.28748H18.2849V5.71498H19.4324V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M12.5701 22.86V21.72H14.8576V20.5725H11.4301V21.72H5.71509V22.86H11.4301V24H19.4326V22.86H12.5701Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M18.285 1.14746H17.145V2.28746H18.285V1.14746Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M17.1449 11.4301H14.8574V12.5701H17.1449V11.4301Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M16.0049 19.4325H14.8574V20.5725H16.0049V19.4325Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M17.145 0H13.7175V1.1475H17.145V0Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M14.8575 18.285H13.7175V19.4325H14.8575V18.285Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M14.8575 12.5699H13.7175V13.7174H14.8575V12.5699Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M16.005 2.28748H13.7175V4.57498H16.005V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M13.7176 13.7175H12.5701V18.285H13.7176V13.7175Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M13.7176 1.14746H12.5701V2.28746H13.7176V1.14746Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M12.5699 2.28748H11.4299V4.57498H12.5699V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M11.43 19.4325H10.29V20.5725H11.43V19.4325Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M10.2901 16.005H9.14258V19.4325H10.2901V16.005Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M11.4301 4.57495H9.14258V5.71495H11.4301V4.57495Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M9.14244 14.8575H8.00244V16.005H9.14244V14.8575Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M9.14244 6.86255H8.00244V8.00255H9.14244V6.86255Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M9.14244 2.28748H8.00244V4.57498H9.14244V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M8.00255 1.14746H6.86255V2.28746H8.00255V1.14746Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M8.00245 8.00244H4.57495V9.14244H8.00245V8.00244Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M5.71495 20.5725H4.57495V21.72H5.71495V20.5725Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M6.86249 0H3.42749V1.1475H6.86249V0Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M1.1475 22.86V21.72H0V24H5.715V22.86H1.1475Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M8.0026 13.7175H2.2876V14.8575H8.0026V13.7175Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M5.71499 2.28748H3.42749V4.57498H5.71499V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M3.42746 20.5725H4.57496V19.4325H2.28746V20.5725H1.14746V21.72H3.42746V20.5725Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M3.4276 5.71497H2.2876V8.00247H3.4276V5.71497Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M3.4276 1.14746H2.2876V2.28746H3.4276V1.14746Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M2.28746 18.285H1.14746V19.4325H2.28746V18.285Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M2.28746 8.00244H1.14746V10.2899H2.28746V8.00244Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M2.28746 2.28748H1.14746V5.71498H2.28746V2.28748Z"
className="fill-black/60 dark:fill-white/60"
/>
<path
d="M2.2875 16.005V14.8575H1.1475V10.29H0V18.285H1.1475V16.005H2.2875Z"
className="fill-black/60 dark:fill-white/60"
/>
</g>
<defs>
<clipPath id="clip0_1810_7276">
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
</p>
</div>
<div className="w-full xl:w-3/4 mx-auto relative text-center">
<div data-theme={colorMode} className="mt-10">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 lg:gap-8 text-left">
<div className="space-y-4 lg:space-y-8">
{firstColumn.map((item, i) => {
if (item.type === 'tweet')
return (
<div key={i} className="tweet-wrapper">
<Tweet id={item.id} />
</div>
)
if (item.type === 'youtube')
return (
<div key={i}>
<iframe
width="100%"
height="260"
src={`https://www.youtube.com/embed/${item.id}`}
title="Install Jan to Run LLM Offline and Local First"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
className="rounded-xl"
loading="lazy"
/>
</div>
)
})}
</div>
<div className="space-y-4 lg:space-y-8">
{secondColumn.map((item, i) => {
if (item.type === 'tweet')
return (
<div key={i} className="tweet-wrapper">
<Tweet id={item.id} />
</div>
)
if (item.type === 'youtube')
return (
<div key={i}>
<iframe
width="100%"
height="260"
src={`https://www.youtube.com/embed/${item.id}`}
title="Install Jan to Run LLM Offline and Local First"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
className="rounded-xl"
loading="lazy"
/>
</div>
)
})}
</div>
<div className="space-y-4 lg:space-y-8">
{thirdColumn.map((item, i) => {
if (item.type === 'tweet')
return (
<div key={i} className="tweet-wrapper">
<Tweet id={item.id} />
</div>
)
if (item.type === 'youtube')
return (
<div key={i}>
<iframe
width="100%"
height="260"
src={`https://www.youtube.com/embed/${item.id}`}
title="Install Jan to Run LLM Offline and Local First"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
className="rounded-xl"
loading="lazy"
/>
</div>
)
})}
</div>
<div className="space-y-4 lg:space-y-8">
{fourthColumn.map((item, i) => {
if (item.type === 'tweet')
return (
<div key={i} className="tweet-wrapper">
<Tweet id={item.id} />
</div>
)
if (item.type === 'youtube')
return (
<div key={i}>
<iframe
width="100%"
height="260"
src={`https://www.youtube.com/embed/${item.id}`}
title="Install Jan to Run LLM Offline and Local First"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
className="rounded-xl"
loading="lazy"
/>
</div>
)
})}
</div>
</div>
</div>
</div>
</div>
)
}
export default Testimonial

View File

@ -34,7 +34,7 @@
/* Dark mode styles based on Docusaurus dark theme */ /* Dark mode styles based on Docusaurus dark theme */
[data-theme='dark'] .head_Menu div { [data-theme='dark'] .head_Menu div {
font-weight: bold; font-weight: bold;
background-color: var(--ifm-background-color); /* background-color: var(--ifm-background-color); */
color: var(--ifm-font-color-base); color: var(--ifm-font-color-base);
margin-left: 0.7rem; margin-left: 0.7rem;
font-size: larger; font-size: larger;
@ -42,14 +42,14 @@
[data-theme='dark'] .head_Menu li { [data-theme='dark'] .head_Menu li {
font-weight: normal; font-weight: normal;
background-color: var(--ifm-background-color); /* background-color: var(--ifm-background-color); */
margin-bottom: 5px; margin-bottom: 5px;
color: var(--ifm-font-color-base); color: var(--ifm-font-color-base);
} }
[data-theme='dark'] .head_SubMenu div { [data-theme='dark'] .head_SubMenu div {
font-weight: normal; font-weight: normal;
background-color: var(--ifm-background-color); /* background-color: var(--ifm-background-color); */
color: var(--ifm-font-color-base); color: var(--ifm-font-color-base);
margin-left: 0rem; margin-left: 0rem;
font-size: medium; font-size: medium;

View File

@ -0,0 +1,53 @@
import React, { useState, useEffect } from 'react'
import DownloadApp from '@site/src/containers/DownloadApp'
import ThemedImage from '@theme/ThemedImage'
import Layout from '@theme/Layout'
import Banner from '@site/src/containers/Banner'
import useBaseUrl from '@docusaurus/useBaseUrl'
export default function Download() {
return (
<>
<Banner />
<Layout
title="Download"
description="Jan turns your computer into an AI machine by running LLMs locally on your computer. It's a privacy-focus, local-first, open-source solution."
>
<main>
{/* Hero */}
<div className="text-center px-4 py-20">
<h1 className="text-6xl lg:text-7xl !font-normal leading-tight lg:leading-tight mt-2 font-serif">
Download Jan for your desktop
</h1>
<p className="text-2xl -mt-1 leading-relaxed text-black/60 dark:text-white/60">
Turn your computer into an AI machine
</p>
<div className="my-8">
<DownloadApp />
</div>
<div className="mb-14">
<a
href="https://jan.ai/guides/install/"
target="_blank"
className="text-blue-500 hover:text-blue-500 pr-4 border-r border-black/40 dark:border-white/40 mr-4 inline-block"
>
Installation Guide
</a>
<a
href="https://jan.ai/changelog/"
target="_blank"
className="text-blue-500 hover:text-blue-500"
>
Changelog
</a>
</div>
</div>
</main>
</Layout>
</>
)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
@layer base { @layer base {
html[data-theme="light"] { html[data-theme='light'] {
--custom-radial-blur: #e1e7fd; --custom-radial-blur: #e1e7fd;
--ifm-background-color: #fff; --ifm-background-color: #fff;
--ifm-color-primary: #2563eb; /* New Primary Blue */ --ifm-color-primary: #2563eb; /* New Primary Blue */
@ -14,7 +14,7 @@
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
} }
html[data-theme="dark"] { html[data-theme='dark'] {
--custom-radial-blur: #1d1b48; --custom-radial-blur: #1d1b48;
--ifm-background-color: #18181b; --ifm-background-color: #18181b;
--ifm-color-primary: #ffffff; /* New Primary Blue */ --ifm-color-primary: #ffffff; /* New Primary Blue */
@ -27,6 +27,92 @@
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
} }
.react-tweet-theme {
--tweet-container-margin: 1.5rem 0;
--tweet-header-font-size: 0.9375rem;
--tweet-header-line-height: 1.25rem;
--tweet-body-font-size: 1.25rem;
--tweet-body-font-weight: 400;
--tweet-body-line-height: 1.5rem;
--tweet-body-margin: 0;
--tweet-quoted-container-margin: 0.75rem 0;
--tweet-quoted-body-font-size: 0.938rem;
--tweet-quoted-body-font-weight: 400;
--tweet-quoted-body-line-height: 1.25rem;
--tweet-quoted-body-margin: 0.25rem 0 0.75rem 0;
--tweet-info-font-size: 0.9375rem;
--tweet-info-line-height: 1.25rem;
--tweet-actions-font-size: 0.875rem;
--tweet-actions-line-height: 1rem;
--tweet-actions-font-weight: 700;
--tweet-actions-icon-size: 1.25em;
--tweet-actions-icon-wrapper-size: calc(
var(--tweet-actions-icon-size) + 0.75em
);
--tweet-replies-font-size: 0.875rem;
--tweet-replies-line-height: 1rem;
--tweet-replies-font-weight: 700;
}
:is([data-theme='light'], .light) :where(.react-tweet-theme),
:where(.react-tweet-theme) {
--tweet-skeleton-gradient: linear-gradient(
270deg,
#fafafa,
#eaeaea,
#eaeaea,
#fafafa
);
--tweet-border: 1px solid #cfd9de;
--tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif;
--tweet-font-color: #0f1419;
--tweet-font-color-secondary: #536471;
--tweet-bg-color: #fff;
--tweet-bg-color-hover: #f7f9f9;
--tweet-quoted-bg-color-hover: rgba(0, 0, 0, 0.03);
--tweet-color-blue-primary: #1d9bf0;
--tweet-color-blue-primary-hover: #1a8cd8;
--tweet-color-blue-secondary: #006fd6;
--tweet-color-blue-secondary-hover: rgba(0, 111, 214, 0.1);
--tweet-color-red-primary: #f91880;
--tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1);
--tweet-color-green-primary: #00ba7c;
--tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1);
--tweet-twitter-icon-color: var(--tweet-font-color);
--tweet-verified-old-color: #829aab;
--tweet-verified-blue-color: var(--tweet-color-blue-primary);
}
:is([data-theme='dark'], .dark) :where(.react-tweet-theme) {
--tweet-skeleton-gradient: linear-gradient(
270deg,
#15202b,
#1e2732,
#1e2732,
#15202b
);
--tweet-border: 1px solid #425364;
--tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif;
--tweet-font-color: #f7f9f9;
--tweet-font-color-secondary: #8b98a5;
--tweet-bg-color: #333333;
--tweet-bg-color-hover: #1e2732;
--tweet-quoted-bg-color-hover: hsla(0, 0%, 100%, 0.03);
--tweet-color-blue-primary: #1d9bf0;
--tweet-color-blue-primary-hover: #1a8cd8;
--tweet-color-blue-secondary: #6bc9fb;
--tweet-color-blue-secondary-hover: rgba(107, 201, 251, 0.1);
--tweet-color-red-primary: #f91880;
--tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1);
--tweet-color-green-primary: #00ba7c;
--tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1);
--tweet-twitter-icon-color: var(--tweet-font-color);
--tweet-verified-old-color: #829aab;
--tweet-verified-blue-color: #fff;
}
pre, pre,
code { code {
@apply text-sm; @apply text-sm;
@ -35,7 +121,11 @@
body { body {
@apply text-base; @apply text-base;
@apply antialiased; @apply antialiased;
@apply bg-white dark:bg-[#18181B]; @apply bg-white dark:bg-[#0C0C0C];
}
#__docusaurus {
@apply bg-white dark:bg-[#0C0C0C];
} }
img { img {
@ -65,3 +155,19 @@
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05); box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
} }
} }
.tweet-wrapper {
[class*='actions_'] {
display: none !important;
}
[class*='authorFollow_'] {
display: none !important;
}
[class*='replies_'] {
margin-top: 10px;
}
}
.font-serif {
letter-spacing: -4px;
}

View File

@ -29,6 +29,32 @@
0px -1px 1px 0px rgba(0, 0, 0, 0.1) inset, 0px -1px 1px 0px rgba(0, 0, 0, 0.1) inset,
0px 1px 1px 0px #4c4c4c inset; 0px 1px 1px 0px #4c4c4c inset;
} }
.card-wrapper {
border-radius: 16px;
background: linear-gradient(180deg, #fafafa 0%, #ededed 100%);
box-shadow:
0px 4px 12px 0px rgba(0, 0, 0, 0.12),
0px -1px 1px 0px rgba(0, 0, 0, 0.1) inset,
0px 1px 1px 0px #fff inset;
}
.card-wrapper-dark {
border-radius: 12px;
background: var(
--Linear-dark,
linear-gradient(
268deg,
rgba(117, 117, 117, 0.38) 0%,
rgba(121, 119, 128, 0.33) 100%
)
);
box-shadow:
0px 4px 12px 0px rgba(0, 0, 0, 0.12),
0px -1px 1px 0px rgba(0, 0, 0, 0.1) inset,
0px 0.2px 1px 0px #fff inset;
}
.card { .card {
@apply rounded-xl border bg-gray-50 border-gray-50 dark:border-[#202231] dark:bg-[#111217]/50; @apply rounded-xl border bg-gray-50 border-gray-50 dark:border-[#202231] dark:bg-[#111217]/50;

View File

@ -1,15 +1,17 @@
@import "tailwindcss/base"; @import url('https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap&family=Inter:wght@100..900&display=swap');
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "./components/base.scss"; @import 'tailwindcss/base';
@import "./components/typography.scss"; @import 'tailwindcss/components';
@import "./components/card.scss"; @import 'tailwindcss/utilities';
@import "./tweaks/navbar.scss"; @import './components/base.scss';
@import "./tweaks/breadcrumb.scss"; @import './components/typography.scss';
@import "./tweaks/markdown.scss"; @import './components/card.scss';
@import "./tweaks/redocusaurus.scss";
@import "./tweaks/sidebar.scss";
@import "../css/custom.css"; @import './tweaks/navbar.scss';
@import './tweaks/breadcrumb.scss';
@import './tweaks/markdown.scss';
@import './tweaks/redocusaurus.scss';
@import './tweaks/sidebar.scss';
@import '../css/custom.css';

View File

@ -2,7 +2,7 @@
@apply bg-transparent py-0 shadow-none px-0; @apply bg-transparent py-0 shadow-none px-0;
&__inner { &__inner {
@apply border border-gray-200 dark:border-gray-800 bg-white/80 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-4 lg:px-8 relative; @apply border-b border-gray-200 dark:border-gray-800 bg-white/80 dark:bg-[#09090B]/50 backdrop-blur-md flex items-center h-14 px-4 lg:px-8 relative;
} }
&__logo { &__logo {
@ -19,7 +19,7 @@
font-size: 18px; font-size: 18px;
} }
[class*="searchBox_"] { [class*='searchBox_'] {
display: none; display: none;
} }
} }

View File

@ -1,23 +1,33 @@
import React from "react"; import React from 'react'
import clsx from "clsx"; import clsx from 'clsx'
import ErrorBoundary from "@docusaurus/ErrorBoundary"; import ErrorBoundary from '@docusaurus/ErrorBoundary'
import { import {
PageMetadata, PageMetadata,
SkipToContentFallbackId, SkipToContentFallbackId,
ThemeClassNames, ThemeClassNames,
} from "@docusaurus/theme-common"; } from '@docusaurus/theme-common'
import { useKeyboardNavigation } from "@docusaurus/theme-common/internal"; import { useKeyboardNavigation } from '@docusaurus/theme-common/internal'
import SkipToContent from "@theme/SkipToContent"; import SkipToContent from '@theme/SkipToContent'
import AnnouncementBar from "@theme/AnnouncementBar"; import AnnouncementBar from '@theme/AnnouncementBar'
import Navbar from "@theme/Navbar"; import Navbar from '@theme/Navbar'
import Footer from "@site/src/containers/Footer"; import Footer from '@site/src/containers/Footer'
import LayoutProvider from "@theme/Layout/Provider"; import LayoutProvider from '@theme/Layout/Provider'
import ErrorPageContent from "@theme/ErrorPageContent"; import ErrorPageContent from '@theme/ErrorPageContent'
import styles from "./styles.module.scss"; import styles from './styles.module.scss'
import NavBarExtension from "../NavbarExtension"; import NavBarExtension from '../NavbarExtension'
import { useLocation } from "react-router-dom"; import { useLocation } from 'react-router-dom'
const allowedPaths = ["/docs/", "/developer/", "/api-reference/", "/guides/", "/guides", "/docs", "/developer", "/api-reference", "/changelog"]; const allowedPaths = [
'/docs/',
'/developer/',
'/api-reference/',
'/guides/',
'/guides',
'/docs',
'/developer',
'/api-reference',
'/changelog',
]
export default function Layout(props) { export default function Layout(props) {
const { const {
@ -27,12 +37,14 @@ export default function Layout(props) {
// Not really layout-related, but kept for convenience/retro-compatibility // Not really layout-related, but kept for convenience/retro-compatibility
title, title,
description, description,
} = props; } = props
useKeyboardNavigation(); useKeyboardNavigation()
const location = useLocation(); const location = useLocation()
const isAllowedPath = allowedPaths.some(path => location.pathname.startsWith(path)); const isAllowedPath = allowedPaths.some((path) =>
location.pathname.startsWith(path)
)
return ( return (
<LayoutProvider> <LayoutProvider>
@ -42,20 +54,19 @@ export default function Layout(props) {
<AnnouncementBar /> <AnnouncementBar />
<Navbar/> <Navbar />
{isAllowedPath ? <NavBarExtension /> : ""} {isAllowedPath ? <NavBarExtension /> : ''}
{/* {console.log("Is allowed path?", location.pathname)} */} {/* {console.log("Is allowed path?", location.pathname)} */}
<div <div
id={SkipToContentFallbackId} id={SkipToContentFallbackId}
className={clsx( className={clsx(
ThemeClassNames.wrapper.main, ThemeClassNames.wrapper.main,
styles.mainWrapper, styles.mainWrapper,
wrapperClassName, wrapperClassName,
isAllowedPath && "mt-0 md:mt-11" isAllowedPath && 'mt-0 md:mt-11'
)} )}
> >
<ErrorBoundary fallback={(params) => <ErrorPageContent {...params} />}> <ErrorBoundary fallback={(params) => <ErrorPageContent {...params} />}>
@ -65,5 +76,5 @@ export default function Layout(props) {
{!noFooter && <Footer />} {!noFooter && <Footer />}
</LayoutProvider> </LayoutProvider>
); )
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

BIN
docs/static/img/homepage/features01.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
docs/static/img/homepage/features02.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/static/img/homepage/features03.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/static/img/homepage/features04.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/static/img/homepage/mapbase.webp vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

314
docs/static/img/og-image.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.7 MiB

View File

@ -1,67 +1,68 @@
// tailwind.config.js // tailwind.config.js
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"], content: ['./src/**/*.{js,jsx,ts,tsx}'],
darkMode: ["class", '[data-theme="dark"]'], darkMode: ['class', '[data-theme="dark"]'],
theme: { theme: {
animation: { animation: {
wave: "wave 2.5s linear infinite", 'wave': 'wave 2.5s linear infinite',
enter: "enter 200ms ease-out", 'enter': 'enter 200ms ease-out',
"slide-in": "slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)", 'slide-in': 'slide-in 1.2s cubic-bezier(.41,.73,.51,1.02)',
leave: "leave 150ms ease-in forwards", 'leave': 'leave 150ms ease-in forwards',
"bounce-down": "bounce-down 3s infinite", 'bounce-down': 'bounce-down 3s infinite',
}, },
keyframes: { keyframes: {
wave: { 'wave': {
"0%": { transform: "rotate( 0.0deg)" }, '0%': { transform: 'rotate( 0.0deg)' },
"10%": { transform: "rotate(14.0deg)" }, '10%': { transform: 'rotate(14.0deg)' },
"20%": { transform: "rotate(-8.0deg)" }, '20%': { transform: 'rotate(-8.0deg)' },
"30%": { transform: "rotate(14.0deg)" }, '30%': { transform: 'rotate(14.0deg)' },
"40%": { transform: "rotate(-4.0deg)" }, '40%': { transform: 'rotate(-4.0deg)' },
"50%": { transform: "rotate(10.0deg)" }, '50%': { transform: 'rotate(10.0deg)' },
"60%": { transform: "rotate( 0.0deg)" }, '60%': { transform: 'rotate( 0.0deg)' },
"100%": { transform: "rotate( 0.0deg)" }, '100%': { transform: 'rotate( 0.0deg)' },
}, },
enter: { 'enter': {
"0%": { transform: "scale(0.8)", opacity: "0" }, '0%': { transform: 'scale(0.8)', opacity: '0' },
"100%": { transform: "scale(1)", opacity: "1" }, '100%': { transform: 'scale(1)', opacity: '1' },
}, },
leave: { 'leave': {
"0%": { transform: "scale(1)", opacity: "1" }, '0%': { transform: 'scale(1)', opacity: '1' },
"100%": { transform: "scale(0.8)", opacity: "0" }, '100%': { transform: 'scale(0.8)', opacity: '0' },
}, },
"slide-in": { 'slide-in': {
"0%": { transform: "translateY(-100%)" }, '0%': { transform: 'translateY(-100%)' },
"100%": { transform: "translateY(0)" }, '100%': { transform: 'translateY(0)' },
}, },
"bounce-down": { 'bounce-down': {
"0%,20%, 50%,80%,100%": { transform: "translateY(0)" }, '0%,20%, 50%,80%,100%': { transform: 'translateY(0)' },
"40%": { transform: "translateY(-8px)" }, '40%': { transform: 'translateY(-8px)' },
"60%": { transform: "translateY(-4px)" }, '60%': { transform: 'translateY(-4px)' },
}, },
}, },
container: { container: {
center: true, center: true,
padding: "16px", padding: '16px',
}, },
fontFamily: { fontFamily: {
sans: [ sans: [
"Inter", 'Inter',
"-apple-system", '-apple-system',
"BlinkMacSystemFont", 'BlinkMacSystemFont',
"Segoe UI", 'Segoe UI',
"Roboto", 'Roboto',
"Oxygen-Sans", 'Oxygen-Sans',
"Ubuntu,Cantarell", 'Ubuntu,Cantarell',
"Helvetica", 'Helvetica',
"sans-serif", 'sans-serif',
], ],
serif: ['Josefin Sans'],
}, },
extend: { extend: {
backgroundImage: { backgroundImage: {
'custom-img': "url('/img/homepage-new/bg.png')", 'custom-img': "url('/img/homepage-new/bg.png')",
} },
}, },
}, },
plugins: [require("tailwindcss-animate")], plugins: [require('tailwindcss-animate')],
}; }

View File

@ -1156,7 +1156,7 @@
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.23.7": "@babel/runtime@^7.21.0", "@babel/runtime@^7.24.0":
version "7.24.0" version "7.24.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e"
integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==
@ -1646,7 +1646,7 @@
"@docusaurus/theme-search-algolia" "3.1.0" "@docusaurus/theme-search-algolia" "3.1.0"
"@docusaurus/types" "3.1.0" "@docusaurus/types" "3.1.0"
"@docusaurus/react-loadable@5.5.2", "react-loadable@npm:@docusaurus/react-loadable@5.5.2": "@docusaurus/react-loadable@5.5.2":
version "5.5.2" version "5.5.2"
resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce" resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce"
integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ== integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==
@ -2743,6 +2743,13 @@
"@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-jsx" "^6.5.1"
"@svgr/plugin-svgo" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1"
"@swc/helpers@^0.5.3":
version "0.5.6"
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.6.tgz#d16d8566b7aea2bef90d059757e2d77f48224160"
integrity sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==
dependencies:
tslib "^2.4.0"
"@szmarczak/http-timer@^5.0.1": "@szmarczak/http-timer@^5.0.1":
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a"
@ -4846,6 +4853,13 @@ dagre-d3-es@7.0.10:
d3 "^7.8.2" d3 "^7.8.2"
lodash-es "^4.17.21" lodash-es "^4.17.21"
date-fns@^2.30.0:
version "2.30.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
dependencies:
"@babel/runtime" "^7.21.0"
dayjs@^1.11.7: dayjs@^1.11.7:
version "1.11.10" version "1.11.10"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
@ -5152,10 +5166,10 @@ dot-prop@^6.0.1:
dependencies: dependencies:
is-obj "^2.0.0" is-obj "^2.0.0"
dotenv@^16.3.1: dotenv@^16.4.5:
version "16.3.1" version "16.4.5"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
duplexer@^0.1.2: duplexer@^0.1.2:
version "0.1.2" version "0.1.2"
@ -7083,6 +7097,11 @@ lru-cache@^6.0.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
lucide-react@^0.291.0:
version "0.291.0"
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.291.0.tgz#d6db8f5117a68c8bbc6ed51d800879fa6a471978"
integrity sha512-79jHlT9Je2PXSvXIBGDkItCK7In2O9iKnnSJ/bJxvIBOFaX2Ex0xEcC4fRS/g0F2uQGFejjmn2qWhwdc5wicMQ==
lunr@^2.3.9: lunr@^2.3.9:
version "2.3.9" version "2.3.9"
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
@ -9294,6 +9313,11 @@ react-helmet-async@^1.3.0:
react-fast-compare "^3.2.0" react-fast-compare "^3.2.0"
shallowequal "^1.1.0" shallowequal "^1.1.0"
react-hook-form@^7.47.0:
version "7.51.0"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.51.0.tgz#757ae71b37c26e00590bd3788508287dcc5ecdaf"
integrity sha512-BggOy5j58RdhdMzzRUHGOYhSz1oeylFAv6jUSG86OvCIvlAvS7KvnRY7yoAf2pfEiPN7BesnR0xx73nEk3qIiw==
react-icons@^4.11.0: react-icons@^4.11.0:
version "4.12.0" version "4.12.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.12.0.tgz#54806159a966961bfd5cdb26e492f4dafd6a8d78" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.12.0.tgz#54806159a966961bfd5cdb26e492f4dafd6a8d78"
@ -9325,6 +9349,14 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1:
dependencies: dependencies:
"@babel/runtime" "^7.10.3" "@babel/runtime" "^7.10.3"
"react-loadable@npm:@docusaurus/react-loadable@5.5.2":
version "5.5.2"
resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce"
integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==
dependencies:
"@types/react" "*"
prop-types "^15.6.2"
react-router-config@^5.1.1: react-router-config@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988"
@ -9368,6 +9400,16 @@ react-tabs@^4.3.0:
clsx "^1.1.0" clsx "^1.1.0"
prop-types "^15.5.0" prop-types "^15.5.0"
react-tweet@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-tweet/-/react-tweet-3.2.0.tgz#653571842298b1c57076ec38f022ba640c3d2dde"
integrity sha512-eYLAX5ViOICQT/vkte/IzYZZDoBnl7hDO3Ns4++lKEFr/+BohPK5Rg+Lvbfx78Qtn3AjfDG5c6n+rOt7c2J6qg==
dependencies:
"@swc/helpers" "^0.5.3"
clsx "^2.0.0"
date-fns "^2.30.0"
swr "^2.2.4"
"react@^17.0.0 || ^18.2.0", react@^18.2.0: "react@^17.0.0 || ^18.2.0", react@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@ -10340,7 +10382,16 @@ stickyfill@^1.1.1:
resolved "https://registry.yarnpkg.com/stickyfill/-/stickyfill-1.1.1.tgz#39413fee9d025c74a7e59ceecb23784cc0f17f02" resolved "https://registry.yarnpkg.com/stickyfill/-/stickyfill-1.1.1.tgz#39413fee9d025c74a7e59ceecb23784cc0f17f02"
integrity sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA== integrity sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: "string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -10394,7 +10445,14 @@ stringify-object@3.3.0, stringify-object@^3.3.0:
is-obj "^1.0.1" is-obj "^1.0.1"
is-regexp "^1.0.0" is-regexp "^1.0.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: "strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@ -10549,12 +10607,20 @@ swagger2openapi@^7.0.6:
yaml "^1.10.0" yaml "^1.10.0"
yargs "^17.0.1" yargs "^17.0.1"
tailwind-merge@^2.0.0: swr@^2.2.4:
version "2.2.1" version "2.2.5"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.1.tgz#3f10f296a2dba1d88769de8244fafd95c3324aeb" resolved "https://registry.yarnpkg.com/swr/-/swr-2.2.5.tgz#063eea0e9939f947227d5ca760cc53696f46446b"
integrity sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q== integrity sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==
dependencies: dependencies:
"@babel/runtime" "^7.23.7" client-only "^0.0.1"
use-sync-external-store "^1.2.0"
tailwind-merge@^2.0.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.2.tgz#87341e7604f0e20499939e152cd2841f41f7a3df"
integrity sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==
dependencies:
"@babel/runtime" "^7.24.0"
tailwind-merge@^2.1.0: tailwind-merge@^2.1.0:
version "2.2.0" version "2.2.0"
@ -10721,7 +10787,7 @@ tslib@2.5.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
tslib@^2.0.3, tslib@^2.6.0: tslib@^2.0.3, tslib@^2.4.0, tslib@^2.6.0:
version "2.6.2" version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
@ -10980,6 +11046,11 @@ use-editable@^2.3.3:
resolved "https://registry.yarnpkg.com/use-editable/-/use-editable-2.3.3.tgz#a292fe9ba4c291cd28d1cc2728c75a5fc8d9a33f" resolved "https://registry.yarnpkg.com/use-editable/-/use-editable-2.3.3.tgz#a292fe9ba4c291cd28d1cc2728c75a5fc8d9a33f"
integrity sha512-7wVD2JbfAFJ3DK0vITvXBdpd9JAz5BcKAAolsnLBuBn6UDDwBGuCIAGvR3yA2BNKm578vAMVHFCWaOcA+BhhiA== integrity sha512-7wVD2JbfAFJ3DK0vITvXBdpd9JAz5BcKAAolsnLBuBn6UDDwBGuCIAGvR3yA2BNKm578vAMVHFCWaOcA+BhhiA==
use-sync-external-store@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@ -11289,8 +11360,16 @@ wordwrap@^1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
name wrap-ansi-cjs version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==