1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-05-13 21:46:37 +02:00

Doc: Refactored documentation, split it into smaller articles, and added search (#9132)

This commit is contained in:
Laurent Cozic 2023-10-30 11:32:14 +00:00 committed by GitHub
parent f94cc0fe3c
commit 5f6370d7ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
237 changed files with 11124 additions and 3131 deletions

View File

@ -14,6 +14,7 @@ Modules/TinyMCE/IconPack/postinstall.js
Modules/TinyMCE/JoplinLists/
Modules/TinyMCE/langs/
node_modules/
packages/doc-builder/
packages/app-cli/build
packages/app-cli/build/
packages/app-cli/locales
@ -976,6 +977,7 @@ packages/renderer/index.js
packages/renderer/noteStyle.js
packages/renderer/pathUtils.js
packages/renderer/utils.js
packages/tools/build-release-stats.test.js
packages/tools/build-release-stats.js
packages/tools/build-translation.js
packages/tools/build-welcome.js
@ -1014,12 +1016,15 @@ packages/tools/utils/loadSponsors.js
packages/tools/utils/translation.js
packages/tools/website/build.js
packages/tools/website/buildTranslations.js
packages/tools/website/processDocs.test.js
packages/tools/website/processDocs.js
packages/tools/website/updateDownloadPage.js
packages/tools/website/updateNews.js
packages/tools/website/utils/applyTranslations.test.js
packages/tools/website/utils/applyTranslations.js
packages/tools/website/utils/convertLinksToLocale.test.js
packages/tools/website/utils/convertLinksToLocale.js
packages/tools/website/utils/frontMatter.test.js
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/news.js
packages/tools/website/utils/openGraph.test.js

View File

@ -48,5 +48,5 @@ OS specifics:
<!--
Please attach a debug log. Issues without a debug log are likely to stall.
For information on how to collect a log file: https://joplinapp.org/debugging/
For information on how to collect a log file: https://joplinapp.org/help/apps/debugging/
-->

View File

@ -94,6 +94,17 @@ if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
fi
fi
# =============================================================================
# Check that the website builder can run without errors
# =============================================================================
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
if [ "$IS_LINUX" == "1" ]; then
echo "Step: Running website builder..."
node packages/tools/website/processDocs.js --env dev
fi
fi
# =============================================================================
# Run linter for pull requests only. We also don't want this to make the desktop
# release randomly fail.

4
.gitignore vendored
View File

@ -958,6 +958,7 @@ packages/renderer/index.js
packages/renderer/noteStyle.js
packages/renderer/pathUtils.js
packages/renderer/utils.js
packages/tools/build-release-stats.test.js
packages/tools/build-release-stats.js
packages/tools/build-translation.js
packages/tools/build-welcome.js
@ -996,12 +997,15 @@ packages/tools/utils/loadSponsors.js
packages/tools/utils/translation.js
packages/tools/website/build.js
packages/tools/website/buildTranslations.js
packages/tools/website/processDocs.test.js
packages/tools/website/processDocs.js
packages/tools/website/updateDownloadPage.js
packages/tools/website/updateNews.js
packages/tools/website/utils/applyTranslations.test.js
packages/tools/website/utils/applyTranslations.js
packages/tools/website/utils/convertLinksToLocale.test.js
packages/tools/website/utils/convertLinksToLocale.js
packages/tools/website/utils/frontMatter.test.js
packages/tools/website/utils/frontMatter.js
packages/tools/website/utils/news.js
packages/tools/website/utils/openGraph.test.js

View File

@ -1,2 +1,3 @@
packages/app-clipper/popup/
packages/app-cli/tests/support/plugins/
packages/app-cli/tests/support/plugins/
packages/doc-builder/

View File

@ -77,7 +77,7 @@ function setupDownloadPage() {
} else if (os === 'linux') {
// If it's Linux, the user should probably install it using the
// install script so we redirect to the install section
window.location = 'https://joplinapp.org/help/#desktop-applications';
window.location = 'https://joplinapp.org/help/install';
} else {
// Otherwise, start the download
const downloadLink = downloadLinks[os];

View File

@ -42,8 +42,8 @@
<p>This is just an overview of the main features. The full changelog is available there:</p>
<ul>
<li>Desktop: <a href="https://joplinapp.org/changelog">https://joplinapp.org/changelog</a></li>
<li>Android: <a href="https://joplinapp.org/changelog_android">https://joplinapp.org/changelog_android</a></li>
<li>iOS: <a href="https://joplinapp.org/changelog_ios">https://joplinapp.org/changelog_ios</a></li>
<li>Android: <a href="https://joplinapp.org/help/about/changelog/android">https://joplinapp.org/help/about/changelog/android</a></li>
<li>iOS: <a href="https://joplinapp.org/help/about/changelog/ios">https://joplinapp.org/help/about/changelog/ios</a></li>
</ul>
]]></description><link>https://joplinapp.org/news/20230508-release-2-12/</link><guid isPermaLink="false">20230508-release-2-12</guid><pubDate>Wed, 06 Sep 2023 12:00:00 GMT</pubDate><twitter-text>What&apos;s new in Joplin 2.12</twitter-text></item><item><title><![CDATA[What's new in Joplin 2.11]]></title><description><![CDATA[<h2>Desktop<a name="desktop" href="#desktop" class="heading-anchor">🔗</a></h2>
<h3>Add support for plugin user data<a name="add-support-for-plugin-user-data" href="#add-support-for-plugin-user-data" class="heading-anchor">🔗</a></h3>
@ -72,8 +72,8 @@
<p>This is just an overview of the main features. The full changelog is available there:</p>
<ul>
<li>Desktop: <a href="https://joplinapp.org/changelog">https://joplinapp.org/changelog</a></li>
<li>Android: <a href="https://joplinapp.org/changelog_android">https://joplinapp.org/changelog_android</a></li>
<li>iOS: <a href="https://joplinapp.org/changelog_ios">https://joplinapp.org/changelog_ios</a></li>
<li>Android: <a href="https://joplinapp.org/help/about/changelog/android">https://joplinapp.org/help/about/changelog/android</a></li>
<li>iOS: <a href="https://joplinapp.org/help/about/changelog/ios">https://joplinapp.org/help/about/changelog/ios</a></li>
</ul>
]]></description><link>https://joplinapp.org/news/20230508-release-2-11/</link><guid isPermaLink="false">20230508-release-2-11</guid><pubDate>Fri, 14 Jul 2023 12:00:00 GMT</pubDate><twitter-text>What&apos;s new in Joplin 2.11</twitter-text></item><item><title><![CDATA[What's new in Joplin 2.10]]></title><description><![CDATA[<p>Great news! Joplin 2.10 is here and we've made some amazing improvements and bug fixes, with a focus on the mobile app.</p>
<h1>New design for &quot;New note&quot; and &quot;New to-do&quot; buttons<a name="new-design-for-new-note-and-new-to-do-buttons" href="#new-design-for-new-note-and-new-to-do-buttons" class="heading-anchor">🔗</a></h1>
@ -181,8 +181,8 @@
<p>As always, a lot of work went into the Android and iOS app too, which include 37 improvements, bug fixes, and security fixes.</p>
<p>See here for the changelogs:</p>
<ul>
<li><a href="https://joplinapp.org/changelog/">Desktop app changelog</a></li>
<li><a href="https://joplinapp.org/changelog_android/">Android app changelog</a></li>
<li><a href="https://joplinapp.org/help/about/changelog">Desktop app changelog</a></li>
<li><a href="https://joplinapp.org/help/about/changelog/android/">Android app changelog</a></li>
</ul>
<h2>About the Android version<a name="about-the-android-version" href="#about-the-android-version" class="heading-anchor">🔗</a></h2>
<p>Unfortunately we cannot publish the Android version because it is based on a framework version that Google does not accept. To upgrade the app a lot of changes are needed and another round of pre-releases, and therefore there will not be a 2.9 version for Google Play. You may however download the official APK directly from there: <a href="https://github.com/laurent22/joplin-android/releases/tag/android-v2.9.8">Android 2.9 Official Release</a></p>
@ -232,7 +232,7 @@
<p>To make use of this feature, simply select <strong>Also publish linked notes</strong> when publishing a note.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/news/20220606-publish-website.png" alt=""></p>
<h1>And more!<a name="and-more" href="#and-more" class="heading-anchor">🔗</a></h1>
<p>In total there are 38 changes to improve the app reliability, security and usability. Full changelog is at <a href="https://joplinapp.org/changelog/">https://joplinapp.org/changelog/</a></p>
<p>In total there are 38 changes to improve the app reliability, security and usability. Full changelog is at <a href="https://joplinapp.org/help/about/changelog">https://joplinapp.org/help/about/changelog</a></p>
]]></description><link>https://joplinapp.org/news/20220606-release-2-8/</link><guid isPermaLink="false">20220606-release-2-8</guid><pubDate>Mon, 06 Jun 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin received 6 Contributor Projects for GSoC 2022!]]></title><description><![CDATA[<p>We are glad to announce that Google allocated us six projects this year for Google Summer of Code! So this is six contributors who will be working on various parts of the apps, both desktop and mobile, over the summer.</p>
<p>Over the next few weeks, till 13 June, will be the Community Bonding Period during which GSoC contributors get to know mentors, read documentation, and get up to speed to begin working on their projects.</p>
<p>Here's the full list of projects, contributors and mentors.</p>
@ -291,7 +291,7 @@
<p>In the coming month (<strong>March 7 - April 3</strong>), contributors will start getting involved in the forum and start discussing project ideas with the mentors and community. It's also a good time to start looking at Joplin's source code, perhaps work on fixing bugs or implement small features to get familiar with the source code, and to show us your skills.</p>
<p>One difference with previous years is that anyone, not just students, are allowed to participate.</p>
<p>Additionally, last year Google only allowed smaller projects, while this year they allow again small and large projects, so we've indicated this in the idea list - the small ones are <strong>175 hours</strong>, and the large ones <strong>350 hours</strong>.</p>
]]></description><link>https://joplinapp.org/news/20220308-gsoc2022-start/</link><guid isPermaLink="false">20220308-gsoc2022-start</guid><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.7 is available!]]></title><description><![CDATA[<p>This new release is largely focused on bug fixing and optimising various parts of the apps. There's about 26 improvements and 25 bugs and security fixes included - as always many of these apply to both the mobile and desktop app (see the <a href="https://joplinapp.org/changelog/">desktop changelog</a> and <a href="https://joplinapp.org/changelog_android/">mobile changelog</a>).</p>
]]></description><link>https://joplinapp.org/news/20220308-gsoc2022-start/</link><guid isPermaLink="false">20220308-gsoc2022-start</guid><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate><twitter-text></twitter-text></item><item><title><![CDATA[Joplin 2.7 is available!]]></title><description><![CDATA[<p>This new release is largely focused on bug fixing and optimising various parts of the apps. There's about 26 improvements and 25 bugs and security fixes included - as always many of these apply to both the mobile and desktop app (see the <a href="https://joplinapp.org/help/about/changelog">desktop changelog</a> and <a href="https://joplinapp.org/help/about/changelog/android/">mobile changelog</a>).</p>
<p>Many thanks to all the contributors who helped create this release!</p>
<p>Below are some of the more noticeable changes:</p>
<h1>Notebook custom icons<a name="notebook-custom-icons" href="#notebook-custom-icons" class="heading-anchor">🔗</a></h1>
@ -336,8 +336,8 @@
<p>Exporting a single note as HTML is now more user friendly as all images, scripts, styles and other attachments are all packed into a single HTML file (Previously it would create multiples files and directories). This makes it easier to share the complete note with someone who doesn't have Joplin.</p>
<p><strong>Other changes and bug fixes</strong></p>
<p>This release includes a total of 19 new features and improvements and 16 bug fixes. See the 2.6.x changelogs for more details:</p>
<p><a href="https://joplinapp.org/changelog/">https://joplinapp.org/changelog/</a></p>
<p><a href="https://joplinapp.org/changelog_android/">https://joplinapp.org/changelog_android/</a></p>
<p><a href="https://joplinapp.org/changelog_ios/">https://joplinapp.org/changelog_ios/</a></p>
<p><a href="https://joplinapp.org/changelog_cli/">https://joplinapp.org/changelog_cli/</a></p>
<p><a href="https://joplinapp.org/help/about/changelog">https://joplinapp.org/help/about/changelog</a></p>
<p><a href="https://joplinapp.org/help/about/changelog/android/">https://joplinapp.org/help/about/changelog/android/</a></p>
<p><a href="https://joplinapp.org/help/about/changelog/ios/">https://joplinapp.org/help/about/changelog/ios/</a></p>
<p><a href="https://joplinapp.org/help/about/changelog/cli/">https://joplinapp.org/help/about/changelog/cli/</a></p>
]]></description><link>https://joplinapp.org/news/20211217-120324/</link><guid isPermaLink="false">20211217-120324</guid><pubDate>Fri, 17 Dec 2021 12:03:24 GMT</pubDate><twitter-text></twitter-text></item></channel></rss>

View File

@ -16,7 +16,7 @@
<a href="{{baseUrl}}/news/" class="fw500">News</a>
<a href="{{baseUrl}}/help/" class="fw500">Help</a>
<a href="{{forumUrl}}" class="fw500">Forum</a>
<a href="{{baseUrl}}/cn/" class="fw500">中文</a>
<!-- <a href="{{baseUrl}}/cn/" class="fw500">中文</a> -->
<!--
<div class="dropdown language-switcher">
@ -39,7 +39,7 @@
</div>
<div class="col-9 text-right d-block d-md-none navbar-mobile-content">
{{> twitterLink}}
<a href="{{baseUrl}}/cn/" class="fw500 chinese-page-link">中文</a>
<!-- <a href="{{baseUrl}}/cn/" class="fw500 chinese-page-link">中文</a> -->
{{> joplinCloudButton}}
{{> supportButton}}

538
README.md
View File

@ -2,66 +2,23 @@
[![Donate using PayPal](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=E8JMYD2LQ8MMA&no_recurring=0&item_name=I+rely+on+donations+to+maintain+and+improve+the+Joplin+open+source+project.+Thank+you+for+your+help+-+it+makes+a+difference%21&currency_code=EUR) [![Sponsor on GitHub](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/GitHub-Badge.svg)](https://github.com/sponsors/laurent22/) [![Become a patron](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Patreon-Badge.svg)](https://www.patreon.com/joplin) [![Donate using IBAN](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-IBAN.svg)](https://joplinapp.org/donate/#donations)
<!-- DONATELINKS -->
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" /> **Joplin** is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
<img width="64" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/LinuxIcons/256x256.png" align="left" style="margin-right:15px"/> <b>Joplin</b> is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](#markdown).
Notes exported from Evernote [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
Notes exported from Evernote [can be imported](https://github.com/laurent22/joplin/blob/dev/readme/apps/import_export.md) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
The notes can be securely [synchronised](#synchronisation) using [end-to-end encryption](#encryption) with various cloud services including Nextcloud, Dropbox, OneDrive and [Joplin Cloud](https://joplinapp.org/plans/).
Joplin is "offline first", which means you always have all your data on your phone or computer. This ensures that your notes are always accessible, whether you have an internet connection or not.
The notes can be securely [synchronised](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/index.md) using [end-to-end encryption](https://github.com/laurent22/joplin/blob/dev/readme/apps/sync/e2ee.md) with various cloud services including Nextcloud, Dropbox, OneDrive and [Joplin Cloud](https://joplinapp.org/plans/).
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
The application is available for Windows, Linux, macOS, Android and iOS. A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
The application is available for Windows, Linux, macOS, Android and iOS. A [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/apps/clipper.md), to save web pages and screenshots from your browser, is also available for [Firefox](https://addons.mozilla.org/firefox/addon/joplin-web-clipper/) and [Chrome](https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB).
<div class="top-screenshot"><img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/home-top-img.png" style="max-width: 100%; max-height: 35em;"></div>
# Installation
# Help and documentation
Three types of applications are available: for **desktop** (Windows, macOS and Linux), for **mobile** (Android and iOS) and for **terminal** (Windows, macOS, Linux and FreeBSD). All the applications have similar user interfaces and can synchronise with each other.
## Desktop applications
Operating System | Download
---|---
Windows (32 and 64-bit) | <a href='https://objects.joplinusercontent.com/v2.12.19/Joplin-Setup-2.12.19.exe?source=JoplinWebsite&type=New'><img alt='Get it on Windows' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeWindows.png'/></a>
macOS | <a href='https://objects.joplinusercontent.com/v2.12.19/Joplin-2.12.19.dmg?source=JoplinWebsite&type=New'><img alt='Get it on macOS' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeMacOS.png'/></a>
Linux | <a href='https://objects.joplinusercontent.com/v2.12.19/Joplin-2.12.19.AppImage?source=JoplinWebsite&type=New'><img alt='Get it on Linux' width="134px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeLinux.png'/></a>
**On Windows**, you may also use the <a href='https://objects.joplinusercontent.com/v2.12.19/JoplinPortable.exe?source=JoplinWebsite&type=New'>Portable version</a>. The [portable application](https://en.wikipedia.org/wiki/Portable_application) allows installing the software on a portable device such as a USB key. Simply copy the file JoplinPortable.exe in any directory on that USB key ; the application will then create a directory called "JoplinProfile" next to the executable file.
**On Linux**, the recommended way is to use the following installation script as it will handle the desktop icon too:
<pre><code style="word-break: break-all">wget -O - https://raw.githubusercontent.com/laurent22/joplin/dev/Joplin_install_and_update.sh | bash</code></pre>
The install and update script supports the [following flags](https://github.com/laurent22/joplin/blob/dev/Joplin_install_and_update.sh#L50) (around line 50 at the time of this writing).
## Mobile applications
Operating System | Download | Alt. Download
---|---|---
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeAndroid.png'/></a> | or download the [APK file](https://objects.joplinusercontent.com/v2.12.3/joplin-v2.12.3.apk?source=JoplinWebsite&type=New)
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/BadgeIOS.png'/></a> | -
## Terminal application
Operating system | Method
-----------------|----------------
macOS, Linux, or Windows (via [WSL](https://msdn.microsoft.com/en-us/commandline/wsl/faq?f=255&MSPPError=-2147217396)) | **Important:** First, [install Node 12+](https://nodejs.org/en/download/package-manager/).<br/><br/>`NPM_CONFIG_PREFIX=~/.joplin-bin npm install -g joplin`<br/>`sudo ln -s ~/.joplin-bin/bin/joplin /usr/bin/joplin`<br><br>By default, the application binary will be installed under `~/.joplin-bin`. You may change this directory if needed. Alternatively, if your npm permissions are setup as described [here](https://docs.npmjs.com/getting-started/fixing-npm-permissions#option-2-change-npms-default-directory-to-another-directory) (Option 2) then simply running `npm -g install joplin` would work.
To start it, type `joplin`.
For usage information, please refer to the full [Joplin Terminal Application Documentation](https://joplinapp.org/terminal/).
## Web Clipper
The Web Clipper is a browser extension that allows you to save web pages and screenshots from your browser. For more information on how to install and use it, see the [Web Clipper Help Page](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md).
## Unofficial Alternative Distributions
There are a number of unofficial alternative Joplin distributions. If you do not want to or cannot use appimages or any of the other officially supported releases then you may wish to consider these.
However these come with a caveat in that they are not officially supported so certain issues may not be supportable by the main project. Rather support requests, bug reports and general advice would need to go to the maintainers of these distributions.
A community maintained list of these distributions can be found here: [Unofficial Joplin distributions](https://discourse.joplinapp.org/t/unofficial-alternative-joplin-distributions/23703)
For more information about the applications, see the [Joplin documentation](https://joplinapp.org)
# Sponsors
@ -80,427 +37,12 @@ A community maintained list of these distributions can be found here: [Unofficia
| <img width="50" src="https://avatars2.githubusercontent.com/u/126279083?s=96&v=4"/></br>[matmoly](https://github.com/matmoly) | <img width="50" src="https://avatars2.githubusercontent.com/u/1788010?s=96&v=4"/></br>[maxtruxa](https://github.com/maxtruxa) | <img width="50" src="https://avatars2.githubusercontent.com/u/31054972?s=96&v=4"/></br>[saarantras](https://github.com/saarantras) | <img width="50" src="https://avatars2.githubusercontent.com/u/327998?s=96&v=4"/></br>[sif](https://github.com/sif) |
| <img width="50" src="https://avatars2.githubusercontent.com/u/765564?s=96&v=4"/></br>[taskcruncher](https://github.com/taskcruncher) | <img width="50" src="https://avatars2.githubusercontent.com/u/333944?s=96&v=4"/></br>[tateisu](https://github.com/tateisu) | | |
<!-- SPONSORS-GITHUB -->
<!-- TOC -->
# Table of contents
- Applications
- [Desktop application](https://github.com/laurent22/joplin/blob/dev/readme/desktop.md)
- [Mobile applications](https://github.com/laurent22/joplin/blob/dev/readme/mobile.md)
- [Terminal application](https://github.com/laurent22/joplin/blob/dev/readme/terminal.md)
- [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md)
- Support
- [Joplin Forum](https://discourse.joplinapp.org)
- [Markdown Guide](https://github.com/laurent22/joplin/blob/dev/readme/markdown.md)
- [How to enable end-to-end encryption](https://github.com/laurent22/joplin/blob/dev/readme/e2ee.md)
- [What is a conflict?](https://github.com/laurent22/joplin/blob/dev/readme/conflict.md)
- [How to enable debug mode](https://github.com/laurent22/joplin/blob/dev/readme/debugging.md)
- [About the Rich Text editor limitations](https://github.com/laurent22/joplin/blob/dev/readme/rich_text_editor.md)
- [External links](https://github.com/laurent22/joplin/blob/dev/readme/external_links.md)
- [FAQ](https://github.com/laurent22/joplin/blob/dev/readme/faq.md)
- Joplin Cloud
- [Sharing a notebook](https://github.com/laurent22/joplin/blob/dev/readme/share_notebook.md)
- [Publishing a note](https://github.com/laurent22/joplin/blob/dev/readme/publish_note.md)
- [Email to Note](https://github.com/laurent22/joplin/blob/dev/readme/email_to_note.md)
- Joplin API - Get Started
- [Joplin API Overview](https://github.com/laurent22/joplin/blob/dev/readme/api/overview.md)
- [Plugin development](https://github.com/laurent22/joplin/blob/dev/readme/api/get_started/plugins.md)
- [Plugin tutorial](https://github.com/laurent22/joplin/blob/dev/readme/api/tutorials/toc_plugin.md)
- Joplin API - References
- [Plugin API](https://joplinapp.org/api/references/plugin_api/classes/joplin.html)
- [Data API](https://github.com/laurent22/joplin/blob/dev/readme/api/references/rest_api.md)
- [Plugin manifest](https://github.com/laurent22/joplin/blob/dev/readme/api/references/plugin_manifest.md)
- [Plugin loading rules](https://github.com/laurent22/joplin/blob/dev/readme/api/references/plugin_loading_rules.md)
- [Plugin theming](https://github.com/laurent22/joplin/blob/dev/readme/api/references/plugin_theming.md)
- Development
- [How to build the apps](https://github.com/laurent22/joplin/blob/dev/BUILD.md)
- [Writing a technical spec](https://github.com/laurent22/joplin/blob/dev/readme/technical_spec.md)
- [Desktop application styling](https://github.com/laurent22/joplin/blob/dev/readme/spec/desktop_styling.md)
- [Note history spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md)
- [Synchronisation spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync.md)
- [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md)
- [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md)
- [Overall Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/architecture.md)
- [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md)
- [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md)
- [E2EE: Technical spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md)
- [E2EE: Workflow](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee/workflow.md)
- [Server: File URL Format](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_file_url_format.md)
- [Server: Delta Sync](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_delta_sync.md)
- [Server: Sharing](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_sharing.md)
- [Read-only items](https://github.com/laurent22/joplin/blob/dev/readme/spec/read_only.md)
- Google Summer of Code 2022
- [Google Summer of Code 2022](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/index.md)
- [How to submit a GSoC pull request](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/pull_request_guidelines.md)
- [Project Ideas](https://github.com/laurent22/joplin/blob/dev/readme/gsoc2022/ideas.md)
- About
- [Changelog (Desktop App)](https://github.com/laurent22/joplin/blob/dev/readme/changelog.md)
- [Changelog (Android)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_android.md)
- [Changelog (iOS)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_ios.md)
- [Changelog (CLI App)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_cli.md)
- [Changelog (Server)](https://github.com/laurent22/joplin/blob/dev/readme/changelog_server.md)
- [Guiding principles](https://github.com/laurent22/joplin/blob/dev/readme/principles.md)
- [Stats](https://github.com/laurent22/joplin/blob/dev/readme/stats.md)
- [Brand guidelines](https://joplinapp.org/brand)
- [Release cycle](https://github.com/laurent22/joplin/blob/dev/readme/release_cycle.md)
- [Donate](https://github.com/laurent22/joplin/blob/dev/readme/donate.md)
<!-- TOC -->
# Features
- Desktop, mobile and terminal applications.
- [Web Clipper](https://github.com/laurent22/joplin/blob/dev/readme/clipper.md) for Firefox and Chrome.
- End To End Encryption (E2EE).
- Note history (revisions).
- Synchronisation with various services, including Nextcloud, Dropbox, WebDAV and OneDrive.
- Offline first, so the entire data is always available on the device even without an internet connection.
- Import Enex files (Evernote export format) and Markdown files.
- Export JEX files (Joplin Export format) and raw files.
- Support notes, to-dos, tags and notebooks.
- Sort notes by multiple criteria - title, updated time, etc.
- Support for alarms (notifications) in mobile and desktop applications.
- Markdown notes, which are rendered with images and formatting in the desktop and mobile applications. Support for extra features such as math notation and checkboxes.
- Choice of both Markdown and Rich Text (WYSIWYG) editors.
- File attachment support - images are displayed, other files are linked and can be opened in the relevant application.
- Inline display of PDF, video and audio files.
- Goto Anything feature.
- Search functionality.
- Geo-location support.
- Supports multiple languages.
- External editor support - open notes in your favorite external editor with one click in Joplin.
- Extensible functionality through plugin and data APIs.
- Custom CSS support for customisation of both the rendered markdown and overall user interface.
- Customisable layout allows toggling, movement and sizing of various elements.
- Keyboard shortcuts are editable and allow binding of most Joplin commands with export/import functionality.
- Multiple profile support.
# Importing
## Importing from Evernote
Joplin was designed as a replacement for Evernote and so can import complete Evernote notebooks, as well as notes, tags, resources (attached files) and note metadata (such as author, geo-location, etc.) via ENEX files. In terms of data, the only two things that might slightly differ are:
- Recognition data - Evernote images, in particular scanned (or photographed) documents have [recognition data](https://en.wikipedia.org/wiki/Optical_character_recognition) associated with them. It is the text that Evernote has been able to recognise in the document. This data is not preserved when the note are imported into Joplin. However, should it become supported in the search tool or other parts of Joplin, it should be possible to regenerate this recognition data since the actual image would still be available.
- Colour, font sizes and faces - Evernote text is stored as HTML and this is converted to Markdown during the import process. For notes that are mostly plain text or with basic formatting (bold, italic, bullet points, links, etc.) this is a lossless conversion, and the note, once rendered back to HTML should be very similar. Tables are also imported and converted to Markdown tables. For very complex notes, some formatting data might be lost - in particular colours, font sizes and font faces will not be imported. The text itself however is always imported in full regardless of formatting. If it is essential that this extra data is preserved then Joplin also allows import of ENEX files as HTML.
To import Evernote data, first export your Evernote notebooks to ENEX files as described [here](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restore-import-notes-and-notebooks). Then follow these steps:
In the **desktop application**, open File > Import > ENEX and select your file. The notes will be imported into a new separate notebook. If needed they can then be moved to a different notebook, or the notebook can be renamed, etc.
In the **terminal application**, in [command-line mode](https://github.com/laurent22/joplin/blob/dev/readme/terminal.md#command-line-mode), type `import /path/to/file.enex`. This will import the notes into a new notebook named after the filename.
## Importing from Markdown files
Joplin can import notes from plain Markdown file. You can either import a complete directory of Markdown files or individual files.
In the **desktop application**:
* **File import**: Go to File > Import > MD - Markdown (file) and select the Markdown file. This file will then be imported to the currently selected Notebook.
* **Directory import**: Go to File > Import > MD - Markdown (directory) and select the top level of the directory that is being imported. Directory (folder) structure will be preserved in the Notebook > Subnotebook > Note structure within Joplin.
In the **terminal application**, in [command-line mode](https://github.com/laurent22/joplin/blob/dev/readme/terminal.md#command-line-mode), type `import --format md /path/to/file.md` or `import --format md /path/to/directory/`.
## Importing from other applications
In general the way to import notes from any application into Joplin is to convert the notes to ENEX files (Evernote format) and to import these ENEX files into Joplin using the method above. Most note-taking applications support ENEX files so it should be relatively straightforward. For help about specific applications, see below:
* Standard Notes: Please see [this tutorial](https://programadorwebvalencia.com/migrate-notes-from-standard-notes-to-joplin/)
* Tomboy Notes: Export the notes to ENEX files [as described here](https://askubuntu.com/questions/243691/how-can-i-export-my-tomboy-notes-into-evernote/608551) for example, and import these ENEX files into Joplin.
* OneNote: First [import the notes from OneNote into Evernote](https://discussion.evernote.com/topic/107736-is-there-a-way-to-import-from-onenote-into-evernote-on-the-mac/). Then export the ENEX file from Evernote and import it into Joplin.
* NixNote: Synchronise with Evernote, then export the ENEX files and import them into Joplin. More info [in this thread](https://discourse.joplinapp.org/t/import-from-nixnote/183/3).
# Exporting
Joplin can export to the JEX format (Joplin Export file), which is a tar file that can contain multiple notes, notebooks, etc. This is a lossless format in that all the notes, but also metadata such as geo-location, updated time, tags, etc. are preserved. This format is convenient for backup purposes and can be re-imported into Joplin. A "raw" format is also available. This is the same as the JEX format except that the data is saved to a directory and each item represented by a single file.
Joplin is also capable of exporting to a number of other formats including HTML and PDF which can be done for single notes, notebooks or everything.
# Synchronisation
One of the goals of Joplin is to avoid being tied to any particular company or service, whether it is Evernote, Google or Microsoft. As such the synchronisation is designed without any hard dependency to any particular service. Most of the synchronisation process is done at an abstract level and access to external services, such as Nextcloud or Dropbox, is done via lightweight drivers. It is easy to support new services by creating simple drivers that provide a filesystem-like interface, i.e. the ability to read, write, delete and list items. It is also simple to switch from one service to another.
Currently, synchronisation is possible with Joplin Cloud, Nextcloud, S3, WebDAV, Dropbox, OneDrive or the local filesystem. To enable synchronisation please follow the instructions below. After that, the application will synchronise in the background whenever it is running, or you can click on "Synchronise" to start a synchronisation manually. Joplin will background sync automatically after any content change is made on the local application.
If the **terminal client** has been installed, it is possible to also synchronise outside of the user interface by typing `joplin sync` from the terminal. This can be used to setup a cron script to synchronise at a regular interval. For example, this would do it every 30 minutes:
` */30 * * * * /path/to/joplin sync`
## Nextcloud synchronisation
<img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/nextcloud-logo-background.png" width="100" align="left"> <a href="https://nextcloud.com/">Nextcloud</a> is a self-hosted, private cloud solution. It can store documents, images and videos but also calendars, passwords and countless other things and can sync them to your laptop or phone. As you can host your own Nextcloud server, you own both the data on your device and infrastructure used for synchronisation. As such it is a good fit for Joplin. The platform is also well supported and with a strong community, so it is likely to be around for a while - since it's open source anyway, it is not a service that can be closed, it can exist on a server for as long as one chooses.
In the **desktop application** or **mobile application**, go to the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md) and select Nextcloud as the synchronisation target. Then input the WebDAV URL (to get it, click on Settings in the bottom left corner of the page, in Nextcloud), this is normally `https://example.com/nextcloud/remote.php/webdav/Joplin` (**make sure to create the "Joplin" directory in Nextcloud**), and set the username and password. If it does not work, please [see this explanation](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) for more details.
In the **terminal application**, you will need to set the `sync.target` config variable and all the `sync.5.path`, `sync.5.username` and `sync.5.password` config variables to, respectively the Nextcloud WebDAV URL, your username and your password. This can be done from the command line mode using:
:config sync.5.path https://example.com/nextcloud/remote.php/webdav/Joplin
:config sync.5.username YOUR_USERNAME
:config sync.5.password YOUR_PASSWORD
:config sync.target 5
If synchronisation does not work, please consult the logs in the app profile directory - it is often due to a misconfigured URL or password. The log should indicate what the exact issue is.
## WebDAV synchronisation
Select the "WebDAV" synchronisation target and follow the same instructions as for Nextcloud above (for the **terminal application** you will need to select sync target 6 rather than 5)
WebDAV-compatible services that are known to work with Joplin:
- [Apache WebDAV Module](https://httpd.apache.org/docs/current/mod/mod_dav.html)
- [DriveHQ](https://www.drivehq.com)
- [Fastmail](https://www.fastmail.com/)
- [HiDrive](https://www.strato.fr/stockage-en-ligne/) from Strato. [Setup help](https://github.com/laurent22/joplin/issues/309)
- [Nginx WebDAV Module](https://nginx.org/en/docs/http/ngx_http_dav_module.html)
- [Nextcloud](https://nextcloud.com/)
- [OwnCloud](https://owncloud.org/)
- [Seafile](https://www.seafile.com/)
- [Stack](https://www.transip.nl/stack/)
- [Synology WebDAV Server](https://www.synology.com/en-us/dsm/packages/WebDAVServer)
- [WebDAV Nav](https://www.schimera.com/products/webdav-nav-server/), a macOS server.
- [Zimbra](https://www.zimbra.com/)
## Dropbox synchronisation
When syncing with Dropbox, Joplin creates a sub-directory in Dropbox, in `/Apps/Joplin` and reads/writes the notes and notebooks in it. The application does not have access to anything outside this directory.
In the **desktop application** or **mobile application**, select "Dropbox" as the synchronisation target in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md) (it is selected by default). Then, to initiate the synchronisation process, click on the "Synchronise" button in the sidebar and follow the instructions.
In the **terminal application**, to initiate the synchronisation process, type `:sync`. You will be asked to follow a link to authorise the application.
## OneDrive synchronisation
When syncing with OneDrive, Joplin creates a sub-directory in OneDrive, in /Apps/Joplin and reads/writes the notes and notebooks in it. The application does not have access to anything outside this directory.
In the **desktop application** or **mobile application**, select "OneDrive" as the synchronisation target in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md). Then, to initiate the synchronisation process, click on the "Synchronise" button in the sidebar and follow the instructions.
In the **terminal application**, to initiate the synchronisation process, type `:sync`. You will be asked to follow a link to authorise the application (simply input your Microsoft credentials - you do not need to register with OneDrive).
## S3 synchronisation
As of Joplin 2.x.x, Joplin supports multiple S3 providers. We expose some options that will need to be configured depending on your provider of choice. We have tested with UpCloud, AWS, and Linode. others should work as well.
In the **desktop application** or **mobile application**, select "S3 (Beta)" as the synchronisation target in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md).
- **S3 Bucket:** The name of your Bucket, such as `joplin-bucket`
- **S3 URL:** Fully qualified URL; For AWS this should be `https://s3.<regionName>.amazonaws.com/`
- **S3 Access Key & S3 Secret Key:** The User's programmatic access key. To create a new key & secret on AWS, visit [IAM Security Credentials](https://console.aws.amazon.com/iam/home#/security_credentials). For other providers follow their documentation.
- **S3 Region:** Some providers require you to provide the region of your bucket. This is usually in the form of "eu-west1" or something similar depending on your region. For providers that do not require a region, you can leave it blank.
- **Force Path Style**: This setting enables Joplin to talk to S3 providers using an older style S3 Path. Depending on your provider you may need to try with this on and off.
While creating a new Bucket for Joplin, disable **Bucket Versioning**, enable **Block all public access** and enable **Default encryption** with `Amazon S3 key (SSE-S3)`. Some providers do not expose these options, and it could create a syncing problem. Do attempt and report back so we can update the documentation appropriately.
To add a **Bucket Policy** from the AWS S3 Web Console, navigate to the **Permissions** tab. Temporarily disable **Block all public access** to edit the Bucket policy, something along the lines of:
```
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::joplin-bucket",
"arn:aws:s3:::joplin-bucket/*"
]
}
]
}
```
### Configuration settings for tested providers
All providers will require a bucket, Access Key, and Secret Key.
If you provide a configuration and you receive "success!" on the "check config" then your S3 sync should work for your provider. If you do not receive success, you may need to adjust your settings, or save them, restart the app, and attempt a sync. This may reveal more clear error messaging that will help you deduce the problem.
### AWS
- URL: `https://s3.<region>.amazonaws.com/` (fill in your region, a complete list of endpoint adresses can be found [here](https://docs.aws.amazon.com/general/latest/gr/s3.html))
- Region: required
- Force Path Style: unchecked
### Linode
- URL: `https://<region>.linodeobjects.com` (region is in the URL provided by Linode; this URL is also the same as the URL provided by Linode with the bucket name removed)
- Region: Anything you want to type, can't be left empty
- Force Path Style: unchecked
### UpCloud
- URL: `https://<account>.<region>.upcloudobjects.com` (They will provide you with multiple URLs, the one that follows this pattern should work.)
- Region: required
- Force Path Style: unchecked
# Encryption
Joplin supports end-to-end encryption (E2EE) on all the applications. E2EE is a system where only the owner of the notes, notebooks, tags or resources can read them. It prevents potential eavesdroppers - including telecom providers, internet providers, and even the developers of Joplin from being able to access the data. Please see the [End-To-End Encryption Tutorial](https://github.com/laurent22/joplin/blob/dev/readme/e2ee.md) for more information about this feature and how to enable it.
For a more technical description, mostly relevant for development or to review the method being used, please see the [Encryption specification](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md).
# Note history
The Joplin applications automatically save previous versions of your notes at regular intervals. These versions are synced across devices and can be viewed from the desktop application. To do so, click on the "Information" button on a note, then click on "Previous version of this note". From this screen you can view the previous versions of the note as well as restore any of them.
This feature can be disabled from the "Note history" section in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md), and it is also possible to change for how long the history of a note is saved.
More information please see the [Note History page](https://github.com/laurent22/joplin/blob/dev/readme/note_history.md).
# External text editor
Joplin notes can be opened and edited using an external editor of your choice. It can be a simple text editor like Notepad++ or Sublime Text or an actual Markdown editor like Typora. In that case, images will also be displayed within the editor. To open the note in an external editor, click on the icon in the toolbar or press Ctrl+E (or Cmd+E). Your default text editor will be used to open the note. If needed, you can also specify the editor directly in the General Options, under "Text editor command".
# Attachments
Any kind of file can be attached to a note. In Markdown, links to these files are represented as a simple ID to the attachment, clicking on this link will open the file in the default application. In the case of audio, video and pdf files, these will be displayed inline with the note and so can be viewed or played within Joplin.
In the **desktop application**, files can be attached either by clicking the "Attach file" icon in the editor or via drag and drop. If you prefer to create a link to a local file instead, hold the ALT key while performing the drag and drop operation. You can also copy and paste images directly in the editor via Ctrl+V.
Resources that are not attached to any note will be automatically deleted in accordance to the [Note History](#note-history) settings.
**Important:** Resources larger than 10 MB are not currently supported on mobile. They will crash the application when synchronising so it is recommended not to attach such resources at the moment. The issue is being looked at.
## Downloading attachments
The way the attachments are downloaded during synchronisation can be customised in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md), under "Attachment download behaviour". The default option ("Always") is to download all the attachments, all the time, so that the data is available even when the device is offline. There is also the option to download the attachments manually (option "Manual"), by clicking on it, or automatically (Option "Auto"), in which case the attachments are downloaded only when a note is opened. These options should help saving disk space and network bandwidth, especially on mobile.
# Notifications
In the desktop and mobile apps, an alarm can be associated with any to-do. It will be triggered at the given time by displaying a notification. How the notification will be displayed depends on the operating system since each has a different way to handle this. Please see below for the requirements for the desktop applications:
- **Windows**: >= 8. Make sure the Action Center is enabled on Windows. Task bar balloon for Windows < 8. Growl as fallback. Growl takes precedence over Windows balloons.
- **macOS**: >= 10.8 or Growl if earlier.
- **Linux**: `notify-send` tool, delivered through packages `notify-osd`, `libnotify-bin` or `libnotify-tools`. GNOME should have this by default, but install `libnotify-tools` if using KDE Plasma.
See [documentation and flow chart for reporter choice](https://github.com/mikaelbr/node-notifier/blob/master/DECISION_FLOW.md)
On mobile, the alarms will be displayed using the built-in notification system.
If for any reason the notifications do not work, please [open an issue](https://github.com/laurent22/joplin/issues).
# Sub-notebooks
Sub-notebooks allow organising multiple notebooks into a tree of notebooks. For example it can be used to regroup all the notebooks related to work, to family or to a particular project under a parent notebook.
![](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/SubNotebooks.png)
- In the **desktop application**, to create a subnotebook, drag and drop it onto another notebook. To move it back to the root, drag and drop it on the "Notebooks" header. Currently only the desktop app can be used to organise the notebooks.
- The **mobile application** supports displaying and collapsing/expanding the tree of notebooks, however it does not currently support moving the subnotebooks to different notebooks.
- The **terminal app** supports displaying the tree of subnotebooks but it does not support collapsing/expanding them or moving the subnotebooks around.
# Markdown
Joplin uses and renders a Github-flavoured Markdown with a few variations and additions. In particular it adds math formula support, interactive checkboxes and support for note links. Joplin also supports Markdown plugins which allow enabling and disabling various advanced Markdown features. Have a look at the [Markdown Guide](https://github.com/laurent22/joplin/blob/dev/readme/markdown.md) for more information.
# Custom CSS
Rendered markdown can be customized by placing a userstyle file in the profile directory `~/.config/joplin-desktop/userstyle.css` (This path might be different on your device - check at the top of the `General` page of the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md) for the exact path). This file supports standard CSS syntax. Joplin ***must*** be restarted for the new css to be applied, please ensure that Joplin is not closing to the tray, but is actually exiting. Note that this file is used for both displaying the notes and printing the notes. Be aware how the CSS may look printed (for example, printing white text over a black background is usually not wanted).
The whole UI can be customized by placing a custom editor style file in the profile directory `~/.config/joplin-desktop/userchrome.css`.
Important: userstyle.css and userchrome.css are provided for your convenience, but they are advanced settings, and styles you define may break from one version to the next. If you want to use them, please know that it might require regular development work from you to keep them working. The Joplin team cannot make a commitment to keep the application HTML structure stable.
# Plugins
The **desktop app** has the ability to extend beyond its standard functionality by the way of plugins. These plugins adhere to the Joplin [plugin API](https://joplinapp.org/api/references/plugin_api/classes/joplin.html) and can be installed & configured within the application via the `Plugins` page of the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md).
From this menu you can search for plugins uploaded to the [Joplin plugins](https://github.com/joplin/plugins) repository as well as manual installation of plugins using a 'Joplin Plugin Archive' (*.jpl) file.
Once the application is reloaded the plugins will appear within the plugins menu where they can be toggled on/off or removed entirely.
For more information see [Plugins](https://github.com/laurent22/joplin/blob/dev/readme/plugins.md)
# Searching
Joplin implements the SQLite Full Text Search (FTS4) extension. It means the content of all the notes is indexed in real time and search queries return results very fast. Both [Simple FTS Queries](https://www.sqlite.org/fts3.html#simple_fts_queries) and [Full-Text Index Queries](https://www.sqlite.org/fts3.html#full_text_index_queries) are supported. See below for the list of supported queries:
One caveat of SQLite FTS is that it does not support languages which do not use Latin word boundaries (spaces, tabs, punctuation). To solve this issue, Joplin has a custom search mode, that does not use FTS, but still has all of its features (multi term search, filters, etc.). One of its drawbacks is that it can get slow on larger note collections. Also, the sorting of the results will be less accurate, as the ranking algorithm (BM25) is, for now, only implemented for FTS. Finally, in this mode there are no restrictions on using the `*` wildcard (`swim*`, `*swim` and `ast*rix` all work). This search mode is currently enabled if one of the following languages are detected:
- Chinese
- Japanese
- Korean
- Thai
## Supported queries
Search type | Description | Example
------------|-------------|---------
Single word | Returns all the notes that contain this term. | For example, searching for `cat` will return all the notes that contain this exact word. Note: it will not return the notes that contain the substring - thus, for "cat", notes that contain "cataclysmic" or "prevaricate" will **not** be returned.
Multiple word | Returns all the notes that contain **all** these words, but not necessarily next to each other. | `dog cat` - will return any notes that contain the words "dog" and "cat" anywhere in the note, no necessarily in that order nor next to each other. It will **not** return results that contain "dog" or "cat" only.
Phrase | Add double quotes to return the notes that contain exactly this phrase. | `"shopping list"` - will return the notes that contain these **exact terms** next to each other and in this order. It will **not** return for example a note that contains "going shopping with my list".
Prefix | Add a wildcard to return all the notes that contain a term with a specified prefix. | `swim*` - will return all the notes that contain eg. "swim", but also "swimming", "swimsuit", etc. IMPORTANT: The wildcard **can only be at the end** - it will be ignored at the beginning of a word (eg. `*swim`) and will be treated as a literal asterisk in the middle of a word (eg. `ast*rix`)
Switch to basic search | One drawback of Full Text Search is that it ignores most non-alphabetical characters. However in some cases you might want to search for this too. To do that, you can use basic search. You switch to this mode by prefixing your search with a slash `/`. This won't provide the benefits of FTS but it will allow searching exactly for what you need. Note that it can also be much slower, even extremely slow, depending on your query. | `/"- [ ]"` - will return all the notes that contain unchecked checkboxes.
## Search filters
You can also use search filters to further restrict the search.
| Operator | Description | Example |
| --- | --- | --- |
|**-**|If placed before a text term, it excludes the notes that contain that term. You can also place it before a filter to negate it. |`-spam` searches for all notes without the word `spam`.<br>`office -trash` searches for all notes with the word `office` and without the word `trash`.|
|**any:**|Return notes that satisfy any/all of the required conditions. `any:0` is the default, which means all conditions must be satisfied.|`any:1 cat dog` will return notes that have the word `cat` or `dog`.<br>`any:0 cat dog` will return notes with both the words `cat` and `dog`. |
| **title:** <br> **body:**|Restrict your search to just the title or the body field.|`title:"hello world"` searches for notes whose title contains `hello` and `world`.<br>`title:hello -body:world` searches for notes whose title contains `hello` and body does not contain `world`.
| **tag:** |Restrict the search to the notes with the specified tags.|`tag:office` searches for all notes having tag office.<br>`tag:office tag:important` searches for all notes having both office and important tags.<br>`tag:office -tag:spam` searches for notes having tag `office` which do not have tag `spam`.<br>`any:1 tag:office tag:spam` searches for notes having tag `office` or tag `spam`.<br>`tag:be*ful` does a search with wildcards.<br>`tag:*` returns all notes with tags.<br>`-tag:*` returns all notes without tags.|
| **notebook:** | Restrict the search to the specified notebook(s). |`notebook:books` limits the search scope within `books` and all its subnotebooks.<br>`notebook:wheel*time` does a wildcard search.|
| **created:** <br> **updated:** <br> **due:**| Searches for notes created/updated on dates specified using YYYYMMDD format. You can also search relative to the current day, week, month, or year. | `created:20201218` will return notes created on or after December 18, 2020.<br>`-updated:20201218` will return notes updated before December 18, 2020.<br>`created:20200118 -created:20201215` will return notes created between January 18, 2020, and before December 15, 2020.<br>`created:202001 -created:202003` will return notes created on or after January and before March 2020.<br>`updated:1997 -updated:2020` will return all notes updated between the years 1997 and 2019.<br>`created:day-2` searches for all notes created in the past two days.<br>`updated:year-0` searches all notes updated in the current year.<br>`-due:day+7` will return all todos which are due or will be due in the next seven days.<br>`-due:day-5` searches all todos that are overdue for more than 5 days.|
| **type:** |Restrict the search to either notes or todos. | `type:note` to return all notes<br>`type:todo` to return all todos |
| **iscompleted:** | Restrict the search to either completed or uncompleted todos. | `iscompleted:1` to return all completed todos<br>`iscompleted:0` to return all uncompleted todos|
|**latitude:** <br> **longitude:** <br> **altitude:**|Filter by location|`latitude:40 -latitude:50` to return notes with latitude >= 40 and < 50 |
|**resource:**|Filter by attachment MIME type|`resource:image/jpeg` to return notes with a jpeg attachment.<br>`-resource:application/pdf` to return notes without a pdf attachment.<br>`resource:image/*` to return notes with any images.|
|**sourceurl:**|Filter by source URL|`sourceurl:https://www.google.com`<br>`sourceurl:*joplinapp.org` to perform a wildcard search.|
|**id:**|Filter by note ID|`id:9cbc1b4f242043a9b8a50627508bccd5` return a note with the specified id |
Note: In the CLI client you have to escape the query using `--` when using negated filters.
Eg. `:search -- "-tag:tag1"`.
The filters are implicitly connected by and/or connectives depending on the following rules:
- By default, all filters are connected by "AND".
- To override this default behaviour, use the `any` filter, in which case the search terms will be connected by "OR" instead.
- There's an exception for the `notebook` filters which are connected by "OR". The reason being that no note can be in multiple notebooks at once.
Incorrect search filters are interpreted as a phrase search, e.g. misspelled `nootebook:Example` or non-existing `https://joplinapp.org`.
## Search order
Notes are sorted by "relevance". Currently it means the notes that contain the requested terms the most times are on top. For queries with multiple terms, it also matters how close to each other the terms are. This is a bit experimental so if you notice a search query that returns unexpected results, please report it in the forum, providing as many details as possible to replicate the issue.
# Goto Anything
In the desktop application, press <kbd>Ctrl+P</kbd> or <kbd>Cmd+P</kbd> and type a note title or part of its content to jump to it. Or type <kbd>#</kbd> followed by a tag name, or <kbd>@</kbd> followed by a notebook name.
# Multiple profile support
To create a new profile, open File > Switch profile and select Create new profile, enter the profile name and press OK. The app will automatically switch to this new profile, which you can now configure.
To switch back to the previous profile, again open File > Switch profile and select Default.
Note that profiles all share certain settings, such as language, font size, theme, etc. This is done so that you don't have reconfigure every details when switching profiles. Other settings such as sync configuration is per profile.
The feature is available on desktop only for now, and should be ported to mobile relatively soon.
# Donations
Donations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.
Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/readme/donate.md) for information on how to support the development of Joplin.
Please see the [donation page](https://github.com/laurent22/joplin/blob/dev/readme/about/donate.md) for information on how to support the development of Joplin.
# Community
@ -518,68 +60,6 @@ Name | Description
Please see the guide for information on how to contribute to the development of Joplin: https://github.com/laurent22/joplin/blob/dev/CONTRIBUTING.md
# Localisation
Joplin is currently available in the languages below. If you would like to contribute a **new translation**, it is quite straightforward, please follow these steps:
- [Download Poedit](https://poedit.net/), the translation editor, and install it.
- [Download the file to be translated](https://raw.githubusercontent.com/laurent22/joplin/dev/packages/tools/locales/joplin.pot).
- In Poedit, open this .pot file, go into the Catalog menu and click Configuration. Change "Country" and "Language" to your own country and language.
- From then you can translate the file.
- Once it is done, please [open a pull request](https://github.com/laurent22/joplin/pulls) and add the file to it.
This translation will apply to the three applications - desktop, mobile and terminal.
To **update a translation**, follow the same steps as above but instead of getting the .pot file, get the .po file for your language from the table below.
Current translations:
<!-- LOCALE-TABLE-AUTO-GENERATED -->
&nbsp; | Language | Po File | Last translator | Percent done
---|---|---|---|---
<img src="https://joplinapp.org/images/flags/country-4x3/arableague.png" width="16px"/> | Arabic | [ar](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ar.po) | [Whaell O](mailto:Whaell@protonmail.com) | 84%
<img src="https://joplinapp.org/images/flags/es/basque_country.png" width="16px"/> | Basque | [eu](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eu.po) | juan.abasolo@ehu.eus | 21%
<img src="https://joplinapp.org/images/flags/country-4x3/ba.png" width="16px"/> | Bosnian (Bosna i Hercegovina) | [bs_BA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bs_BA.po) | [Derviš T.](mailto:dervis.t@pm.me) | 54%
<img src="https://joplinapp.org/images/flags/country-4x3/bg.png" width="16px"/> | Bulgarian (България) | [bg_BG](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/bg_BG.po) | | 42%
<img src="https://joplinapp.org/images/flags/es/catalonia.png" width="16px"/> | Catalan | [ca](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ca.po) | [Xavi Ivars](mailto:xavi.ivars@gmail.com) | 92%
<img src="https://joplinapp.org/images/flags/country-4x3/hr.png" width="16px"/> | Croatian (Hrvatska) | [hr_HR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hr_HR.po) | [Milo Ivir](mailto:mail@milotype.de) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/cz.png" width="16px"/> | Czech (Česká republika) | [cs_CZ](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/cs_CZ.po) | Fejby | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/dk.png" width="16px"/> | Dansk (Danmark) | [da_DK](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/da_DK.po) | ERYpTION | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/de.png" width="16px"/> | Deutsch (Deutschland) | [de_DE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/de_DE.po) | [Mr-Kanister](mailto:viger_gtrc@simplelogin.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/ee.png" width="16px"/> | Eesti Keel (Eesti) | [et_EE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/et_EE.po) | | 42%
<img src="https://joplinapp.org/images/flags/country-4x3/gb.png" width="16px"/> | English (United Kingdom) | [en_GB](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_GB.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/us.png" width="16px"/> | English (United States of America) | [en_US](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/en_US.po) | | 100%
<img src="https://joplinapp.org/images/flags/country-4x3/es.png" width="16px"/> | Español (España) | [es_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/es_ES.po) | [Francisco Villaverde](mailto:teko.gr@gmail.com) | 93%
<img src="https://joplinapp.org/images/flags/esperanto.png" width="16px"/> | Esperanto | [eo](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/eo.po) | Marton Paulo | 24%
<img src="https://joplinapp.org/images/flags/country-4x3/fi.png" width="16px"/> | Finnish (Suomi) | [fi_FI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fi_FI.po) | mrkaato0 | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/fr.png" width="16px"/> | Français (France) | [fr_FR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fr_FR.po) | Laurent Cozic | 100%
<img src="https://joplinapp.org/images/flags/es/galicia.png" width="16px"/> | Galician (España) | [gl_ES](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/gl_ES.po) | [Marcos Lans](mailto:marcoslansgarza@gmail.com) | 27%
<img src="https://joplinapp.org/images/flags/country-4x3/id.png" width="16px"/> | Indonesian (Indonesia) | [id_ID](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/id_ID.po) | [Wisnu Adi Santoso](mailto:waditos@gmail.com) | 84%
<img src="https://joplinapp.org/images/flags/country-4x3/it.png" width="16px"/> | Italiano (Italia) | [it_IT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/it_IT.po) | [Manuel Tassi](mailto:mannivuwiki@gmail.com) | 76%
<img src="https://joplinapp.org/images/flags/country-4x3/hu.png" width="16px"/> | Magyar (Magyarország) | [hu_HU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/hu_HU.po) | [Magyari Balázs](mailto:balmag@gmail.com) | 73%
<img src="https://joplinapp.org/images/flags/country-4x3/be.png" width="16px"/> | Nederlands (België, Belgique, Belgien) | [nl_BE](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_BE.po) | | 74%
<img src="https://joplinapp.org/images/flags/country-4x3/nl.png" width="16px"/> | Nederlands (Nederland) | [nl_NL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nl_NL.po) | [MHolkamp](mailto:mholkamp@users.noreply.github.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/no.png" width="16px"/> | Norwegian (Norge, Noreg) | [nb_NO](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/nb_NO.po) | [Mats Estensen](mailto:code@mxe.no) | 83%
<img src="https://joplinapp.org/images/flags/country-4x3/ir.png" width="16px"/> | Persian | [fa](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/fa.po) | [Kourosh Firoozbakht](mailto:kourox@protonmail.com) | 52%
<img src="https://joplinapp.org/images/flags/country-4x3/pl.png" width="16px"/> | Polski (Polska) | [pl_PL](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pl_PL.po) | [X3NO](mailto:X3NO@disroot.org) | 85%
<img src="https://joplinapp.org/images/flags/country-4x3/br.png" width="16px"/> | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_BR.po) | [Fernando Nagase](mailto:nagase.fernando@gmail.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/pt.png" width="16px"/> | Português (Portugal) | [pt_PT](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/pt_PT.po) | [Diogo Caveiro](mailto:dcaveiro@yahoo.com) | 68%
<img src="https://joplinapp.org/images/flags/country-4x3/ro.png" width="16px"/> | Română | [ro](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ro.po) | [Cristi Duluta](mailto:cristi.duluta@gmail.com) | 48%
<img src="https://joplinapp.org/images/flags/country-4x3/si.png" width="16px"/> | Slovenian (Slovenija) | [sl_SI](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sl_SI.po) | [Martin Korelič](mailto:martin.korelic@protonmail.com) | 76%
<img src="https://joplinapp.org/images/flags/country-4x3/se.png" width="16px"/> | Svenska | [sv](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sv.po) | [Jonatan Nyberg](mailto:jonatan@autistici.org) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/th.png" width="16px"/> | Thai (ประเทศไทย) | [th_TH](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/th_TH.po) | | 34%
<img src="https://joplinapp.org/images/flags/country-4x3/vn.png" width="16px"/> | Tiếng Việt | [vi](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/vi.po) | | 73%
<img src="https://joplinapp.org/images/flags/country-4x3/tr.png" width="16px"/> | Türkçe (Türkiye) | [tr_TR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/tr_TR.po) | [Arda Kılıçdağı](mailto:arda@kilicdagi.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/ua.png" width="16px"/> | Ukrainian (Україна) | [uk_UA](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/uk_UA.po) | [Vyacheslav Andreykiv](mailto:vandreykiv@gmail.com) | 95%
<img src="https://joplinapp.org/images/flags/country-4x3/gr.png" width="16px"/> | Ελληνικά (Ελλάδα) | [el_GR](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/el_GR.po) | [Harris Arvanitis](mailto:xaris@tuta.io) | 94%
<img src="https://joplinapp.org/images/flags/country-4x3/ru.png" width="16px"/> | Русский (Россия) | [ru_RU](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ru_RU.po) | [Титан](mailto:fignin@ya.ru) | 96%
<img src="https://joplinapp.org/images/flags/country-4x3/rs.png" width="16px"/> | српски језик (Србија) | [sr_RS](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/sr_RS.po) | | 61%
<img src="https://joplinapp.org/images/flags/country-4x3/cn.png" width="16px"/> | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_CN.po) | [qx100](mailto:ztymaxwell@gmail.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/tw.png" width="16px"/> | 中文 (繁體) | [zh_TW](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/zh_TW.po) | [Kevin Hsu](mailto:kevin.hsu.hws@gmail.com) | 84%
<img src="https://joplinapp.org/images/flags/country-4x3/jp.png" width="16px"/> | 日本語 (日本) | [ja_JP](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ja_JP.po) | [genneko](mailto:genneko217@gmail.com) | 97%
<img src="https://joplinapp.org/images/flags/country-4x3/kr.png" width="16px"/> | 한국어 | [ko](https://github.com/laurent22/joplin/blob/dev/packages/tools/locales/ko.po) | [Ji-Hyeon Gim](mailto:potatogim@potatogim.net) | 84%
<!-- LOCALE-TABLE-AUTO-GENERATED -->
# Contributors
Thank you to everyone who've contributed to Joplin's source code!

View File

@ -1,9 +1 @@
<strong>Joplin</strong> is a note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in <a href="#markdown">Markdown format</a>.
Notes exported from Evernote and other applications <a href="https://joplinapp.org/help/#importing">can be imported</a> into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
The notes can be securely <a href="https://joplinapp.org/help/#synchronisation">synchronised</a> using <a href="https://joplinapp.org/help/#encryption">end-to-end encryption</a> with various cloud services including Nextcloud, Dropbox, OneDrive and <a href="https://joplinapp.org/plans/">Joplin Cloud</a>.
Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.
The application is available for Windows, Linux, macOS, Android and iOS. A <a href="https://joplinapp.org/clipper/">Web Clipper</a>, to save web pages and screenshots from your browser, is also available for <a href="https://addons.mozilla.org/firefox/addon/joplin-web-clipper/">Firefox</a> and <a href="https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB">Chrome</a>.
<strong>Joplin</strong> is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in <a href="https://joplinapp.org/help/apps/markdown">Markdown format</a>.</p><p>Notes exported from Evernote <a href="https://joplinapp.org/help/apps/import_export">can be imported</a> into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.</p><p>Joplin is "offline first", which means you always have all your data on your phone or computer. This ensures that your notes are always accessible, whether you have an internet connection or not.</p><p>The notes can be securely <a href="https://joplinapp.org/help/apps/sync">synchronised</a> using <a href="https://joplinapp.org/help/apps/sync/e2ee">end-to-end encryption</a> with various cloud services including Nextcloud, Dropbox, OneDrive and <a href="https://joplinapp.org/plans/" target="_blank" rel="noopener noreferrer">Joplin Cloud</a>.</p><p>Full text search is available on all platforms to quickly find the information you need. The app can be customised using plugins and themes, and you can also easily create your own.</p><p>The application is available for Windows, Linux, macOS, Android and iOS. A <a href="https://joplinapp.org/help/apps/clipper">Web Clipper</a>, to save web pages and screenshots from your browser, is also available for <a href="https://addons.mozilla.org/firefox/addon/joplin-web-clipper/" target="_blank" rel="noopener noreferrer">Firefox</a> and <a href="https://chrome.google.com/webstore/detail/joplin-web-clipper/alofnhikmmkdbbbgpnglcpdollgjjfek?hl=en-GB" target="_blank" rel="noopener noreferrer">Chrome</a>.</p><div class="top-screenshot"><img loading="lazy" src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/home-top-img.png" class="img_node_modules-@docusaurus-theme-classic-lib-theme-MDXComponents-Img-styles-module" style="max-width: 100%; max-height: 35em;">

View File

@ -23,7 +23,7 @@
"buildSettingJsonSchema": "yarn workspace joplin start settingschema ../../../joplin-website/docs/schema/settings.json",
"buildTranslations": "node packages/tools/build-translation.js",
"buildWebsiteTranslations": "node packages/tools/website/buildTranslations.js",
"buildWebsite": "node ./packages/tools/website/build.js && yarn run buildPluginDoc && yarn run buildSettingJsonSchema",
"buildWebsite": "node ./packages/tools/website/processDocs.js --env prod && node ./packages/tools/website/build.js && yarn run buildPluginDoc && yarn run buildSettingJsonSchema",
"checkLibPaths": "node ./packages/tools/checkLibPaths.js",
"checkIgnoredFiles": "node ./packages/tools/checkIgnoredFiles.js",
"circularDependencyCheck": "madge --warning --circular --extensions js ./",
@ -58,7 +58,7 @@
"updateIgnored": "node packages/tools/gulp/tasks/updateIgnoredTypeScriptBuildRun.js",
"updatePluginTypes": "./packages/generator-joplin/updateTypes.sh",
"watch": "yarn workspaces foreach --parallel --verbose --interlaced --jobs 999 run watch",
"watchWebsite": "nodemon --verbose --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
"watchWebsite": "nodemon --delay 1 --watch Assets/WebsiteAssets --watch packages/tools/website --watch packages/tools/website/utils --watch packages/doc-builder/build --ext md,ts,js,mustache,css,tsx,gif,png,svg --exec \"node packages/tools/website/build.js && http-server --port 8077 ../joplin-website/docs -a localhost\""
},
"husky": {
"hooks": {

View File

@ -75,7 +75,7 @@ class Command extends BaseCommand {
lines.push('```');
lines.push('');
lines.push('# Authorisation');
lines.push('## Authorisation');
lines.push('');
lines.push('To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');
lines.push('');
@ -85,10 +85,10 @@ class Command extends BaseCommand {
lines.push('');
lines.push('In the documentation below, the token will not be specified every time however you will need to include it.');
lines.push('');
lines.push('If needed you may also [request the token programmatically](https://github.com/laurent22/joplin/blob/dev/readme/spec/clipper_auth.md)');
lines.push('If needed you may also [request the token programmatically](https://github.com/laurent22/joplin/blob/dev/readme/dev/spec/clipper_auth.md)');
lines.push('');
lines.push('# Using the API');
lines.push('## Using the API');
lines.push('');
lines.push('All the calls, unless noted otherwise, receives and send **JSON data**. For example to create a new note:');
lines.push('');
@ -108,7 +108,7 @@ class Command extends BaseCommand {
lines.push('* **DELETE**: To delete items.');
lines.push('');
lines.push('# Filtering data');
lines.push('## Filtering data');
lines.push('');
lines.push('You can change the fields that will be returned by the API using the `fields=` query parameter, which takes a list of comma separated fields. For example, to get the longitude and latitude of a note, use this:');
lines.push('');
@ -121,7 +121,7 @@ class Command extends BaseCommand {
lines.push('By default API results will contain the following fields: **id**, **parent_id**, **title**');
lines.push('');
lines.push('# Pagination');
lines.push('## Pagination');
lines.push('');
lines.push('All API calls that return multiple results will be paginated and will return the following structure:');
lines.push('');
@ -164,24 +164,24 @@ async function fetchAllNotes() {
lines.push('```');
lines.push('');
lines.push('# Error handling');
lines.push('## Error handling');
lines.push('');
lines.push('In case of an error, an HTTP status code >= 400 will be returned along with a JSON object that provides more info about the error. The JSON object is in the format `{ "error": "description of error" }`.');
lines.push('');
lines.push('# About the property types');
lines.push('## About the property types');
lines.push('');
lines.push('* Text is UTF-8.');
lines.push('* All date/time are Unix timestamps in milliseconds.');
lines.push('* Booleans are integer values 0 or 1.');
lines.push('');
lines.push('# Testing if the service is available');
lines.push('## Testing if the service is available');
lines.push('');
lines.push('Call **GET /ping** to check if the service is available. It should return "JoplinClipperServer" if it works.');
lines.push('');
lines.push('# Searching');
lines.push('## Searching');
lines.push('');
lines.push('Call **GET /search?query=YOUR_QUERY** to search for notes. This end-point supports the `field` parameter which is recommended to use so that you only get the data that you need. The query syntax is as described in the main documentation: https://joplinapp.org/help/#searching');
lines.push('');
@ -192,7 +192,7 @@ async function fetchAllNotes() {
lines.push('To retrieve all the tags that start with `project-`: **GET /search?query=project-*&type=tag**');
lines.push('');
lines.push('# Item type IDs');
lines.push('## Item type IDs');
lines.push('');
lines.push('Item type IDs might be refered to in certain object you will retrieve from the API. This is the correspondance between name and ID:');
lines.push('');
@ -240,7 +240,7 @@ async function fetchAllNotes() {
// });
}
lines.push(`# ${toTitleCase(tableName)}`);
lines.push(`## ${toTitleCase(tableName)}`);
lines.push('');
if (model.type === BaseModel.TYPE_FOLDER) {
@ -248,12 +248,12 @@ async function fetchAllNotes() {
lines.push('');
}
lines.push('## Properties');
lines.push('### Properties');
lines.push('');
lines.push(this.createPropertiesTable(tableFields));
lines.push('');
lines.push(`## GET /${tableName}`);
lines.push(`### GET /${tableName}`);
lines.push('');
lines.push(`Gets all ${tableName}`);
lines.push('');
@ -263,50 +263,50 @@ async function fetchAllNotes() {
lines.push('');
}
lines.push(`## GET /${tableName}/:id`);
lines.push(`### GET /${tableName}/:id`);
lines.push('');
lines.push(`Gets ${singular} with ID :id`);
lines.push('');
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## GET /tags/:id/notes');
lines.push('### GET /tags/:id/notes');
lines.push('');
lines.push('Gets all the notes with this tag.');
lines.push('');
}
if (model.type === BaseModel.TYPE_NOTE) {
lines.push('## GET /notes/:id/tags');
lines.push('### GET /notes/:id/tags');
lines.push('');
lines.push('Gets all the tags attached to this note.');
lines.push('');
lines.push('## GET /notes/:id/resources');
lines.push('### GET /notes/:id/resources');
lines.push('');
lines.push('Gets all the resources attached to this note.');
lines.push('');
}
if (model.type === BaseModel.TYPE_FOLDER) {
lines.push('## GET /folders/:id/notes');
lines.push('### GET /folders/:id/notes');
lines.push('');
lines.push('Gets all the notes inside this folder.');
lines.push('');
}
if (model.type === BaseModel.TYPE_RESOURCE) {
lines.push('## GET /resources/:id/file');
lines.push('### GET /resources/:id/file');
lines.push('');
lines.push('Gets the actual file associated with this resource.');
lines.push('');
lines.push('## GET /resources/:id/notes');
lines.push('### GET /resources/:id/notes');
lines.push('');
lines.push('Gets the notes (IDs) associated with a resource.');
lines.push('');
}
lines.push(`## POST /${tableName}`);
lines.push(`### POST /${tableName}`);
lines.push('');
lines.push(`Creates a new ${singular}`);
lines.push('');
@ -343,7 +343,7 @@ async function fetchAllNotes() {
}
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## POST /tags/:id/notes');
lines.push('### POST /tags/:id/notes');
lines.push('');
lines.push('Post a note to this endpoint to add the tag to the note. The note data must at least contain an ID property (all other properties will be ignored).');
lines.push('');
@ -366,7 +366,7 @@ async function fetchAllNotes() {
lines.push('');
lines.push(' curl --data \'{ "title": "Image test", "body": "Here is Joplin icon:", "image_data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="}\' http://127.0.0.1:41184/notes');
lines.push('');
lines.push('### Creating a note with a specific ID');
lines.push('#### Creating a note with a specific ID');
lines.push('');
lines.push('When a new note is created, it is automatically assigned a new unique ID so **normally you do not need to set the ID**. However, if for some reason you want to set it, you can supply it as the `id` property. It needs to be a **32 characters long string** in hexadecimal. **Make sure it is unique**, for example by generating it using whatever GUID function is available in your programming language.');
lines.push('');
@ -374,7 +374,7 @@ async function fetchAllNotes() {
lines.push('');
}
lines.push(`## PUT /${tableName}/:id`);
lines.push(`### PUT /${tableName}/:id`);
lines.push('');
lines.push(`Sets the properties of the ${singular} with ID :id`);
lines.push('');
@ -384,13 +384,13 @@ async function fetchAllNotes() {
lines.push('');
}
lines.push(`## DELETE /${tableName}/:id`);
lines.push(`### DELETE /${tableName}/:id`);
lines.push('');
lines.push(`Deletes the ${singular} with ID :id`);
lines.push('');
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## DELETE /tags/:id/notes/:note_id');
lines.push('### DELETE /tags/:id/notes/:note_id');
lines.push('');
lines.push('Remove the tag from the note.');
lines.push('');
@ -400,15 +400,15 @@ async function fetchAllNotes() {
{
const tableFields = reg.db().tableFields('item_changes', { includeDescription: true });
lines.push('# Events');
lines.push('## Events');
lines.push('');
lines.push('This end point can be used to retrieve the latest note changes. Currently only note changes are tracked.');
lines.push('');
lines.push('## Properties');
lines.push('### Properties');
lines.push('');
lines.push(this.createPropertiesTable(tableFields));
lines.push('');
lines.push('## GET /events');
lines.push('### GET /events');
lines.push('');
lines.push('Returns a paginated list of recent events. A `cursor` property should be provided, which tells from what point in time the events should be returned. The API will return a `cursor` property, to tell from where to resume retrieving events, as well as an `has_more` (tells if more changes can be retrieved) and `items` property, which will contain the list of events. Events are kept for up to 90 days.');
lines.push('');
@ -416,7 +416,7 @@ async function fetchAllNotes() {
lines.push('');
lines.push('The results are paginated so you may need multiple calls to retrieve all the events. Use the `has_more` property to know if more can be retrieved.');
lines.push('');
lines.push('## GET /events/:id');
lines.push('### GET /events/:id');
lines.push('');
lines.push('Returns the event with the given ID.');
}

View File

@ -33,7 +33,7 @@ class Command extends BaseCommand {
const stdoutWidth = app().commandStdoutMaxWidth();
if (args.command === 'shortcuts' || args.command === 'keymap') {
this.stdout(_('For information on how to customise the shortcuts please visit %s', 'https://joplinapp.org/terminal/#shortcuts'));
this.stdout(_('For information on how to customise the shortcuts please visit %s', 'https://joplinapp.org/help/apps/terminal#shortcuts'));
this.stdout('');
if (

View File

@ -4,7 +4,7 @@ This is the official Joplin Plugin Repository
## Installation
To install any of these plugins, open the desktop application, then go to the "Plugins" section in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/config_screen.md). You can then search for any plugin and install it from there.
To install any of these plugins, open the desktop application, then go to the "Plugins" section in the [Configuration screen](https://github.com/laurent22/joplin/blob/dev/readme/apps/config_screen.md). You can then search for any plugin and install it from there.
## Plugins

View File

@ -132,7 +132,7 @@ class AppComponent extends Component {
};
this.clipperServerHelpLink_click = () => {
bridge().tabsCreate({ url: 'https://joplinapp.org/clipper/' });
bridge().tabsCreate({ url: 'https://joplinapp.org/help/apps/clipper' });
};
this.folderSelect_change = (event) => {

View File

@ -113,7 +113,7 @@ export default async function checkForUpdates(inBackground: boolean, parentWindo
} else if (buttonIndex === 1) {
await addSkippedVersion(release.version);
} else if (buttonIndex === 2) {
void bridge().openExternal('https://joplinapp.org/changelog/');
void bridge().openExternal('https://joplinapp.org/help/about/changelog/desktop');
}
}
}

View File

@ -10,7 +10,7 @@ interface Props {
}
const openMissingPasswordFAQ = () =>
bridge().openExternal('https://joplinapp.org/faq#why-did-my-sync-and-encryption-passwords-disappear-after-updating-joplin');
bridge().openExternal('https://joplinapp.org/help/faq#why-did-my-sync-and-encryption-passwords-disappear-after-updating-joplin');
// A link to a specific part of the FAQ related to passwords being cleared when upgrading
// to a MacOS/ARM release.

View File

@ -473,7 +473,7 @@ function NoteEditor(props: NoteEditorProps) {
}
const onRichTextReadMoreLinkClick = useCallback(() => {
bridge().openExternal('https://joplinapp.org/rich_text_editor');
bridge().openExternal('https://joplinapp.org/help/apps/rich_text_editor');
}, []);
const onRichTextDismissLinkClick = useCallback(() => {

View File

@ -291,10 +291,10 @@ const EncryptionConfigScreen = (props: Props) => {
<Text>{_('For more information about End-To-End Encryption (E2EE) and advice on how to enable it please check the documentation:')}</Text>
<TouchableOpacity
onPress={() => {
Linking.openURL('https://joplinapp.org/e2ee/');
Linking.openURL('https://joplinapp.org/help/apps/sync/e2ee');
}}
>
<Text>https://joplinapp.org/e2ee/</Text>
<Text>https://joplinapp.org/help/apps/sync/e2ee</Text>
</TouchableOpacity>
</View>
}

30
packages/doc-builder/.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Docs are auto-generated using processDoc.js
/docs
/help
/blog
/news
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Static files
/static/images
/static/*.png

View File

@ -0,0 +1,41 @@
# Website
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View File

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View File

@ -0,0 +1,174 @@
// @ts-check
// Note: type annotations allow type checking and IDEs autocompletion
const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');
// To make their weird linter happy
process.env.WEBSITE_BASE_URL = process.env.WEBSITE_BASE_URL || '';
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Joplin',
tagline: 'Free your notes!',
favicon: 'img/favicon.ico',
// Set the production url of your site here
url: process.env.WEBSITE_BASE_URL,
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
// Even if you don't use internalization, you can use this field to set useful
// metadata like html lang. For example, if your site is Chinese, you may want
// to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
plugins: [
[
require.resolve('docusaurus-lunr-search'),
{
// Options here
},
],
],
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
path: 'help',
routeBasePath: 'help',
sidebarPath: require.resolve('./sidebars.js'),
breadcrumbs: false,
editUrl: (params) => {
return 'https://github.com/laurent22/joplin/tree/dev/readme/' + params.docPath;
},
},
blog: {
showReadingTime: true,
blogSidebarCount: 'ALL',
path: 'news',
routeBasePath: 'news',
editUrl: (params) => {
return 'https://github.com/laurent22/joplin/tree/dev/readme/news/' + params.blogPath;
},
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
sitemap: {
changefreq: 'weekly',
priority: 0.5,
filename: 'sitemap.xml',
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
navbar: {
title: '',
logo: {
alt: 'Joplin',
src: 'images/logo-text-blue.svg',
href: process.env.WEBSITE_BASE_URL,
target: '_self',
},
items: [
{
to: '/news',
label: 'News',
position: 'right',
},
{
type: 'docSidebar',
sidebarId: 'helpSidebar',
position: 'right',
label: 'Help',
},
{
to: 'https://discourse.joplinapp.org',
label: 'Forum',
position: 'right',
},
{
to: process.env.WEBSITE_BASE_URL + '/plans',
label: 'Joplin Cloud',
position: 'right',
className: 'navbar-custom-buttons plans-button',
},
{
to: process.env.WEBSITE_BASE_URL + '/donate',
label: '♡ Support us',
position: 'right',
className: 'navbar-custom-buttons sponsor-button',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Community',
items: [
{
label: 'Twitter',
href: 'https://twitter.com/joplinapp',
},
{
label: 'Patreon',
href: 'https://www.patreon.com/joplin',
},
{
label: 'LinkedIn',
href: 'https://www.linkedin.com/company/joplin',
},
{
label: 'Discord',
href: 'https://discord.gg/VSj7AFHvpq',
},
{
label: 'Mastodon',
href: 'https://mastodon.social/@joplinapp',
},
{
label: 'Lemmy',
href: 'https://sopuli.xyz/c/joplinapp',
},
{
label: 'GitHub',
href: 'https://github.com/laurent22/joplin/',
},
],
},
{
title: 'Legal',
items: [
{
label: 'Privacy Policy',
to: process.env.WEBSITE_BASE_URL + '/privacy',
},
],
},
],
copyright: `Copyright © 2016-${new Date().getFullYear()} Laurent Cozic`,
},
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
},
}),
};
module.exports = config;

View File

@ -0,0 +1,51 @@
{
"name": "@joplin/doc-builder",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "WEBSITE_BASE_URL=http://localhost:8077 BROWSERSLIST_IGNORE_OLD_DATA=true docusaurus start --no-minify",
"_build": "BROWSERSLIST_IGNORE_OLD_DATA=true docusaurus build",
"buildDev": "NODE_ENV=development BROWSERSLIST_IGNORE_OLD_DATA=true docusaurus build --no-minify",
"build": "",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "WEBSITE_BASE_URL=http://localhost:8077 docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "2.4.3",
"@docusaurus/preset-classic": "2.4.3",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.4.3",
"@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-brands-svg-icons": "6.4.2",
"@fortawesome/free-regular-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/react-fontawesome": "0.2.0",
"docusaurus-lunr-search": "3.2.0"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"engines": {
"node": ">=16.14"
}
}

View File

@ -0,0 +1,33 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
// @ts-check
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
helpSidebar: [{type: 'autogenerated', dirName: '.'}],
// But you can create a sidebar manually
/*
tutorialSidebar: [
'intro',
'hello',
{
type: 'category',
label: 'Tutorial',
items: ['tutorial-basics/create-a-document'],
},
],
*/
};
module.exports = sidebars;

View File

@ -0,0 +1,64 @@
import React from 'react';
import clsx from 'clsx';
import styles from './styles.module.css';
const FeatureList = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and
used to get your website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go
ahead and move your docs into the <code>docs</code> directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can
be extended while reusing the same header and footer.
</>
),
},
];
function Feature({Svg, title, description}) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<h3>{title}</h3>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}

View File

@ -0,0 +1,73 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #0557ba;
--ifm-color-primary-dark: #003a81;
--ifm-color-primary-darker: #003a81;
--ifm-color-primary-darkest: #002450;
--ifm-color-primary-light: #4f9cf9;
--ifm-color-primary-lighter: #71adf7;
--ifm-color-primary-lightest: #a0c9fc;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #1e74dd;
--ifm-color-primary-dark: #1e74dd;
--ifm-color-primary-darker: #1e74dd;
--ifm-color-primary-darkest: #175aac;
--ifm-color-primary-light: #1e74dd;
--ifm-color-primary-lighter: #1e74dd;
--ifm-color-primary-lightest: #4b89d4;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
.menu__link {
font-weight: normal;
}
.menu__link--active {
font-weight: bold;
}
.navbar-custom-buttons {
margin-right: 15px;
}
.plans-button {
border: 1px solid var(--ifm-color-primary);
border-radius: 100px;
color: var(--ifm-color-primary);
}
.plans-button:hover {
border-color: var(--ifm-color-primary-lighter);
color: var(--ifm-color-primary-lighter);
}
.sponsor-button {
border-radius: 100px;
color: white;
background-color: var(--ifm-color-primary-light);
}
.sponsor-button:hover {
background-color: var(--ifm-color-primary-lighter);
color: white;
}
/* So that the code in markdown.md wraps. Otherwise the table takes too much space horizontally */
pre code {
white-space: pre-wrap;
}
.sidebarItemLinkActive_node_modules-\@docusaurus-theme-classic-lib-theme-BlogSidebar-Desktop-styles-module {
font-weight: bold;
}

View File

@ -0,0 +1,41 @@
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import styles from './index.module.css';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link
className="button button--secondary button--lg"
to="/">
Docusaurus Tutorial - 5min
</Link>
</div>
</div>
</header>
);
}
export default function Home() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />">
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
);
}

View File

@ -0,0 +1,23 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}

View File

@ -0,0 +1,7 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.

View File

@ -0,0 +1,15 @@
import React from 'react';
// Import the original mapper
import MDXComponents from '@theme-original/MDXComponents';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; // Import the FontAwesomeIcon component.
import { library } from '@fortawesome/fontawesome-svg-core'; // Import the library component.
import { fab } from '@fortawesome/free-brands-svg-icons'; // Import all brands icons.
import { fas } from '@fortawesome/free-solid-svg-icons'; // Import all solid icons.
library.add(fab, fas); // Add all icons to the library so you can use them without importing them individually.
export default {
// Re-use the default mapping
...MDXComponents,
icon: FontAwesomeIcon, // Make the FontAwesomeIcon component available in MDX as <icon />.
};

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -0,0 +1,171 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1088" height="687.962" viewBox="0 0 1088 687.962">
<title>Easy to Use</title>
<g id="Group_12" data-name="Group 12" transform="translate(-57 -56)">
<g id="Group_11" data-name="Group 11" transform="translate(57 56)">
<path id="Path_83" data-name="Path 83" d="M1017.81,560.461c-5.27,45.15-16.22,81.4-31.25,110.31-20,38.52-54.21,54.04-84.77,70.28a193.275,193.275,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.282,657.282,0,0,0-104.09-13.16q-14.97-.675-29.97-.67c-15.42.02-293.07,5.29-360.67-131.57-16.69-33.76-28.13-75-32.24-125.27-11.63-142.12,52.29-235.46,134.74-296.47,155.97-115.41,369.76-110.57,523.43,7.88C941.15,276.621,1036.99,396.031,1017.81,560.461Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_84" data-name="Path 84" d="M986.56,670.771c-20,38.52-47.21,64.04-77.77,80.28a193.272,193.272,0,0,1-27.46,11.94c-55.61,19.3-117.85,14.18-166.74,3.99a657.3,657.3,0,0,0-104.09-13.16q-14.97-.675-29.97-.67-23.13.03-46.25,1.72c-100.17,7.36-253.82-6.43-321.42-143.29L382,283.981,444.95,445.6l20.09,51.59,55.37-75.98L549,381.981l130.2,149.27,36.8-81.27L970.78,657.9l14.21,11.59Z" transform="translate(-56 -106.019)" fill="#f2f2f2"/>
<path id="Path_85" data-name="Path 85" d="M302,282.962l26-57,36,83-31-60Z" opacity="0.1"/>
<path id="Path_86" data-name="Path 86" d="M610.5,753.821q-14.97-.675-29.97-.67L465.04,497.191Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_87" data-name="Path 87" d="M464.411,315.191,493,292.962l130,150-132-128Z" opacity="0.1"/>
<path id="Path_88" data-name="Path 88" d="M908.79,751.051a193.265,193.265,0,0,1-27.46,11.94L679.2,531.251Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<circle id="Ellipse_11" data-name="Ellipse 11" cx="3" cy="3" r="3" transform="translate(479 98.962)" fill="#f2f2f2"/>
<circle id="Ellipse_12" data-name="Ellipse 12" cx="3" cy="3" r="3" transform="translate(396 201.962)" fill="#f2f2f2"/>
<circle id="Ellipse_13" data-name="Ellipse 13" cx="2" cy="2" r="2" transform="translate(600 220.962)" fill="#f2f2f2"/>
<circle id="Ellipse_14" data-name="Ellipse 14" cx="2" cy="2" r="2" transform="translate(180 265.962)" fill="#f2f2f2"/>
<circle id="Ellipse_15" data-name="Ellipse 15" cx="2" cy="2" r="2" transform="translate(612 96.962)" fill="#f2f2f2"/>
<circle id="Ellipse_16" data-name="Ellipse 16" cx="2" cy="2" r="2" transform="translate(736 192.962)" fill="#f2f2f2"/>
<circle id="Ellipse_17" data-name="Ellipse 17" cx="2" cy="2" r="2" transform="translate(858 344.962)" fill="#f2f2f2"/>
<path id="Path_89" data-name="Path 89" d="M306,121.222h-2.76v-2.76h-1.48v2.76H299V122.7h2.76v2.759h1.48V122.7H306Z" fill="#f2f2f2"/>
<path id="Path_90" data-name="Path 90" d="M848,424.222h-2.76v-2.76h-1.48v2.76H841V425.7h2.76v2.759h1.48V425.7H848Z" fill="#f2f2f2"/>
<path id="Path_91" data-name="Path 91" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_92" data-name="Path 92" d="M1144,719.981c0,16.569-243.557,74-544,74s-544-57.431-544-74,243.557,14,544,14S1144,703.413,1144,719.981Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<ellipse id="Ellipse_18" data-name="Ellipse 18" cx="544" cy="30" rx="544" ry="30" transform="translate(0 583.962)" fill="#3f3d56"/>
<path id="Path_93" data-name="Path 93" d="M624,677.981c0,33.137-14.775,24-33,24s-33,9.137-33-24,33-96,33-96S624,644.844,624,677.981Z" transform="translate(-56 -106.019)" fill="#ff6584"/>
<path id="Path_94" data-name="Path 94" d="M606,690.66c0,15.062-6.716,10.909-15,10.909s-15,4.153-15-10.909,15-43.636,15-43.636S606,675.6,606,690.66Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<rect id="Rectangle_97" data-name="Rectangle 97" width="92" height="18" rx="9" transform="translate(489 604.962)" fill="#2f2e41"/>
<rect id="Rectangle_98" data-name="Rectangle 98" width="92" height="18" rx="9" transform="translate(489 586.962)" fill="#2f2e41"/>
<path id="Path_95" data-name="Path 95" d="M193,596.547c0,55.343,34.719,100.126,77.626,100.126" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_96" data-name="Path 96" d="M270.626,696.673c0-55.965,38.745-101.251,86.626-101.251" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_97" data-name="Path 97" d="M221.125,601.564c0,52.57,22.14,95.109,49.5,95.109" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_98" data-name="Path 98" d="M270.626,696.673c0-71.511,44.783-129.377,100.126-129.377" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_99" data-name="Path 99" d="M254.3,697.379s11.009-.339,14.326-2.7,16.934-5.183,17.757-1.395,16.544,18.844,4.115,18.945-28.879-1.936-32.19-3.953S254.3,697.379,254.3,697.379Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_100" data-name="Path 100" d="M290.716,710.909c-12.429.1-28.879-1.936-32.19-3.953-2.522-1.536-3.527-7.048-3.863-9.591l-.368.014s.7,8.879,4.009,10.9,19.761,4.053,32.19,3.953c3.588-.029,4.827-1.305,4.759-3.2C294.755,710.174,293.386,710.887,290.716,710.909Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_101" data-name="Path 101" d="M777.429,633.081c0,38.029,23.857,68.8,53.341,68.8" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_102" data-name="Path 102" d="M830.769,701.882c0-38.456,26.623-69.575,59.525-69.575" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_103" data-name="Path 103" d="M796.755,636.528c0,36.124,15.213,65.354,34.014,65.354" transform="translate(-56 -106.019)" fill="#6c63ff"/>
<path id="Path_104" data-name="Path 104" d="M830.769,701.882c0-49.139,30.773-88.9,68.8-88.9" transform="translate(-56 -106.019)" fill="#3f3d56"/>
<path id="Path_105" data-name="Path 105" d="M819.548,702.367s7.565-.233,9.844-1.856,11.636-3.562,12.2-.958,11.368,12.949,2.828,13.018-19.844-1.33-22.119-2.716S819.548,702.367,819.548,702.367Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_106" data-name="Path 106" d="M844.574,711.664c-8.54.069-19.844-1.33-22.119-2.716-1.733-1.056-2.423-4.843-2.654-6.59l-.253.01s.479,6.1,2.755,7.487,13.579,2.785,22.119,2.716c2.465-.02,3.317-.9,3.27-2.2C847.349,711.159,846.409,711.649,844.574,711.664Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_107" data-name="Path 107" d="M949.813,724.718s11.36-1.729,14.5-4.591,16.89-7.488,18.217-3.667,19.494,17.447,6.633,19.107-30.153,1.609-33.835-.065S949.813,724.718,949.813,724.718Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_108" data-name="Path 108" d="M989.228,734.173c-12.86,1.659-30.153,1.609-33.835-.065-2.8-1.275-4.535-6.858-5.2-9.45l-.379.061s1.833,9.109,5.516,10.783,20.975,1.725,33.835.065c3.712-.479,4.836-1.956,4.529-3.906C993.319,732.907,991.991,733.817,989.228,734.173Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_109" data-name="Path 109" d="M670.26,723.9s9.587-1.459,12.237-3.875,14.255-6.32,15.374-3.095,16.452,14.725,5.6,16.125-25.448,1.358-28.555-.055S670.26,723.9,670.26,723.9Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_110" data-name="Path 110" d="M703.524,731.875c-10.853,1.4-25.448,1.358-28.555-.055-2.367-1.076-3.827-5.788-4.39-7.976l-.32.051s1.547,7.687,4.655,9.1,17.7,1.456,28.555.055c3.133-.4,4.081-1.651,3.822-3.3C706.977,730.807,705.856,731.575,703.524,731.875Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_111" data-name="Path 111" d="M178.389,719.109s7.463-1.136,9.527-3.016,11.1-4.92,11.969-2.409,12.808,11.463,4.358,12.553-19.811,1.057-22.23-.043S178.389,719.109,178.389,719.109Z" transform="translate(-56 -106.019)" fill="#a8a8a8"/>
<path id="Path_112" data-name="Path 112" d="M204.285,725.321c-8.449,1.09-19.811,1.057-22.23-.043-1.842-.838-2.979-4.506-3.417-6.209l-.249.04s1.2,5.984,3.624,7.085,13.781,1.133,22.23.043c2.439-.315,3.177-1.285,2.976-2.566C206.973,724.489,206.1,725.087,204.285,725.321Z" transform="translate(-56 -106.019)" opacity="0.2"/>
<path id="Path_113" data-name="Path 113" d="M439.7,707.337c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873,42.118-36.793,93.694-36.793S439.7,677.117,439.7,707.337Z" transform="translate(-56 -106.019)" opacity="0.1"/>
<path id="Path_114" data-name="Path 114" d="M439.7,699.9c0,30.22-42.124,20.873-93.7,20.873s-93.074,9.347-93.074-20.873S295.04,663.1,346.616,663.1,439.7,669.676,439.7,699.9Z" transform="translate(-56 -106.019)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(312.271 493.733)">
<path id="Path_40" data-name="Path 40" d="M99,52h91.791V89.153H99Z" transform="translate(5.904 -14.001)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M24.855,163.927A21.828,21.828,0,0,1,5.947,153a21.829,21.829,0,0,0,18.908,32.782H46.71V163.927Z" transform="translate(-3 -4.634)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M121.861,61.1l76.514-4.782V45.39A21.854,21.854,0,0,0,176.52,23.535H78.173L75.441,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L64.513,18.8a3.154,3.154,0,0,0-5.464,0l-2.732,4.732L53.586,18.8a3.154,3.154,0,0,0-5.464,0L45.39,23.535c-.024,0-.046,0-.071,0l-4.526-4.525a3.153,3.153,0,0,0-5.276,1.414l-1.5,5.577-5.674-1.521a3.154,3.154,0,0,0-3.863,3.864L26,34.023l-5.575,1.494a3.155,3.155,0,0,0-1.416,5.278l4.526,4.526c0,.023,0,.046,0,.07L18.8,48.122a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,59.05a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,69.977a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,80.9a3.154,3.154,0,0,0,0,5.464L23.535,89.1,18.8,91.832a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,102.76a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,113.687a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,124.615a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,135.542a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,146.469a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,157.4a3.154,3.154,0,0,0,0,5.464l4.732,2.732L18.8,168.324a3.154,3.154,0,0,0,0,5.464l4.732,2.732A21.854,21.854,0,0,0,45.39,198.375H176.52a21.854,21.854,0,0,0,21.855-21.855V89.1l-76.514-4.782a11.632,11.632,0,0,1,0-23.219" transform="translate(-1.681 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,186.71h32.782V143H143Z" transform="translate(9.984 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M196.71,159.855a5.438,5.438,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(10.912 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,124.855h32.782V103H153Z" transform="translate(10.912 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M194.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.814,2.814,0,0,0,.349.035" transform="translate(12.767 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M65.087,56.891a2.732,2.732,0,0,1-2.732-2.732,8.2,8.2,0,0,0-16.391,0,2.732,2.732,0,0,1-5.464,0,13.659,13.659,0,0,1,27.319,0,2.732,2.732,0,0,1-2.732,2.732" transform="translate(0.478 -15.068)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,191.347h65.565a21.854,21.854,0,0,0,21.855-21.855V93H124.855A21.854,21.854,0,0,0,103,114.855Z" transform="translate(6.275 -10.199)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M173.216,129.787H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0-54.434H118.535a1.093,1.093,0,1,1,0-2.185h54.681a1.093,1.093,0,0,1,0,2.185m0,21.652H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186m0,21.855H118.535a1.093,1.093,0,1,1,0-2.186h54.681a1.093,1.093,0,0,1,0,2.186M189.585,61.611c-.013,0-.024-.007-.037-.005-3.377.115-4.974,3.492-6.384,6.472-1.471,3.114-2.608,5.139-4.473,5.078-2.064-.074-3.244-2.406-4.494-4.874-1.436-2.835-3.075-6.049-6.516-5.929-3.329.114-4.932,3.053-6.346,5.646-1.5,2.762-2.529,4.442-4.5,4.364-2.106-.076-3.225-1.972-4.52-4.167-1.444-2.443-3.112-5.191-6.487-5.1-3.272.113-4.879,2.606-6.3,4.808-1.5,2.328-2.552,3.746-4.551,3.662-2.156-.076-3.27-1.65-4.558-3.472-1.447-2.047-3.077-4.363-6.442-4.251-3.2.109-4.807,2.153-6.224,3.954-1.346,1.709-2.4,3.062-4.621,2.977a1.093,1.093,0,0,0-.079,2.186c3.3.11,4.967-1.967,6.417-3.81,1.286-1.635,2.4-3.045,4.582-3.12,2.1-.09,3.091,1.218,4.584,3.327,1.417,2,3.026,4.277,6.263,4.394,3.391.114,5.022-2.42,6.467-4.663,1.292-2,2.406-3.734,4.535-3.807,1.959-.073,3.026,1.475,4.529,4.022,1.417,2.4,3.023,5.121,6.324,5.241,3.415.118,5.064-2.863,6.5-5.5,1.245-2.282,2.419-4.437,4.5-4.509,1.959-.046,2.981,1.743,4.492,4.732,1.412,2.79,3.013,5.95,6.365,6.071l.185,0c3.348,0,4.937-3.36,6.343-6.331,1.245-2.634,2.423-5.114,4.444-5.216Z" transform="translate(7.109 -13.11)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,186.71h43.71V143H83Z" transform="translate(4.42 -5.561)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 109.327, 91.085)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="92.361" height="36.462" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(1.531 23.03)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="5.336" height="5.336" rx="1" transform="translate(16.797 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="5.336" height="5.336" rx="1" transform="translate(23.12 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="5.336" height="5.336" rx="1" transform="translate(29.444 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="5.336" height="5.336" rx="1" transform="translate(35.768 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="5.336" height="5.336" rx="1" transform="translate(42.091 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="5.336" height="5.336" rx="1" transform="translate(48.415 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="5.336" height="5.336" rx="1" transform="translate(54.739 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="5.336" height="5.336" rx="1" transform="translate(61.063 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="5.336" height="5.336" rx="1" transform="translate(67.386 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M1.093,0H14.518a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0ZM75,0H88.426a1.093,1.093,0,0,1,1.093,1.093V4.243a1.093,1.093,0,0,1-1.093,1.093H75a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,75,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(1.531 10.261)">
<path id="Path_52" data-name="Path 52" d="M1.093,0H6.218A1.093,1.093,0,0,1,7.31,1.093V4.242A1.093,1.093,0,0,1,6.218,5.335H1.093A1.093,1.093,0,0,1,0,4.242V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="5.336" height="5.336" rx="1" transform="translate(58.888 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="5.336" height="5.336" rx="1" transform="translate(65.212 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="5.336" height="5.336" rx="1" transform="translate(71.536 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="5.336" height="5.336" rx="1" transform="translate(77.859 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(91.05 9.546) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M1.093,0H6.219A1.093,1.093,0,0,1,7.312,1.093v3.15A1.093,1.093,0,0,1,6.219,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.093A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="5.336" height="5.336" rx="1" transform="translate(8.299 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="5.336" height="5.336" rx="1" transform="translate(14.623 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="5.336" height="5.336" rx="1" transform="translate(20.947 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="5.336" height="5.336" rx="1" transform="translate(27.271 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="5.336" height="5.336" rx="1" transform="translate(33.594 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="5.336" height="5.336" rx="1" transform="translate(39.918 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="5.336" height="5.336" rx="1" transform="translate(46.242 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="5.336" height="5.336" rx="1" transform="translate(52.565 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="5.336" height="5.336" rx="1" transform="translate(58.889 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="5.336" height="5.336" rx="1" transform="translate(65.213 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="5.336" height="5.336" rx="1" transform="translate(71.537 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="5.336" height="5.336" rx="1" transform="translate(77.86 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(1.531 16.584)">
<path id="Path_54" data-name="Path 54" d="M1.093,0h7.3A1.093,1.093,0,0,1,9.485,1.093v3.15A1.093,1.093,0,0,1,8.392,5.336h-7.3A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(10.671 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="5.336" height="5.336" rx="1" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="5.336" height="5.336" rx="1" transform="translate(25.295 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="5.336" height="5.336" rx="1" transform="translate(31.619 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="5.336" height="5.336" rx="1" transform="translate(37.942 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="5.336" height="5.336" rx="1" transform="translate(44.265 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="5.336" height="5.336" rx="1" transform="translate(50.589 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="5.336" height="5.336" rx="1" transform="translate(56.912 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="5.336" height="5.336" rx="1" transform="translate(63.236 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M1.094,0H8A1.093,1.093,0,0,1,9.091,1.093v3.15A1.093,1.093,0,0,1,8,5.336H1.093A1.093,1.093,0,0,1,0,4.243V1.094A1.093,1.093,0,0,1,1.093,0Z" transform="translate(80.428 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(1.531 29.627)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="5.336" height="5.336" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="5.336" height="5.336" rx="1" transform="translate(6.324 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="5.336" height="5.336" rx="1" transform="translate(12.647 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="5.336" height="5.336" rx="1" transform="translate(18.971 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M1.093,0H31.515a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H1.093A1.093,1.093,0,0,1,0,4.244V1.093A1.093,1.093,0,0,1,1.093,0ZM34.687,0h3.942a1.093,1.093,0,0,1,1.093,1.093V4.244a1.093,1.093,0,0,1-1.093,1.093H34.687a1.093,1.093,0,0,1-1.093-1.093V1.093A1.093,1.093,0,0,1,34.687,0Z" transform="translate(25.294 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="5.336" height="5.336" rx="1" transform="translate(66.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="5.336" height="5.336" rx="1" transform="translate(72.327 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="5.336" height="5.336" rx="1" transform="translate(84.183 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(83.59 2.273) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M5.336,0V1.18A1.093,1.093,0,0,1,4.243,2.273H1.093A1.093,1.093,0,0,1,0,1.18V0Z" transform="translate(78.255 3.063)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="88.927" height="2.371" rx="1.085" transform="translate(1.925 1.17)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="4.986" height="1.581" rx="0.723" transform="translate(4.1 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="4.986" height="1.581" rx="0.723" transform="translate(10.923 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="4.986" height="1.581" rx="0.723" transform="translate(16.173 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="4.986" height="1.581" rx="0.723" transform="translate(21.421 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="4.986" height="1.581" rx="0.723" transform="translate(26.671 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="4.986" height="1.581" rx="0.723" transform="translate(33.232 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="4.986" height="1.581" rx="0.723" transform="translate(38.48 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="4.986" height="1.581" rx="0.723" transform="translate(43.73 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="4.986" height="1.581" rx="0.723" transform="translate(48.978 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="4.986" height="1.581" rx="0.723" transform="translate(55.54 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="4.986" height="1.581" rx="0.723" transform="translate(60.788 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="4.986" height="1.581" rx="0.723" transform="translate(66.038 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="4.986" height="1.581" rx="0.723" transform="translate(72.599 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="4.986" height="1.581" rx="0.723" transform="translate(77.847 1.566)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="4.986" height="1.581" rx="0.723" transform="translate(83.097 1.566)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M146.71,159.855a5.439,5.439,0,0,0-.7.07c-.042-.164-.081-.329-.127-.493a5.457,5.457,0,1,0-5.4-9.372q-.181-.185-.366-.367a5.454,5.454,0,1,0-9.384-5.4c-.162-.046-.325-.084-.486-.126a5.467,5.467,0,1,0-10.788,0c-.162.042-.325.08-.486.126a5.457,5.457,0,1,0-9.384,5.4,21.843,21.843,0,1,0,36.421,21.02,5.452,5.452,0,1,0,.7-10.858" transform="translate(6.275 -6.025)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,124.855h43.71V103H83Z" transform="translate(4.42 -9.271)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M134.855,116.765a2.732,2.732,0,1,0,0-5.464,2.811,2.811,0,0,0-.349.035c-.022-.082-.04-.164-.063-.246a2.733,2.733,0,0,0-1.052-5.253,2.7,2.7,0,0,0-1.648.566q-.09-.093-.184-.184a2.7,2.7,0,0,0,.553-1.633,2.732,2.732,0,0,0-5.245-1.07,10.928,10.928,0,1,0,0,21.031,2.732,2.732,0,0,0,5.245-1.07,2.7,2.7,0,0,0-.553-1.633q.093-.09.184-.184a2.7,2.7,0,0,0,1.648.566,2.732,2.732,0,0,0,1.052-5.253c.023-.081.042-.164.063-.246a2.811,2.811,0,0,0,.349.035" transform="translate(7.202 -9.377)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M143.232,42.33a2.967,2.967,0,0,1-.535-.055,2.754,2.754,0,0,1-.514-.153,2.838,2.838,0,0,1-.471-.251,4.139,4.139,0,0,1-.415-.339,3.2,3.2,0,0,1-.338-.415A2.7,2.7,0,0,1,140.5,39.6a2.968,2.968,0,0,1,.055-.535,3.152,3.152,0,0,1,.152-.514,2.874,2.874,0,0,1,.252-.47,2.633,2.633,0,0,1,.753-.754,2.837,2.837,0,0,1,.471-.251,2.753,2.753,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,4.019,4.019,0,0,1,.339.415,2.786,2.786,0,0,1,.251.47,2.864,2.864,0,0,1,.208,1.049,2.77,2.77,0,0,1-.8,1.934,4.139,4.139,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459m21.855-1.366a2.789,2.789,0,0,1-1.935-.8,4.162,4.162,0,0,1-.338-.415,2.7,2.7,0,0,1-.459-1.519,2.789,2.789,0,0,1,.8-1.934,4.139,4.139,0,0,1,.415-.339,2.838,2.838,0,0,1,.471-.251,2.752,2.752,0,0,1,.514-.153,2.527,2.527,0,0,1,1.071,0,2.654,2.654,0,0,1,.983.4,4.139,4.139,0,0,1,.415.339,2.79,2.79,0,0,1,.8,1.934,3.069,3.069,0,0,1-.055.535,2.779,2.779,0,0,1-.153.514,3.885,3.885,0,0,1-.251.47,4.02,4.02,0,0,1-.339.415,4.138,4.138,0,0,1-.415.339,2.722,2.722,0,0,1-1.519.459" transform="translate(9.753 -15.532)" fill-rule="evenodd"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1,170 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1041.277" height="554.141" viewBox="0 0 1041.277 554.141">
<title>Powered by React</title>
<g id="Group_24" data-name="Group 24" transform="translate(-440 -263)">
<g id="Group_23" data-name="Group 23" transform="translate(439.989 262.965)">
<path id="Path_299" data-name="Path 299" d="M1040.82,611.12q-1.74,3.75-3.47,7.4-2.7,5.67-5.33,11.12c-.78,1.61-1.56,3.19-2.32,4.77-8.6,17.57-16.63,33.11-23.45,45.89A73.21,73.21,0,0,1,942.44,719l-151.65,1.65h-1.6l-13,.14-11.12.12-34.1.37h-1.38l-17.36.19h-.53l-107,1.16-95.51,1-11.11.12-69,.75H429l-44.75.48h-.48l-141.5,1.53-42.33.46a87.991,87.991,0,0,1-10.79-.54h0c-1.22-.14-2.44-.3-3.65-.49a87.38,87.38,0,0,1-51.29-27.54C116,678.37,102.75,655,93.85,629.64q-1.93-5.49-3.6-11.12C59.44,514.37,97,380,164.6,290.08q4.25-5.64,8.64-11l.07-.08c20.79-25.52,44.1-46.84,68.93-62,44-26.91,92.75-34.49,140.7-11.9,40.57,19.12,78.45,28.11,115.17,30.55,3.71.24,7.42.42,11.11.53,84.23,2.65,163.17-27.7,255.87-47.29,3.69-.78,7.39-1.55,11.12-2.28,66.13-13.16,139.49-20.1,226.73-5.51a189.089,189.089,0,0,1,26.76,6.4q5.77,1.86,11.12,4c41.64,16.94,64.35,48.24,74,87.46q1.37,5.46,2.37,11.11C1134.3,384.41,1084.19,518.23,1040.82,611.12Z" transform="translate(-79.34 -172.91)" fill="#f2f2f2"/>
<path id="Path_300" data-name="Path 300" d="M576.36,618.52a95.21,95.21,0,0,1-1.87,11.12h93.7V618.52Zm-78.25,62.81,11.11-.09V653.77c-3.81-.17-7.52-.34-11.11-.52ZM265.19,618.52v11.12h198.5V618.52ZM1114.87,279h-74V191.51q-5.35-2.17-11.12-4V279H776.21V186.58c-3.73.73-7.43,1.5-11.12,2.28V279H509.22V236.15c-3.69-.11-7.4-.29-11.11-.53V279H242.24V217c-24.83,15.16-48.14,36.48-68.93,62h-.07v.08q-4.4,5.4-8.64,11h8.64V618.52h-83q1.66,5.63,3.6,11.12h79.39v93.62a87,87,0,0,0,12.2,2.79c1.21.19,2.43.35,3.65.49h0a87.991,87.991,0,0,0,10.79.54l42.33-.46v-97H498.11v94.21l11.11-.12V629.64H765.09V721l11.12-.12V629.64H1029.7v4.77c.76-1.58,1.54-3.16,2.32-4.77q2.63-5.45,5.33-11.12,1.73-3.64,3.47-7.4v-321h76.42Q1116.23,284.43,1114.87,279ZM242.24,618.52V290.08H498.11V618.52Zm267,0V290.08H765.09V618.52Zm520.48,0H776.21V290.08H1029.7Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_301" data-name="Path 301" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" fill="#65617d"/>
<path id="Path_302" data-name="Path 302" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l46.65-28,93.6-.78,2-.01.66-.01,2-.03,44.94-.37,2.01-.01.64-.01,2-.01L315,509.3l.38-.01,35.55-.3h.29l277.4-2.34,6.79-.05h.68l5.18-.05,37.65-.31,2-.03,1.85-.02h.96l11.71-.09,2.32-.03,3.11-.02,9.75-.09,15.47-.13,2-.02,3.48-.02h.65l74.71-.64Z" opacity="0.2"/>
<path id="Path_303" data-name="Path 303" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_304" data-name="Path 304" d="M375.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_305" data-name="Path 305" d="M377.44,656.57v24.49a6.13,6.13,0,0,1-3.5,5.54,6,6,0,0,1-2.5.6l-34.9.74a6,6,0,0,1-2.7-.57,6.12,6.12,0,0,1-3.57-5.57V656.57Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<rect id="Rectangle_137" data-name="Rectangle 137" width="47.17" height="31.5" transform="translate(680.92 483.65)" fill="#3f3d56"/>
<rect id="Rectangle_138" data-name="Rectangle 138" width="47.17" height="31.5" transform="translate(680.92 483.65)" opacity="0.1"/>
<rect id="Rectangle_139" data-name="Rectangle 139" width="47.17" height="31.5" transform="translate(678.92 483.65)" fill="#3f3d56"/>
<path id="Path_306" data-name="Path 306" d="M298.09,483.65v4.97l-47.17,1.26v-6.23Z" opacity="0.1"/>
<path id="Path_307" data-name="Path 307" d="M460.69,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6a4,4,0,0,1,3.95,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_308" data-name="Path 308" d="M265.19,481.32v181.2h-.05a4,4,0,0,1-3.95-3.95V485.27a4,4,0,0,1,3.95-3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_309" data-name="Path 309" d="M194.59,319.15h177.5V467.4l-177.5,4Z" fill="#39374d"/>
<path id="Path_310" data-name="Path 310" d="M726.09,483.65v6.41l-47.17-1.26v-5.15Z" opacity="0.1"/>
<path id="Path_311" data-name="Path 311" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0L672,657.42a4,4,0,0,1-3.85-3.95V485.27a4,4,0,0,1,3.95-3.95H863.7a4,4,0,0,1,3.99,3.95Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_312" data-name="Path 312" d="M867.69,485.27v173.3a4,4,0,0,1-4,3.95h0V481.32h0a4,4,0,0,1,4,3.95Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_313" data-name="Path 313" d="M775.59,319.15H598.09V467.4l177.5,4Z" fill="#39374d"/>
<path id="Path_314" data-name="Path 314" d="M663.19,485.27v168.2a4,4,0,0,1-3.85,3.95l-191.65,5.1h0a4,4,0,0,1-4-3.95V485.27a4,4,0,0,1,3.95-3.95h191.6A4,4,0,0,1,663.19,485.27Z" transform="translate(-79.34 -172.91)" fill="#65617d"/>
<path id="Path_315" data-name="Path 315" d="M397.09,319.15h177.5V467.4l-177.5,4Z" fill="#4267b2"/>
<path id="Path_316" data-name="Path 316" d="M863.09,533.65v13l-151.92,1.4-1.62.03-57.74.53-1.38.02-17.55.15h-.52l-106.98.99L349.77,551.4h-.15l-44.65.42-.48.01-198.4,1.82v-15l202.51-1.33h.48l40.99-.28h.19l283.08-1.87h.29l.17-.01h.47l4.79-.03h1.46l74.49-.5,4.4-.02.98-.01Z" opacity="0.1"/>
<circle id="Ellipse_111" data-name="Ellipse 111" cx="51.33" cy="51.33" r="51.33" transform="translate(435.93 246.82)" fill="#fbbebe"/>
<path id="Path_317" data-name="Path 317" d="M617.94,550.07s-99.5,12-90,0c3.44-4.34,4.39-17.2,4.2-31.85-.06-4.45-.22-9.06-.45-13.65-1.1-22-3.75-43.5-3.75-43.5s87-41,77-8.5c-4,13.13-2.69,31.57.35,48.88.89,5.05,1.92,10,3,14.7a344.66,344.66,0,0,0,9.65,33.92Z" transform="translate(-79.34 -172.91)" fill="#fbbebe"/>
<path id="Path_318" data-name="Path 318" d="M585.47,546c11.51-2.13,23.7-6,34.53-1.54,2.85,1.17,5.47,2.88,8.39,3.86s6.12,1.22,9.16,1.91c10.68,2.42,19.34,10.55,24.9,20s8.44,20.14,11.26,30.72l6.9,25.83c6,22.45,12,45.09,13.39,68.3a2437.506,2437.506,0,0,1-250.84,1.43c5.44-10.34,11-21.31,10.54-33s-7.19-23.22-4.76-34.74c1.55-7.34,6.57-13.39,9.64-20.22,8.75-19.52,1.94-45.79,17.32-60.65,6.92-6.68,17-9.21,26.63-8.89,12.28.41,24.85,4.24,37,6.11C555.09,547.48,569.79,548.88,585.47,546Z" transform="translate(-79.34 -172.91)" fill="#ff6584"/>
<path id="Path_319" data-name="Path 319" d="M716.37,657.17l-.1,1.43v.1l-.17,2.3-1.33,18.51-1.61,22.3-.46,6.28-1,13.44v.17l-107,1-175.59,1.9v.84h-.14v-1.12l.45-14.36.86-28.06.74-23.79.07-2.37a10.53,10.53,0,0,1,11.42-10.17c4.72.4,10.85.89,18.18,1.41l3,.22c42.33,2.94,120.56,6.74,199.5,2,1.66-.09,3.33-.19,5-.31,12.24-.77,24.47-1.76,36.58-3a10.53,10.53,0,0,1,11.6,11.23Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_320" data-name="Path 320" d="M429.08,725.44v-.84l175.62-1.91,107-1h.3v-.17l1-13.44.43-6,1.64-22.61,1.29-17.9v-.44a10.617,10.617,0,0,0-.11-2.47.3.3,0,0,0,0-.1,10.391,10.391,0,0,0-2-4.64,10.54,10.54,0,0,0-9.42-4c-12.11,1.24-24.34,2.23-36.58,3-1.67.12-3.34.22-5,.31-78.94,4.69-157.17.89-199.5-2l-3-.22c-7.33-.52-13.46-1-18.18-1.41a10.54,10.54,0,0,0-11.24,8.53,11,11,0,0,0-.18,1.64l-.68,22.16L429.54,710l-.44,14.36v1.12Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
<path id="Path_321" data-name="Path 321" d="M716.67,664.18l-1.23,15.33-1.83,22.85-.46,5.72-1,12.81-.06.64v.17h0l-.15,1.48.11-1.48h-.29l-107,1-175.65,1.9v-.28l.49-14.36,1-28.06.64-18.65A6.36,6.36,0,0,1,434.3,658a6.25,6.25,0,0,1,3.78-.9c2.1.17,4.68.37,7.69.59,4.89.36,10.92.78,17.94,1.22,13,.82,29.31,1.7,48,2.42,52,2,122.2,2.67,188.88-3.17,3-.26,6.1-.55,9.13-.84a6.26,6.26,0,0,1,3.48.66,5.159,5.159,0,0,1,.86.54,6.14,6.14,0,0,1,2,2.46,3.564,3.564,0,0,1,.25.61A6.279,6.279,0,0,1,716.67,664.18Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_322" data-name="Path 322" d="M377.44,677.87v3.19a6.13,6.13,0,0,1-3.5,5.54l-40.1.77a6.12,6.12,0,0,1-3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_323" data-name="Path 323" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_324" data-name="Path 324" d="M298.59,515.57l-52.25,1V507.9l52.25-1Z" opacity="0.1"/>
<path id="Path_325" data-name="Path 325" d="M300.59,515.57l-52.25,1V507.9l52.25-1Z" fill="#3f3d56"/>
<path id="Path_326" data-name="Path 326" d="M758.56,679.87v3.19a6.13,6.13,0,0,0,3.5,5.54l40.1.77a6.12,6.12,0,0,0,3.57-5.57v-3Z" transform="translate(-79.34 -172.91)" opacity="0.1"/>
<path id="Path_327" data-name="Path 327" d="M678.72,517.57l52.25,1V509.9l-52.25-1Z" opacity="0.1"/>
<path id="Path_328" data-name="Path 328" d="M676.72,517.57l52.25,1V509.9l-52.25-1Z" fill="#3f3d56"/>
<path id="Path_329" data-name="Path 329" d="M534.13,486.79c.08,7-3.16,13.6-5.91,20.07a163.491,163.491,0,0,0-12.66,74.71c.73,11,2.58,22,.73,32.9s-8.43,21.77-19,24.9c17.53,10.45,41.26,9.35,57.76-2.66,8.79-6.4,15.34-15.33,21.75-24.11a97.86,97.86,0,0,1-13.31,44.75A103.43,103.43,0,0,0,637,616.53c4.31-5.81,8.06-12.19,9.72-19.23,3.09-13-1.22-26.51-4.51-39.5a266.055,266.055,0,0,1-6.17-33c-.43-3.56-.78-7.22.1-10.7,1-4.07,3.67-7.51,5.64-11.22,5.6-10.54,5.73-23.3,2.86-34.88s-8.49-22.26-14.06-32.81c-4.46-8.46-9.3-17.31-17.46-22.28-5.1-3.1-11-4.39-16.88-5.64l-25.37-5.43c-5.55-1.19-11.26-2.38-16.87-1.51-9.47,1.48-16.14,8.32-22,15.34-4.59,5.46-15.81,15.71-16.6,22.86-.72,6.59,5.1,17.63,6.09,24.58,1.3,9,2.22,6,7.3,11.52C532,478.05,534.07,482,534.13,486.79Z" transform="translate(-79.34 -172.91)" fill="#3f3d56"/>
</g>
<g id="docusaurus_keytar" transform="translate(670.271 615.768)">
<path id="Path_40" data-name="Path 40" d="M99,52h43.635V69.662H99Z" transform="translate(-49.132 -33.936)" fill="#fff" fill-rule="evenodd"/>
<path id="Path_41" data-name="Path 41" d="M13.389,158.195A10.377,10.377,0,0,1,4.4,153a10.377,10.377,0,0,0,8.988,15.584H23.779V158.195Z" transform="translate(-3 -82.47)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_42" data-name="Path 42" d="M66.967,38.083l36.373-2.273V30.615A10.389,10.389,0,0,0,92.95,20.226H46.2l-1.3-2.249a1.5,1.5,0,0,0-2.6,0L41,20.226l-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-1.3-2.249a1.5,1.5,0,0,0-2.6,0l-1.3,2.249-.034,0-2.152-2.151a1.5,1.5,0,0,0-2.508.672L25.21,21.4l-2.7-.723a1.5,1.5,0,0,0-1.836,1.837l.722,2.7-2.65.71a1.5,1.5,0,0,0-.673,2.509l2.152,2.152c0,.011,0,.022,0,.033l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6L20.226,41l-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3-2.249,1.3a1.5,1.5,0,0,0,0,2.6l2.249,1.3A10.389,10.389,0,0,0,30.615,103.34H92.95A10.389,10.389,0,0,0,103.34,92.95V51.393L66.967,49.12a5.53,5.53,0,0,1,0-11.038" transform="translate(-9.836 -17.226)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_43" data-name="Path 43" d="M143,163.779h15.584V143H143Z" transform="translate(-70.275 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_44" data-name="Path 44" d="M173.779,148.389a2.582,2.582,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-75.08 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_45" data-name="Path 45" d="M153,113.389h15.584V103H153Z" transform="translate(-75.08 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_46" data-name="Path 46" d="M183.389,108.944a1.3,1.3,0,1,0,0-2.6,1.336,1.336,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.337,1.337,0,0,0,.166.017" transform="translate(-84.691 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_47" data-name="Path 47" d="M52.188,48.292a1.3,1.3,0,0,1-1.3-1.3,3.9,3.9,0,0,0-7.792,0,1.3,1.3,0,1,1-2.6,0,6.493,6.493,0,0,1,12.987,0,1.3,1.3,0,0,1-1.3,1.3" transform="translate(-21.02 -28.41)" fill-rule="evenodd"/>
<path id="Path_48" data-name="Path 48" d="M103,139.752h31.168a10.389,10.389,0,0,0,10.389-10.389V93H113.389A10.389,10.389,0,0,0,103,103.389Z" transform="translate(-51.054 -53.638)" fill="#ffff50" fill-rule="evenodd"/>
<path id="Path_49" data-name="Path 49" d="M141.1,94.017H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0-25.877H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.293H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m0,10.389H115.106a.519.519,0,1,1,0-1.039H141.1a.519.519,0,0,1,0,1.039m7.782-47.993c-.006,0-.011,0-.018,0-1.605.055-2.365,1.66-3.035,3.077-.7,1.48-1.24,2.443-2.126,2.414-.981-.035-1.542-1.144-2.137-2.317-.683-1.347-1.462-2.876-3.1-2.819-1.582.054-2.344,1.451-3.017,2.684-.715,1.313-1.2,2.112-2.141,2.075-1-.036-1.533-.938-2.149-1.981-.686-1.162-1.479-2.467-3.084-2.423-1.555.053-2.319,1.239-2.994,2.286-.713,1.106-1.213,1.781-2.164,1.741-1.025-.036-1.554-.784-2.167-1.65-.688-.973-1.463-2.074-3.062-2.021a3.815,3.815,0,0,0-2.959,1.879c-.64.812-1.14,1.456-2.2,1.415a.52.52,0,0,0-.037,1.039,3.588,3.588,0,0,0,3.05-1.811c.611-.777,1.139-1.448,2.178-1.483,1-.043,1.47.579,2.179,1.582.674.953,1.438,2.033,2.977,2.089,1.612.054,2.387-1.151,3.074-2.217.614-.953,1.144-1.775,2.156-1.81.931-.035,1.438.7,2.153,1.912.674,1.141,1.437,2.434,3.006,2.491,1.623.056,2.407-1.361,3.09-2.616.592-1.085,1.15-2.109,2.14-2.143.931-.022,1.417.829,2.135,2.249.671,1.326,1.432,2.828,3.026,2.886l.088,0c1.592,0,2.347-1.6,3.015-3.01.592-1.252,1.152-2.431,2.113-2.479Z" transform="translate(-55.378 -38.552)" fill-rule="evenodd"/>
<path id="Path_50" data-name="Path 50" d="M83,163.779h20.779V143H83Z" transform="translate(-41.443 -77.665)" fill="#3ecc5f" fill-rule="evenodd"/>
<g id="Group_8" data-name="Group 8" transform="matrix(0.966, -0.259, 0.259, 0.966, 51.971, 43.3)">
<rect id="Rectangle_3" data-name="Rectangle 3" width="43.906" height="17.333" rx="2" transform="translate(0 0)" fill="#d8d8d8"/>
<g id="Group_2" data-name="Group 2" transform="translate(0.728 10.948)">
<rect id="Rectangle_4" data-name="Rectangle 4" width="2.537" height="2.537" rx="1" transform="translate(7.985 0)" fill="#4a4a4a"/>
<rect id="Rectangle_5" data-name="Rectangle 5" width="2.537" height="2.537" rx="1" transform="translate(10.991 0)" fill="#4a4a4a"/>
<rect id="Rectangle_6" data-name="Rectangle 6" width="2.537" height="2.537" rx="1" transform="translate(13.997 0)" fill="#4a4a4a"/>
<rect id="Rectangle_7" data-name="Rectangle 7" width="2.537" height="2.537" rx="1" transform="translate(17.003 0)" fill="#4a4a4a"/>
<rect id="Rectangle_8" data-name="Rectangle 8" width="2.537" height="2.537" rx="1" transform="translate(20.009 0)" fill="#4a4a4a"/>
<rect id="Rectangle_9" data-name="Rectangle 9" width="2.537" height="2.537" rx="1" transform="translate(23.015 0)" fill="#4a4a4a"/>
<rect id="Rectangle_10" data-name="Rectangle 10" width="2.537" height="2.537" rx="1" transform="translate(26.021 0)" fill="#4a4a4a"/>
<rect id="Rectangle_11" data-name="Rectangle 11" width="2.537" height="2.537" rx="1" transform="translate(29.028 0)" fill="#4a4a4a"/>
<rect id="Rectangle_12" data-name="Rectangle 12" width="2.537" height="2.537" rx="1" transform="translate(32.034 0)" fill="#4a4a4a"/>
<path id="Path_51" data-name="Path 51" d="M.519,0H6.9A.519.519,0,0,1,7.421.52v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0ZM35.653,0h6.383a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H35.652a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,35.652,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_3" data-name="Group 3" transform="translate(0.728 4.878)">
<path id="Path_52" data-name="Path 52" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_13" data-name="Rectangle 13" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_14" data-name="Rectangle 14" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_15" data-name="Rectangle 15" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_16" data-name="Rectangle 16" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_17" data-name="Rectangle 17" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_18" data-name="Rectangle 18" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_19" data-name="Rectangle 19" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_20" data-name="Rectangle 20" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_21" data-name="Rectangle 21" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_22" data-name="Rectangle 22" width="2.537" height="2.537" rx="1" transform="translate(31 0)" fill="#4a4a4a"/>
<rect id="Rectangle_23" data-name="Rectangle 23" width="2.537" height="2.537" rx="1" transform="translate(34.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_24" data-name="Rectangle 24" width="2.537" height="2.537" rx="1" transform="translate(37.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_25" data-name="Rectangle 25" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_4" data-name="Group 4" transform="translate(43.283 4.538) rotate(180)">
<path id="Path_53" data-name="Path 53" d="M.519,0H2.956a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.519A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_26" data-name="Rectangle 26" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_27" data-name="Rectangle 27" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_28" data-name="Rectangle 28" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_29" data-name="Rectangle 29" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_30" data-name="Rectangle 30" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_31" data-name="Rectangle 31" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_32" data-name="Rectangle 32" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_33" data-name="Rectangle 33" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_34" data-name="Rectangle 34" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_35" data-name="Rectangle 35" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_36" data-name="Rectangle 36" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_37" data-name="Rectangle 37" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_38" data-name="Rectangle 38" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_39" data-name="Rectangle 39" width="2.537" height="2.537" rx="1" transform="translate(3.945 0)" fill="#4a4a4a"/>
<rect id="Rectangle_40" data-name="Rectangle 40" width="2.537" height="2.537" rx="1" transform="translate(6.951 0)" fill="#4a4a4a"/>
<rect id="Rectangle_41" data-name="Rectangle 41" width="2.537" height="2.537" rx="1" transform="translate(9.958 0)" fill="#4a4a4a"/>
<rect id="Rectangle_42" data-name="Rectangle 42" width="2.537" height="2.537" rx="1" transform="translate(12.964 0)" fill="#4a4a4a"/>
<rect id="Rectangle_43" data-name="Rectangle 43" width="2.537" height="2.537" rx="1" transform="translate(15.97 0)" fill="#4a4a4a"/>
<rect id="Rectangle_44" data-name="Rectangle 44" width="2.537" height="2.537" rx="1" transform="translate(18.976 0)" fill="#4a4a4a"/>
<rect id="Rectangle_45" data-name="Rectangle 45" width="2.537" height="2.537" rx="1" transform="translate(21.982 0)" fill="#4a4a4a"/>
<rect id="Rectangle_46" data-name="Rectangle 46" width="2.537" height="2.537" rx="1" transform="translate(24.988 0)" fill="#4a4a4a"/>
<rect id="Rectangle_47" data-name="Rectangle 47" width="2.537" height="2.537" rx="1" transform="translate(27.994 0)" fill="#4a4a4a"/>
<rect id="Rectangle_48" data-name="Rectangle 48" width="2.537" height="2.537" rx="1" transform="translate(31.001 0)" fill="#4a4a4a"/>
<rect id="Rectangle_49" data-name="Rectangle 49" width="2.537" height="2.537" rx="1" transform="translate(34.007 0)" fill="#4a4a4a"/>
<rect id="Rectangle_50" data-name="Rectangle 50" width="2.537" height="2.537" rx="1" transform="translate(37.013 0)" fill="#4a4a4a"/>
<rect id="Rectangle_51" data-name="Rectangle 51" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
</g>
<g id="Group_6" data-name="Group 6" transform="translate(0.728 7.883)">
<path id="Path_54" data-name="Path 54" d="M.519,0h3.47a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(0 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<g id="Group_5" data-name="Group 5" transform="translate(5.073 0)">
<rect id="Rectangle_52" data-name="Rectangle 52" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_53" data-name="Rectangle 53" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_54" data-name="Rectangle 54" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_55" data-name="Rectangle 55" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<rect id="Rectangle_56" data-name="Rectangle 56" width="2.537" height="2.537" rx="1" transform="translate(12.025 0)" fill="#4a4a4a"/>
<rect id="Rectangle_57" data-name="Rectangle 57" width="2.537" height="2.537" rx="1" transform="translate(15.031 0)" fill="#4a4a4a"/>
<rect id="Rectangle_58" data-name="Rectangle 58" width="2.537" height="2.537" rx="1" transform="translate(18.037 0)" fill="#4a4a4a"/>
<rect id="Rectangle_59" data-name="Rectangle 59" width="2.537" height="2.537" rx="1" transform="translate(21.042 0)" fill="#4a4a4a"/>
<rect id="Rectangle_60" data-name="Rectangle 60" width="2.537" height="2.537" rx="1" transform="translate(24.049 0)" fill="#4a4a4a"/>
<rect id="Rectangle_61" data-name="Rectangle 61" width="2.537" height="2.537" rx="1" transform="translate(27.055 0)" fill="#4a4a4a"/>
<rect id="Rectangle_62" data-name="Rectangle 62" width="2.537" height="2.537" rx="1" transform="translate(30.061 0)" fill="#4a4a4a"/>
</g>
<path id="Path_55" data-name="Path 55" d="M.52,0H3.8a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.017V.52A.519.519,0,0,1,.519,0Z" transform="translate(38.234 0)" fill="#4a4a4a" fill-rule="evenodd"/>
</g>
<g id="Group_7" data-name="Group 7" transform="translate(0.728 14.084)">
<rect id="Rectangle_63" data-name="Rectangle 63" width="2.537" height="2.537" rx="1" transform="translate(0 0)" fill="#4a4a4a"/>
<rect id="Rectangle_64" data-name="Rectangle 64" width="2.537" height="2.537" rx="1" transform="translate(3.006 0)" fill="#4a4a4a"/>
<rect id="Rectangle_65" data-name="Rectangle 65" width="2.537" height="2.537" rx="1" transform="translate(6.012 0)" fill="#4a4a4a"/>
<rect id="Rectangle_66" data-name="Rectangle 66" width="2.537" height="2.537" rx="1" transform="translate(9.018 0)" fill="#4a4a4a"/>
<path id="Path_56" data-name="Path 56" d="M.519,0H14.981A.519.519,0,0,1,15.5.519v1.5a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,2.018V.519A.519.519,0,0,1,.519,0Zm15.97,0h1.874a.519.519,0,0,1,.519.519v1.5a.519.519,0,0,1-.519.519H16.489a.519.519,0,0,1-.519-.519V.519A.519.519,0,0,1,16.489,0Z" transform="translate(12.024 0)" fill="#4a4a4a" fill-rule="evenodd"/>
<rect id="Rectangle_67" data-name="Rectangle 67" width="2.537" height="2.537" rx="1" transform="translate(31.376 0)" fill="#4a4a4a"/>
<rect id="Rectangle_68" data-name="Rectangle 68" width="2.537" height="2.537" rx="1" transform="translate(34.382 0)" fill="#4a4a4a"/>
<rect id="Rectangle_69" data-name="Rectangle 69" width="2.537" height="2.537" rx="1" transform="translate(40.018 0)" fill="#4a4a4a"/>
<path id="Path_57" data-name="Path 57" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(39.736 1.08) rotate(180)" fill="#4a4a4a"/>
<path id="Path_58" data-name="Path 58" d="M2.537,0V.561a.519.519,0,0,1-.519.519H.519A.519.519,0,0,1,0,.561V0Z" transform="translate(37.2 1.456)" fill="#4a4a4a"/>
</g>
<rect id="Rectangle_70" data-name="Rectangle 70" width="42.273" height="1.127" rx="0.564" transform="translate(0.915 0.556)" fill="#4a4a4a"/>
<rect id="Rectangle_71" data-name="Rectangle 71" width="2.37" height="0.752" rx="0.376" transform="translate(1.949 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_72" data-name="Rectangle 72" width="2.37" height="0.752" rx="0.376" transform="translate(5.193 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_73" data-name="Rectangle 73" width="2.37" height="0.752" rx="0.376" transform="translate(7.688 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_74" data-name="Rectangle 74" width="2.37" height="0.752" rx="0.376" transform="translate(10.183 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_75" data-name="Rectangle 75" width="2.37" height="0.752" rx="0.376" transform="translate(12.679 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_76" data-name="Rectangle 76" width="2.37" height="0.752" rx="0.376" transform="translate(15.797 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_77" data-name="Rectangle 77" width="2.37" height="0.752" rx="0.376" transform="translate(18.292 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_78" data-name="Rectangle 78" width="2.37" height="0.752" rx="0.376" transform="translate(20.788 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_79" data-name="Rectangle 79" width="2.37" height="0.752" rx="0.376" transform="translate(23.283 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_80" data-name="Rectangle 80" width="2.37" height="0.752" rx="0.376" transform="translate(26.402 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_81" data-name="Rectangle 81" width="2.37" height="0.752" rx="0.376" transform="translate(28.897 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_82" data-name="Rectangle 82" width="2.37" height="0.752" rx="0.376" transform="translate(31.393 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_83" data-name="Rectangle 83" width="2.37" height="0.752" rx="0.376" transform="translate(34.512 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_84" data-name="Rectangle 84" width="2.37" height="0.752" rx="0.376" transform="translate(37.007 0.744)" fill="#d8d8d8" opacity="0.136"/>
<rect id="Rectangle_85" data-name="Rectangle 85" width="2.37" height="0.752" rx="0.376" transform="translate(39.502 0.744)" fill="#d8d8d8" opacity="0.136"/>
</g>
<path id="Path_59" data-name="Path 59" d="M123.779,148.389a2.583,2.583,0,0,0-.332.033c-.02-.078-.038-.156-.06-.234a2.594,2.594,0,1,0-2.567-4.455q-.086-.088-.174-.175a2.593,2.593,0,1,0-4.461-2.569c-.077-.022-.154-.04-.231-.06a2.6,2.6,0,1,0-5.128,0c-.077.02-.154.038-.231.06a2.594,2.594,0,1,0-4.461,2.569,10.384,10.384,0,1,0,17.314,9.992,2.592,2.592,0,1,0,.332-5.161" transform="translate(-51.054 -75.262)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_60" data-name="Path 60" d="M83,113.389h20.779V103H83Z" transform="translate(-41.443 -58.444)" fill="#3ecc5f" fill-rule="evenodd"/>
<path id="Path_61" data-name="Path 61" d="M123.389,108.944a1.3,1.3,0,1,0,0-2.6,1.338,1.338,0,0,0-.166.017c-.01-.039-.019-.078-.03-.117a1.3,1.3,0,0,0-.5-2.5,1.285,1.285,0,0,0-.783.269q-.043-.044-.087-.087a1.285,1.285,0,0,0,.263-.776,1.3,1.3,0,0,0-2.493-.509,5.195,5.195,0,1,0,0,10,1.3,1.3,0,0,0,2.493-.509,1.285,1.285,0,0,0-.263-.776q.044-.043.087-.087a1.285,1.285,0,0,0,.783.269,1.3,1.3,0,0,0,.5-2.5c.011-.038.02-.078.03-.117a1.335,1.335,0,0,0,.166.017" transform="translate(-55.859 -57.894)" fill="#44d860" fill-rule="evenodd"/>
<path id="Path_62" data-name="Path 62" d="M141.8,38.745a1.41,1.41,0,0,1-.255-.026,1.309,1.309,0,0,1-.244-.073,1.349,1.349,0,0,1-.224-.119,1.967,1.967,0,0,1-.2-.161,1.52,1.52,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.41,1.41,0,0,1,.026-.255,1.5,1.5,0,0,1,.072-.244,1.364,1.364,0,0,1,.12-.223,1.252,1.252,0,0,1,.358-.358,1.349,1.349,0,0,1,.224-.119,1.309,1.309,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.968,1.968,0,0,1,.2.161,1.908,1.908,0,0,1,.161.2,1.322,1.322,0,0,1,.12.223,1.361,1.361,0,0,1,.1.5,1.317,1.317,0,0,1-.379.919,1.968,1.968,0,0,1-.2.161,1.346,1.346,0,0,1-.223.119,1.332,1.332,0,0,1-.5.1m10.389-.649a1.326,1.326,0,0,1-.92-.379,1.979,1.979,0,0,1-.161-.2,1.282,1.282,0,0,1-.218-.722,1.326,1.326,0,0,1,.379-.919,1.967,1.967,0,0,1,.2-.161,1.351,1.351,0,0,1,.224-.119,1.308,1.308,0,0,1,.244-.073,1.2,1.2,0,0,1,.509,0,1.262,1.262,0,0,1,.468.192,1.967,1.967,0,0,1,.2.161,1.326,1.326,0,0,1,.379.919,1.461,1.461,0,0,1-.026.255,1.323,1.323,0,0,1-.073.244,1.847,1.847,0,0,1-.119.223,1.911,1.911,0,0,1-.161.2,1.967,1.967,0,0,1-.2.161,1.294,1.294,0,0,1-.722.218" transform="translate(-69.074 -26.006)" fill-rule="evenodd"/>
</g>
<g id="React-icon" transform="translate(906.3 541.56)">
<path id="Path_330" data-name="Path 330" d="M263.668,117.179c0-5.827-7.3-11.35-18.487-14.775,2.582-11.4,1.434-20.477-3.622-23.382a7.861,7.861,0,0,0-4.016-1v4a4.152,4.152,0,0,1,2.044.466c2.439,1.4,3.5,6.724,2.672,13.574-.2,1.685-.52,3.461-.914,5.272a86.9,86.9,0,0,0-11.386-1.954,87.469,87.469,0,0,0-7.459-8.965c5.845-5.433,11.332-8.41,15.062-8.41V78h0c-4.931,0-11.386,3.514-17.913,9.611-6.527-6.061-12.982-9.539-17.913-9.539v4c3.712,0,9.216,2.959,15.062,8.356a84.687,84.687,0,0,0-7.405,8.947,83.732,83.732,0,0,0-11.4,1.972c-.412-1.793-.717-3.532-.932-5.2-.843-6.85.2-12.175,2.618-13.592a3.991,3.991,0,0,1,2.062-.466v-4h0a8,8,0,0,0-4.052,1c-5.039,2.9-6.168,11.96-3.568,23.328-11.153,3.443-18.415,8.947-18.415,14.757,0,5.828,7.3,11.35,18.487,14.775-2.582,11.4-1.434,20.477,3.622,23.382a7.882,7.882,0,0,0,4.034,1c4.931,0,11.386-3.514,17.913-9.611,6.527,6.061,12.982,9.539,17.913,9.539a8,8,0,0,0,4.052-1c5.039-2.9,6.168-11.96,3.568-23.328C256.406,128.511,263.668,122.988,263.668,117.179Zm-23.346-11.96c-.663,2.313-1.488,4.7-2.421,7.083-.735-1.434-1.506-2.869-2.349-4.3-.825-1.434-1.7-2.833-2.582-4.2C235.517,104.179,237.974,104.645,240.323,105.219Zm-8.212,19.1c-1.4,2.421-2.833,4.716-4.321,6.85-2.672.233-5.379.359-8.1.359-2.708,0-5.415-.126-8.069-.341q-2.232-3.2-4.339-6.814-2.044-3.523-3.73-7.136c1.112-2.4,2.367-4.805,3.712-7.154,1.4-2.421,2.833-4.716,4.321-6.85,2.672-.233,5.379-.359,8.1-.359,2.708,0,5.415.126,8.069.341q2.232,3.2,4.339,6.814,2.044,3.523,3.73,7.136C234.692,119.564,233.455,121.966,232.11,124.315Zm5.792-2.331c.968,2.4,1.793,4.805,2.474,7.136-2.349.574-4.823,1.058-7.387,1.434.879-1.381,1.757-2.8,2.582-4.25C236.4,124.871,237.167,123.419,237.9,121.984ZM219.72,141.116a73.921,73.921,0,0,1-4.985-5.738c1.614.072,3.263.126,4.931.126,1.685,0,3.353-.036,4.985-.126A69.993,69.993,0,0,1,219.72,141.116ZM206.38,130.555c-2.546-.377-5-.843-7.352-1.417.663-2.313,1.488-4.7,2.421-7.083.735,1.434,1.506,2.869,2.349,4.3S205.5,129.192,206.38,130.555ZM219.63,93.241a73.924,73.924,0,0,1,4.985,5.738c-1.614-.072-3.263-.126-4.931-.126-1.686,0-3.353.036-4.985.126A69.993,69.993,0,0,1,219.63,93.241ZM206.362,103.8c-.879,1.381-1.757,2.8-2.582,4.25-.825,1.434-1.6,2.869-2.331,4.3-.968-2.4-1.793-4.805-2.474-7.136C201.323,104.663,203.8,104.179,206.362,103.8Zm-16.227,22.449c-6.348-2.708-10.454-6.258-10.454-9.073s4.106-6.383,10.454-9.073c1.542-.663,3.228-1.255,4.967-1.811a86.122,86.122,0,0,0,4.034,10.92,84.9,84.9,0,0,0-3.981,10.866C193.38,127.525,191.694,126.915,190.134,126.252Zm9.647,25.623c-2.439-1.4-3.5-6.724-2.672-13.574.2-1.686.52-3.461.914-5.272a86.9,86.9,0,0,0,11.386,1.954,87.465,87.465,0,0,0,7.459,8.965c-5.845,5.433-11.332,8.41-15.062,8.41A4.279,4.279,0,0,1,199.781,151.875Zm42.532-13.663c.843,6.85-.2,12.175-2.618,13.592a3.99,3.99,0,0,1-2.062.466c-3.712,0-9.216-2.959-15.062-8.356a84.689,84.689,0,0,0,7.405-8.947,83.731,83.731,0,0,0,11.4-1.972A50.194,50.194,0,0,1,242.313,138.212Zm6.9-11.96c-1.542.663-3.228,1.255-4.967,1.811a86.12,86.12,0,0,0-4.034-10.92,84.9,84.9,0,0,0,3.981-10.866c1.775.556,3.461,1.165,5.039,1.829,6.348,2.708,10.454,6.258,10.454,9.073C259.67,119.994,255.564,123.562,249.216,126.252Z" fill="#61dafb"/>
<path id="Path_331" data-name="Path 331" d="M320.8,78.4Z" transform="translate(-119.082 -0.328)" fill="#61dafb"/>
<circle id="Ellipse_112" data-name="Ellipse 112" cx="8.194" cy="8.194" r="8.194" transform="translate(211.472 108.984)" fill="#61dafb"/>
<path id="Path_332" data-name="Path 332" d="M520.5,78.1Z" transform="translate(-282.975 -0.082)" fill="#61dafb"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,40 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1129" height="663" viewBox="0 0 1129 663">
<title>Focus on What Matters</title>
<circle cx="321" cy="321" r="321" fill="#f2f2f2" />
<ellipse cx="559" cy="635.49998" rx="514" ry="27.50002" fill="#3f3d56" />
<ellipse cx="558" cy="627" rx="460" ry="22" opacity="0.2" />
<rect x="131" y="152.5" width="840" height="50" fill="#3f3d56" />
<path d="M166.5,727.3299A21.67009,21.67009,0,0,0,188.1701,749H984.8299A21.67009,21.67009,0,0,0,1006.5,727.3299V296h-840Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<path d="M984.8299,236H188.1701A21.67009,21.67009,0,0,0,166.5,257.6701V296h840V257.6701A21.67009,21.67009,0,0,0,984.8299,236Z" transform="translate(-35.5 -118.5)" opacity="0.2" />
<circle cx="181" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="217" cy="147.5" r="13" fill="#3f3d56" />
<circle cx="253" cy="147.5" r="13" fill="#3f3d56" />
<rect x="168" y="213.5" width="337" height="386" rx="5.33505" fill="#606060" />
<rect x="603" y="272.5" width="284" height="22" rx="5.47638" fill="#2e8555" />
<rect x="537" y="352.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="396.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="440.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="537" y="484.5" width="416" height="15" rx="5.47638" fill="#2e8555" />
<rect x="865" y="552.5" width="88" height="26" rx="7.02756" fill="#3ecc5f" />
<path d="M1088.60287,624.61594a30.11371,30.11371,0,0,0,3.98291-15.266c0-13.79652-8.54358-24.98081-19.08256-24.98081s-19.08256,11.18429-19.08256,24.98081a30.11411,30.11411,0,0,0,3.98291,15.266,31.248,31.248,0,0,0,0,30.53213,31.248,31.248,0,0,0,0,30.53208,31.248,31.248,0,0,0,0,30.53208,30.11408,30.11408,0,0,0-3.98291,15.266c0,13.79652,8.54353,24.98081,19.08256,24.98081s19.08256-11.18429,19.08256-24.98081a30.11368,30.11368,0,0,0-3.98291-15.266,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53208,31.248,31.248,0,0,0,0-30.53213Z" transform="translate(-35.5 -118.5)" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="460.31783" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<ellipse cx="1038.00321" cy="429.78574" rx="19.08256" ry="24.9808" fill="#3f3d56" />
<path d="M1144.93871,339.34489a91.61081,91.61081,0,0,0,7.10658-10.46092l-50.141-8.23491,54.22885.4033a91.566,91.566,0,0,0,1.74556-72.42605l-72.75449,37.74139,67.09658-49.32086a91.41255,91.41255,0,1,0-150.971,102.29805,91.45842,91.45842,0,0,0-10.42451,16.66946l65.0866,33.81447-69.40046-23.292a91.46011,91.46011,0,0,0,14.73837,85.83669,91.40575,91.40575,0,1,0,143.68892,0,91.41808,91.41808,0,0,0,0-113.02862Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M981.6885,395.8592a91.01343,91.01343,0,0,0,19.56129,56.51431,91.40575,91.40575,0,1,0,143.68892,0C1157.18982,436.82067,981.6885,385.60008,981.6885,395.8592Z" transform="translate(-35.5 -118.5)" opacity="0.1" />
<path d="M365.62,461.43628H477.094v45.12043H365.62Z" transform="translate(-35.5 -118.5)" fill="#fff" fill-rule="evenodd" />
<path d="M264.76252,608.74122a26.50931,26.50931,0,0,1-22.96231-13.27072,26.50976,26.50976,0,0,0,22.96231,39.81215H291.304V608.74122Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M384.17242,468.57061l92.92155-5.80726V449.49263a26.54091,26.54091,0,0,0-26.54143-26.54143H331.1161l-3.31768-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622-3.31767-5.74622a3.83043,3.83043,0,0,0-6.63536,0l-3.31768,5.74622L301.257,417.205a3.83043,3.83043,0,0,0-6.63536,0L291.304,422.9512c-.02919,0-.05573.004-.08625.004l-5.49674-5.49541a3.8293,3.8293,0,0,0-6.4071,1.71723l-1.81676,6.77338L270.607,424.1031a3.82993,3.82993,0,0,0-4.6912,4.69253l1.84463,6.89148-6.77072,1.81411a3.8315,3.8315,0,0,0-1.71988,6.40975l5.49673,5.49673c0,.02787-.004.05574-.004.08493l-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74621,3.31768L259.0163,466.081a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31767a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768L259.0163,558.976a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768-5.74622,3.31768a3.83042,3.83042,0,0,0,0,6.63535l5.74622,3.31768-5.74622,3.31768a3.83043,3.83043,0,0,0,0,6.63536l5.74622,3.31768A26.54091,26.54091,0,0,0,291.304,635.28265H450.55254A26.5409,26.5409,0,0,0,477.094,608.74122V502.5755l-92.92155-5.80727a14.12639,14.12639,0,0,1,0-28.19762" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,635.28265h39.81214V582.19979H424.01111Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15393-.59852A6.62668,6.62668,0,1,0,482.80568,590.21q-.2203-.22491-.44457-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39414-.10218-.59056-.15262a6.63957,6.63957,0,1,0-13.10086,0c-.1964.05042-.39414.09687-.59056.15262a6.62767,6.62767,0,1,0-11.39688,6.56369,26.52754,26.52754,0,1,0,44.23127,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M437.28182,555.65836H477.094V529.11693H437.28182Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M490.36468,545.70532a3.31768,3.31768,0,0,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M317.84538,466.081a3.31768,3.31768,0,0,1-3.31767-3.31768,9.953,9.953,0,1,0-19.90608,0,3.31768,3.31768,0,1,1-6.63535,0,16.58839,16.58839,0,1,1,33.17678,0,3.31768,3.31768,0,0,1-3.31768,3.31768" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M370.92825,635.28265h79.62429A26.5409,26.5409,0,0,0,477.094,608.74122v-92.895H397.46968a26.54091,26.54091,0,0,0-26.54143,26.54143Z" transform="translate(-35.5 -118.5)" fill="#ffff50" fill-rule="evenodd" />
<path d="M457.21444,556.98543H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,1,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0-66.10674H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.29459H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414m0,26.54143H390.80778a1.32707,1.32707,0,0,1,0-2.65414h66.40666a1.32707,1.32707,0,0,1,0,2.65414M477.094,474.19076c-.01592,0-.0292-.008-.04512-.00663-4.10064.13934-6.04083,4.24132-7.75274,7.86024-1.78623,3.78215-3.16771,6.24122-5.43171,6.16691-2.50685-.09024-3.94007-2.92222-5.45825-5.91874-1.74377-3.44243-3.73438-7.34667-7.91333-7.20069-4.04227.138-5.98907,3.70784-7.70631,6.857-1.82738,3.35484-3.07084,5.39455-5.46887,5.30033-2.55727-.09289-3.91619-2.39536-5.48877-5.06013-1.75306-2.96733-3.77951-6.30359-7.8775-6.18946-3.97326.13669-5.92537,3.16507-7.64791,5.83912-1.82207,2.82666-3.09872,4.5492-5.52725,4.447-2.61832-.09289-3.9706-2.00388-5.53522-4.21611-1.757-2.4856-3.737-5.299-7.82308-5.16231-3.88567.13271-5.83779,2.61434-7.559,4.80135-1.635,2.07555-2.9116,3.71846-5.61218,3.615a1.32793,1.32793,0,1,0-.09555,2.65414c4.00377.134,6.03154-2.38873,7.79257-4.6275,1.562-1.9853,2.91027-3.69855,5.56441-3.78879,2.55594-.10882,3.75429,1.47968,5.56707,4.04093,1.7212,2.43385,3.67465,5.19416,7.60545,5.33616,4.11789.138,6.09921-2.93946,7.8536-5.66261,1.56861-2.43385,2.92221-4.53461,5.50734-4.62352,2.37944-.08892,3.67466,1.79154,5.50072,4.885,1.72121,2.91557,3.67069,6.21865,7.67977,6.36463,4.14709.14332,6.14965-3.47693,7.89475-6.68181,1.51155-2.77092,2.93814-5.38791,5.46621-5.4755,2.37944-.05573,3.62025,2.11668,5.45558,5.74622,1.71459,3.388,3.65875,7.22591,7.73019,7.37321l.22429.004c4.06614,0,5.99571-4.08074,7.70364-7.68905,1.51154-3.19825,2.94211-6.21069,5.3972-6.33411Z" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
<path d="M344.38682,635.28265h53.08286V582.19979H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M424.01111,602.10586a6.60242,6.60242,0,0,0-.848.08493c-.05042-.19906-.09821-.39945-.15394-.59852A6.62667,6.62667,0,1,0,416.45211,590.21q-.2203-.22491-.44458-.44589a6.62391,6.62391,0,1,0-11.39689-6.56369c-.1964-.05575-.39413-.10218-.59054-.15262a6.63957,6.63957,0,1,0-13.10084,0c-.19641.05042-.39414.09687-.59055.15262a6.62767,6.62767,0,1,0-11.39689,6.56369,26.52755,26.52755,0,1,0,44.2313,25.52756,6.6211,6.6211,0,1,0,.848-13.18579" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M344.38682,555.65836h53.08286V529.11693H344.38682Z" transform="translate(-35.5 -118.5)" fill="#3ecc5f" fill-rule="evenodd" />
<path d="M410.74039,545.70532a3.31768,3.31768,0,1,0,0-6.63536,3.41133,3.41133,0,0,0-.42333.04247c-.02655-.09953-.04911-.19907-.077-.29859a3.319,3.319,0,0,0-1.278-6.37923,3.28174,3.28174,0,0,0-2.00122.68742q-.10947-.11346-.22294-.22295a3.282,3.282,0,0,0,.67149-1.98265,3.31768,3.31768,0,0,0-6.37-1.2992,13.27078,13.27078,0,1,0,0,25.54082,3.31768,3.31768,0,0,0,6.37-1.2992,3.282,3.282,0,0,0-.67149-1.98265q.11347-.10947.22294-.22294a3.28174,3.28174,0,0,0,2.00122.68742,3.31768,3.31768,0,0,0,1.278-6.37923c.02786-.0982.05042-.19907.077-.29859a3.41325,3.41325,0,0,0,.42333.04246" transform="translate(-35.5 -118.5)" fill="#44d860" fill-rule="evenodd" />
<path d="M424.01111,447.8338a3.60349,3.60349,0,0,1-.65028-.06636,3.34415,3.34415,0,0,1-.62372-.18579,3.44679,3.44679,0,0,1-.572-.30522,5.02708,5.02708,0,0,1-.50429-.4114,3.88726,3.88726,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.60248,3.60248,0,0,1,.06636-.65027,3.82638,3.82638,0,0,1,.18447-.62373,3.48858,3.48858,0,0,1,.30656-.57064,3.197,3.197,0,0,1,.91436-.91568,3.44685,3.44685,0,0,1,.572-.30523,3.344,3.344,0,0,1,.62372-.18578,3.06907,3.06907,0,0,1,1.30053,0,3.22332,3.22332,0,0,1,1.19436.491,5.02835,5.02835,0,0,1,.50429.41139,4.8801,4.8801,0,0,1,.41139.50429,3.38246,3.38246,0,0,1,.30522.57064,3.47806,3.47806,0,0,1,.25215,1.274A3.36394,3.36394,0,0,1,426.36,446.865a5.02708,5.02708,0,0,1-.50429.4114,3.3057,3.3057,0,0,1-1.84463.55737m26.54143-1.65884a3.38754,3.38754,0,0,1-2.35024-.96877,5.04185,5.04185,0,0,1-.41007-.50428,3.27532,3.27532,0,0,1-.55737-1.84463,3.38659,3.38659,0,0,1,.96744-2.34892,5.02559,5.02559,0,0,1,.50429-.41139,3.44685,3.44685,0,0,1,.572-.30523,3.3432,3.3432,0,0,1,.62373-.18579,3.06952,3.06952,0,0,1,1.30052,0,3.22356,3.22356,0,0,1,1.19436.491,5.02559,5.02559,0,0,1,.50429.41139,3.38792,3.38792,0,0,1,.96876,2.34892,3.72635,3.72635,0,0,1-.06636.65026,3.37387,3.37387,0,0,1-.18579.62373,4.71469,4.71469,0,0,1-.30522.57064,4.8801,4.8801,0,0,1-.41139.50429,5.02559,5.02559,0,0,1-.50429.41139,3.30547,3.30547,0,0,1-1.84463.55737" transform="translate(-35.5 -118.5)" fill-rule="evenodd" />
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -27,6 +27,11 @@ export interface MarkdownTableRow {
[key: string]: string;
}
export interface MarkdownTable {
header: MarkdownTableHeader[];
rows: MarkdownTableRow[];
}
const markdownUtils = {
// Titles for markdown links only need escaping for [ and ]
escapeTitleText(text: string) {

View File

@ -444,7 +444,7 @@ export default class Resource extends BaseItem {
await Note.save({
title: _('Attachment conflict: "%s"', resource.title),
body: _('There was a [conflict](%s) on the attachment below.\n\n%s', 'https://joplinapp.org/conflict/', Resource.markdownTag(conflictResource)),
body: _('There was a [conflict](%s) on the attachment below.\n\n%s', 'https://joplinapp.org/help/apps/conflict', Resource.markdownTag(conflictResource)),
parent_id: await this.resourceConflictFolderId(),
}, { changeSource: ItemChange.SOURCE_SYNC });
}

View File

@ -393,7 +393,7 @@ class Setting extends BaseModel {
wysiwygNo = ` ${_('(wysiwyg: %s)', _('no'))}`;
}
const emptyDirWarning = _('Attention: If you change this location, make sure you copy all your content to it before syncing, otherwise all files will be removed! See the FAQ for more details: %s', 'https://joplinapp.org/faq/');
const emptyDirWarning = _('Attention: If you change this location, make sure you copy all your content to it before syncing, otherwise all files will be removed! See the FAQ for more details: %s', 'https://joplinapp.org/help/faq');
// A "public" setting means that it will show up in the various config screens (or config command for the CLI tool), however
// if if private a setting might still be handled and modified by the app. For instance, the settings related to sorting notes are not
@ -1364,7 +1364,7 @@ class Setting extends BaseModel {
autoUpdateEnabled: { value: true, type: SettingItemType.Bool, storage: SettingStorage.File, isGlobal: true, section: 'application', public: platform !== 'linux', appTypes: [AppType.Desktop], label: () => _('Automatically check for updates') },
'autoUpdate.includePreReleases': { value: false, type: SettingItemType.Bool, section: 'application', storage: SettingStorage.File, isGlobal: true, public: true, appTypes: [AppType.Desktop], label: () => _('Get pre-releases when checking for updates'), description: () => _('See the pre-release page for more details: %s', 'https://joplinapp.org/prereleases') },
'autoUpdate.includePreReleases': { value: false, type: SettingItemType.Bool, section: 'application', storage: SettingStorage.File, isGlobal: true, public: true, appTypes: [AppType.Desktop], label: () => _('Get pre-releases when checking for updates'), description: () => _('See the pre-release page for more details: %s', 'https://joplinapp.org/help/about/prereleases') },
'clipperServer.autoStart': { value: false, type: SettingItemType.Bool, storage: SettingStorage.File, isGlobal: true, public: false },
'sync.interval': {
value: 300,

View File

@ -4,7 +4,7 @@ module.exports = {
{
"id": "8a1556e382704160808e9a7bef7135d3",
"title": "1. Welcome to Joplin!",
"body": "# Welcome to Joplin!\n\nJoplin is a free, open source note taking and to-do application, which helps you write and organise your notes, and synchronise them between your devices. The notes are searchable, can be copied, tagged and modified either from the application directly or from your own text editor. The notes are in [Markdown format](https://joplinapp.org/help/#markdown). Joplin is available as a **desktop**, **mobile** and **terminal** application.\n\nThe notes in this notebook give an overview of what Joplin can do and how to use it. In general, the three applications share roughly the same functionalities; any differences will be clearly indicated.\n\n![](./AllClients.png)\n\n## Joplin is divided into three parts\n\nJoplin has three main columns:\n\n- **Sidebar** contains the list of your notebooks and tags, as well as the synchronisation status.\n\n- **Note List** contains the current list of notes - either the notes in the currently selected notebook, the notes in the currently selected tag, or search results.\n\n- **Note Editor** is the place where you write your notes. There is a **Rich Text editor** and a **Markdown editor** - click on the **Toggle editor** button in the top right hand corner to switch between both! You may also use an [external editor](https://joplinapp.org/help/#external-text-editor) to edit notes. For example you can use Typora as an external editor and it will display the note as well as any embedded images.\n\n## Writing notes in Markdown\n\nMarkdown is a lightweight markup language with plain text formatting syntax. Joplin supports a [Github-flavoured Markdown syntax](https://joplinapp.org/markdown/) with a few variations and additions.\n\nIn general, while Markdown is a markup language, it is meant to be human readable, even without being rendered. This is a simple example (you can see how it looks in the viewer panel):\n\n* * *\n\n# Heading\n\n## Sub-heading\n\nParagraphs are separated by a blank line. Text attributes _italic_, **bold** and `monospace` are supported. You can create bullet lists:\n\n* apples\n* oranges\n* pears\n\nOr numbered lists:\n\n1. wash\n2. rinse\n3. repeat\n\nThis is a [link](https://joplinapp.org) and, finally, below is a horizontal rule:\n\n* * *\n\nA lot more is possible including adding code samples, math formulae or checkbox lists - see the [Markdown documentation](https://joplinapp.org/help/#markdown) for more information.\n\n## Organising your notes\n\n### With notebooks\n\nJoplin notes are organised into a tree of notebooks and sub-notebooks.\n\n- On **desktop**, you can create a notebook by clicking on New Notebook, then you can drag and drop them into other notebooks to organise them as you wish.\n- On **mobile**, press the \"+\" icon and select \"New notebook\".\n- On **terminal**, press `:mn`\n\n![](./SubNotebooks.png)\n\n### With tags\n\nThe second way to organise your notes is using tags:\n\n- On **desktop**, right-click on any note in the Note List, and select \"Edit tags\". You can then add the tags, separating them by commas.\n- On **mobile**, open the note and press the \"⋮\" button and select \"Tags\".\n- On **terminal**, type `:help tag` for the available commands.\n",
"body": "# Welcome to Joplin!\n\nJoplin is a free, open source note taking and to-do application, which helps you write and organise your notes, and synchronise them between your devices. The notes are searchable, can be copied, tagged and modified either from the application directly or from your own text editor. The notes are in [Markdown format](https://joplinapp.org/help/apps/markdown). Joplin is available as a **desktop**, **mobile** and **terminal** application.\n\nThe notes in this notebook give an overview of what Joplin can do and how to use it. In general, the three applications share roughly the same functionalities; any differences will be clearly indicated.\n\n![](./AllClients.png)\n\n## Joplin is divided into three parts\n\nJoplin has three main columns:\n\n- **Sidebar** contains the list of your notebooks and tags, as well as the synchronisation status.\n\n- **Note List** contains the current list of notes - either the notes in the currently selected notebook, the notes in the currently selected tag, or search results.\n\n- **Note Editor** is the place where you write your notes. There is a **Rich Text editor** and a **Markdown editor** - click on the **Toggle editor** button in the top right hand corner to switch between both! You may also use an [external editor](https://joplinapp.org/help/apps/external_text_editor) to edit notes. For example you can use Typora as an external editor and it will display the note as well as any embedded images.\n\n## Writing notes in Markdown\n\nMarkdown is a lightweight markup language with plain text formatting syntax. Joplin supports a [Github-flavoured Markdown syntax](https://joplinapp.org/help/apps/markdown) with a few variations and additions.\n\nIn general, while Markdown is a markup language, it is meant to be human readable, even without being rendered. This is a simple example (you can see how it looks in the viewer panel):\n\n* * *\n\n# Heading\n\n## Sub-heading\n\nParagraphs are separated by a blank line. Text attributes _italic_, **bold** and `monospace` are supported. You can create bullet lists:\n\n* apples\n* oranges\n* pears\n\nOr numbered lists:\n\n1. wash\n2. rinse\n3. repeat\n\nThis is a [link](https://joplinapp.org) and, finally, below is a horizontal rule:\n\n* * *\n\nA lot more is possible including adding code samples, math formulae or checkbox lists - see the [Markdown documentation](https://joplinapp.org/help/apps/markdown) for more information.\n\n## Organising your notes\n\n### With notebooks\n\nJoplin notes are organised into a tree of notebooks and sub-notebooks.\n\n- On **desktop**, you can create a notebook by clicking on New Notebook, then you can drag and drop them into other notebooks to organise them as you wish.\n- On **mobile**, press the \"+\" icon and select \"New notebook\".\n- On **terminal**, press `:mn`\n\n![](./SubNotebooks.png)\n\n### With tags\n\nThe second way to organise your notes is using tags:\n\n- On **desktop**, right-click on any note in the Note List, and select \"Edit tags\". You can then add the tags, separating them by commas.\n- On **mobile**, open the note and press the \"⋮\" button and select \"Tags\".\n- On **terminal**, type `:help tag` for the available commands.\n",
"resources": {
"./AllClients.png": {
"id": "5c05172554194f95b60971f6d577cc1a",
@ -20,21 +20,21 @@ module.exports = {
{
"id": "b863cbc514cb4cafbae8dd6a4fcad919",
"title": "2. Importing and exporting notes",
"body": "# Importing and exporting notes\n\n## Importing from Evernote\n\nJoplin can import complete Evernote notebooks, as well as notes, tags, images, attached files and note metadata (such as author, geo-location, etc.) via ENEX files.\n\nTo import Evernote data, first export your Evernote notebooks to ENEX files as described [here](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restore-import-notes-and-notebooks). Then, on **desktop**, do the following: Open File > Import > ENEX and select your file. The notes will be imported into a new separate notebook. If needed they can then be moved to a different notebook, or the notebook can be renamed, etc. Read [more about Evernote import](https://joplinapp.org/help/#importing-from-evernote).\n\n# Importing from other apps\n\nJoplin can also import notes from [many other apps](https://github.com/laurent22/joplin#importing-from-other-applications) as well as [from Markdown or text files](https://github.com/laurent22/joplin#importing-from-markdown-files).\n\n# Exporting notes\n\nJoplin can export to the JEX format (Joplin Export file), which is an archive that can contain multiple notes, notebooks, etc. This is a format mostly designed for backup purposes. You may also export to other formats such as plain Markdown files, to JSON or to PDF. Find out [more about exporting notes](https://github.com/laurent22/joplin#exporting) on the official website.",
"body": "# Importing and exporting notes\n\n## Importing from Evernote\n\nJoplin can import complete Evernote notebooks, as well as notes, tags, images, attached files and note metadata (such as author, geo-location, etc.) via ENEX files.\n\nTo import Evernote data, first export your Evernote notebooks to ENEX files as described [here](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restore-import-notes-and-notebooks). Then, on **desktop**, do the following: Open File > Import > ENEX and select your file. The notes will be imported into a new separate notebook. If needed they can then be moved to a different notebook, or the notebook can be renamed, etc. Read [more about Evernote import](https://joplinapp.org/help/apps/import_export#importing-from-evernote).\n\n# Importing from other apps\n\nJoplin can also import notes from [many other apps](https://joplinapp.org/help/apps/import_export#importing-from-other-applications) as well as [from Markdown or text files](https://joplinapp.org/help/apps/import_export#importing-from-markdown-files).\n\n# Exporting notes\n\nJoplin can export to the JEX format (Joplin Export file), which is an archive that can contain multiple notes, notebooks, etc. This is a format mostly designed for backup purposes. You may also export to other formats such as plain Markdown files, to JSON or to PDF. Find out [more about exporting notes](https://joplinapp.org/help/apps/import_export#exporting) on the official website.",
"resources": {},
"parent_id": "9bb5d498aba74cc6a047cfdc841e82a1"
},
{
"id": "25b656aac0564d1a91ab98295aa3cc58",
"title": "3. Synchronising your notes",
"body": "# Synchronising your notes\n\nJoplin allows you to synchronise your data using various file hosting services. The supported cloud services are the following:\n\n## Setting up Joplin Cloud synchronisation\n\n[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.\n\nTo use it, go to the config screen, then to the Synchronisation section. In the list of sync target, select \"Joplin Cloud\". Enter your email and password, and you're ready to use Joplin Cloud.\n\n## Setting up Dropbox synchronisation\n\nSelect \"Dropbox\" as the synchronisation target in the config screen. Then, to initiate the synchronisation process, click on the \"Synchronise\" button in the sidebar and follow the instructions.\n\n## Setting up Nextcloud synchronisation\n\nNextcloud is a self-hosted, private cloud solution. To set it up, go to the config screen and select Nextcloud as the synchronisation target. Then input the WebDAV URL (to get it, go to your Nextcloud page, click on Settings in the bottom left corner of the page and copy the URL). Note that it has to be the **full URL**, so for example if you want the notes to be under `/Joplin`, the URL would be something like `https://example.com/remote.php/webdav/Joplin` (note that \"/Joplin\" part). And **make sure to create the \"/Joplin\" directory in Nextcloud**. Finally set the username and password. If it does not work, please [see this explanation](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) for more details.\n\n## Setting up OneDrive or WebDAV synchronisation\n\nOneDrive and WebDAV are also supported as synchronisation services. Please see [the synchronisation documentation](https://github.com/laurent22/joplin#synchronisation) for more information.\n\n## Using End-To-End Encryption\n\nJoplin supports end-to-end encryption (E2EE) on all the applications. E2EE is a system where only the owner of the data can read it. It prevents potential eavesdroppers - including telecom providers, internet providers, and even the developers of Joplin from being able to access the data. Please see the [End-To-End Encryption Tutorial](https://joplinapp.org/e2ee/) for more information about this feature and how to enable it.\n",
"body": "# Synchronising your notes\n\nJoplin allows you to synchronise your data using various file hosting services. The supported cloud services are the following:\n\n## Setting up Joplin Cloud synchronisation\n\n[Joplin Cloud](https://joplinapp.org/plans/) is a web service specifically designed for Joplin. Besides synchronising your data, it also allows you to publish a note to the internet, or share a notebook with your friends, family or colleagues. Joplin Cloud, compared to other services, also features a number of performance improvements allowing for faster synchronisation.\n\nTo use it, go to the config screen, then to the Synchronisation section. In the list of sync target, select \"Joplin Cloud\". Enter your email and password, and you're ready to use Joplin Cloud.\n\n## Setting up Dropbox synchronisation\n\nSelect \"Dropbox\" as the synchronisation target in the config screen. Then, to initiate the synchronisation process, click on the \"Synchronise\" button in the sidebar and follow the instructions.\n\n## Setting up Nextcloud synchronisation\n\nNextcloud is a self-hosted, private cloud solution. To set it up, go to the config screen and select Nextcloud as the synchronisation target. Then input the WebDAV URL (to get it, go to your Nextcloud page, click on Settings in the bottom left corner of the page and copy the URL). Note that it has to be the **full URL**, so for example if you want the notes to be under `/Joplin`, the URL would be something like `https://example.com/remote.php/webdav/Joplin` (note that \"/Joplin\" part). And **make sure to create the \"/Joplin\" directory in Nextcloud**. Finally set the username and password. If it does not work, please [see this explanation](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) for more details.\n\n## Setting up OneDrive or WebDAV synchronisation\n\nOneDrive and WebDAV are also supported as synchronisation services. Please see [the synchronisation documentation](https://github.com/laurent22/joplin#synchronisation) for more information.\n\n## Using End-To-End Encryption\n\nJoplin supports end-to-end encryption (E2EE) on all the applications. E2EE is a system where only the owner of the data can read it. It prevents potential eavesdroppers - including telecom providers, internet providers, and even the developers of Joplin from being able to access the data. Please see the [End-To-End Encryption Tutorial](https://joplinapp.org/help/apps/sync/e2ee) for more information about this feature and how to enable it.\n",
"resources": {},
"parent_id": "9bb5d498aba74cc6a047cfdc841e82a1"
},
{
"id": "2ee48f80889447429a3cccb04a466072",
"title": "4. Tips",
"body": "# Tips\n\nThe first few notes should have given you an overview of the main functionalities of Joplin, but there's more it can do. See below for some of these features and how to get more help using the app:\n\n## Web clipper\n\n![](./WebClipper.png)\n\nThe Web Clipper is a browser extension that allows you to save web pages and screenshots from your browser. To start using it, open the Joplin desktop application, go to the Web Clipper Options and follow the instructions.\n\nMore info on the official website: https://joplinapp.org/clipper/\n\n## Plugins\n\nJoplin supports many plugins that allows you to add new features to the app, such as tabs, a table of content for your notes, a way to manage favourite notes, and many other ones. To add a plugin, go to the \"Plugins\" section in the config screen. From there you can search and install plugins, as well as search or update plugins.\n\n## Attachments\n\nAny kind of file can be attached to a note. In Markdown, links to these files are represented as an ID. In the note viewer, these files, if they are images, will be displayed or, if they are other files (PDF, text files, etc.) they will be displayed as links. Clicking on this link will open the file in the default application.\n\nImages can be attached either by clicking on \"Attach file\" or by pasting (with `Ctrl+V` or `Cmd+V`) an image directly in the editor, or by drag and dropping an image.\n\nMore info about attachments: https://joplinapp.org/help/#attachments\n\n## Search\n\nJoplin supports advanced search queries, which are fully documented on the official website: https://joplinapp.org/help/#searching\n\n## Alarms\n\nAn alarm can be associated with any to-do. It will be triggered at the given time by displaying a notification. To use this feature, see the documentation: https://joplinapp.org/help/#notifications\n\n## Markdown advanced tips\n\nJoplin uses and renders [Github-flavoured Markdown](https://joplinapp.org/markdown/) with a few variations and additions.\n\nFor example, tables are supported:\n\n| Tables | Are | Cool |\n| ------------- |:-------------:| -----:|\n| col 3 is | right-aligned | $1600 |\n| col 2 is | centered | $12 |\n| zebra stripes | are neat | $1 |\n\nYou can also create lists of checkboxes. These checkboxes can be ticked directly in the viewer, or by adding an \"x\" inside:\n\n- [ ] Milk\n- [ ] Eggs\n- [x] Beer\n\nMath expressions can be added using the [KaTeX notation](https://khan.github.io/KaTeX/):\n\n$$\nf(x) = \\int_{-\\infty}^\\infty\n \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n \\,d\\xi\n$$\n\nVarious other tricks are possible, such as using HTML, or customising the CSS. See the Markdown documentation for more info - https://joplinapp.org/markdown/\n\n## Community and further help\n\n- For general discussion about Joplin, user support, software development questions, and to discuss new features, go to the [Joplin Forum](https://discourse.joplinapp.org/). It is possible to login with your GitHub account.\n- The latest news are posted [on the Patreon page](https://www.patreon.com/joplin).\n- For bug reports and feature requests, go to the [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues).\n\n## Donations\n\nDonations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.\n\nPlease see the [donation page](https://joplinapp.org/donate/) for information on how to support the development of Joplin.",
"body": "# Tips\n\nThe first few notes should have given you an overview of the main functionalities of Joplin, but there's more it can do. See below for some of these features and how to get more help using the app:\n\n## Web clipper\n\n![](./WebClipper.png)\n\nThe Web Clipper is a browser extension that allows you to save web pages and screenshots from your browser. To start using it, open the Joplin desktop application, go to the Web Clipper Options and follow the instructions.\n\nMore info on the official website: https://joplinapp.org/help/apps/clipper\n\n## Plugins\n\nJoplin supports many plugins that allows you to add new features to the app, such as tabs, a table of content for your notes, a way to manage favourite notes, and many other ones. To add a plugin, go to the \"Plugins\" section in the config screen. From there you can search and install plugins, as well as search or update plugins.\n\n## Attachments\n\nAny kind of file can be attached to a note. In Markdown, links to these files are represented as an ID. In the note viewer, these files, if they are images, will be displayed or, if they are other files (PDF, text files, etc.) they will be displayed as links. Clicking on this link will open the file in the default application.\n\nImages can be attached either by clicking on \"Attach file\" or by pasting (with `Ctrl+V` or `Cmd+V`) an image directly in the editor, or by drag and dropping an image.\n\nMore info about attachments: https://joplinapp.org/help/apps/attachments\n\n## Search\n\nJoplin supports advanced search queries, which are fully documented on the official website: https://joplinapp.org/help/apps/search\n\n## Alarms\n\nAn alarm can be associated with any to-do. It will be triggered at the given time by displaying a notification. To use this feature, see the documentation: https://joplinapp.org/help/apps/notifications\n\n## Markdown advanced tips\n\nJoplin uses and renders [Github-flavoured Markdown](https://joplinapp.org/help/apps/markdown) with a few variations and additions.\n\nFor example, tables are supported:\n\n| Tables | Are | Cool |\n| ------------- |:-------------:| -----:|\n| col 3 is | right-aligned | $1600 |\n| col 2 is | centered | $12 |\n| zebra stripes | are neat | $1 |\n\nYou can also create lists of checkboxes. These checkboxes can be ticked directly in the viewer, or by adding an \"x\" inside:\n\n- [ ] Milk\n- [ ] Eggs\n- [x] Beer\n\nMath expressions can be added using the [KaTeX notation](https://khan.github.io/KaTeX/):\n\n$$\nf(x) = \\int_{-\\infty}^\\infty\n \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n \\,d\\xi\n$$\n\nVarious other tricks are possible, such as using HTML, or customising the CSS. See the Markdown documentation for more info - https://joplinapp.org/help/apps/markdown\n\n## Community and further help\n\n- For general discussion about Joplin, user support, software development questions, and to discuss new features, go to the [Joplin Forum](https://discourse.joplinapp.org/). It is possible to login with your GitHub account.\n- The latest news are posted [on the Patreon page](https://www.patreon.com/joplin).\n- For bug reports and feature requests, go to the [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues).\n\n## Donations\n\nDonations to Joplin support the development of the project. Developing quality applications mostly takes time, but there are also some expenses, such as digital certificates to sign the applications, app store fees, hosting, etc. Most of all, your donation will make it possible to keep up the current development standard.\n\nPlease see the [donation page](https://joplinapp.org/donate/) for information on how to support the development of Joplin.",
"resources": {
"./WebClipper.png": {
"id": "30cf9214f5054c4da3b23eed7211a6e0",
@ -64,28 +64,28 @@ module.exports = {
{
"id": "223a99e0dad4c8882988f446815ea28c",
"title": "1. Bienvenue dans Joplin !",
"body": "# Bienvenue dans Joplin !\n\nJoplin est une application gratuite et open source de prise de notes, qui vous aide à rédiger et à organiser vos notes, et à les synchroniser entre vos appareils. Les notes sont consultables, peuvent être copiées, étiquetées et modifiées directement depuis l'application ou depuis votre propre éditeur de texte. Les notes sont au [format Markdown](https://joplinapp.org/help/#markdown). Joplin est disponible en tant qu'application de **bureau**, **mobile** et **terminal**.\n\nLes notes de ce carnet donnent un aperçu de ce que Joplin peut faire et comment l'utiliser. En général, les trois applications partagent à peu près les mêmes fonctionnalités ; toute différence sera clairement indiquée.\n\n![](./AllClients.png)\n\n## Joplin est divisé en trois parties\n\nJoplin a trois colonnes principales :\n\n- La **barre latérale** contient la liste de vos carnets et étiquettes, ainsi que l'état de la synchronisation.\n\n- La **liste de notes** contient la liste actuelle des notes - soit les notes du bloc-notes actuellement sélectionné, les notes de l'étiquette actuellement sélectionnée ou les résultats de la recherche.\n\n- L'**éditeur de notes** est là où vous écrivez vos notes. Il existe un **éditeur de texte enrichi** et un **éditeur Markdown** - cliquez sur le bouton **Basculer l'éditeur** dans le coin supérieur droit pour basculer entre les deux ! Vous pouvez également utiliser un [éditeur externe](https://joplinapp.org/help/#external-text-editor) pour modifier les notes. Par exemple, vous pouvez utiliser Typora comme éditeur externe et il affichera la note ainsi que toutes les images intégrées.\n\n## Écrire des notes en Markdown\n\nMarkdown est un langage de balisage léger. Joplin prend en charge une [syntaxe Markdown à saveur Github](https://joplinapp.org/markdown/) avec quelques variantes et ajouts.\n\nEn général, bien que Markdown soit un langage de balisage, il lisible directement. Ceci est un exemple simple (vous pouvez voir à quoi il ressemble dans le panneau de visualisation) :\n\n* * *\n\n# En-tête\n\n## Sous-titre\n\nLes paragraphes sont séparés par une ligne blanche. Les attributs de texte _italique_, **gras** et `monospace` sont pris en charge. Vous pouvez créer des listes à puces :\n\n* pommes\n* des oranges\n* des poires\n\nOu des listes numérotées :\n\n1. laver\n2. rincer\n3. répéter\n\nCeci est un [lien](https://joplinapp.org) et, enfin, ci-dessous est une règle horizontale :\n\n* * *\n\nBeaucoup plus est possible, y compris l'ajout d'exemples de code informatique, de formules mathématiques ou de listes de cases à cocher - voir la [documentation Markdown](https://joplinapp.org/help/#markdown) pour plus d'informations.\n\n## Organiser vos notes\n\n### Avec des carnets\n\nLes notes de Joplin sont organisées en une arborescence de carnets et de sous-carnets.\n\n- Sur l'appli de **bureau**, vous pouvez créer un carnet en cliquant sur \"Nouveau carnet\", puis vous pouvez les faire glisser et les déposer dans d'autres carnets pour les organiser comme vous le souhaitez.\n- Sur **mobile**, appuyez sur l'icône \"+\" et sélectionnez \"Nouveau carnet\".\n- Sur le **terminal**, appuyez sur `:mn`\n\n![](./SubNotebooks.png)\n\n### Avec des étiquettes\n\nLa deuxième façon d'organiser vos notes consiste à utiliser des étiquettes :\n\n- Sur **bureau**, faites un clic droit sur n'importe quelle note dans la liste des notes et sélectionnez \"Modifier les étiquettes\". Vous pouvez ensuite ajouter les étiquettes en les séparant par des virgules.\n- Sur **mobile**, ouvrez la note et appuyez sur le bouton \"⋮\" et sélectionnez \"étiquettes\".\n- Sur le **terminal**, tapez `:help tag` pour les commandes disponibles.\n",
"body": "# Bienvenue dans Joplin !\n\nJoplin est une application gratuite et open source de prise de notes, qui vous aide à rédiger et à organiser vos notes, et à les synchroniser entre vos appareils. Les notes sont consultables, peuvent être copiées, étiquetées et modifiées directement depuis l'application ou depuis votre propre éditeur de texte. Les notes sont au [format Markdown](https://joplinapp.org/help/apps/markdown). Joplin est disponible en tant qu'application de **bureau**, **mobile** et **terminal**.\n\nLes notes de ce carnet donnent un aperçu de ce que Joplin peut faire et comment l'utiliser. En général, les trois applications partagent à peu près les mêmes fonctionnalités ; toute différence sera clairement indiquée.\n\n![](./AllClients.png)\n\n## Joplin est divisé en trois parties\n\nJoplin a trois colonnes principales :\n\n- La **barre latérale** contient la liste de vos carnets et étiquettes, ainsi que l'état de la synchronisation.\n\n- La **liste de notes** contient la liste actuelle des notes - soit les notes du bloc-notes actuellement sélectionné, les notes de l'étiquette actuellement sélectionnée ou les résultats de la recherche.\n\n- L'**éditeur de notes** est là où vous écrivez vos notes. Il existe un **éditeur de texte enrichi** et un **éditeur Markdown** - cliquez sur le bouton **Basculer l'éditeur** dans le coin supérieur droit pour basculer entre les deux ! Vous pouvez également utiliser un [éditeur externe](https://joplinapp.org/help/apps/external_text_editor) pour modifier les notes. Par exemple, vous pouvez utiliser Typora comme éditeur externe et il affichera la note ainsi que toutes les images intégrées.\n\n## Écrire des notes en Markdown\n\nMarkdown est un langage de balisage léger. Joplin prend en charge une [syntaxe Markdown à saveur Github](https://joplinapp.org/help/apps/markdown) avec quelques variantes et ajouts.\n\nEn général, bien que Markdown soit un langage de balisage, il lisible directement. Ceci est un exemple simple (vous pouvez voir à quoi il ressemble dans le panneau de visualisation) :\n\n* * *\n\n# En-tête\n\n## Sous-titre\n\nLes paragraphes sont séparés par une ligne blanche. Les attributs de texte _italique_, **gras** et `monospace` sont pris en charge. Vous pouvez créer des listes à puces :\n\n* pommes\n* des oranges\n* des poires\n\nOu des listes numérotées :\n\n1. laver\n2. rincer\n3. répéter\n\nCeci est un [lien](https://joplinapp.org) et, enfin, ci-dessous est une règle horizontale :\n\n* * *\n\nBeaucoup plus est possible, y compris l'ajout d'exemples de code informatique, de formules mathématiques ou de listes de cases à cocher - voir la [documentation Markdown](https://joplinapp.org/help/apps/markdown) pour plus d'informations.\n\n## Organiser vos notes\n\n### Avec des carnets\n\nLes notes de Joplin sont organisées en une arborescence de carnets et de sous-carnets.\n\n- Sur l'appli de **bureau**, vous pouvez créer un carnet en cliquant sur \"Nouveau carnet\", puis vous pouvez les faire glisser et les déposer dans d'autres carnets pour les organiser comme vous le souhaitez.\n- Sur **mobile**, appuyez sur l'icône \"+\" et sélectionnez \"Nouveau carnet\".\n- Sur le **terminal**, appuyez sur `:mn`\n\n![](./SubNotebooks.png)\n\n### Avec des étiquettes\n\nLa deuxième façon d'organiser vos notes consiste à utiliser des étiquettes :\n\n- Sur **bureau**, faites un clic droit sur n'importe quelle note dans la liste des notes et sélectionnez \"Modifier les étiquettes\". Vous pouvez ensuite ajouter les étiquettes en les séparant par des virgules.\n- Sur **mobile**, ouvrez la note et appuyez sur le bouton \"⋮\" et sélectionnez \"étiquettes\".\n- Sur le **terminal**, tapez `:help tag` pour les commandes disponibles.\n",
"resources": {},
"parent_id": "5494e8c3dcfc84c1549ed22fb3a89265"
},
{
"id": "21648b1b1b541e7bb87cff262bcc6b54",
"title": "2. Importer et exporter des notes",
"body": "# Importer et exporter des notes\n\n## Importation depuis Evernote\n\nJoplin peut importer des carnets complets depuis Evernote, ainsi que des notes, des étiquettes, des images, des fichiers joints et des métadonnées de note (telles que l'auteur, la géolocalisation, etc.) via des fichiers ENEX.\n\nPour importer des données Evernote, exportez d'abord vos carnets Evernote vers des fichiers ENEX comme décrit [ici](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restaurer-importer-notes-et-carnets). Ensuite, sur **bureau**, procédez comme suit : Ouvrez Fichier > Importer > ENEX et sélectionnez votre fichier. Les notes seront importées dans un nouveau cahier séparé. Si nécessaire, ils peuvent ensuite être déplacés vers un autre carnet, ou le carnet peut être renommé, etc. [En savoir plus sur l'importation Evernote](https://joplinapp.org/help/#importing-from-evernote).\n\n# Importation à partir d'autres applications\n\nJoplin peut également importer des notes depuis [de nombreuses autres applications](https://github.com/laurent22/joplin#importing-from-other-applications) ainsi que [depuis Markdown ou depuis des fichiers texte](https://github.com/laurent22/joplin#importing-from-markdown-files).\n\n# Exporter des notes\n\nJoplin peut exporter au format JEX (fichier d'exportation Joplin), qui est une archive pouvant contenir plusieurs notes, cahiers, etc. Il s'agit d'un format principalement conçu à des fins de sauvegarde. Vous pouvez également exporter vers d'autres formats tels que des fichiers Markdown simples, vers JSON ou vers PDF. Découvrez [l'exportation de notes](https://github.com/laurent22/joplin#exporting) sur le site officiel.",
"body": "# Importer et exporter des notes\n\n## Importation depuis Evernote\n\nJoplin peut importer des carnets complets depuis Evernote, ainsi que des notes, des étiquettes, des images, des fichiers joints et des métadonnées de note (telles que l'auteur, la géolocalisation, etc.) via des fichiers ENEX.\n\nPour importer des données Evernote, exportez d'abord vos carnets Evernote vers des fichiers ENEX comme décrit [ici](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restaurer-importer-notes-et-carnets). Ensuite, sur **bureau**, procédez comme suit : Ouvrez Fichier > Importer > ENEX et sélectionnez votre fichier. Les notes seront importées dans un nouveau cahier séparé. Si nécessaire, ils peuvent ensuite être déplacés vers un autre carnet, ou le carnet peut être renommé, etc. [En savoir plus sur l'importation Evernote](https://joplinapp.org/help/apps/import_export#importing-from-evernote).\n\n# Importation à partir d'autres applications\n\nJoplin peut également importer des notes depuis [de nombreuses autres applications](https://joplinapp.org/help/apps/import_export#importing-from-other-applications) ainsi que [depuis Markdown ou depuis des fichiers texte](https://joplinapp.org/help/apps/import_export#importing-from-markdown-files).\n\n# Exporter des notes\n\nJoplin peut exporter au format JEX (fichier d'exportation Joplin), qui est une archive pouvant contenir plusieurs notes, cahiers, etc. Il s'agit d'un format principalement conçu à des fins de sauvegarde. Vous pouvez également exporter vers d'autres formats tels que des fichiers Markdown simples, vers JSON ou vers PDF. Découvrez [l'exportation de notes](https://joplinapp.org/help/apps/import_export#exporting) sur le site officiel.",
"resources": {},
"parent_id": "5494e8c3dcfc84c1549ed22fb3a89265"
},
{
"id": "3adfa574c0264f68f4c33c4133e734fb",
"title": "3. Synchroniser vos notes",
"body": "# Synchroniser vos notes\n\nJoplin vous permet de synchroniser vos données à l'aide de divers services d'hébergement de fichiers. Les services cloud pris en charge sont les suivants :\n\n## Configuration de la synchronisation Joplin Cloud\n\n[Joplin Cloud](https://joplinapp.org/plans/) est un service Web spécialement conçu pour Joplin. Outre la synchronisation de vos données, il vous permet également de publier une note sur Internet ou de partager un carnet avec vos amis, votre famille ou vos collègues. Joplin Cloud, par rapport à d'autres services, présente également un certain nombre d'améliorations des performances permettant une synchronisation plus rapide.\n\nPour l'utiliser, rendez-vous dans l'écran de configuration, puis dans la rubrique Synchronisation. Dans la liste des cibles de synchronisation, sélectionnez \"Joplin Cloud\". Entrez votre e-mail et votre mot de passe, et vous êtes prêt à utiliser Joplin Cloud.\n\n## Configuration de la synchronisation Dropbox\n\nSélectionnez \"Dropbox\" comme cible de synchronisation dans l'écran de configuration. Ensuite, pour lancer le processus de synchronisation, cliquez sur le bouton \"Synchroniser\" dans la barre latérale et suivez les instructions.\n\n## Configuration de la synchronisation Nextcloud\n\nNextcloud est une solution de cloud pouvant être auto-hébergée. Pour le configurer, accédez à l'écran de configuration et sélectionnez Nextcloud comme cible de synchronisation. Saisissez ensuite l'URL WebDAV (pour l'obtenir, rendez-vous sur votre page Nextcloud, cliquez sur Paramètres dans le coin inférieur gauche de la page et copiez l'URL). Notez qu'il doit s'agir de l'**URL complète**, donc par exemple si vous voulez que les notes soient sous `/Joplin`, l'URL serait quelque chose comme `https://example.com/remote.php/webdav /Joplin` (notez que la partie \"/Joplin\"). Et **assurez-vous de créer le répertoire \"/Joplin\" dans Nextcloud**. Définissez enfin le nom d'utilisateur et le mot de passe. Si cela ne fonctionne pas, veuillez [voir cette explication](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) pour plus de détails.\n\n## Configuration de la synchronisation OneDrive ou WebDAV\n\nOneDrive et WebDAV sont également pris en charge en tant que services de synchronisation. Veuillez consulter [la documentation de synchronisation](https://github.com/laurent22/joplin#synchronisation) pour plus d'informations.\n\n## Utilisation du chiffrement de bout en bout\n\nJoplin prend en charge le chiffrement de bout en bout (E2EE) sur toutes les applications. E2EE est un système où seul le propriétaire des données peut les lire. Il empêche les espions potentiels, y compris les fournisseurs de télécommunications, les fournisseurs d'accès Internet et même les développeurs de Joplin, d'accéder aux données. Veuillez consulter le [tutoriel sur le chiffrement de bout en bout](https://joplinapp.org/e2ee/) pour plus d'informations sur cette fonctionnalité et comment l'activer.",
"body": "# Synchroniser vos notes\n\nJoplin vous permet de synchroniser vos données à l'aide de divers services d'hébergement de fichiers. Les services cloud pris en charge sont les suivants :\n\n## Configuration de la synchronisation Joplin Cloud\n\n[Joplin Cloud](https://joplinapp.org/plans/) est un service Web spécialement conçu pour Joplin. Outre la synchronisation de vos données, il vous permet également de publier une note sur Internet ou de partager un carnet avec vos amis, votre famille ou vos collègues. Joplin Cloud, par rapport à d'autres services, présente également un certain nombre d'améliorations des performances permettant une synchronisation plus rapide.\n\nPour l'utiliser, rendez-vous dans l'écran de configuration, puis dans la rubrique Synchronisation. Dans la liste des cibles de synchronisation, sélectionnez \"Joplin Cloud\". Entrez votre e-mail et votre mot de passe, et vous êtes prêt à utiliser Joplin Cloud.\n\n## Configuration de la synchronisation Dropbox\n\nSélectionnez \"Dropbox\" comme cible de synchronisation dans l'écran de configuration. Ensuite, pour lancer le processus de synchronisation, cliquez sur le bouton \"Synchroniser\" dans la barre latérale et suivez les instructions.\n\n## Configuration de la synchronisation Nextcloud\n\nNextcloud est une solution de cloud pouvant être auto-hébergée. Pour le configurer, accédez à l'écran de configuration et sélectionnez Nextcloud comme cible de synchronisation. Saisissez ensuite l'URL WebDAV (pour l'obtenir, rendez-vous sur votre page Nextcloud, cliquez sur Paramètres dans le coin inférieur gauche de la page et copiez l'URL). Notez qu'il doit s'agir de l'**URL complète**, donc par exemple si vous voulez que les notes soient sous `/Joplin`, l'URL serait quelque chose comme `https://example.com/remote.php/webdav /Joplin` (notez que la partie \"/Joplin\"). Et **assurez-vous de créer le répertoire \"/Joplin\" dans Nextcloud**. Définissez enfin le nom d'utilisateur et le mot de passe. Si cela ne fonctionne pas, veuillez [voir cette explication](https://github.com/laurent22/joplin/issues/61#issuecomment-373282608) pour plus de détails.\n\n## Configuration de la synchronisation OneDrive ou WebDAV\n\nOneDrive et WebDAV sont également pris en charge en tant que services de synchronisation. Veuillez consulter [la documentation de synchronisation](https://joplinapp.org/help/apps/sync/) pour plus d'informations.\n\n## Utilisation du chiffrement de bout en bout\n\nJoplin prend en charge le chiffrement de bout en bout (E2EE) sur toutes les applications. E2EE est un système où seul le propriétaire des données peut les lire. Il empêche les espions potentiels, y compris les fournisseurs de télécommunications, les fournisseurs d'accès Internet et même les développeurs de Joplin, d'accéder aux données. Veuillez consulter le [tutoriel sur le chiffrement de bout en bout](https://joplinapp.org/help/apps/sync/e2ee) pour plus d'informations sur cette fonctionnalité et comment l'activer.",
"resources": {},
"parent_id": "5494e8c3dcfc84c1549ed22fb3a89265"
},
{
"id": "4d0ffc5beb024e6c498129ad814d156e",
"title": "4. Trucs & Astuces",
"body": "# Trucs & Astuces\n\nLes premières notes vous ont donné un aperçu des principales fonctionnalités de Joplin, mais il peut faire plus. Voir ci-dessous pour certaines de ces fonctionnalités et comment obtenir plus d'aide en utilisant l'application :\n\n## Web Clipper\n\n![](./WebClipper.png)\n\nLe Web Clipper est une extension de navigateur qui vous permet d'enregistrer des pages Web et des captures d'écran à partir de votre navigateur. Pour commencer à l'utiliser, ouvrez l'application de bureau Joplin, accédez aux options du Web Clipper et suivez les instructions.\n\nPlus d'infos sur le site officiel : https://joplinapp.org/clipper/\n\n## Plugins\n\nJoplin prend en charge de nombreux plugins qui vous permettent d'ajouter de nouvelles fonctionnalités à l'application, telles que des onglets, une table des matières pour vos notes, un moyen de gérer les notes préférées et bien d'autres. Pour ajouter un plugin, rendez-vous dans la section \"Plugins\" de l'écran de configuration. À partir de là, vous pouvez rechercher et installer des plugins, ainsi que rechercher ou mettre à jour des plugins.\n\n## Pièces jointes\n\nTout type de fichier peut être joint à une note. Dans Markdown, les liens vers ces fichiers sont représentés par un ID. Dans le visualiseur de notes, ces fichiers, s'il s'agit d'images, seront affichés ou, s'il s'agit d'autres fichiers (PDF, fichiers texte, etc.), ils seront affichés sous forme de liens. Cliquer sur ce lien ouvrira le fichier dans l'application par défaut.\n\nLes images peuvent être jointes soit en cliquant sur \"Joindre un fichier\", soit en collant (avec `Ctrl+V` ou `Cmd+V`) une image directement dans l'éditeur, soit en glissant-déposant une image.\n\nPlus d'infos sur les pièces jointes : https://joplinapp.org/help/#attachments\n\n## Recherche\n\nJoplin prend en charge les requêtes de recherche avancées, qui sont entièrement documentées sur le site officiel : https://joplinapp.org/help/#searching\n\n## Alarmes\n\nUne alarme peut être associée à n'importe quelle tâche. Elle sera déclenchée à l'heure indiquée par l'affichage d'une notification. Pour utiliser cette fonctionnalité, consultez la documentation : https://joplinapp.org/help/#notifications\n\n## Conseils avancés Markdown\n\nJoplin utilise et rend [Github-flavored Markdown](https://joplinapp.org/markdown/) avec quelques variations et ajouts.\n\nPar exemple, les tableaux sont pris en charge :\n\n| Les tableaux | Sont | Cools |\n| ------------- |:-------------:| -----:|\n| col 3 est | alignée à droite | $1600 |\n| col 2 est | centrée | $12 |\n\nVous pouvez également créer des listes de cases à cocher. Ces cases peuvent être cochées directement dans le visualiseur, ou en ajoutant un \"x\" à l'intérieur :\n\n- [ ] Lait\n- [ ] Œufs\n- [x] Bière\n\nDes expressions mathématiques peuvent être ajoutées à l'aide de la [notation KaTeX](https://khan.github.io/KaTeX/) :\n\n$$\nf(x) = \\int_{-\\infty}^\\infty\n \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n \\,d\\xi\n$$\n\nDiverses autres astuces sont possibles, telles que l'utilisation de HTML ou la personnalisation du CSS. Voir la documentation Markdown pour plus d'informations - https://joplinapp.org/markdown/\n\n## Communauté et aide supplémentaire\n\n- Pour une discussion générale sur Joplin, l'assistance aux utilisateurs, les questions de développement logiciel et pour discuter des nouvelles fonctionnalités, rendez-vous sur le [Forum Joplin](https://discourse.joplinapp.org/). Il est possible de se connecter avec votre compte GitHub.\n- Les dernières nouvelles sont publiées [sur la page Patreon](https://www.patreon.com/joplin).\n- Pour les rapports de bugs et les demandes de fonctionnalités, accédez au [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues).\n\n## Donations\n\nLes dons à Joplin soutiennent le développement du projet. Développer des applications de qualité prend généralement du temps, mais il y a aussi des dépenses, comme les certificats numériques pour signer les applications, les frais d'app store, l'hébergement, etc. Surtout, votre don permettra de maintenir le standard de développement actuel.\n\nVeuillez consulter la [page de don](https://joplinapp.org/donate/) pour savoir comment soutenir le développement de Joplin.",
"body": "# Trucs & Astuces\n\nLes premières notes vous ont donné un aperçu des principales fonctionnalités de Joplin, mais il peut faire plus. Voir ci-dessous pour certaines de ces fonctionnalités et comment obtenir plus d'aide en utilisant l'application :\n\n## Web Clipper\n\n![](./WebClipper.png)\n\nLe Web Clipper est une extension de navigateur qui vous permet d'enregistrer des pages Web et des captures d'écran à partir de votre navigateur. Pour commencer à l'utiliser, ouvrez l'application de bureau Joplin, accédez aux options du Web Clipper et suivez les instructions.\n\nPlus d'infos sur le site officiel : https://joplinapp.org/help/apps/clipper/\n\n## Plugins\n\nJoplin prend en charge de nombreux plugins qui vous permettent d'ajouter de nouvelles fonctionnalités à l'application, telles que des onglets, une table des matières pour vos notes, un moyen de gérer les notes préférées et bien d'autres. Pour ajouter un plugin, rendez-vous dans la section \"Plugins\" de l'écran de configuration. À partir de là, vous pouvez rechercher et installer des plugins, ainsi que rechercher ou mettre à jour des plugins.\n\n## Pièces jointes\n\nTout type de fichier peut être joint à une note. Dans Markdown, les liens vers ces fichiers sont représentés par un ID. Dans le visualiseur de notes, ces fichiers, s'il s'agit d'images, seront affichés ou, s'il s'agit d'autres fichiers (PDF, fichiers texte, etc.), ils seront affichés sous forme de liens. Cliquer sur ce lien ouvrira le fichier dans l'application par défaut.\n\nLes images peuvent être jointes soit en cliquant sur \"Joindre un fichier\", soit en collant (avec `Ctrl+V` ou `Cmd+V`) une image directement dans l'éditeur, soit en glissant-déposant une image.\n\nPlus d'infos sur les pièces jointes : https://joplinapp.org/help/apps/attachments\n\n## Recherche\n\nJoplin prend en charge les requêtes de recherche avancées, qui sont entièrement documentées sur le site officiel : https://joplinapp.org/help/apps/search\n\n## Alarmes\n\nUne alarme peut être associée à n'importe quelle tâche. Elle sera déclenchée à l'heure indiquée par l'affichage d'une notification. Pour utiliser cette fonctionnalité, consultez la documentation : https://joplinapp.org/help/apps/notifications\n\n## Conseils avancés Markdown\n\nJoplin utilise et rend [Github-flavored Markdown](https://joplinapp.org/help/apps/markdown) avec quelques variations et ajouts.\n\nPar exemple, les tableaux sont pris en charge :\n\n| Les tableaux | Sont | Cools |\n| ------------- |:-------------:| -----:|\n| col 3 est | alignée à droite | $1600 |\n| col 2 est | centrée | $12 |\n\nVous pouvez également créer des listes de cases à cocher. Ces cases peuvent être cochées directement dans le visualiseur, ou en ajoutant un \"x\" à l'intérieur :\n\n- [ ] Lait\n- [ ] Œufs\n- [x] Bière\n\nDes expressions mathématiques peuvent être ajoutées à l'aide de la [notation KaTeX](https://khan.github.io/KaTeX/) :\n\n$$\nf(x) = \\int_{-\\infty}^\\infty\n \\hat f(\\xi)\\,e^{2 \\pi i \\xi x}\n \\,d\\xi\n$$\n\nDiverses autres astuces sont possibles, telles que l'utilisation de HTML ou la personnalisation du CSS. Voir la documentation Markdown pour plus d'informations - https://joplinapp.org/markdown/\n\n## Communauté et aide supplémentaire\n\n- Pour une discussion générale sur Joplin, l'assistance aux utilisateurs, les questions de développement logiciel et pour discuter des nouvelles fonctionnalités, rendez-vous sur le [Forum Joplin](https://discourse.joplinapp.org/). Il est possible de se connecter avec votre compte GitHub.\n- Les dernières nouvelles sont publiées [sur la page Patreon](https://www.patreon.com/joplin).\n- Pour les rapports de bugs et les demandes de fonctionnalités, accédez au [GitHub Issue Tracker](https://github.com/laurent22/joplin/issues).\n\n## Donations\n\nLes dons à Joplin soutiennent le développement du projet. Développer des applications de qualité prend généralement du temps, mais il y a aussi des dépenses, comme les certificats numériques pour signer les applications, les frais d'app store, l'hébergement, etc. Surtout, votre don permettra de maintenir le standard de développement actuel.\n\nVeuillez consulter la [page de don](https://joplinapp.org/donate/) pour savoir comment soutenir le développement de Joplin.",
"resources": {},
"parent_id": "5494e8c3dcfc84c1549ed22fb3a89265"
},

View File

@ -174,7 +174,7 @@ From `packages/server`, run `npm run start-dev`
# Changelog
[View the changelog](https://github.com/laurent22/joplin/blob/dev/readme/changelog_server.md)
[View the changelog](https://github.com/laurent22/joplin/blob/dev/readme/about/changelog/changelog_server.md)
# License

View File

@ -0,0 +1,36 @@
import { replaceGitHubInternalLinks } from './build-release-stats';
describe('build-release-stats', () => {
it('should replace GitHub internal link', async () => {
const testCases = [
[
'(15ce5cd)',
'([15ce5cd](https://github.com/laurent22/joplin/commit/15ce5cd))',
],
[
'(#8532 by Henry Heino)',
'([#8532](https://github.com/laurent22/joplin/issues/8532) by Henry Heino)',
],
[
'([15ce5cd](https://github.com/laurent22/joplin/commit/15ce5cd))',
'([15ce5cd](https://github.com/laurent22/joplin/commit/15ce5cd))',
],
[
'([#8532](https://github.com/laurent22/joplin/issues/8532) by Henry Heino)',
'([#8532](https://github.com/laurent22/joplin/issues/8532) by Henry Heino)',
],
[
'list (#8825) (#8194 by [@CptMeetKat](https://github.com/CptMeetKat))',
'list ([#8825](https://github.com/laurent22/joplin/issues/8825)) ([#8194](https://github.com/laurent22/joplin/issues/8194) by [@CptMeetKat](https://github.com/CptMeetKat))',
],
];
for (const [input, expected] of testCases) {
const actual = replaceGitHubInternalLinks(input);
expect(actual).toBe(expected);
}
});
});

View File

@ -1,3 +1,5 @@
/* eslint-disable import/prefer-default-export */
import fetch from 'node-fetch';
import { writeFile, readFile, pathExists } from 'fs-extra';
import { dirname } from '@joplin/lib/path-utils';
@ -30,7 +32,7 @@ interface Release extends GitHubRelease {
}
const rootDir = dirname(dirname(__dirname));
const statsFilePath = `${rootDir}/readme/stats.md`;
const statsFilePath = `${rootDir}/readme/about/stats.md`;
function endsWith(str: string, suffix: string) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
@ -61,10 +63,26 @@ function downloadCounts(release: GitHubRelease) {
return output;
}
export const replaceGitHubInternalLinks = (body: string) => {
body = body.replace(/#(\d+)(.{2})/g, (_match: string, v1: string, v2: string) => {
if (v2.startsWith('](')) {
// The issue number is already a link, so skip it
return `#${v1}${v2}`;
} else {
return `[#${v1}](https://github.com/laurent22/joplin/issues/${v1})${v2}`;
}
});
body = body.replace(/\(([0-9a-z]{7})\)/g, '([$1](https://github.com/laurent22/joplin/commit/$1))');
return body;
};
function createChangeLog(releases: Release[]) {
const output = [];
output.push('# Joplin changelog');
output.push('# Joplin Desktop Changelog');
for (let i = 0; i < releases.length; i++) {
const r = releases[i];
@ -72,8 +90,7 @@ function createChangeLog(releases: Release[]) {
const preReleaseString = r.prerelease ? ' (Pre-release)' : '';
s.push(`## ${r.tag_name}${preReleaseString} - ${r.published_at}`);
s.push('');
let body = r.body.replace(/#(\d+)/g, '[#$1](https://github.com/laurent22/joplin/issues/$1)');
body = body.replace(/\(([0-9a-z]{7})\)/g, '([$1](https://github.com/laurent22/joplin/commit/$1))');
const body = replaceGitHubInternalLinks(r.body);
s.push(body);
output.push(s.join('\n'));
}
@ -92,7 +109,7 @@ async function main() {
if (updateStats && await pathExists(statsFilePath)) {
const md = await readFile(statsFilePath, 'utf8');
const info = stripOffFrontMatter(md);
const info = stripOffFrontMatter(md).header;
if (!info.updated) throw new Error('Missing front matter property: updated');
const now = new Date();
@ -179,7 +196,7 @@ async function main() {
if (updateChangelog) {
console.info('Build stats: Updating changelog...');
const changelogText = createChangeLog(rows);
await writeFile(`${rootDir}/readme/changelog.md`, changelogText);
await writeFile(`${rootDir}/readme/about/changelog/desktop.md`, changelogText);
}
if (!updateStats) return;
@ -238,8 +255,11 @@ async function main() {
await writeFile(statsFilePath, statsText);
}
main().catch((error) => {
console.error('Fatal error');
console.error(error);
process.exit(1);
});
if (require.main === module) {
// eslint-disable-next-line promise/prefer-await-to-then
main().catch((error) => {
console.error('Fatal error');
console.error(error);
process.exit(1);
});
}

View File

@ -310,7 +310,7 @@ function translationStatusToMdTable(status: TranslationStatus[]) {
async function updateReadmeWithStats(stats: TranslationStatus[]) {
await insertContentIntoFile(
`${rootDir}/README.md`,
`${rootDir}/readme/dev/localisation.md`,
'<!-- LOCALE-TABLE-AUTO-GENERATED -->\n',
'\n<!-- LOCALE-TABLE-AUTO-GENERATED -->',
translationStatusToMdTable(stats),

View File

@ -42,10 +42,12 @@
"yargs": "17.7.2"
},
"devDependencies": {
"@docusaurus/plugin-sitemap": "2.4.3",
"@joplin/fork-htmlparser2": "^4.1.46",
"@rmp135/sql-ts": "1.18.0",
"@types/fs-extra": "11.0.2",
"@types/jest": "29.5.4",
"@types/js-yaml": "4.0.8",
"@types/markdown-it": "13.0.2",
"@types/mustache": "4.2.3",
"@types/node": "18.17.19",
@ -55,9 +57,11 @@
"gulp": "4.0.2",
"html-entities": "1.4.0",
"jest": "29.6.4",
"js-yaml": "4.1.0",
"rss": "1.2.2",
"sass": "1.67.0",
"sqlite3": "5.1.6",
"style-to-js": "1.1.8",
"typescript": "5.1.6"
},
"gitHead": "eb4b0e64eab40a51b0895d3a40a9d8c3cb7b1b14"

View File

@ -267,7 +267,7 @@ async function main() {
console.info(`Main download URL: ${releaseFiles['main'].downloadUrl}`);
const changelogPath = `${rootDir}/readme/changelog_android.md`;
const changelogPath = `${rootDir}/readme/about/changelog/android.md`;
await completeReleaseWithChangelog(changelogPath, version, tagName, 'Android', isPreRelease);
}

View File

@ -2,7 +2,7 @@ import { execCommand } from '@joplin/utils';
import { rootDir, completeReleaseWithChangelog } from './tool-utils';
const appDir = `${rootDir}/packages/app-cli`;
const changelogPath = `${rootDir}/readme/changelog_cli.md`;
const changelogPath = `${rootDir}/readme/about/changelog/cli.md`;
// Start with node Tools/release-cli.js --changelog-from cli-v1.0.126
// to specify from where the changelog should be created

View File

@ -72,7 +72,7 @@ async function main() {
const tagName = `ios-v${newVersion}`;
console.info(`Tag name: ${tagName}`);
const changelogPath = `${rootDir}/readme/changelog_ios.md`;
const changelogPath = `${rootDir}/readme/about/changelog/ios.md`;
await completeReleaseWithChangelog(changelogPath, newVersion, tagName, 'iOS', false);
}

View File

@ -17,7 +17,7 @@ async function main() {
const versionSuffix = ''; // isPreRelease ? '-beta' : '';
const tagName = `server-${version}${versionSuffix}`;
const changelogPath = `${rootDir}/readme/changelog_server.md`;
const changelogPath = `${rootDir}/readme/about/changelog/server.md`;
await completeReleaseWithChangelog(changelogPath, version, tagName, 'Server', false);
}

View File

@ -1,7 +1,7 @@
import * as fs from 'fs-extra';
import { fileExtension } from '@joplin/lib/path-utils';
import { gitHubLatestRelease, GitHubRelease } from './tool-utils';
const readmePath = `${__dirname}/../../README.md`;
const destMarkdownPath = `${__dirname}/../../readme/install.md`;
async function msleep(ms: number) {
return new Promise((resolve) => {
@ -52,13 +52,13 @@ export const downloadUrl = (release: GitHubRelease, os: OS, portable = false) =>
};
function readmeContent() {
if (!fs.existsSync(readmePath)) throw new Error(`Cannot find ${readmePath}`);
return fs.readFileSync(readmePath, 'utf8');
if (!fs.existsSync(destMarkdownPath)) throw new Error(`Cannot find ${destMarkdownPath}`);
return fs.readFileSync(destMarkdownPath, 'utf8');
}
function setReadmeContent(content: string) {
if (!fs.existsSync(readmePath)) throw new Error(`Cannot find ${readmePath}`);
return fs.writeFileSync(readmePath, content);
if (!fs.existsSync(destMarkdownPath)) throw new Error(`Cannot find ${destMarkdownPath}`);
return fs.writeFileSync(destMarkdownPath, content);
}
async function main(argv: any) {

View File

@ -0,0 +1,13 @@
# Joplin Website Builder
The website is mostly built by rendering Markdown files under `/readme` to HTML. More advanced pages such as the homepage or Plans page are created using a Mustache template.
Docusaurus is used to build the Help and News pages.
## To build the website
Run `yarn buildWebsite`, which will run all the required commands in the correct order. This will create the website in a relative directory `../joplin-website/docs`.
## To watch the website
To watch the website run `yarn watchWebsite`. If changing the Help or News pages, run `yarn start` from `packages/doc-builder`.

View File

@ -10,7 +10,7 @@ import { readmeFileTitle, replaceGitHubByWebsiteLinks } from './utils/parser';
import { extractOpenGraphTags, OpenGraphTags } from './utils/openGraph';
import { readCredentialFileJson } from '@joplin/lib/utils/credentialFiles';
import { getNewsDateString } from './utils/news';
import { parsePoFile, parseTranslations, Translations } from '../utils/translation';
import { Translations } from '../utils/translation';
import { setLocale } from '@joplin/lib/locale';
import applyTranslations from './utils/applyTranslations';
import { loadSponsors } from '../utils/loadSponsors';
@ -36,7 +36,7 @@ const path = require('path');
const md5File = require('md5-file');
const docDir = `${dirname(dirname(dirname(dirname(__dirname))))}/joplin-website/docs`;
if (!pathExistsSync(docDir)) throw new Error(`Doc directory does not exist: ${docDir}`);
if (!pathExistsSync(docDir)) throw new Error(`"docs" directory does not exist: ${docDir}`);
const websiteAssetDir = `${rootDir}/Assets/WebsiteAssets`;
const readmeDir = `${rootDir}/readme`;
@ -49,16 +49,16 @@ const partialDir = `${websiteAssetDir}/templates/partials`;
const discussLink = 'https://discourse.joplinapp.org/c/news/9';
let tocMd_: string = null;
const tocHtml_: Record<string, string> = {};
const tocRegex_ = /<!-- TOC -->([^]*)<!-- TOC -->/;
function tocMd() {
if (tocMd_) return tocMd_;
const md = readFileSync(`${rootDir}/README.md`, 'utf8');
const toc = md.match(tocRegex_);
tocMd_ = toc[1];
return tocMd_;
}
// let tocMd_: string = null;
// const tocHtml_: Record<string, string> = {};
// const tocRegex_ = /<!-- TOC -->([^]*)<!-- TOC -->/;
// function tocMd() {
// if (tocMd_) return tocMd_;
// const md = readFileSync(`${rootDir}/README.md`, 'utf8');
// const toc = md.match(tocRegex_);
// tocMd_ = toc[1];
// return tocMd_;
// }
const donateLinksRegex_ = /<!-- DONATELINKS -->([^]*)<!-- DONATELINKS -->/;
async function getDonateLinks() {
@ -70,18 +70,18 @@ async function getDonateLinks() {
return `<div class="donate-links">\n\n${matches[1].trim()}\n\n</div>`;
}
function tocHtml(locale: Locale) {
if (tocHtml_[locale.lang]) return tocHtml_[locale.lang];
const markdownIt = getMarkdownIt();
let md = tocMd();
md = md.replace(/# Table of contents/, '');
md = replaceGitHubByWebsiteLinks(md);
md = convertLinksToLocale(md, locale);
let output = markdownIt.render(md);
output = `<div>${output}</div>`;
tocHtml_[locale.lang] = output;
return output;
}
// function tocHtml(locale: Locale) {
// if (tocHtml_[locale.lang]) return tocHtml_[locale.lang];
// const markdownIt = getMarkdownIt();
// let md = tocMd();
// md = md.replace(/# Table of contents/, '');
// md = replaceGitHubByWebsiteLinks(md);
// md = convertLinksToLocale(md, locale);
// let output = markdownIt.render(md);
// output = `<div>${output}</div>`;
// tocHtml_[locale.lang] = output;
// return output;
// }
const baseUrl = '';
const cssBasePath = `${websiteAssetDir}/css`;
@ -143,7 +143,7 @@ function defaultTemplateParams(assetUrls: AssetUrls, locale: Locale = null): Tem
imageBaseUrl: `${baseUrl}/images`,
cssBaseUrl,
jsBaseUrl,
tocHtml: tocHtml(locale),
// tocHtml: tocHtml(locale),
yyyy: (new Date()).getFullYear().toString(),
templateHtml: mainTemplateHtml,
forumUrl: 'https://discourse.joplinapp.org/',
@ -211,44 +211,44 @@ function renderFileToHtml(sourcePath: string, targetPath: string, templateParams
}
}
function makeHomePageMd(readmePath: string) {
let md = readFileSync(readmePath, 'utf8');
md = md.replace(tocRegex_, '');
// function makeHomePageMd(readmePath: string) {
// let md = readFileSync(readmePath, 'utf8');
// md = md.replace(tocRegex_, '');
// HACK: GitHub needs the \| or the inline code won't be displayed correctly inside the table,
// while MarkdownIt doesn't and will in fact display the \. So we remove it here.
md = md.replace(/\\\| bash/g, '| bash');
// // HACK: GitHub needs the \| or the inline code won't be displayed correctly inside the table,
// // while MarkdownIt doesn't and will in fact display the \. So we remove it here.
// md = md.replace(/\\\| bash/g, '| bash');
// We strip-off the donate links because they are added back (with proper
// classes and CSS).
md = md.replace(donateLinksRegex_, '');
// // We strip-off the donate links because they are added back (with proper
// // classes and CSS).
// md = md.replace(donateLinksRegex_, '');
return md;
}
// return md;
// }
const processNewsMarkdown = (md: string, mdFilePath: string): string => {
const info = stripOffFrontMatter(md);
md = info.doc.trim();
const dateString = getNewsDateString(info, mdFilePath);
const dateString = getNewsDateString(info.header, mdFilePath);
md = md.replace(/^# (.*)/, `# [$1](https://github.com/laurent22/joplin/blob/dev/readme/news/${path.basename(mdFilePath)})\n\n*Published on **${dateString}***\n\n`);
md += `\n\n* * *\n\n[<i class="fab fa-discourse"></i> Discuss on the forum](${discussLink})`;
return md;
};
const makeNewsFrontPage = async (sourceFilePaths: string[], targetFilePath: string, templateParams: TemplateParams) => {
const maxNewsPerPage = 20;
// const makeNewsFrontPage = async (sourceFilePaths: string[], targetFilePath: string, templateParams: TemplateParams) => {
// const maxNewsPerPage = 20;
const frontPageMd: string[] = [];
// const frontPageMd: string[] = [];
for (const mdFilePath of sourceFilePaths) {
let md = await readFile(mdFilePath, 'utf8');
md = processNewsMarkdown(md, mdFilePath);
frontPageMd.push(md);
if (frontPageMd.length >= maxNewsPerPage) break;
}
// for (const mdFilePath of sourceFilePaths) {
// let md = await readFile(mdFilePath, 'utf8');
// md = processNewsMarkdown(md, mdFilePath);
// frontPageMd.push(md);
// if (frontPageMd.length >= maxNewsPerPage) break;
// }
renderPageToHtml(frontPageMd.join('\n\n* * *\n\n'), targetFilePath, templateParams);
};
// renderPageToHtml(frontPageMd.join('\n\n* * *\n\n'), targetFilePath, templateParams);
// };
const isNewsFile = (filePath: string): boolean => {
return filePath.includes('readme/news/');
@ -271,16 +271,16 @@ const updatePageLanguage = (html: string, lang: string): string => {
async function main() {
const supportedLocales: Record<string, Locale> = {
'en_GB': enGbLocale,
'zh_CN': {
htmlTranslations: parseTranslations(await parsePoFile(`${websiteAssetDir}/locales/zh_CN.po`)),
lang: 'zh-cn',
pathPrefix: 'cn',
},
'fr_FR': {
htmlTranslations: {},
lang: 'fr-fr',
pathPrefix: 'fr',
},
// 'zh_CN': {
// htmlTranslations: parseTranslations(await parsePoFile(`${websiteAssetDir}/locales/zh_CN.po`)),
// lang: 'zh-cn',
// pathPrefix: 'cn',
// },
// 'fr_FR': {
// htmlTranslations: {},
// lang: 'fr-fr',
// pathPrefix: 'fr',
// },
};
// delete supportedLocales['zh_CN'];
@ -288,8 +288,12 @@ async function main() {
setLocale('en_GB');
await remove(`${docDir}`);
await copy(websiteAssetDir, `${docDir}`);
await remove(docDir);
const docBuilderDir = `${rootDir}/packages/doc-builder`;
await copy(`${docBuilderDir}/build`, docDir);
await copy(websiteAssetDir, docDir);
const sponsors = process.env.SKIP_SPONSOR_PROCESSING ? { github: [], orgs: [] } : await loadSponsors();
const partials = await loadMustachePartials(partialDir);
@ -306,38 +310,38 @@ async function main() {
// HELP PAGE
// =============================================================
let readmePath = `${rootDir}/README.md`;
// let readmePath = `${rootDir}/README.md`;
let sourceMarkdownFile = 'README.md';
let targetDocDir = docDir;
// let sourceMarkdownFile = 'README.md';
// let targetDocDir = docDir;
if (localeName !== 'en_GB') {
const possibleSource = `${rootDir}/readme/_i18n/${localeName}/README.md`;
if (await pathExists(possibleSource)) {
sourceMarkdownFile = possibleSource;
readmePath = possibleSource;
} else {
console.warn(`Cannot find source file: ${possibleSource}`);
}
// if (localeName !== 'en_GB') {
// const possibleSource = `${rootDir}/readme/_i18n/${localeName}/README.md`;
// if (await pathExists(possibleSource)) {
// sourceMarkdownFile = possibleSource;
// readmePath = possibleSource;
// } else {
// console.warn(`Cannot find source file: ${possibleSource}`);
// }
targetDocDir = `${docDir}/${locale.pathPrefix}`;
}
// targetDocDir = `${docDir}/${locale.pathPrefix}`;
// }
const readmeMd = makeHomePageMd(readmePath);
// const readmeMd = makeHomePageMd(readmePath);
renderPageToHtml(readmeMd, `${targetDocDir}/help/index.html`, {
sourceMarkdownFile,
donateLinksMd,
partials,
sponsors,
assetUrls,
openGraph: {
title: 'Joplin documentation',
description: '',
url: 'https://joplinapp.org/help/',
},
locale,
});
// renderPageToHtml(readmeMd, `${targetDocDir}/help/index.html`, {
// sourceMarkdownFile,
// donateLinksMd,
// partials,
// sponsors,
// assetUrls,
// openGraph: {
// title: 'Joplin documentation',
// description: '',
// url: 'https://joplinapp.org/help/',
// },
// locale,
// });
// =============================================================
// FRONT PAGE
@ -444,10 +448,24 @@ async function main() {
setLocale('en_GB');
// =============================================================
// All other pages are generated dynamically from the
// Markdown files under /readme
// =============================================================
// ==========================================================================
// All other pages are generated dynamically from the Markdown files under
// /readme
//
// 2023-10-23: This was used to build the Help pages from the Markdown
// files, however this is now done using Docusaurus. A few files still need
// to be at the root however, and so we keep that process here for now. Any
// file that need to be processed should go in the `filesToProcess` array.
// Eventually all that should probably be moved to Docusaurus or to some
// static pages.
// ==========================================================================
const filesToProcess = [
'download.md',
'privacy.md',
'donate.md',
'connection_check.md',
];
interface SourceInfo {
title: string;
@ -467,7 +485,7 @@ async function main() {
const filenameNoExt = basename(input, '.md');
return `news/${filenameNoExt}/index.html`;
} else {
// Input is for example "readme/spec/interop_with_frontmatter.md",
// Input is for example "readme/dev/spec/interop_with_frontmatter.md",
// and we need to convert it to
// "docs/spec/interop_with_frontmatter/index.html" and prefix it
// with the website repo full path.
@ -498,6 +516,7 @@ async function main() {
const newsFilePaths: string[] = [];
for (const mdFile of mdFiles) {
if (!filesToProcess.includes(basename(mdFile))) continue;
if (mdFile.startsWith('readme/_i18n')) continue;
for (const [localeName, locale] of Object.entries(supportedLocales)) {
@ -545,24 +564,27 @@ async function main() {
});
}
newsFilePaths.sort((a, b) => {
return a.toLowerCase() > b.toLowerCase() ? -1 : +1;
});
// newsFilePaths.sort((a, b) => {
// return a.toLowerCase() > b.toLowerCase() ? -1 : +1;
// });
// await makeNewsFrontPage(newsFilePaths, `${docDir}/news/index.html`, {
// ...defaultTemplateParams(assetUrls, null),
// title: 'What\'s new',
// pageName: 'news',
// partials,
// showToc: false,
// showImproveThisDoc: false,
// donateLinksMd,
// openGraph: {
// title: 'Joplin - what\'s new',
// description: 'News about the Joplin open source application',
// url: 'https://joplinapp.org/news/',
// },
// });
await makeNewsFrontPage(newsFilePaths, `${docDir}/news/index.html`, {
...defaultTemplateParams(assetUrls, null),
title: 'What\'s new',
pageName: 'news',
partials,
showToc: false,
showImproveThisDoc: false,
donateLinksMd,
openGraph: {
title: 'Joplin - what\'s new',
description: 'News about the Joplin open source application',
url: 'https://joplinapp.org/news/',
},
});
// setLocale('zh_CN');
// const translations = parseTranslations(await parsePoFile(`${websiteAssetDir}/locales/zh_CN.po`));

View File

@ -0,0 +1,50 @@
import { readFile } from 'fs/promises';
import { processMarkdownDoc } from './processDocs';
import { basename } from 'path';
import { readdirSync } from 'fs';
const sampleDir = `${__dirname}/processDocsTestSamples`;
interface TestCase {
sourcePath: string;
outputPath: string;
}
const makeTestCases = () => {
const output: TestCase[] = [];
const files = readdirSync(sampleDir);
for (const file of files) {
if (file.endsWith('.mdx')) continue;
// if (!file.endsWith('blockquotes.md')) continue;
const sourcePath = `${sampleDir}/${file}`;
const outputPath = `${sampleDir}/${basename(file, '.md')}.mdx`;
output.push({
sourcePath,
outputPath,
});
}
return output;
};
describe('website/processDocs', () => {
test.each(makeTestCases())('process a Markdown doc: $sourcePath', async (testCase: TestCase) => {
const { sourcePath, outputPath } = testCase;
const sourceContent = await readFile(sourcePath, 'utf-8');
const expected = await readFile(outputPath, 'utf-8');
const actual = processMarkdownDoc(sourceContent, { });
if (actual !== expected) {
console.info(`
EXPECTED =======================================
${expected}
ACTUAL =========================================
${actual}`);
}
expect(actual).toBe(expected);
});
});

View File

@ -0,0 +1,509 @@
/* eslint-disable import/prefer-default-export */
import { execCommand, getRootDir } from '@joplin/utils';
import { readFile, readdir, stat, writeFile } from 'fs/promises';
import * as MarkdownIt from 'markdown-it';
import { htmlentities, isSelfClosingTag } from '@joplin/utils/html';
import { compileWithFrontMatter, stripOffFrontMatter } from './utils/frontMatter';
import StateCore = require('markdown-it/lib/rules_core/state_core');
import { copy, mkdirp, remove, pathExists } from 'fs-extra';
import { basename, dirname } from 'path';
import markdownUtils, { MarkdownTable } from '@joplin/lib/markdownUtils';
import { readmeFileTitle } from './utils/parser';
import { chdir } from 'process';
import yargs = require('yargs');
const md5File = require('md5-file');
const htmlparser2 = require('@joplin/fork-htmlparser2');
const styleToJs = require('style-to-js').default;
const crypto = require('crypto');
interface Config {
baseUrl: string;
docusaurusBuildEnabled: boolean;
docusaurusBuildCommand: string;
}
interface List {
type: 'bullet' | 'number';
}
interface Context {
currentTable?: MarkdownTable;
currentTableContent?: string[];
currentTableCellIndex?: number;
inHeader?: boolean;
listStack?: List[];
listStarting?: boolean;
currentLinkAttrs?: any;
inFence?: boolean;
processedFiles?: string[];
isNews?: boolean;
donateLinks?: string;
inQuote?: boolean;
}
const configs: Record<string, Config> = {
dev: {
baseUrl: 'http://localhost:8077',
docusaurusBuildCommand: 'buildDev',
docusaurusBuildEnabled: true,
},
prod: {
baseUrl: 'https://joplinapp.org',
docusaurusBuildCommand: '_build',
docusaurusBuildEnabled: true,
},
};
const md5 = (s: string) => {
return crypto.createHash('md5').update(s).digest('hex');
};
const parseHtml = (html: string) => {
const output: string[] = [];
interface Tag {
name: string;
}
const tagStack: Tag[] = [];
const currentTag = () => {
if (!tagStack.length) return { name: '', processed: false };
return tagStack[tagStack.length - 1];
};
const parser = new htmlparser2.Parser({
onopentag: (name: string, attrs: Record<string, any>) => {
tagStack.push({ name });
const closingSign = isSelfClosingTag(name) ? '/>' : '>';
const attrHtml: string[] = [];
for (const n in attrs) {
if (!attrs.hasOwnProperty(n)) continue;
let escapedValue = `"${htmlentities(attrs[n])}"`;
if (n === 'style') {
escapedValue = `{${JSON.stringify(styleToJs(attrs.style))}}`;
}
attrHtml.push(`${n}=${escapedValue}`);
}
output.push(`<${name} ${attrHtml.join(' ')}${closingSign}`);
},
ontext: (decodedText: string) => {
output.push(htmlentities(decodedText));
},
onclosetag: (name: string) => {
const current = currentTag();
if (current.name === name) tagStack.pop();
if (isSelfClosingTag(name)) return;
output.push(`</${name}>`);
},
}, { decodeEntities: true });
parser.write(html);
parser.end();
return output.join('');
};
const escapeForMdx = (s: string): string => {
return s
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/`/g, '\\`');
};
const paragraphBreak = '///PARAGRAPH_BREAK///';
const blockQuoteStart = '///BLOCK_QUOTE_START///';
const blockQuoteEnd = '///BLOCK_QUOTE_END///';
const processToken = (token: any, output: string[], context: Context): void => {
if (!context.listStack) context.listStack = [];
let contentProcessed = false;
const type = token.type as string;
const currentList = context.listStack.length ? context.listStack[context.listStack.length - 1] : null;
const doEscapeForMdx = (text: string) => {
if (context.inFence) return text;
return escapeForMdx(text);
};
const content: string[] = [];
if (type === 'heading_open') {
content.push(paragraphBreak);
content.push(`${token.markup} `);
} else if (type === 'heading_close') {
content.push(paragraphBreak);
} else if (type === 'paragraph_open' || type === 'paragraph_close') {
if (!currentList) {
content.push(paragraphBreak);
}
} else if (type === 'fence') {
context.inFence = true;
content.push(`\`\`\`${token.info || ''}\n`);
} else if (type === 'html_block') {
contentProcessed = true,
content.push(parseHtml(token.content.trim()));
} else if (type === 'html_inline') {
contentProcessed = true,
content.push(parseHtml(token.content.trim()));
} else if (type === 'code_inline') {
contentProcessed = true,
content.push(`\`${token.content}\``);
} else if (type === 'code_block') {
contentProcessed = true;
content.push(`\`\`\`\n${token.content}\`\`\``);
content.push(paragraphBreak);
} else if (type === 'strong_open' || type === 'strong_close') {
content.push('**');
} else if (type === 'em_open' || type === 'em_close') {
content.push('*');
} else if (type === 'blockquote_open' || type === 'blockquote_close') {
content.push(type === 'blockquote_open' ? blockQuoteStart : blockQuoteEnd);
} else if (type === 'table_open') {
context.currentTable = {
header: [],
rows: [],
};
context.currentTableContent = [];
} else if (type === 'th_open') {
context.currentTable.header.push({
label: '',
name: `${context.currentTable.header.length}`,
disableHtmlEscape: true,
});
} else if (type === 'thead_open') {
context.inHeader = true;
} else if (type === 'thead_close') {
context.inHeader = false;
} else if (type === 'th_close') {
context.currentTable.header[context.currentTable.header.length - 1].label = context.currentTableContent.join('');
context.currentTableContent = [];
} else if (type === 'tr_open') {
if (!context.inHeader) {
context.currentTable.rows.push({});
context.currentTableCellIndex = 0;
}
} else if (type === 'td_open') {
const row = context.currentTable.rows[context.currentTable.rows.length - 1];
row[`${context.currentTableCellIndex}`] = '';
} else if (type === 'td_close') {
const row = context.currentTable.rows[context.currentTable.rows.length - 1];
row[`${context.currentTableCellIndex}`] = context.currentTableContent.join('');
context.currentTableCellIndex++;
context.currentTableContent = [];
} else if (type === 'table_close') {
const tableMd = markdownUtils.createMarkdownTable(context.currentTable.header, context.currentTable.rows);
content.push(paragraphBreak);
content.push(tableMd);
content.push(paragraphBreak);
context.currentTable = null;
} else if (type === 'bullet_list_open') {
context.listStarting = !context.listStack.length;
context.listStack.push({ type: 'bullet' });
} else if (type === 'ordered_list_open') {
context.listStarting = !context.listStack.length;
context.listStack.push({ type: 'number' });
} else if (type === 'bullet_list_close' || type === 'ordered_list_close') {
context.listStack.pop();
if (!context.listStack.length) content.push(paragraphBreak);
} else if (type === 'list_item_open') {
if (!context.listStarting) content.push('\n');
context.listStarting = false;
const indent = '\t'.repeat((context.listStack.length - 1));
if (currentList.type === 'bullet') content.push(`${indent}- `);
if (currentList.type === 'number') content.push(`${indent + token.info}. `);
} else if (type === 'image') {
(context.currentTable ? context.currentTableContent : content).push('![');
} else if (type === 'link_open') {
content.push('[');
context.currentLinkAttrs = token.attrs;
} else if (type === 'link_close') {
const href = context.currentLinkAttrs.find((a: string[]) => a[0] === 'href')[1];
content.push(`](${escapeForMdx(href)})`);
context.currentLinkAttrs = null;
}
if (token.children) {
for (const child of token.children) {
processToken(child, content, context);
}
} else if (token.content && !contentProcessed) {
content.push(doEscapeForMdx(token.content));
}
if (type === 'fence') {
content.push('```');
content.push(paragraphBreak);
context.inFence = false;
}
if (type === 'image') {
let src: string = token.attrs.find((a: string[]) => a[0] === 'src')[1];
if (!src.startsWith('http') && !src.startsWith('/')) src = `/${src}`;
content.push(`](${doEscapeForMdx(src)})`);
}
for (const c of content) {
if (context.currentTable) {
context.currentTableContent.push(c);
} else {
output.push(c);
}
}
};
const resolveParagraphBreaks = (output: string[]): string[] => {
if (!output.length) return output;
while (output.length && output[0] === paragraphBreak) {
output.splice(0, 1);
}
while (output.length && output[output.length - 1] === paragraphBreak) {
output.pop();
}
let previous = '';
const newOutput: string[] = [];
for (const s of output) {
if (s === paragraphBreak && previous === paragraphBreak) continue;
newOutput.push(s === paragraphBreak ? '\n\n' : s);
previous = s;
}
return newOutput;
};
const resolveBlockQuotes = (output: string): string => {
if (!output) return output;
const lines = output.split('\n');
let inQuotes = false;
const quotedLines: string[] = [];
const newOutput: string[] = [];
for (const line of lines) {
if (line === blockQuoteStart) {
inQuotes = true;
} else if (line === blockQuoteEnd) {
inQuotes = false;
const s = quotedLines.join('\n').trim().split('\n').map(l => `> ${l}`).join('\n');
newOutput.push(s);
} else if (inQuotes) {
quotedLines.push(line);
} else {
newOutput.push(line);
}
}
return newOutput.join('\n');
};
const processUrls = (md: string) => {
md = md
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*)\/index\.md/g, '/help/$1')
.replace(/https:\/\/github.com\/laurent22\/joplin\/blob\/dev\/readme\/(.*)\.md/g, '/help/$1');
return md;
};
export const processMarkdownDoc = (sourceContent: string, context: Context): string => {
const markdownIt = new MarkdownIt({
breaks: true,
linkify: true,
html: true,
});
let items: string[] = [];
markdownIt.core.ruler.push('converter', (state: StateCore) => {
const tokens = state.tokens;
// console.info(JSON.stringify(tokens, null, '\t'));
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
processToken(token, items, context);
}
});
const mdAndFrontMatter = stripOffFrontMatter(sourceContent);
markdownIt.render(mdAndFrontMatter.doc);
items = resolveParagraphBreaks(items);
const output = resolveBlockQuotes(processUrls(items.join('').trim()));
return compileWithFrontMatter({
...mdAndFrontMatter,
doc: output,
});
};
const processMarkdownFile = async (sourcePath: string, destPath: string, context: Context) => {
context.processedFiles.push(destPath);
const sourceContent = await readFile(sourcePath, 'utf-8');
const destContent = processMarkdownDoc(sourceContent, context);
await mkdirp(dirname(destPath));
const title = await readmeFileTitle(sourcePath);
const mdAndFrontMatter = stripOffFrontMatter(destContent);
mdAndFrontMatter.header.sidebar_label = title;
if (context.isNews) {
const dateString = basename(sourcePath).split('-')[0];
const formatted = `${dateString.substring(0, 4)}-${dateString.substring(4, 6)}-${dateString.substring(6, 8)}`;
mdAndFrontMatter.header.date = formatted;
}
mdAndFrontMatter.doc = mdAndFrontMatter.doc.replace(/^# (.*)\n/, `# $1\n\n${context.donateLinks}\n\n`);
if (mdAndFrontMatter.header.forum_url) {
// mdAndFrontMatter.doc += `\n\n* * *\n\n[<i class="fab fa-discourse"></i> Discuss on the forum](${mdAndFrontMatter.header.forum_url})`;
mdAndFrontMatter.doc += `\n\n* * *\n\n[<icon icon="fa-brands fa-discourse" size="lg" /> Discuss on the forum](${mdAndFrontMatter.header.forum_url})`;
}
const fullContent = compileWithFrontMatter(mdAndFrontMatter);
if (await pathExists(destPath)) {
const existingMd5 = await md5File(destPath);
const newMd5 = md5(fullContent);
if (existingMd5 === newMd5) return;
}
await writeFile(destPath, fullContent, 'utf-8');
};
const processDocFiles = async (sourceDir: string, destDir: string, excluded: string[], context: Context) => {
if (!context.processedFiles) context.processedFiles = [];
const files = await readdir(sourceDir);
for (const file of files) {
const fullPath = `${sourceDir}/${file}`;
if (excluded.includes(fullPath)) continue;
const info = await stat(fullPath);
const destPath = `${destDir}/${file}`;
if (info.isDirectory()) {
await processDocFiles(fullPath, destPath, excluded, context);
} else {
if (file.endsWith('.md')) {
console.info(`Process: ${fullPath}`);
await processMarkdownFile(fullPath, destPath, context);
} else if (file === '_category_.yml') {
context.processedFiles.push(destPath);
await copy(fullPath, destPath);
}
}
}
};
export const deleteUnprocessedFiles = async (dirPath: string, processedFiles: string[]) => {
const files = await readdir(dirPath);
for (const file of files) {
const fullPath = `${dirPath}/${file}`;
const info = await stat(fullPath);
if (info.isDirectory()) {
await deleteUnprocessedFiles(fullPath, processedFiles);
} else {
if (!processedFiles.includes(fullPath)) {
console.info(`Delete: ${fullPath}`);
await remove(fullPath);
}
}
}
};
const copyFile = async (sourceFile: string, destFile: string) => {
console.info(`Copy: ${destFile}`);
await copy(sourceFile, destFile);
};
const getDonateLinks = () => {
return `<div className="donate-links">
[![Donate using PayPal](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=E8JMYD2LQ8MMA&no_recurring=0&item_name=I+rely+on+donations+to+maintain+and+improve+the+Joplin+open+source+project.+Thank+you+for+your+help+-+it+makes+a+difference%21&currency_code=EUR) [![Sponsor on GitHub](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/GitHub-Badge.svg)](https://github.com/sponsors/laurent22/) [![Become a patron](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Patreon-Badge.svg)](https://www.patreon.com/joplin) [![Donate using IBAN](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/badges/Donate-IBAN.svg)](https://joplinapp.org/donate/#donations)
</div>`;
};
export const buildDocusaurus = async (docBuilderDir: string, buildCommand: string, baseUrl: string) => {
chdir(docBuilderDir);
await execCommand(`yarn ${buildCommand}`, {
env: {
WEBSITE_BASE_URL: baseUrl,
},
});
};
async function main() {
const argv = await yargs.argv;
const env = argv.env as string;
if (!env) throw new Error('Env must be specified: either "dev" or "prod"');
const config = { ...configs[env] };
if ('docuBuild' in argv && !argv.docuBuild) config.docusaurusBuildEnabled = false;
const rootDir = await getRootDir();
const docBuilderDir = `${rootDir}/packages/doc-builder`;
const destHelpDir = `${docBuilderDir}/help`;
const newsDestDir = `${docBuilderDir}/news`;
const readmeDir = `${rootDir}/readme`;
const donateLinks = getDonateLinks();
const mainContext: Context = { donateLinks };
await processDocFiles(readmeDir, destHelpDir, [
`${readmeDir}/_i18n`,
`${readmeDir}/cla.md`,
`${readmeDir}/download.md`,
`${readmeDir}/faq_joplin_cloud.md`,
`${readmeDir}/privacy.md`,
`${readmeDir}/donate.md`,
`${readmeDir}/connection_check.md`,
`${readmeDir}/welcome`,
`${readmeDir}/news`,
], mainContext);
await deleteUnprocessedFiles(destHelpDir, mainContext.processedFiles);
const newsContext: Context = { isNews: true, donateLinks };
await processDocFiles(`${readmeDir}/news`, newsDestDir, [], newsContext);
await deleteUnprocessedFiles(newsDestDir, newsContext.processedFiles);
await copyFile(`${rootDir}/Assets/WebsiteAssets/images`, `${docBuilderDir}/static/images`);
if (config.docusaurusBuildEnabled) {
await buildDocusaurus(docBuilderDir, config.docusaurusBuildCommand, config.baseUrl);
} else {
console.info('Skipping Docusaurus build...');
}
}
if (require.main === module) {
// eslint-disable-next-line promise/prefer-await-to-then
main().catch((error) => {
console.error('Fatal error');
console.error(error);
process.exit(1);
});
}

View File

@ -0,0 +1,5 @@
This is a quote:
> "I never said that!"
>
> ― Albert Einstein

View File

@ -0,0 +1,5 @@
This is a quote:
> "I never said that!"
>
> ― Albert Einstein

View File

@ -0,0 +1,8 @@
This is a code block:
```javascript
const test = 123;
console.info(test);
```
## Followed by a header

View File

@ -0,0 +1,8 @@
This is a code block:
```javascript
const test = 123;
console.info(test);
```
## Followed by a header

View File

@ -0,0 +1,3 @@
One paragraph
Two paragraph

View File

@ -0,0 +1,3 @@
One paragraph
Two paragraph

View File

@ -0,0 +1 @@
\`escapedCode();\`

View File

@ -0,0 +1 @@
\`escapedCode();\`

View File

@ -0,0 +1 @@
Some **bold text** and some *italic text* &lt;EscapedTag&gt;

View File

@ -0,0 +1 @@
Some **bold text** and some *italic text* &lt;EscapedTag&gt;

View File

@ -0,0 +1,17 @@
# One
## One one
Some text
## One two
More text
# Two
End
<img src="https://example.com/img.png"/>
# Image and header

View File

@ -0,0 +1,17 @@
# One
## One one
Some text
## One two
More text
# Two
End
<img src="https://example.com/img.png"/>
# Image and header

View File

@ -0,0 +1,7 @@
# Joplin Android app changelog
## [android-v2.13.4](https://github.com/laurent22/joplin/releases/tag/android-v2.13.4) (Pre-release) - 2023-10-24T18:29:09Z
- Fixed: Improve list toggle logic (#9103) (#9066 by Henry Heino)
## [android-v2.13.2](https://github.com/laurent22/joplin/releases/tag/android-v2.13.2) (Pre-release) - 2023-10-07T16:42:16Z

View File

@ -0,0 +1,7 @@
# Joplin Android app changelog
## [android-v2.13.4](https://github.com/laurent22/joplin/releases/tag/android-v2.13.4) (Pre-release) - 2023-10-24T18:29:09Z
- Fixed: Improve list toggle logic (#9103) (#9066 by Henry Heino)
## [android-v2.13.2](https://github.com/laurent22/joplin/releases/tag/android-v2.13.2) (Pre-release) - 2023-10-07T16:42:16Z

View File

@ -0,0 +1,5 @@
One paragraph
<img src="https://joplinapp.org/images/logo-text.svg" width="40">
Two paragraph

View File

@ -0,0 +1,5 @@
One paragraph
<img src="https://joplinapp.org/images/logo-text.svg" width="40"/>
Two paragraph

View File

@ -0,0 +1,3 @@
| Link |
| --- |
| [![Image description](https://example.com/image.svg)](https://example.com/link) |

View File

@ -0,0 +1,3 @@
| Link |
| ----- |
| [![Image description](https://example.com/image.svg)](https://example.com/link) |

View File

@ -0,0 +1,6 @@
This needs to be converted:
Some indented
Text
Unindented

View File

@ -0,0 +1,8 @@
This needs to be converted:
```
Some indented
Text
```
Unindented

View File

@ -0,0 +1 @@
If `yarn dist` fails, it may need administrative rights.

View File

@ -0,0 +1 @@
If `yarn dist` fails, it may need administrative rights.

View File

@ -0,0 +1,3 @@
One image: ![some alt text](https://joplinapp.org/images/logo-text-blue.svg)
Some link: [hello](https://joplinapp.org)

View File

@ -0,0 +1,3 @@
One image: ![some alt text](https://joplinapp.org/images/logo-text-blue.svg)
Some link: [hello](https://joplinapp.org)

View File

@ -0,0 +1,14 @@
- One
- Two
- Four
- Five
- Six
- Seven
Some paragraph
1. One
1. Two
2. three
2. Foud
3. Five

View File

@ -0,0 +1,14 @@
- One
- Two
- Four
- Five
- Six
- Seven
Some paragraph
1. One
1. Two
2. three
2. Foud
3. Five

View File

@ -0,0 +1 @@
<img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/WebExtensionScreenshot.png" style="max-width: 50%; border: 1px solid gray;">

View File

@ -0,0 +1 @@
<img src="https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/WebExtensionScreenshot.png" style={{"maxWidth":"50%","border":"1px solid gray"}}/>

View File

@ -0,0 +1,18 @@
| First Header | Second Header |
| --------------- | --------------- |
| Content Cell A1 | Content Cell A2 |
| Content Cell A2 | Content Cell B2 |
<img src="https://test"/>
| Header |
| --- |
| Content |
Paragraph
# With a BR tag
| Header |
| --- |
| Line 1<br>Line 2 |

View File

@ -0,0 +1,18 @@
| First Header | Second Header |
| ----- | ----- |
| Content Cell A1 | Content Cell A2 |
| Content Cell A2 | Content Cell B2 |
<img src="https://test"/>
| Header |
| ----- |
| Content |
Paragraph
# With a BR tag
| Header |
| ----- |
| Line 1<br />Line 2 |

View File

@ -2,7 +2,7 @@ import { readFile } from 'fs-extra';
import { rootDir, insertContentIntoFile } from '../tool-utils';
async function getReadmeMd() {
return readFile(`${rootDir}/README.md`, 'utf8');
return readFile(`${rootDir}/readme/install.md`, 'utf8');
}
async function createDownloadButtonsHtml(readmeMd: string): Promise<Record<string, string>> {

View File

@ -70,7 +70,7 @@ const generateRssFeed = async (posts: Post[]) => {
const feedItems: any[] = [];
for (const post of posts.reverse()) {
const content = await getPostContent(post);
const postDate = getNewsDate(content.parsed, post.path);
const postDate = getNewsDate(content.parsed.header, post.path);
const html = markdownToHtml(content.body);
if (pubDate === null) pubDate = postDate;
@ -78,11 +78,11 @@ const generateRssFeed = async (posts: Post[]) => {
feedItems.push({
title: content.title,
description: html,
url: `https://joplinapp.org/news/${post.id}/`,
url: `https://joplinapp.org/news/${post.id}`,
guid: post.id,
date: postDate,
custom_elements: [
{ 'twitter-text': content.parsed.tweet },
{ 'twitter-text': content.parsed.header.tweet },
],
});
@ -161,7 +161,7 @@ const main = async () => {
});
const postUrl = `https://discourse.joplinapp.org/t/${topic.topic_id}`;
content.parsed.forum_url = postUrl;
content.parsed.header.forum_url = postUrl;
const compiled = compileWithFrontMatter(content.parsed);
await writeFile(post.path, compiled, 'utf8');

View File

@ -0,0 +1,58 @@
import { compileWithFrontMatter, stripOffFrontMatter } from './frontMatter';
const moment = require('moment');
const testCases: any[][] = [
// =============================================================
[
`
---
tweet: Introducing the "GitHub Action Raw Log Viewer" extension for Chrome
forum_url: https://discourse.joplinapp.org/t/29139
created: 2019-09-29T14:28:34.000+00:00
updated: 2019-09-29T14:30:50.000+00:00
---
Body
`
,
{
tweet: 'Introducing the "GitHub Action Raw Log Viewer" extension for Chrome',
forum_url: 'https://discourse.joplinapp.org/t/29139',
created: moment('2019-09-29T14:28:34.000+00:00').toDate(),
updated: moment('2019-09-29T14:30:50.000+00:00').toDate(),
},
'Body',
`
---
tweet: Introducing the "GitHub Action Raw Log Viewer" extension for Chrome
forum_url: https://discourse.joplinapp.org/t/29139
created: 2019-09-29T14:28:34.000Z
updated: 2019-09-29T14:30:50.000Z
---
Body
`,
],
];
describe('frontMatter', () => {
it('should strip-off FrontMatter', async () => {
for (const [doc, frontMatter, body, compiled] of testCases) {
const actual = stripOffFrontMatter(doc.trim());
expect(actual.doc).toBe(body);
expect(actual.header).toEqual(frontMatter);
const actualCompiled = compileWithFrontMatter(actual);
expect(actualCompiled).toBe(compiled.trim());
}
});
});

View File

@ -1,30 +1,32 @@
import * as yaml from 'js-yaml';
const moment = require('moment');
export interface MarkdownAndFrontMatter {
doc: string;
export interface FrontMatter {
created?: Date;
updated?: Date;
source_url?: string;
forum_url?: string;
tweet?: string;
// Docusaurus
sidebar_label?: string;
sidebar_position?: number;
date?: string;
}
const readProp = (line: string): string[] => {
line = line.trim();
const d = line.indexOf(':');
return [line.substr(0, d).trim(), line.substr(d + 1).trim()];
};
export interface MarkdownAndFrontMatter {
doc: string;
header: FrontMatter;
}
export const stripOffFrontMatter = (md: string): MarkdownAndFrontMatter => {
if (md.indexOf('---') !== 0) return { doc: md };
if (md.indexOf('---') !== 0) return { doc: md, header: {} };
let state = 'start';
const lines = md.split('\n');
const docLines: string[] = [];
const output: MarkdownAndFrontMatter = {
doc: '',
};
const headerLines: string[] = [];
for (const line of lines) {
if (state === 'start') {
@ -40,10 +42,7 @@ export const stripOffFrontMatter = (md: string): MarkdownAndFrontMatter => {
}
const propLine = line.trim();
if (propLine) {
const p = readProp(propLine);
(output as any)[p[0]] = p[1];
}
headerLines.push(propLine);
}
if (state === 'out') {
@ -57,12 +56,13 @@ export const stripOffFrontMatter = (md: string): MarkdownAndFrontMatter => {
if (state !== 'doc') throw new Error('Front matter block was not closed with "---"');
output.doc = docLines.join('\n');
const header: Record<string, any> = yaml.load(headerLines.join('\n'), { schema: yaml.FAILSAFE_SCHEMA });
if (output.created) output.created = moment(output.created).toDate();
if (output.updated) output.updated = moment(output.updated).toDate();
if (header.created) header.created = moment(header.created).toDate();
if (header.updated) header.updated = moment(header.updated).toDate();
if ('sidebar_position' in header) header.sidebar_position = Number(header.sidebar_position);
return output;
return { header, doc: docLines.join('\n') };
};
// ---
@ -80,16 +80,15 @@ const formatFrontMatterValue = (key: string, value: any) => {
export const compileWithFrontMatter = (md: MarkdownAndFrontMatter): string => {
const output: string[] = [];
const header: string[] = [];
for (const [key, value] of Object.entries(md)) {
if (key === 'doc') continue;
header.push(`${key}: ${formatFrontMatterValue(key, value)}`);
}
if (header.length) {
if (Object.keys(md.header).length) {
const header = { ...md.header };
for (const [key, value] of Object.entries(header)) {
(header as any)[key] = formatFrontMatterValue(key, value);
}
const headerString = yaml.dump(header, { noCompatMode: true, schema: yaml.FAILSAFE_SCHEMA, lineWidth: 100000 });
output.push('---');
output.push(header.join('\n'));
output.push(headerString.trim());
output.push('---');
output.push('');
}

View File

@ -1,14 +1,14 @@
/* eslint-disable import/prefer-default-export */
import { MarkdownAndFrontMatter } from './frontMatter';
import { FrontMatter } from './frontMatter';
import { basename } from 'path';
const moment = require('moment');
export const getNewsDateString = (info: MarkdownAndFrontMatter, mdFilePath: string): string => {
export const getNewsDateString = (info: FrontMatter, mdFilePath: string): string => {
return moment(getNewsDate(info, mdFilePath)).format('D MMM YYYY');
};
export const getNewsDate = (info: MarkdownAndFrontMatter, mdFilePath: string): Date => {
export const getNewsDate = (info: FrontMatter, mdFilePath: string): Date => {
// If the date is set in the metadata, we get it from there. Otherwise we
// derive it from the filename (eg. 20220224-release-2-7.md)

View File

@ -8,6 +8,7 @@ interface ExecCommandOptions {
showStdout?: boolean;
showStderr?: boolean;
quiet?: boolean;
env?: Record<string, any>;
}
export default async (command: string | string[], options: ExecCommandOptions | null = null): Promise<string> => {
@ -16,6 +17,7 @@ export default async (command: string | string[], options: ExecCommandOptions |
showStdout: true,
showStderr: true,
quiet: false,
env: {},
...options,
};
@ -36,7 +38,7 @@ export default async (command: string | string[], options: ExecCommandOptions |
const args: string[] = typeof command === 'string' ? splitCommandString(command) : command as string[];
const executableName = args[0];
args.splice(0, 1);
const promise = execa(executableName, args);
const promise = execa(executableName, args, { env: options.env });
if (options.showStdout && promise.stdout) promise.stdout.pipe(process.stdout);
if (options.showStderr && promise.stderr) promise.stderr.pipe(process.stderr);
const result = await promise;

View File

@ -2,4 +2,41 @@
const Entities = require('html-entities').AllHtmlEntities;
const selfClosingElements = [
'area',
'base',
'basefont',
'br',
'col',
'command',
'embed',
'frame',
'hr',
'img',
'input',
'isindex',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr',
];
export const htmlentities = new Entities().encode;
export const attributesHtml = (attr: Record<string, any>) => {
const output = [];
for (const n in attr) {
if (!attr.hasOwnProperty(n)) continue;
output.push(`${n}="${htmlentities(attr[n])}"`);
}
return output.join(' ');
};
export const isSelfClosingTag = (tagName: string) => {
return selfClosingElements.includes(tagName.toLowerCase());
};

View File

@ -1,6 +1,6 @@
# Bienvenue dans Joplin !
Joplin est une application gratuite et open source de prise de notes, qui vous aide à rédiger et à organiser vos notes, et à les synchroniser entre vos appareils. Les notes sont consultables, peuvent être copiées, étiquetées et modifiées directement depuis l'application ou depuis votre propre éditeur de texte. Les notes sont au [format Markdown](https://joplinapp.org/help/#markdown). Joplin est disponible en tant qu'application de **bureau**, **mobile** et **terminal**.
Joplin est une application gratuite et open source de prise de notes, qui vous aide à rédiger et à organiser vos notes, et à les synchroniser entre vos appareils. Les notes sont consultables, peuvent être copiées, étiquetées et modifiées directement depuis l'application ou depuis votre propre éditeur de texte. Les notes sont au [format Markdown](https://joplinapp.org/help/apps/markdown). Joplin est disponible en tant qu'application de **bureau**, **mobile** et **terminal**.
Les notes de ce carnet donnent un aperçu de ce que Joplin peut faire et comment l'utiliser. En général, les trois applications partagent à peu près les mêmes fonctionnalités ; toute différence sera clairement indiquée.
@ -14,11 +14,11 @@ Joplin a trois colonnes principales :
- La **liste de notes** contient la liste actuelle des notes - soit les notes du bloc-notes actuellement sélectionné, les notes de l'étiquette actuellement sélectionnée ou les résultats de la recherche.
- L'**éditeur de notes** est là où vous écrivez vos notes. Il existe un **éditeur de texte enrichi** et un **éditeur Markdown** - cliquez sur le bouton **Basculer l'éditeur** dans le coin supérieur droit pour basculer entre les deux ! Vous pouvez également utiliser un [éditeur externe](https://joplinapp.org/help/#external-text-editor) pour modifier les notes. Par exemple, vous pouvez utiliser Typora comme éditeur externe et il affichera la note ainsi que toutes les images intégrées.
- L'**éditeur de notes** est là où vous écrivez vos notes. Il existe un **éditeur de texte enrichi** et un **éditeur Markdown** - cliquez sur le bouton **Basculer l'éditeur** dans le coin supérieur droit pour basculer entre les deux ! Vous pouvez également utiliser un [éditeur externe](https://joplinapp.org/help/apps/external_text_editor) pour modifier les notes. Par exemple, vous pouvez utiliser Typora comme éditeur externe et il affichera la note ainsi que toutes les images intégrées.
## Écrire des notes en Markdown
Markdown est un langage de balisage léger. Joplin prend en charge une [syntaxe Markdown à saveur Github](https://joplinapp.org/markdown/) avec quelques variantes et ajouts.
Markdown est un langage de balisage léger. Joplin prend en charge une [syntaxe Markdown à saveur Github](https://joplinapp.org/help/apps/markdown) avec quelques variantes et ajouts.
En général, bien que Markdown soit un langage de balisage, il lisible directement. Ceci est un exemple simple (vous pouvez voir à quoi il ressemble dans le panneau de visualisation) :
@ -44,7 +44,7 @@ Ceci est un [lien](https://joplinapp.org) et, enfin, ci-dessous est une règle h
* * *
Beaucoup plus est possible, y compris l'ajout d'exemples de code informatique, de formules mathématiques ou de listes de cases à cocher - voir la [documentation Markdown](https://joplinapp.org/help/#markdown) pour plus d'informations.
Beaucoup plus est possible, y compris l'ajout d'exemples de code informatique, de formules mathématiques ou de listes de cases à cocher - voir la [documentation Markdown](https://joplinapp.org/help/apps/markdown) pour plus d'informations.
## Organiser vos notes

View File

@ -4,12 +4,12 @@
Joplin peut importer des carnets complets depuis Evernote, ainsi que des notes, des étiquettes, des images, des fichiers joints et des métadonnées de note (telles que l'auteur, la géolocalisation, etc.) via des fichiers ENEX.
Pour importer des données Evernote, exportez d'abord vos carnets Evernote vers des fichiers ENEX comme décrit [ici](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restaurer-importer-notes-et-carnets). Ensuite, sur **bureau**, procédez comme suit : Ouvrez Fichier > Importer > ENEX et sélectionnez votre fichier. Les notes seront importées dans un nouveau cahier séparé. Si nécessaire, ils peuvent ensuite être déplacés vers un autre carnet, ou le carnet peut être renommé, etc. [En savoir plus sur l'importation Evernote](https://joplinapp.org/help/#importing-from-evernote).
Pour importer des données Evernote, exportez d'abord vos carnets Evernote vers des fichiers ENEX comme décrit [ici](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restaurer-importer-notes-et-carnets). Ensuite, sur **bureau**, procédez comme suit : Ouvrez Fichier > Importer > ENEX et sélectionnez votre fichier. Les notes seront importées dans un nouveau cahier séparé. Si nécessaire, ils peuvent ensuite être déplacés vers un autre carnet, ou le carnet peut être renommé, etc. [En savoir plus sur l'importation Evernote](https://joplinapp.org/help/apps/import_export#importing-from-evernote).
# Importation à partir d'autres applications
Joplin peut également importer des notes depuis [de nombreuses autres applications](https://github.com/laurent22/joplin#importing-from-other-applications) ainsi que [depuis Markdown ou depuis des fichiers texte](https://github.com/laurent22/joplin#importing-from-markdown-files).
Joplin peut également importer des notes depuis [de nombreuses autres applications](https://joplinapp.org/help/apps/import_export#importing-from-other-applications) ainsi que [depuis Markdown ou depuis des fichiers texte](https://joplinapp.org/help/apps/import_export#importing-from-markdown-files).
# Exporter des notes
Joplin peut exporter au format JEX (fichier d'exportation Joplin), qui est une archive pouvant contenir plusieurs notes, cahiers, etc. Il s'agit d'un format principalement conçu à des fins de sauvegarde. Vous pouvez également exporter vers d'autres formats tels que des fichiers Markdown simples, vers JSON ou vers PDF. Découvrez [l'exportation de notes](https://github.com/laurent22/joplin#exporting) sur le site officiel.
Joplin peut exporter au format JEX (fichier d'exportation Joplin), qui est une archive pouvant contenir plusieurs notes, cahiers, etc. Il s'agit d'un format principalement conçu à des fins de sauvegarde. Vous pouvez également exporter vers d'autres formats tels que des fichiers Markdown simples, vers JSON ou vers PDF. Découvrez [l'exportation de notes](https://joplinapp.org/help/apps/import_export#exporting) sur le site officiel.

View File

@ -18,8 +18,8 @@ Nextcloud est une solution de cloud pouvant être auto-hébergée. Pour le confi
## Configuration de la synchronisation OneDrive ou WebDAV
OneDrive et WebDAV sont également pris en charge en tant que services de synchronisation. Veuillez consulter [la documentation de synchronisation](https://github.com/laurent22/joplin#synchronisation) pour plus d'informations.
OneDrive et WebDAV sont également pris en charge en tant que services de synchronisation. Veuillez consulter [la documentation de synchronisation](https://joplinapp.org/help/apps/sync/) pour plus d'informations.
## Utilisation du chiffrement de bout en bout
Joplin prend en charge le chiffrement de bout en bout (E2EE) sur toutes les applications. E2EE est un système où seul le propriétaire des données peut les lire. Il empêche les espions potentiels, y compris les fournisseurs de télécommunications, les fournisseurs d'accès Internet et même les développeurs de Joplin, d'accéder aux données. Veuillez consulter le [tutoriel sur le chiffrement de bout en bout](https://joplinapp.org/e2ee/) pour plus d'informations sur cette fonctionnalité et comment l'activer.
Joplin prend en charge le chiffrement de bout en bout (E2EE) sur toutes les applications. E2EE est un système où seul le propriétaire des données peut les lire. Il empêche les espions potentiels, y compris les fournisseurs de télécommunications, les fournisseurs d'accès Internet et même les développeurs de Joplin, d'accéder aux données. Veuillez consulter le [tutoriel sur le chiffrement de bout en bout](https://joplinapp.org/help/apps/sync/e2ee) pour plus d'informations sur cette fonctionnalité et comment l'activer.

View File

@ -8,7 +8,7 @@ Les premières notes vous ont donné un aperçu des principales fonctionnalités
Le Web Clipper est une extension de navigateur qui vous permet d'enregistrer des pages Web et des captures d'écran à partir de votre navigateur. Pour commencer à l'utiliser, ouvrez l'application de bureau Joplin, accédez aux options du Web Clipper et suivez les instructions.
Plus d'infos sur le site officiel : https://joplinapp.org/clipper/
Plus d'infos sur le site officiel : https://joplinapp.org/help/apps/clipper/
## Plugins
@ -20,19 +20,19 @@ Tout type de fichier peut être joint à une note. Dans Markdown, les liens vers
Les images peuvent être jointes soit en cliquant sur "Joindre un fichier", soit en collant (avec `Ctrl+V` ou `Cmd+V`) une image directement dans l'éditeur, soit en glissant-déposant une image.
Plus d'infos sur les pièces jointes : https://joplinapp.org/help/#attachments
Plus d'infos sur les pièces jointes : https://joplinapp.org/help/apps/attachments
## Recherche
Joplin prend en charge les requêtes de recherche avancées, qui sont entièrement documentées sur le site officiel : https://joplinapp.org/help/#searching
Joplin prend en charge les requêtes de recherche avancées, qui sont entièrement documentées sur le site officiel : https://joplinapp.org/help/apps/search
## Alarmes
Une alarme peut être associée à n'importe quelle tâche. Elle sera déclenchée à l'heure indiquée par l'affichage d'une notification. Pour utiliser cette fonctionnalité, consultez la documentation : https://joplinapp.org/help/#notifications
Une alarme peut être associée à n'importe quelle tâche. Elle sera déclenchée à l'heure indiquée par l'affichage d'une notification. Pour utiliser cette fonctionnalité, consultez la documentation : https://joplinapp.org/help/apps/notifications
## Conseils avancés Markdown
Joplin utilise et rend [Github-flavored Markdown](https://joplinapp.org/markdown/) avec quelques variations et ajouts.
Joplin utilise et rend [Github-flavored Markdown](https://joplinapp.org/help/apps/markdown) avec quelques variations et ajouts.
Par exemple, les tableaux sont pris en charge :

View File

@ -0,0 +1,4 @@
position: 5
label: 'About'
collapsible: true
collapsed: true

Some files were not shown because too many files have changed in this diff Show More