diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..19cec67e --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,58 @@ +name: Deploy website to Pages + +on: + push: + branches: [master] + + # Allows to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Not needed if lastUpdated is not enabled + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci + - name: Build with VitePress + run: npm run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/.vitepress/dist + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml deleted file mode 100644 index 31e91a11..00000000 --- a/.github/workflows/jekyll.yml +++ /dev/null @@ -1,64 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll site to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["master"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Setup Ruby - uses: ruby/setup-ruby@8575951200e472d5f2d95c625da0c7bec8217c42 # v1.161.0 - with: - ruby-version: '3.1' # Not needed with a .ruby-version file - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - cache-version: 0 # Increment this number if you need to re-download cached gems - - name: Setup Pages - id: pages - uses: actions/configure-pages@v5 - - name: Build with Jekyll - # Outputs to the './_site' directory by default - run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" - env: - JEKYLL_ENV: production - - name: Upload artifact - # Automatically uploads an artifact from the './_site' directory by default - uses: actions/upload-pages-artifact@v3 - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 26e3ee96..d082db7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.vitepress/dist +.vitepress/cache _site node_modules tmp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..9803ee42 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "rs.js"] + path = rs.js + url = git@github.com:remotestorage/remotestorage.js.git + branch = master diff --git a/.vitepress/config.mts b/.vitepress/config.mts new file mode 100644 index 00000000..e6c49e30 --- /dev/null +++ b/.vitepress/config.mts @@ -0,0 +1,93 @@ +import { defineConfig } from 'vitepress' +import rsjsConfig from '../rs.js/docs/.vitepress/config.mts' + +type Item = { + text: string; + link: string; + items?: Item[]; +}; + +const prefixLinks = (array: Item[], prefix: string) => { + array.forEach(item => { + if (item.link) { + item.link = prefix + item.link; + } + if (item.items) { + prefixLinks(item.items, prefix); + } + }); +}; + +const rsjsSidebarConfig = rsjsConfig.themeConfig.sidebar +prefixLinks(rsjsSidebarConfig, '/rs.js/docs') + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "remoteStorage", + description: "An open protocol for per-user storage on the Web", + srcExclude: ['./wiki', './rs.js/*.md'], + ignoreDeadLinks: [ + /^http:\/\/localhost/, + ], + + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: "/logo.svg", + externalLinkIcon: true, + outline: { level: [2, 3] }, + + nav: [ + { text: 'Home', link: '/' }, + { text: 'Getting started', link: '/get' }, + { text: 'remoteStorage.js', link: '/rs.js/docs' }, + { text: 'Forums', link: 'https://community.remotestorage.io' }, + ], + + sidebar: { + '/': [ + { + items: [ + { text: 'Getting started', link: '/get' }, + { text: 'How it works', + items: [ + { text: 'Unhosted Web Apps', link: '/unhosted' }, + { text: 'Protocol', link: '/protocol' }, + ] + }, + { text: 'Apps', link: '/apps' }, + { text: 'Servers', link: '/servers' }, + { text: 'Contribute', link: '/contribute' }, + { text: 'Design', link: '/design' }, + ] + } + ], + '/rs.js/': rsjsSidebarConfig + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/remotestorage' }, + { icon: 'mastodon', link: 'https://kosmos.social/@remotestorage' } + ], + + editLink: { + pattern: ({ filePath }) => { + if (filePath.startsWith('rs.js/')) { + return `https://github.com/remotestorage/remotestorage.js/edit/master/${filePath}` + } else { + return `https://github.com/remotestorage/website/edit/master/${filePath}` + } + } + }, + + search: { + provider: 'local' + } + }, + + async transformPageData(pageData, { siteConfig }) { + if (pageData.relativePath.startsWith('rs.js')) { + pageData.titleTemplate = 'remoteStorage.js' + } + return pageData; + } +}) diff --git a/.vitepress/theme/components/Contributors.vue b/.vitepress/theme/components/Contributors.vue new file mode 100644 index 00000000..615e6417 --- /dev/null +++ b/.vitepress/theme/components/Contributors.vue @@ -0,0 +1,53 @@ + + + + + + diff --git a/.vitepress/theme/components/DeveloperFeatures.vue b/.vitepress/theme/components/DeveloperFeatures.vue new file mode 100644 index 00000000..0a0251a0 --- /dev/null +++ b/.vitepress/theme/components/DeveloperFeatures.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/.vitepress/theme/index.js b/.vitepress/theme/index.js new file mode 100644 index 00000000..a2b93cc5 --- /dev/null +++ b/.vitepress/theme/index.js @@ -0,0 +1,20 @@ +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue' +import DefaultTheme from 'vitepress/theme' +import DeveloperFeatures from './components/DeveloperFeatures.vue' +import Contributors from './components/Contributors.vue' +import './style.css' + +/** @type {import('vitepress').Theme} */ +export default { + extends: DefaultTheme, + Layout: () => { + return h(DefaultTheme.Layout, null, { + 'home-features-after': () => h(DeveloperFeatures) + // https://vitepress.dev/guide/extending-default-theme#layout-slots + }) + }, + enhanceApp({ app, router, siteData }) { + app.component('Contributors', Contributors) + } +} diff --git a/.vitepress/theme/style.css b/.vitepress/theme/style.css new file mode 100644 index 00000000..da94ebfb --- /dev/null +++ b/.vitepress/theme/style.css @@ -0,0 +1,140 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attched to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + + :root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + /* --vp-home-hero-name-color: #ff4b03; */ + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 270deg, + #ff6d32 30%, + #ff4b03 + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #bd34fe 50%, + #47caff 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} + diff --git a/Gemfile b/Gemfile deleted file mode 100644 index 667f12f1..00000000 --- a/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -source "https://rubygems.org" - -gem "github-pages", "~> 219", group: :jekyll_plugins -gem "just-the-docs" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 4698b1ae..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,274 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - activesupport (6.0.6.1) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) - colorator (1.1.0) - commonmarker (0.17.13) - ruby-enum (~> 0.5) - concurrent-ruby (1.2.3) - dnsruby (1.72.1) - simpleidn (~> 0.2.1) - em-websocket (0.5.3) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0) - ethon (0.16.0) - ffi (>= 1.15.0) - eventmachine (1.2.7) - execjs (2.9.1) - faraday (2.9.0) - faraday-net_http (>= 2.0, < 3.2) - faraday-net_http (3.1.0) - net-http - ffi (1.16.3) - forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (219) - github-pages-health-check (= 1.17.7) - jekyll (= 3.9.0) - jekyll-avatar (= 0.7.0) - jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.1.6) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.15.1) - jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.13.0) - jekyll-mentions (= 1.6.0) - jekyll-optional-front-matter (= 0.3.2) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.3.0) - jekyll-redirect-from (= 0.16.0) - jekyll-relative-links (= 0.6.1) - jekyll-remote-theme (= 0.4.3) - jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.7.1) - jekyll-sitemap (= 1.4.0) - jekyll-swiss (= 1.0.0) - jekyll-theme-architect (= 0.2.0) - jekyll-theme-cayman (= 0.2.0) - jekyll-theme-dinky (= 0.2.0) - jekyll-theme-hacker (= 0.2.0) - jekyll-theme-leap-day (= 0.2.0) - jekyll-theme-merlot (= 0.2.0) - jekyll-theme-midnight (= 0.2.0) - jekyll-theme-minimal (= 0.2.0) - jekyll-theme-modernist (= 0.2.0) - jekyll-theme-primer (= 0.6.0) - jekyll-theme-slate (= 0.2.0) - jekyll-theme-tactile (= 0.2.0) - jekyll-theme-time-machine (= 0.2.0) - jekyll-titles-from-headings (= 0.5.3) - jemoji (= 0.12.0) - kramdown (= 2.3.1) - kramdown-parser-gfm (= 1.1.0) - liquid (= 4.0.3) - mercenary (~> 0.3) - minima (= 2.5.1) - nokogiri (>= 1.10.4, < 2.0) - rouge (= 3.26.0) - terminal-table (~> 1.4) - github-pages-health-check (1.17.7) - addressable (~> 2.3) - dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (>= 3.0, < 5.0) - typhoeus (~> 1.3) - html-pipeline (2.14.3) - activesupport (>= 2) - nokogiri (>= 1.4) - http_parser.rb (0.8.0) - i18n (0.9.5) - concurrent-ruby (~> 1.0) - jekyll (3.9.0) - addressable (~> 2.4) - colorator (~> 1.0) - em-websocket (~> 0.5) - i18n (~> 0.7) - jekyll-sass-converter (~> 1.0) - jekyll-watch (~> 2.0) - kramdown (>= 1.17, < 3) - liquid (~> 4.0) - mercenary (~> 0.3.3) - pathutil (~> 0.9) - rouge (>= 1.7, < 4) - safe_yaml (~> 1.0) - jekyll-avatar (0.7.0) - jekyll (>= 3.0, < 5.0) - jekyll-coffeescript (1.1.1) - coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) - jekyll (>= 3.7, < 5.0) - jekyll-commonmark-ghpages (0.1.6) - commonmarker (~> 0.17.6) - jekyll-commonmark (~> 1.2) - rouge (>= 2.0, < 4.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.15.1) - jekyll (>= 3.7, < 5.0) - jekyll-gist (1.5.0) - octokit (~> 4.2) - jekyll-github-metadata (2.13.0) - jekyll (>= 3.4, < 5.0) - octokit (~> 4.0, != 4.4.0) - jekyll-include-cache (0.2.1) - jekyll (>= 3.7, < 5.0) - jekyll-mentions (1.6.0) - html-pipeline (~> 2.3) - jekyll (>= 3.7, < 5.0) - jekyll-optional-front-matter (0.3.2) - jekyll (>= 3.0, < 5.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.3.0) - jekyll (>= 3.0, < 5.0) - jekyll-redirect-from (0.16.0) - jekyll (>= 3.3, < 5.0) - jekyll-relative-links (0.6.1) - jekyll (>= 3.3, < 5.0) - jekyll-remote-theme (0.4.3) - addressable (~> 2.0) - jekyll (>= 3.5, < 5.0) - jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) - rubyzip (>= 1.3.0, < 3.0) - jekyll-sass-converter (1.5.2) - sass (~> 3.4) - jekyll-seo-tag (2.7.1) - jekyll (>= 3.8, < 5.0) - jekyll-sitemap (1.4.0) - jekyll (>= 3.7, < 5.0) - jekyll-swiss (1.0.0) - jekyll-theme-architect (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-cayman (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-dinky (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-hacker (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-leap-day (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-merlot (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-midnight (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-minimal (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-modernist (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-primer (0.6.0) - jekyll (> 3.5, < 5.0) - jekyll-github-metadata (~> 2.9) - jekyll-seo-tag (~> 2.0) - jekyll-theme-slate (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-tactile (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-time-machine (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.5.3) - jekyll (>= 3.3, < 5.0) - jekyll-watch (2.2.1) - listen (~> 3.0) - jemoji (0.12.0) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (>= 3.0, < 5.0) - just-the-docs (0.8.2) - jekyll (>= 3.8.5) - jekyll-include-cache - jekyll-seo-tag (>= 2.0) - rake (>= 12.3.1) - kramdown (2.3.1) - rexml - kramdown-parser-gfm (1.1.0) - kramdown (~> 2.0) - liquid (4.0.3) - listen (3.9.0) - rb-fsevent (~> 0.10, >= 0.10.3) - rb-inotify (~> 0.9, >= 0.9.10) - mercenary (0.3.6) - mini_portile2 (2.8.6) - minima (2.5.1) - jekyll (>= 3.5, < 5.0) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - minitest (5.22.3) - net-http (0.4.1) - uri - nokogiri (1.16.4) - mini_portile2 (~> 2.8.2) - racc (~> 1.4) - octokit (4.25.1) - faraday (>= 1, < 3) - sawyer (~> 0.9) - pathutil (0.16.2) - forwardable-extended (~> 2.6) - public_suffix (4.0.7) - racc (1.7.3) - rake (13.2.1) - rb-fsevent (0.11.2) - rb-inotify (0.10.1) - ffi (~> 1.0) - rexml (3.2.6) - rouge (3.26.0) - ruby-enum (0.9.0) - i18n - rubyzip (2.3.2) - safe_yaml (1.0.5) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.9.2) - addressable (>= 2.3.5) - faraday (>= 0.17.3, < 3) - simpleidn (0.2.2) - unf (~> 0.1.4) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) - typhoeus (1.4.1) - ethon (>= 0.9.0) - tzinfo (1.2.11) - thread_safe (~> 0.1) - unf (0.1.4) - unf_ext - unf_ext (0.0.9.1) - unicode-display_width (1.8.0) - uri (0.13.0) - zeitwerk (2.6.13) - -PLATFORMS - ruby - -DEPENDENCIES - github-pages (~> 219) - just-the-docs - -BUNDLED WITH - 2.5.9 diff --git a/README.md b/README.md index d9bef553..2a764d5b 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,44 @@ # remotestorage.io This is the remoteStorage website, running on -[https://remotestorage.io](https://remotestorage.io). +[remotestorage.io](https://remotestorage.io). ## Development -The website is built using [Jekyll](https://jekyllrb.com/) and the -[Just the Docs](https://pmarsceill.github.io/just-the-docs/) theme. +The website is built using [VitePress](https://vitepress.dev/).It includes the +remoteStorage.js documentation via a Git submodule. ### Setup -With [Git](https://git-scm.com) and -[Ruby 2.5 - 2.7](https://www.ruby-lang.org/en/documentation/installation) installed, -run the following command to install dependencies: +With [Git](https://git-scm.com) and [node.js](https://nodejs.org) installed, +and an SSH key associated with your GitHub account... +Clone this repo: + +```sh +git clone git@github.com:remotestorage/website.git +cd website +``` + +Initialize and fetch the rs.js submodule: + +```sh +git submodule update --init ``` -bundle install + +Install the dependencies: + +```sh +npm install ``` ### Running -Run the following command to build the static site to `/_site` and make it -accessible at -http://localhost:4000. -Changes to `.md` files should be visible automatically without refreshing. +Run the local dev server, which automatically updates the local preview site +whenever documents are saved: ``` -bundle exec jekyll serve +npm run docs:dev ``` ### Deployment diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 992cc220..00000000 --- a/_config.yml +++ /dev/null @@ -1,16 +0,0 @@ -# https://github.com/pmarsceill/just-the-docs/blob/master/_config.yml - -title: remoteStorage -description: Open protocol for per-user storage on the Web -repository: remotestorage/website -theme: just-the-docs -permalink: pretty -search_enabled: false - -# Footer "Edit this page on GitHub" link text -gh_edit_link: true # show or hide edit this page link -gh_edit_link_text: "Edit this page on GitHub" -gh_edit_repository: "https://github.com/remotestorage/website" # the github URL for your repo -gh_edit_branch: "master" # the branch that your docs is served from -# gh_edit_source: docs # the source that your files originate from -gh_edit_view_mode: "edit" # "tree" or "edit" if you want the user to jump into the editor immediately diff --git a/apps.md b/apps.md index 70bab94d..af7ea179 100644 --- a/apps.md +++ b/apps.md @@ -1,8 +1,3 @@ ---- -title: Apps -nav_order: 4 ---- - # Apps The following is a list of known apps that have integrated RS as a @@ -16,6 +11,7 @@ may be outdated. ### Productivity / Office | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [Papiers](https://papiers.gitlab.io/) | A simple but powerful note-taking app that syncs with your own cloud. | Notes | [GitLab](https://gitlab.com/papiers) | Full [PWA](https://papiers.gitlab.io/) | | [Todonna](https://todonna.gitlab.io/) | A simple but powerful Todo app that syncs with your own cloud. | Todo | [GitLab](https://gitlab.com/todonna) | Full [PWA](https://todonna.gitlab.io/) | | [Litewrite](https://litewrite.net) | A distraction-free app for simple note taking and writing | documents / [Documents](https://github.com/litewrite/remotestorage-module-documents) | [GitHub](https://github.com/litewrite/litewrite) | [Chrome Web Store](https://chrome.google.com/webstore/detail/litewrite/cbdonnipllnmnkbmeopncohocjggmdkk) Works well on mobile and desktop | @@ -33,6 +29,7 @@ may be outdated. ### Site Builder / Wiki | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [Hyperdraft](https://hyperdraft.rosano.ca) | Turn your text notes into a website. | wikiavec | [GitHub](https://github.com/wikiavec/hyperdraft) | Works well on mobile and desktop | | [TiddlyWiki remoteStorage](https://tiddly.alhur.es/#%24%3A%2Fplugins%2Ffiatjaf%2FremoteStorage) | A [TiddlyWiki](https://tiddlywiki.com/) plugin that enables saving of individual tiddlers to remoteStorage. | tiddlers | [GitHub](https://github.com/fiatjaf/tiddlywiki-remotestorage) | A hosted version you can edit and share without installing anything is available on [https://tiddly.alhur.es/](https://tiddly.alhur.es/) | | [QuikWik](https://quik-wik.5apps.com/) | A small and simple Wiki which uses Markdown syntax and stores data in localStorage and remoteStorage. | wiki | [GitHub](https://github.com/maheee/QuikWik) | @@ -40,12 +37,14 @@ may be outdated. ### Learning / Self-Improvement | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [Kommit](https://kommit.rosano.ca) | Flashcards with spaced-repetition | kommit | [GitHub](https://github.com/kommitapp/kommit) | Works well on mobile and desktop | | [Emoji Log](https://emojilog.rosano.ca) | Personal tracker organized with emoji | emojilog | [GitHub](https://github.com/emojilog/emojilog) | Works well on mobile and desktop | ### Media Consumption | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [Pétrolette](https://petrolette.space/) | A news aggregator / Web page that syncs using Remote Storage | petrolette | [GitLab](https://framagit.org/yphil/petrolett) | Works well on mobile and desktop | | [Àlir](https://alir.5apps.com) | Read-later app | alir | forked on [GitHub](https://github.com/rosano/alir) | Designed for mobiles, works offline | | [Joybox](https://joybox.rosano.ca) | A pinboard for audiovisual media. | joybox | [GitHub](https://github.com/joyboxapp/joybox) | Works well on mobile and desktop | @@ -55,6 +54,7 @@ may be outdated. ### Finance | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [hledger interactive](https://hledger.alhur.es/) | Parser and playground for [hledger](https://hledger.org) journals. | finance | [GitHub](https://github.com/fiatjaf/d) | Can save and load multiple journals to/from remoteStorage | | [Grouptabs](https://grouptabs.5apps.com) | Track expenses in a group of people | gruppenkasse | [GitHub](https://github.com/xMartin/grouptabs) | Best on mobile; needs shared storage account if you want to use it with a group | | [Road To FIRE](https://roadtofire.iliviu.me/) | A portfolio manager app for your stocks, ETFs, mutual funds, bonds, cryptocurrencies, commodities, P2P loans and real estate | asset-portfolio | [GitHub](https://github.com/iLiviu/road-to-fire) | Works well on mobile and desktop | @@ -62,12 +62,14 @@ may be outdated. ### Password | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [LessPass remoteStorage](https://lesspass.alhur.es/) | A new, faster [LessPass](https://lesspass.com/) widget that does autofill and saves options on remoteStorage. | lesspass | [GitHub](https://github.com/fiatjaf/lesspass-remotestorage) | [Firefox Add-on](https://addons.mozilla.org/en-US/firefox/addon/lesspass-remotestorage/) Save password profiles based on the domain you are; supports multiple profiles for each domain | | [PfP: Pain-free Passwords](https://pfp.works/) | A secure and convenient password manager that keeps you in control of your data. | pfp | [GitHub](https://github.com/palant/pfp/) | [Firefox Add-on](https://addons.mozilla.org/addon/easy-passwords/) [Chrome Extension](https://chrome.google.com/webstore/detail/pfp-pain-free-passwords/hplhaekjfmjfnfdllkpjpeenlbclffgh) [Opera Add-on](https://addons.opera.com/en/extensions/details/easy-passwords/) Syncs any number of devices via remoteStorage as long as they share the same master password; remoteStorage server doesn't have to be trusted, data is fully encrypted | ### Miscellaneous | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [Launchlet](https://launchlet.dev) | Run custom JavaScript or CSS on any website via bookmarklet or extension. | launchlet | [GitHub](https://github.com/launchlet/launchlet) | [Chrome Extension](https://chrome.google.com/webstore/detail/launchlet/gmgfdkajnjplpjmodjmmmkfkpjdjgnlf) [Safari Extension](https://github.com/launchlet/launchlet-extension) Works via bookmarklet or browser extension; mostly works on mobile, but best on desktop | | [Sharesome](https://sharesome.5apps.com/) | Share files quickly from your remote storage | shares | [GitHub](https://github.com/skddc/sharesome) | Best on desktop | | [Webmarks](https://webmarks.5apps.com) | Archive your bookmarks in remoteStorage | bookmarks / [bookmarks](https://www.npmjs.com/package/@remotestorage/module-bookmarks) | [GitHub](https://github.com/skddc/webmarks) | Best on desktop | @@ -80,6 +82,7 @@ may be outdated. ### Sample / Tutorial | **Name** | **Description** | **Scope/Module** | **Source Code** | **Store/Catalog & Notes** | +| - | - | - | - | - | | [My Favorite Drinks](https://myfavoritedrinks.remotestorage.io) | Keep a list of your favorite drinks | myfavoritedrinks | [GitHub](https://github.com/RemoteStorage/myfavoritedrinks) | Simple demo app, maintained by rs.js devs | | [Hello](https://hello.0data.app) | Simple Hello World with remoteStorage, Solid, and Fission | todos | [GitHub](https://github.com/0dataapp/hello) | Works well on mobile and desktop | | [Lucchetto Onboard](https://overhide.github.io/armadietto/lucchetto/onboard.html) | Enables in-app purchase SKU onboarding for [luchetto.js](https://www.npmjs.com/package/lucchetto/v/latest) extended RS apps | pay2my.app | [GitHub](https://github.com/overhide/armadietto/blob/master/lucchetto/onboard.html) | wide screens only; featured in the [remote-storage tutorial](https://github.com/overhide/remotestorage-tutorial) | @@ -89,14 +92,14 @@ may be outdated. ## CLI applications, daemons, libraries -| Name | Description | Scope / Module | Source Code | Store/Catalog Links | Comments/Notes | -| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------ | ----------------------------------------------- | ---------------- | -| [remote-storage-uploader](http://github.com/fkooman/remote-storage-uploader) | Send files to public upload folder | upload | [GitHub](https://github.com/fkooman/remote-storage-uploader) | | Written in PHP | -| [rs-backup](https://www.npmjs.com/package/rs-backup) | Backup and restore data from/to RS accounts | \* | [GitHub](https://github.com/skddc/rs-backup) | [NPM](https://www.npmjs.com/package/rs-backup) | Based on node.js | -| [remotestorage-fuse](https://github.com/remotestorage/fuse) | Allows you to access data on any RS-compatible server via the regular filesystem | \* | [GitHub](https://github.com/remotestorage/fuse) | | | -| [hubot-remotestorage-logger](https://github.com/67P/hubot-remotestorage-logger) | Logs chat messages from Hubot daemons to remoteStorage accounts | chat-messages / [remotestorage-module-chat-messages](https://www.npmjs.com/package/remotestorage-module-chat-messages) | [GitHub](https://github.com/67P/hubot-remotestorage-logger) | | | -| [rs-messages-importer](https://github.com/67P/rs-messages-importer) | CLI for importing log archives (currently only ZNC) to remoteStorage | chat-messages | [GitHub](https://github.com/67P/rs-messages-importer) | | | -| [Unifile](https://github.com/silexlabs/unifile) | Node.js library to access cloud storage services with a common API | | [GitHub](https://github.com/silexlabs/unifile) | | | +| Name | Description | Scope / Module | Source Code | Store/Catalog Links | Comments/Notes | +| - | - | - | - | - | - | +| [remote-storage-uploader](http://github.com/fkooman/remote-storage-uploader) | Send files to public upload folder | upload | [GitHub](https://github.com/fkooman/remote-storage-uploader) | | Written in PHP | +| [rs-backup](https://www.npmjs.com/package/rs-backup) | Backup and restore data from/to RS accounts | \* | [GitHub](https://github.com/skddc/rs-backup) | [NPM](https://www.npmjs.com/package/rs-backup) | Based on node.js | +| [remotestorage-fuse](https://github.com/remotestorage/fuse) | Allows you to access data on any RS-compatible server via the regular filesystem | \* | [GitHub](https://github.com/remotestorage/fuse) | | +| [hubot-remotestorage-logger](https://github.com/67P/hubot-remotestorage-logger) | Logs chat messages from Hubot daemons to remoteStorage accounts | chat-messages / [remotestorage-module-chat-messages](https://www.npmjs.com/package/remotestorage-module-chat-messages) | [GitHub](https://github.com/67P/hubot-remotestorage-logger) | | | +| [rs-messages-importer](https://github.com/67P/rs-messages-importer) | CLI for importing log archives (currently only ZNC) to remoteStorage | chat-messages | [GitHub](https://github.com/67P/rs-messages-importer) | | | +| [Unifile](https://github.com/silexlabs/unifile) | | | | | | ## Notes diff --git a/contribute.md b/contribute.md index 2b430791..3399e17b 100644 --- a/contribute.md +++ b/contribute.md @@ -1,72 +1,87 @@ ---- -title: Contribute -nav_order: 6 ---- - -What can I do for remoteStorage? - -* I can code -* I can design -* I can write -* I can run servers -* I can test things - ---- - -# I can code - -## JavaScript - -* Integrate RS in any of your apps. More apps means more users, means more developers, means more apps. -* Help out with the [reference client](https://github.com/remotestorage/remotestorage.js/). There are always [issues](https://github.com/remotestorage/remotestorage.js/issues) to work on -* Help with completing and improving the remoteStorage.js [documentation](http://remotestoragejs.readthedocs.io/en/latest/) (even if it's just questions or feedback). There is more detailed information about how to [contribute to the documentation](http://remotestoragejs.readthedocs.io/en/latest/contributing/docs.html). -* Contribute to any open-source remoteStorage app. Some of them are [listed here](/apps "Apps"). -* Help improving and creating new remoteStorage.js [data modules](https://github.com/remotestorage/modules) -* Help improving [Armadietto](https://github.com/remotestorage/armadietto/), a RS server based on node.js - -## PHP +# What can I do for remoteStorage? + +## I can code + +### JavaScript + +* Integrate RS in any of your apps. More apps means more users, means more + developers, means more apps. +* Help out with the [reference + client](https://github.com/remotestorage/remotestorage.js/). There are always + [issues](https://github.com/remotestorage/remotestorage.js/issues) to work on +* Help with completing and improving the remoteStorage.js + [documentation](./rs.js/docs/) (even if + it's just questions or feedback). There is more detailed information about + how to [contribute to the documentation](./rs.js/docs/contributing/docs). +* Contribute to any open-source remoteStorage app. Some of them are [listed + here](/apps "Apps"). +* Help improving and creating new remoteStorage.js [data + modules](https://github.com/remotestorage/modules) +* Help improving [Armadietto](https://github.com/remotestorage/armadietto/), a + maintained RS server based on node.js + +### PHP * Help out with [php-remote-storage](https://git.sr.ht/~fkooman/php-remote-storage), a remoteStorage server written in PHP -## Rust +### Rust * Contribute to [Mysteryshack](https://github.com/untitaker/mysteryshack), a light-weight, fast, self-contained RS server -## Ruby +### Ruby -* There's an [integration test suite](https://github.com/remotestorage/api-test-suite) for testing local and/or live remoteStorage servers for API compliance, which is written in Ruby (minitest/spec). It's not 100% complete yet. Ping us on the [forums](https://community.remotestorage.io/) or [IRC](https://kiwiirc.com/client/irc.freenode.net/#remotestorage), if you'd like to contribute! -* Write integrations for [Huginn](https://github.com/huginn/huginn) (an open-source IFTTT/Zapier alternative) that automatically copy your data from silos to your own storage +* There is a maintained RS server implementation written in Ruby, consisting of an + [accounts management app and UI](https://gitea.kosmos.org/kosmos/akkounts/) + based on Rails, and a [RS HTTP API based on + Sinatra](https://github.com/5apps/liquor-cabinet) +* There's an [integration test + suite](https://github.com/remotestorage/api-test-suite) for testing local + and/or live remoteStorage servers for API compliance, which is written in + Ruby (minitest/spec). -## Java +### Java * We'd like to create an Android sync adapter that synchronizes calendars and contacts. See [this thread](https://community.remotestorage.io/t/synchronization-with-carddav-caldav/307/4) if you would like to help. * Create an Android app that integrates sharing, for e.g. URLs to the bookmarks category, or images to the shares module. -## C +### C -* There's a [remoteStorage FUSE module](https://github.com/remotestorage/fuse) for mounting storages as filesystems, which needs upgrading to newer protocol versions and finishing in general. -* There's a [remoteStorage server](https://github.com/remotestorage/rs-serve) written in C (with a little node.js helper app), which needs upgrading and has some installation issues. +* There's a [remoteStorage FUSE module](https://github.com/remotestorage/fuse) + for mounting storages as filesystems, which needs upgrading to newer protocol + versions and finishing in general. +* There's a [remoteStorage server](https://github.com/remotestorage/rs-serve) + written in C (with a little node.js helper app), which needs upgrading and + has some installation issues. -# I can design +## I can design -* Improve the design of our website and/or wiki. Both could look much more beautiful with your help. The website repo is located at [https://github.com/remotestorage/website](https://github.com/remotestorage/website) and we have a [waffle.io board for website issues](https://waffle.io/remotestorage/website). -* Design a new landing page for users coming from apps and the RS connect widget. -* Help improve the design of any RS-enabled open source app (see [Apps](/apps "Apps") e.g.). Many of them are in need of better app icons and/or UI/UX improvements. Giving feedback on design decisions and how to improve apps is a good start as well. -* See [Design](/wiki/design "Design") for more info. +* Improve the design of this website. The website repo is located at + [https://github.com/remotestorage/website](https://github.com/remotestorage/website) +* Help improve the design of any RS-enabled open source (see e.g. [apps](/apps)). Or + design a new one and find a developer to help you with implementing it. -# I can write +## I can write -* Add and/or improve content of the RS website, any page on this wiki, or any other project-related content on the Web. -* Help us improve existing technical documentation (lots of room for your contributions/improvements). There are e.g. the [remoteStorage.js API docs](http://remotestoragejs.readthedocs.io/en/latest/), the [remoteStorage.js Beginner's Guide](/wiki/beginners), or any page linked on and including the [Developer Portal](/wiki/developers). -* Help improve documentation, description and marketing materials for RS-enabled open-source [apps](/apps "Apps") and [servers](/servers "Servers"). -* Write about remoteStorage on your website, blog, social media, etc.. Explain the concept to users, developers, providers, and anyone else you think should know about remoteStorage's existence and how it works. -* Improve the language and clarity of the remoteStorage specification draft (see [Protocol](/protocol)). +* Add and/or improve content of the RS website, or any other project-related + content on the Web. +* Help us improve existing technical documentation. e.g. the [remoteStorage.js + docs](./rs.js/docs/) +* Help improve documentation, description and marketing materials for + RS-enabled open-source [apps](/apps) and [servers](/servers). +* Write about remoteStorage on your website, blog, social media, etc.. Explain +* the concept to users, developers, providers, and anyone else you think should + know about remoteStorage's existence and how it works. +* Improve the language and clarity of the [protocol + specification](https://github.com/remotestorage/spec) -# I can run servers +## I can run servers -* Set up a [server](/servers "Server") for yourself and maybe your family and friends! -* Become a commercial or non-profit storage provider. You can either implement your own or use [existing server](/servers "Servers") software as your basis. +* Set up a [server](/servers) for yourself and maybe your family and + friends! +* Become a commercial or non-profit storage provider. You can either implement + your own or use [existing server](/servers) software as your basis. -# I can test things +## I can test things -* Use RS-enabled [apps](/apps "Apps") and/or [servers](/servers "Servers") and report issues and constructive feedback. +* Use RS-enabled [apps](/apps) and/or [servers](/servers) and + report issues and constructive feedback. diff --git a/design.md b/design.md new file mode 100644 index 00000000..a4bf9a69 --- /dev/null +++ b/design.md @@ -0,0 +1,11 @@ +# Design + +## Logo / icon + + + +The remoteStorage logo may be used, integrated, and adapted for anything +related to the [protocol](protocol) or implementations of it. + +You can find the logo, as well as some other assets, in the [remoteStorage +Design](https://github.com/remotestorage/design/) repository. diff --git a/doc/code/index.html b/doc/code/index.html deleted file mode 100644 index fc187a56..00000000 --- a/doc/code/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - Moved to https://remotestorage.github.io/remotestorage.js/ - - - diff --git a/get.md b/get.md index fba2dd88..70113e2a 100644 --- a/get.md +++ b/get.md @@ -1,21 +1,15 @@ ---- -# The remoteStorage widget links to /get, so consider that if renaming this and create appropriate redirects. -title: Getting Started -nav_order: 2 ---- +# Getting started -# Getting Started +Here's how to use an app that allows you to connect your own storage account. -Here are the steps to using an app that allows you to connect your own storage account: 👇 +## Step 1: **Get a remoteStorage account** 🔑 -1. **Create a remoteStorage account** 🔑 +You might be used to signing up _with an app_, but here you sign up _with a storage provider_ so that you can use the same account with multiple apps. - You might be used to signing up 'with an app', but here you sign up with a 'storage provider' so that you can use the *same account with multiple apps*. +- If a friend or administrator has set up an account for you, get the details from them. +- [5apps](https://5apps.com/storage/beta) is a commercial remoteStorage provider that currently offers free storage accounts. +- A more extensive list of options can be found on the [Servers](/servers) page. - - If a friend or administrator has set up an account for you, get the details from them. - - [5apps](https://5apps.com/storage/beta) is a commercial remoteStorage provider that currently offers free storage accounts. - - A more extensive list of options can be found on the [Servers](/servers) page. +## Step 2: **Connect your storage** 🔌 -2. **Connect your storage** 🔌 - - Once you create an account, return to the app to 'connect your storage', or explore some of the other [remoteStorage-compatible apps](/apps). +Once you create an account, return to the app to 'connect your storage', or explore some of the other [remoteStorage-compatible apps](/apps). diff --git a/index.md b/index.md index fbb39ebc..975ff80b 100644 --- a/index.md +++ b/index.md @@ -1,115 +1,50 @@ --- -title: Home -nav_order: 1 -permalink: / +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "remoteStorage" + text: "An open protocol for per-user storage on the Web" + tagline: "Webfinger + OAuth + CORS + REST" + actions: + - theme: brand + text: 'Get Storage' + link: '/get' + + - theme: alt + text: How it works + link: /unhosted + +features: + - title: Own your data + details: "Everything in one place – your place. Use a storage account with a provider you trust, or set up your own storage server. Move house whenever you want. It's your data." + - title: Stay in sync + details: "remoteStorage-enabled apps automatically sync your data across all of your devices, from desktop to tablet to smartphone, and maybe even your TV or VR headset." + - title: "Compatibility & choice" + details: "Use the same data across different apps. Create a to-do list in one app, and track the time on your tasks in another one. Say goodbye to app-specific data silos." + - title: Go offline + details: "Most remoteStorage-enabled apps come with first-class offline support. Use your apps offline on the go, and automatically sync when you're back online." + +devFeaturesTitle: For App Developers 🚧 +devFeatures: + - title: Backend as a service + details: "Develop your web app without worrying about hosting or developing a backend for it. Your users will connect their own backend at runtime. No more worrying about accounts, databases, passwords, etc." + - title: Infinite scalability, zero cost + details: "No matter if 5 hundred or 5 million people are using your app, your backend scales automatically and never costs you a single cent." + - title: JS client library + details: "remoteStorage.js is a JavaScript/TypeScript library that does the heavy lifting to add offline storage and cross-device synchronization to your apps." + link: /rs.js/docs/ + linkText: Learn more --- -
- -
-

remoteStorage

- Open protocol for per-user storage on the Web -
- Webfinger + OAuth + CORS + REST -
-
- ---- - -# Features -{: .fs-9 } - -## For users - -### Own your data - -Everything in one place – your place. Use a storage account with a provider you trust, or set up your own storage server. Move house whenever you want. It's your data. - -### Stay in sync - -remoteStorage-enabled apps automatically sync your data across all of your devices, from desktop to tablet to smartphone, and maybe even your TV or VR headset. - -### Compatibility & choice - -Use the same data across different apps. Create a to-do list in one app, and track the time on your tasks in another one. Say goodbye to app-specific data silos. - -### Go offline - -Most remoteStorage-enabled apps come with first-class offline support. Use your apps offline on the go, and automatically sync when you're back online. - -## For developers - -### Backend as a Service - -Develop your web app without worrying about hosting or even developing the backend for it: your users will connect their own backend at runtime. - -### Infinite Scalability - -No matter if 5 hundred or 5 million users are using your app, your backend scales automatically and never costs you a single cent. - -### Wheels Included - -remoteStorage.js is a JavaScript library that does all the heavy-lifting of connecting to any remoteStorage backend, caching, synchronizing and storing user data. - -[Browse apps](/apps){: .btn .btn-primary .fs-5 .my-4 .mb-md-0 .mr-4 } [Get storage](/servers){: .btn .fs-5 .my-4 .mb-md-0 } - ---- - -# Developer library - -The [remoteStorage.js](https://github.com/remotestorage/remotestorage.js) library does most of the heavy lifting to add offline storage and cross-device synchronization to your apps. No more worrying about accounts, databases, passwords… - -## Setup - -```javascript -const rs = new RemoteStorage(); -rs.access.claim('todos', 'rw'); -rs.caching.enable(); - -const client = rs.scope('/todos/'); -``` - -## Write an object - -```javascript -// Declare an object type to validate if you want (JSON Schema) -client.declareType('todo-item', {}); - -// Write `{"id":"alfa","done":false}` to /todos/alfa.json -await client.storeObject('todo-item', 'alfa.json', { - id: 'alfa', - done: false, -}); -``` - -## Get objects - -```javascript -const specificItem = await client.getObject('alpha.json'); -const allTodoItems = await client.getAll(); -``` - -## Add the Connect Widget UI component - -Use our [drop-in UI widget](https://github.com/remotestorage/remotestorage-widget) for connecting remote storage accounts. - -```javascript -const widget = new Widget(rs); -widget.attach(); -``` - -[Read the documentation](https://remotestoragejs.readthedocs.io){: .btn .btn-primary .fs-5 .my-4 .mb-md-0 .mr-2 } [Protocol details](/protocol){: .btn .fs-5 .my-4 .mb-md-0 } - ---- - -# Community +## Community remoteStorage is a grass-roots standard, developed completely in the open, by the community for the community. Countless individuals have contributed in one way or another over time, and we'd love to welcome you as one of them! +| | | | - | - | | [GitHub](https://github.com/remotestorage) | Where we collaborate on the protocol specification as well as all common source code. | | [Forums](https://community.remotestorage.io) | Our community exchange and support site for everybody from users to developers to providers. | -| [IRC](https://web.libera.chat/#remotestorage) | Some community members are hanging out in #remotestorage on Libera.Chat — say hi! | | [Twitter](https://twitter.com/remotestorage_) / [Fediverse](https://kosmos.social/@remotestorage) | Follow the project on Twitter or on the Fediverse, to receive updates on releases, events, apps, and related news. | | [Mailing List](https://buttondown.email/remotestorage)| A monthly digest about remoteStorage apps, tools, and decentralized news. | | [Events](https://community.remotestorage.io/c/events) | Meet people in person at conferences, hackathons, camps, and other gatherings. | @@ -118,24 +53,11 @@ We would love for you to get involved — check out [What can I do for remoteSto ## Thank you to our contributors! - + ... and everyone not listed here! -
- Join our forum - For everybody from users to developers to providers. -
- ---- - -# Sponsors +## Sponsors

@@ -161,10 +83,6 @@ We would love for you to get involved — check out [What can I do for remoteSto

diff --git a/integrate/index.html b/integrate/index.html deleted file mode 100644 index c7edcdb4..00000000 --- a/integrate/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - Moved to /wiki/developers - - - diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..e6890df7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1790 @@ +{ + "name": "rs-website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rs-website", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "node-fetch": "^3.3.2", + "vitepress": "^1.3.1", + "vue": "^3.4.33" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "dev": true, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz", + "integrity": "sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.23.3.tgz", + "integrity": "sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==", + "dev": true + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz", + "integrity": "sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.23.3.tgz", + "integrity": "sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.23.3.tgz", + "integrity": "sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.23.3.tgz", + "integrity": "sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.23.3.tgz", + "integrity": "sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.23.3.tgz", + "integrity": "sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==", + "dev": true, + "dependencies": { + "@algolia/client-common": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.23.3.tgz", + "integrity": "sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==", + "dev": true + }, + "node_modules/@algolia/logger-console": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.23.3.tgz", + "integrity": "sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==", + "dev": true, + "dependencies": { + "@algolia/logger-common": "4.23.3" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.23.3.tgz", + "integrity": "sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.23.3", + "@algolia/cache-common": "4.23.3", + "@algolia/cache-in-memory": "4.23.3", + "@algolia/client-common": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/logger-console": "4.23.3", + "@algolia/requester-browser-xhr": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/requester-node-http": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz", + "integrity": "sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.23.3.tgz", + "integrity": "sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==", + "dev": true + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz", + "integrity": "sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==", + "dev": true, + "dependencies": { + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.23.3.tgz", + "integrity": "sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==", + "dev": true, + "dependencies": { + "@algolia/cache-common": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/requester-common": "4.23.3" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz", + "integrity": "sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==", + "dev": true + }, + "node_modules/@docsearch/js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.6.0.tgz", + "integrity": "sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==", + "dev": true, + "dependencies": { + "@docsearch/react": "3.6.0", + "preact": "^10.0.0" + } + }, + "node_modules/@docsearch/react": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz", + "integrity": "sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==", + "dev": true, + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.0", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.11.0.tgz", + "integrity": "sha512-VbEhDAhT/2ozO0TPr5/ZQBO/NWLqtk4ZiBf6NplYpF38mKjNfMMied5fNEfIfYfN+cdKvhDB4VMcKvG/g9c3zg==", + "dev": true, + "dependencies": { + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/transformers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.11.0.tgz", + "integrity": "sha512-RNEUyOxF1cPYVG2EvBv0CZeDU1Tp4fSxmsVD2Ofv+8h9hBqqgpq+l+7uyouyqV1JHNlqwRmUwAqrQU3GQQ3csQ==", + "dev": true, + "dependencies": { + "shiki": "1.11.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", + "dev": true, + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", + "dev": true + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "dev": true + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz", + "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", + "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.33", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", + "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", + "dev": true, + "dependencies": { + "@vue/compiler-core": "3.4.33", + "@vue/shared": "3.4.33" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", + "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.33", + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.10", + "postcss": "^8.4.39", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", + "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.33", + "@vue/shared": "3.4.33" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.3.6.tgz", + "integrity": "sha512-z6cKyxdXrIGgA++eyGBfquj6dCplRdgjt+I18fJx8hjWTXDTIyeQvryyEBMchnfZVyvUTjK3QjGjDpLCnJxPjw==", + "dev": true, + "dependencies": { + "@vue/devtools-kit": "^7.3.6" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.3.6.tgz", + "integrity": "sha512-5Ym9V3fkJenEoptqKoo+cgY5RTVwrSssFdzRsuyIgaeiskCT+rRJeQdwoo81tyrQ1mfS7Er1rYZlSzr3Y3L/ew==", + "dev": true, + "dependencies": { + "@vue/devtools-shared": "^7.3.6", + "birpc": "^0.2.17", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.3.6.tgz", + "integrity": "sha512-R/FOmdJV+hhuwcNoxp6e87RRkEeDMVhWH+nOsnHUrwjjsyeXJ2W1475Ozmw+cbZhejWQzftkHVKO28Fuo1yqCw==", + "dev": true, + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz", + "integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==", + "dev": true, + "dependencies": { + "@vue/shared": "3.4.33" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz", + "integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.4.33", + "@vue/shared": "3.4.33" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz", + "integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==", + "dev": true, + "dependencies": { + "@vue/reactivity": "3.4.33", + "@vue/runtime-core": "3.4.33", + "@vue/shared": "3.4.33", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz", + "integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==", + "dev": true, + "dependencies": { + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33" + }, + "peerDependencies": { + "vue": "3.4.33" + } + }, + "node_modules/@vue/shared": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", + "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==", + "dev": true + }, + "node_modules/@vueuse/core": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.0.tgz", + "integrity": "sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g==", + "dev": true, + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.0", + "@vueuse/shared": "10.11.0", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/core/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.11.0.tgz", + "integrity": "sha512-Pp6MtWEIr+NDOccWd8j59Kpjy5YDXogXI61Kb1JxvSfVBO8NzFQkmrKmSZz47i+ZqHnIzxaT38L358yDHTncZg==", + "dev": true, + "dependencies": { + "@vueuse/core": "10.11.0", + "@vueuse/shared": "10.11.0", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^4", + "drauu": "^0.3", + "focus-trap": "^7", + "fuse.js": "^6", + "idb-keyval": "^6", + "jwt-decode": "^3", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^6" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/integrations/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.0.tgz", + "integrity": "sha512-kQX7l6l8dVWNqlqyN3ePW3KmjCQO3ZMgXuBMddIu83CmucrsBfXlH+JoviYyRBws/yLTQO8g3Pbw+bdIoVm4oQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.0.tgz", + "integrity": "sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==", + "dev": true, + "dependencies": { + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared/node_modules/vue-demi": { + "version": "0.14.8", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz", + "integrity": "sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/algoliasearch": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.23.3.tgz", + "integrity": "sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==", + "dev": true, + "dependencies": { + "@algolia/cache-browser-local-storage": "4.23.3", + "@algolia/cache-common": "4.23.3", + "@algolia/cache-in-memory": "4.23.3", + "@algolia/client-account": "4.23.3", + "@algolia/client-analytics": "4.23.3", + "@algolia/client-common": "4.23.3", + "@algolia/client-personalization": "4.23.3", + "@algolia/client-search": "4.23.3", + "@algolia/logger-common": "4.23.3", + "@algolia/logger-console": "4.23.3", + "@algolia/recommend": "4.23.3", + "@algolia/requester-browser-xhr": "4.23.3", + "@algolia/requester-common": "4.23.3", + "@algolia/requester-node-http": "4.23.3", + "@algolia/transporter": "4.23.3" + } + }, + "node_modules/birpc": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.17.tgz", + "integrity": "sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "dev": true, + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true + }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/magic-string": { + "version": "0.30.10", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", + "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true + }, + "node_modules/minisearch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.1.0.tgz", + "integrity": "sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==", + "dev": true + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.22.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.0.tgz", + "integrity": "sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rollup": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/search-insights": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.14.0.tgz", + "integrity": "sha512-OLN6MsPMCghDOqlCtsIsYgtsC0pnwVTyT9Mu6A3ewOj1DxvzZF6COrn2g86E/c05xbktB0XN04m/t1Z+n+fTGw==", + "dev": true, + "peer": true + }, + "node_modules/shiki": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.11.0.tgz", + "integrity": "sha512-NqH/O1zRHvnuk/WfSL6b7+DtI7/kkMMSQGlZhm9DyzSU+SoIHhaw/fBZMr+zp9R8KjdIzkk3JKSC6hORuGDyng==", + "dev": true, + "dependencies": { + "@shikijs/core": "1.11.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dev": true, + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "dev": true + }, + "node_modules/vite": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitepress": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.3.1.tgz", + "integrity": "sha512-soZDpg2rRVJNIM/IYMNDPPr+zTHDA5RbLDHAxacRu+Q9iZ2GwSR0QSUlLs+aEZTkG0SOX1dc8RmUYwyuxK8dfQ==", + "dev": true, + "dependencies": { + "@docsearch/css": "^3.6.0", + "@docsearch/js": "^3.6.0", + "@shikijs/core": "^1.10.3", + "@shikijs/transformers": "^1.10.3", + "@types/markdown-it": "^14.1.1", + "@vitejs/plugin-vue": "^5.0.5", + "@vue/devtools-api": "^7.3.5", + "@vue/shared": "^3.4.31", + "@vueuse/core": "^10.11.0", + "@vueuse/integrations": "^10.11.0", + "focus-trap": "^7.5.4", + "mark.js": "8.11.1", + "minisearch": "^7.0.0", + "shiki": "^1.10.3", + "vite": "^5.3.3", + "vue": "^3.4.31" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz", + "integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-sfc": "3.4.33", + "@vue/runtime-dom": "3.4.33", + "@vue/server-renderer": "3.4.33", + "@vue/shared": "3.4.33" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, + "engines": { + "node": ">= 8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..c6e85966 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "rs-website", + "version": "1.0.0", + "description": "remoteStorage Website", + "directories": { + "doc": "docs" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "fetch-contributors": "node scripts/fetch-contributors.mjs", + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" + }, + "author": "remoteStorage Contributors", + "license": "MIT", + "devDependencies": { + "node-fetch": "^3.3.2", + "vitepress": "^1.3.1", + "vue": "^3.4.33" + } +} diff --git a/protocol.md b/protocol.md index e396d41a..d8ff5d30 100644 --- a/protocol.md +++ b/protocol.md @@ -1,67 +1,56 @@ ---- -title: Protocol -nav_order: 3 ---- +# The remoteStorage Protocol - - -# Unhosted Architecture - -remoteStorage is the first open protocol to enable truly [unhosted](https://unhosted.org) web apps. That means users are in full control of their precious data and where it is stored, while app developers are freed of the burden of hosting, maintaining and protecting a central database. - -## Traditional Web Apps - -In hosted web stacks such as LAMP, .Net, Ruby on Rails, Django, etc…, the developer hosts the app and data, while the user controls device. - - - - -## [No-Backend](https://nobackend.org) Web Apps - -In 100% client-side apps that use CouchDB, Hoodie, Firebase, Parse, Kinto, etc…, the developer provides the app and data, while user controls the device. - - - -## [Unhosted](https://unhosted.org) Web Apps - -In 100% client-side apps that use remoteStorage, Google Drive, Dropbox, etc…, the developer provides only the app, while the user controls the device and data. - - - - -# Using existing standards - -remoteStorage is a creative combination of existing protocols and standards. It aims to re-use existing technologies as much as possible, adding just a small layer of standardization on top to facilitate its usage for per-user storage with simple permissions and offline-capable data sync. +remoteStorage is a creative combination of existing protocols and standards. It +aims to re-use existing technologies as much as possible, adding just a small +layer of standardization on top to facilitate its usage for per-user storage +with simple permissions and offline-capable data sync. ## Discovery: [WebFinger](https://webfinger.net/) -In order for apps to know where to ask permission and later actually sync user data, users give them a user address, basically like with E-Mail or Jabber/XMPP. With that address, apps retrieve storage information for the username on that domain/host. +In order for apps to know where to ask for permissions and sync data, you +give them a user address, which looks the same as an email or XMPP address +(and could be one, too). With that address, apps retrieve storage information +for the username on that domain/host. -[Check out a live example for a 5apps user](https://client.webfinger.net/lookup?resource=tony%405apps.com). + - +[Check out a live example for a 5apps +user](https://client.webfinger.net/lookup?resource=tony%405apps.com). ## Authorization: [OAuth 2.0](https://oauth.net/) -User data is scoped by so-called categories, which are essentially base directories, for which you can give apps read-only or read/write permission. Apps will use OAuth scopes to ask for access to one or more categories. +User data is scoped by so-called categories, which are essentially base +directories, for which you can give either read-only or read/write permission. +Apps will use OAuth scopes to ask for access to one or more categories. -In the example screenshot, [Litewrite](https://litewrite.net/) is asking for read/write access to the "documents" category, using the OAuth scope `documents:rw`. If you allow access, the app will retrieve a bearer token, with which it can read and write to your storage, until you revoke that access on your server. +In this example screenshot, [Litewrite](https://litewrite.net/) is asking for +read/write access to the "documents" category, using the OAuth scope +`documents:rw`. If you allow access, the app will retrieve a bearer token, with +which it can read and write to your storage, until you revoke that access on +your server. - + ## Data Storage & Sync: [HTTP REST](https://en.wikipedia.org/wiki/Representational_state_transfer) -remoteStorage defines a simple key/value store for apps to save and retrieve data. The basic operations are GET/PUT/DELETE requests for specific files/documents. - -In addition to that – and the only special feature aside from plain HTTP – there are directory listings, formatted as JSON-LD. They contain both the content type and size, as well as ETags, which can be used to implement sync mechanisms. The files and listings themselves also carry ETag headers for sync/caching and conditional requests. +remoteStorage defines a simple key/value store for apps to save and retrieve +data. The basic operations are GET/PUT/DELETE requests for specific +files/documents. - +In addition to that – and the only special feature aside from plain HTTP – +there are directory listings, formatted as JSON-LD. They contain both the +content type and size, as well as ETags, which can be used to implement sync +mechanisms. The files and listings themselves also carry ETag headers for +sync/caching and conditional requests. ---- + -See [Datatracker](https://datatracker.ietf.org/doc/html/draft-dejong-remotestorage) or [GitHub](https://github.com/remotestorage/spec) for the full protocol specification. +## Specification +Visit the [IETF +Datatracker](https://datatracker.ietf.org/doc/html/draft-dejong-remotestorage) +or [GitHub](https://github.com/remotestorage/spec) for the full protocol +specification. diff --git a/provide/index.html b/provide/index.html deleted file mode 100644 index c7edcdb4..00000000 --- a/provide/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - Moved to /wiki/developers - - - diff --git a/public/data/contributors.json b/public/data/contributors.json new file mode 100644 index 00000000..18bc4bff --- /dev/null +++ b/public/data/contributors.json @@ -0,0 +1,278 @@ +[ + { + "name": "michielbdejong", + "avatar": "https://avatars.githubusercontent.com/u/408412?v=4", + "github": "https://github.com/michielbdejong", + "commits": 1913 + }, + { + "name": "raucao", + "avatar": "https://avatars.githubusercontent.com/u/842?v=4", + "github": "https://github.com/raucao", + "commits": 1346 + }, + { + "name": "nilclass", + "avatar": "https://avatars.githubusercontent.com/u/104883?v=4", + "github": "https://github.com/nilclass", + "commits": 1203 + }, + { + "name": "galfert", + "avatar": "https://avatars.githubusercontent.com/u/843?v=4", + "github": "https://github.com/galfert", + "commits": 553 + }, + { + "name": "lesion", + "avatar": "https://avatars.githubusercontent.com/u/504700?v=4", + "github": "https://github.com/lesion", + "commits": 347 + }, + { + "name": "jcoglan", + "avatar": "https://avatars.githubusercontent.com/u/9265?v=4", + "github": "https://github.com/jcoglan", + "commits": 287 + }, + { + "name": "ggrin", + "avatar": "https://avatars.githubusercontent.com/u/1177635?v=4", + "github": "https://github.com/ggrin", + "commits": 224 + }, + { + "name": "silverbucket", + "avatar": "https://avatars.githubusercontent.com/u/317571?v=4", + "github": "https://github.com/silverbucket", + "commits": 187 + }, + { + "name": "gregkare", + "avatar": "https://avatars.githubusercontent.com/u/43297?v=4", + "github": "https://github.com/gregkare", + "commits": 119 + }, + { + "name": "rosano", + "avatar": "https://avatars.githubusercontent.com/u/1680612?v=4", + "github": "https://github.com/rosano", + "commits": 99 + }, + { + "name": "DougReeder", + "avatar": "https://avatars.githubusercontent.com/u/378430?v=4", + "github": "https://github.com/DougReeder", + "commits": 78 + }, + { + "name": "xMartin", + "avatar": "https://avatars.githubusercontent.com/u/112532?v=4", + "github": "https://github.com/xMartin", + "commits": 67 + }, + { + "name": "jancborchardt", + "avatar": "https://avatars.githubusercontent.com/u/925062?v=4", + "github": "https://github.com/jancborchardt", + "commits": 56 + }, + { + "name": "untitaker", + "avatar": "https://avatars.githubusercontent.com/u/837573?v=4", + "github": "https://github.com/untitaker", + "commits": 51 + }, + { + "name": "Ragnis", + "avatar": "https://avatars.githubusercontent.com/u/210148?v=4", + "github": "https://github.com/Ragnis", + "commits": 40 + }, + { + "name": "johannesjo", + "avatar": "https://avatars.githubusercontent.com/u/1456265?v=4", + "github": "https://github.com/johannesjo", + "commits": 33 + }, + { + "name": "thornjad", + "avatar": "https://avatars.githubusercontent.com/u/17414927?v=4", + "github": "https://github.com/thornjad", + "commits": 30 + }, + { + "name": "gillisig", + "avatar": "https://avatars.githubusercontent.com/u/5390864?v=4", + "github": "https://github.com/gillisig", + "commits": 23 + }, + { + "name": "dependabot[bot]", + "avatar": "https://avatars.githubusercontent.com/in/29110?v=4", + "github": "https://github.com/apps/dependabot", + "commits": 18 + }, + { + "name": "iLiviu", + "avatar": "https://avatars.githubusercontent.com/u/11668471?v=4", + "github": "https://github.com/iLiviu", + "commits": 16 + }, + { + "name": "Lennie", + "avatar": "https://avatars.githubusercontent.com/u/330102?v=4", + "github": "https://github.com/Lennie", + "commits": 15 + }, + { + "name": "clochix", + "avatar": "https://avatars.githubusercontent.com/u/384908?v=4", + "github": "https://github.com/clochix", + "commits": 11 + }, + { + "name": "pjbollinger", + "avatar": "https://avatars.githubusercontent.com/u/5209474?v=4", + "github": "https://github.com/pjbollinger", + "commits": 8 + }, + { + "name": "klausfl", + "avatar": "https://avatars.githubusercontent.com/u/64592147?v=4", + "github": "https://github.com/klausfl", + "commits": 7 + }, + { + "name": "lewisl9029", + "avatar": "https://avatars.githubusercontent.com/u/6934200?v=4", + "github": "https://github.com/lewisl9029", + "commits": 7 + }, + { + "name": "bencharp", + "avatar": "https://avatars.githubusercontent.com/u/1753250?v=4", + "github": "https://github.com/bencharp", + "commits": 7 + }, + { + "name": "stokito", + "avatar": "https://avatars.githubusercontent.com/u/415502?v=4", + "github": "https://github.com/stokito", + "commits": 5 + }, + { + "name": "greenkeeperio-bot", + "avatar": "https://avatars.githubusercontent.com/u/14790466?v=4", + "github": "https://github.com/greenkeeperio-bot", + "commits": 4 + }, + { + "name": "JakubNer", + "avatar": "https://avatars.githubusercontent.com/u/4973893?v=4", + "github": "https://github.com/JakubNer", + "commits": 4 + }, + { + "name": "steventebrinke", + "avatar": "https://avatars.githubusercontent.com/u/1277338?v=4", + "github": "https://github.com/steventebrinke", + "commits": 3 + }, + { + "name": "jorinvo", + "avatar": "https://avatars.githubusercontent.com/u/738978?v=4", + "github": "https://github.com/jorinvo", + "commits": 3 + }, + { + "name": "Timothee", + "avatar": "https://avatars.githubusercontent.com/u/159328?v=4", + "github": "https://github.com/Timothee", + "commits": 3 + }, + { + "name": "kcchu", + "avatar": "https://avatars.githubusercontent.com/u/800071?v=4", + "github": "https://github.com/kcchu", + "commits": 3 + }, + { + "name": "chicagoduane", + "avatar": "https://avatars.githubusercontent.com/u/109882?v=4", + "github": "https://github.com/chicagoduane", + "commits": 3 + }, + { + "name": "aykevl", + "avatar": "https://avatars.githubusercontent.com/u/729697?v=4", + "github": "https://github.com/aykevl", + "commits": 3 + }, + { + "name": "yPhil-gh", + "avatar": "https://avatars.githubusercontent.com/u/1260520?v=4", + "github": "https://github.com/yPhil-gh", + "commits": 3 + }, + { + "name": "bibz", + "avatar": "https://avatars.githubusercontent.com/u/5141956?v=4", + "github": "https://github.com/bibz", + "commits": 3 + }, + { + "name": "pixelkritzel", + "avatar": "https://avatars.githubusercontent.com/u/1437379?v=4", + "github": "https://github.com/pixelkritzel", + "commits": 3 + }, + { + "name": "ssisk", + "avatar": "https://avatars.githubusercontent.com/u/707137?v=4", + "github": "https://github.com/ssisk", + "commits": 2 + }, + { + "name": "Nezteb", + "avatar": "https://avatars.githubusercontent.com/u/3588798?v=4", + "github": "https://github.com/Nezteb", + "commits": 2 + }, + { + "name": "kevincox", + "avatar": "https://avatars.githubusercontent.com/u/494012?v=4", + "github": "https://github.com/kevincox", + "commits": 2 + }, + { + "name": "Vinnl", + "avatar": "https://avatars.githubusercontent.com/u/4251?v=4", + "github": "https://github.com/Vinnl", + "commits": 2 + }, + { + "name": "jakob-dunning", + "avatar": "https://avatars.githubusercontent.com/u/2395711?v=4", + "github": "https://github.com/jakob-dunning", + "commits": 1 + }, + { + "name": "vcuculo", + "avatar": "https://avatars.githubusercontent.com/u/642555?v=4", + "github": "https://github.com/vcuculo", + "commits": 1 + }, + { + "name": "ebrahim-elgaml", + "avatar": "https://avatars.githubusercontent.com/u/10853051?v=4", + "github": "https://github.com/ebrahim-elgaml", + "commits": 1 + }, + { + "name": "agrueneberg", + "avatar": "https://avatars.githubusercontent.com/u/527708?v=4", + "github": "https://github.com/agrueneberg", + "commits": 1 + } +] \ No newline at end of file diff --git a/img/icon.svg b/public/logo.svg similarity index 100% rename from img/icon.svg rename to public/logo.svg diff --git a/rs.js b/rs.js new file mode 160000 index 00000000..153acf7d --- /dev/null +++ b/rs.js @@ -0,0 +1 @@ +Subproject commit 153acf7da9e15e64e2b65107b394f88796d018b5 diff --git a/rs.js.index.md b/rs.js.index.md new file mode 100644 index 00000000..cf8abe8d --- /dev/null +++ b/rs.js.index.md @@ -0,0 +1,44 @@ +# remoteStorage.js + +## At a glance + +### Setup + +```javascript +const rs = new RemoteStorage(); +rs.access.claim('todos', 'rw'); +rs.caching.enable(); + +const client = rs.scope('/todos/'); +``` + +### Write an object + +```javascript +// Declare an object type to validate if you want (JSON Schema) +client.declareType('todo-item', {}); + +// Write `{"id":"alfa","done":false}` to /todos/alfa.json +await client.storeObject('todo-item', 'alfa.json', { + id: 'alfa', + done: false, +}); +``` + +### Get objects + +```javascript +const specificItem = await client.getObject('alpha.json'); +const allTodoItems = await client.getAll(); +``` + +### Add the Connect Widget UI component + +Use our [drop-in UI widget](https://github.com/remotestorage/remotestorage-widget) for connecting remote storage accounts. + +```javascript +const widget = new Widget(rs); +widget.attach(); +``` + +[]() [Protocol details](/) diff --git a/scripts/fetch-contributors.mjs b/scripts/fetch-contributors.mjs new file mode 100644 index 00000000..1234de99 --- /dev/null +++ b/scripts/fetch-contributors.mjs @@ -0,0 +1,83 @@ +import fetch from 'node-fetch'; +import { promises as fs } from 'fs'; + +const repositories = [ + 'remotestorage/spec', + 'remotestorage/remotestorage.js', + 'remotestorage/remotestorage-widget', + 'remotestorage/modules', + 'remotestorage/design', + 'remotestorage/website', + 'remotestorage/remotestorage.io', + 'remotestorage/api-test-suite', + 'remotestorage/myfavoritedrinks', + 'remotestorage/armadietto', + 'remotestorage/remotestorage-server', + 'remotestorage/remotestorage-ruby', + 'remotestorage/rs-serve', + 'remotestorage/django-remotestorage', + 'remotestorage/fuse', + 'remotestorage/ember-cli-remotestorage', +]; + +const filename = './public/data/contributors.json'; + +const ignoredUsernames = [ + 'dependabot', + 'ember-tomster', +]; + +async function fetchContributors(repo) { + try { + const response = await fetch(`https://api.github.com/repos/${repo}/contributors`, { + headers: { + 'Accept': 'application/vnd.github.v3+json' + } + }); + + if (!response.ok) { + throw new Error(`Failed to fetch contributors for ${repo}: ${response.statusText}`); + } + + const data = await response.json(); + + return data.map(contributor => ({ + name: contributor.login, + avatar: contributor.avatar_url, + github: contributor.html_url, + commits: contributor.contributions + })); + } catch (error) { + console.error(`Failed to fetch contributors for ${repo}: ${error.message}`); + return []; + } +} + +async function fetchAllContributors() { + let allContributors = []; + + for (const repo of repositories) { + const contributors = await fetchContributors(repo); + allContributors = allContributors.concat(contributors); + } + + allContributors = allContributors.filter(contributor => !ignoredUsernames.includes(contributor.name)); + + // Aggregate contributions from the same contributor across different repositories + const aggregatedContributors = allContributors.reduce((acc, contributor) => { + const existing = acc.find(c => c.github === contributor.github); + if (existing) { + existing.commits += contributor.commits; + } else { + acc.push(contributor); + } + return acc; + }, []); + + aggregatedContributors.sort((a, b) => b.commits - a.commits); + + await fs.writeFile(filename, JSON.stringify(aggregatedContributors, null, 2)); + console.log(`Contributors list saved to ${filename}`); +} + +fetchAllContributors(); diff --git a/servers.md b/servers.md index 31867f06..0c81f8f0 100644 --- a/servers.md +++ b/servers.md @@ -1,8 +1,3 @@ ---- -title: Servers -nav_order: 5 ---- - # Servers ## Hosted diff --git a/unhosted.md b/unhosted.md new file mode 100644 index 00000000..b7ee6301 --- /dev/null +++ b/unhosted.md @@ -0,0 +1,31 @@ +# Unhosted Architecture + +remoteStorage is the first open protocol to enable truly +[unhosted](https://unhosted.org) web apps. That means users are in full control +of their precious data and where it is stored, while app developers are freed +of the burden of hosting, maintaining and protecting a central database. + +## Traditional Web Apps + +In hosted web stacks such as LAMP, .Net, Ruby on Rails, Django, etc…, the +developer hosts the app and data, while the user controls device. + + + +## [No-Backend](https://nobackend.org) Web Apps + +In 100% client-side apps that use CouchDB, Hoodie, Firebase, Parse, Kinto, +etc…, the developer provides the app and data, while user controls the device. + + + +## [Unhosted](https://unhosted.org) Web Apps + +In 100% client-side apps that use remoteStorage, Google Drive, Dropbox, etc…, +the developer provides only the app, while the user controls the device and +data. + + diff --git a/wiki/design.md b/wiki/design.md deleted file mode 100644 index 14fd5f1e..00000000 --- a/wiki/design.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Design -parent: Wiki ---- - -This page was moved from the old wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } - -## Repo - - - There's a design repo with logo/icon files etc. on GitHub: - - - We have an ongoing issue about refreshing the official logo there: - - -## Connect Widget - -Another ongoing topic is the refreshing of the connect widget, which is -currently shipped with the remoteStorage.js library. Plans are to -extract it from the core library to a seperate widget add-on library. -@gillisig created a new design and flow, complete with interactive flow -mockups, and raucao started implementing the widget library. - - - [GitHub issue \#862: Extract widget from core code to add-on - library](https://github.com/remotestorage/remotestorage.js/issues/862) - - [remotestorage-widget (new widget - repository)](https://github.com/remotestorage/remotestorage-widget) - - - -## Websites - -We just launched a basic new website, but it still/always needs work. -It's a great point of entry for designers and frontend developers -wanting to contribute to the project. - - - Website repo: - - Waffle board (using GH issues): - - -The wiki is running on -[MediaWiki](https://www.mediawiki.org/wiki/MediaWiki). - - - [Wiki-related - issues](https://github.com/remotestorage/website/issues?q=is%3Aissue+is%3Aopen+label%3Awiki) - -The forums are running on [Discourse](https://www.discourse.org/). - - - [Forums-related - issues](https://github.com/remotestorage/website/issues?q=is%3Aissue+is%3Aopen+label%3Aforums) - -## Stickers - - - You can order prepared RS stickers (with no markup) at the - [Stickermule RS - page](https://www.stickermule.com/en/user/1068777714/stickers) - - 5apps is keeping some MacBook stickers in stock, that [cover your - apple with a glowing RS - logo](https://twitter.com/remotestorage_/status/719972192553996289). - Ask them to send you one. - -## Get involved - -Please contact the core team [on -IRC](https://kiwiirc.com/client/irc.freenode.net/#remotestorage) -(\#remotestorage on Freenode), [the community -forums](https://community.remotestorage.io/), or GitHub if you're -interested in helping out\! You would help an open source project in -need and get your work in front of a lot of people from all around the -world. Small sponsorships/stipends are possible as well. diff --git a/wiki/developers.md b/wiki/developers.md index 7bcfae85..30d8bb07 100644 --- a/wiki/developers.md +++ b/wiki/developers.md @@ -4,18 +4,6 @@ parent: Wiki --- This page was moved from the old wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } - -# Protocol - -- [Overview](/Protocol "Protocol") -- [Latest spec draft](https://tools.ietf.org/html/draft-dejong-remotestorage) - -# remoteStorage.js - -[remoteStorage.js](https://github.com/remotestorage/remotestorage.js/) is a JavaScript library that does all the heavy-lifting of connecting remoteStorage accounts, caching, synchronizing and storing user data. It is well-tested in all modern browsers, and also works in Cordova apps and node.js programs. - -As the reference client, maintained by the RS core team, it always supports the latest protocol versions (but is reasonably backwards-compatible as well). ## Core @@ -24,10 +12,6 @@ As the reference client, maintained by the RS core team, it always supports the - [npm package](https://www.npmjs.com/package/remotestoragejs) - [Adding a new storage back-end](/RemoteStorage.js:Adding_a_new_storage_back-end "RemoteStorage.js:Adding a new storage back-end") -## Data modules - -- [Documentation](https://remotestoragejs.readthedocs.io/en/latest/data-modules.html) - # Tips and Considerations ## Hosting @@ -68,11 +52,3 @@ data, which is transported via the OAuth `state` parameter). **Caveat:** do not get fooled by Safari's Web Inspector. It displays the localStorage content for the origin, but not IndexedDB. - -### Chrome - -... - -### Firefox - -... diff --git a/wiki/modules.md b/wiki/modules.md index af75421c..8a014651 100644 --- a/wiki/modules.md +++ b/wiki/modules.md @@ -4,7 +4,6 @@ parent: Wiki --- This page was moved from the old wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } Data modules are **small add-on libraries** for remoteStorage.js, which extend it for storing certain types of data. App developers can create diff --git a/wiki/notes.md b/wiki/notes.md index 9e0c2741..8baddd8c 100644 --- a/wiki/notes.md +++ b/wiki/notes.md @@ -4,7 +4,6 @@ parent: Wiki --- This page was moved from the wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } This page contains random notes, so we can quickly drop things and move them to the appropriate place later. diff --git a/wiki/protocol.md b/wiki/protocol.md index 105763a3..0fbdaf4d 100644 --- a/wiki/protocol.md +++ b/wiki/protocol.md @@ -4,20 +4,6 @@ parent: Wiki --- This page was moved from the old wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } - -The remoteStorage protocol is a creative combination of existing protocols and standards (mainly [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol), [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), [Webfinger](https://webfinger.net/), [OAuth 2](http://oauth.net/)). It aims to re-use existing technologies as much as possible, adding just a small layer of standardization on top to facilitate its usage for per-user storage with simple permissions and offline-capable data sync. See [this quick explainer](https://remotestorage.io/#explainer-protocol) for some more info, and the spec itself for details. - -## Contents - - \[[hide](#)\] - -- [1 History](#History) -- [2 Process](#Process) -- [3 Versioning](#Versioning) - - [3.1 Current versions](#Current_versions) - - [3.2 Deprecated versions](#Deprecated_versions) -- [4 Useful resources](#Useful_resources) ## History @@ -26,31 +12,3 @@ The first draft of the remoteStorage protocol was originally developed by Michie ## Process Every 6 months (max. 185 days) a new draft version is published, incorporating feedback and contributions from developers, providers and users. All discussion and spec development is done in open collaboration on [the public GitHub repository](https://github.com/remotestorage/spec). Everyone is invited to open new GitHub issues and/or pull requests with their questions, feedback, and changes. - -## Versioning - -**Authors of remoteStorage-enabled apps** are encouraged to use a **recent version of remotestorage.js**, which aims to support each new spec version on the day it is released, at the latest. - -**Implementers of remoteStorage servers and clients** are encouraged to always offer support for the **latest three versions of the spec**. - -**Storage providers** should aim to expose **the previous version of this spec**, so that app authors have six months to update their apps before they become potentially incompatible. - -The latest three versions can be thought of as _new_, _live_, and _old_. When for instance version 03 was published, version 02 moved from _new_ to _live_, and version 01 moved from _live_ to _old_. So during the six months after version k is published, apps should add support for the _new_ version k, while still supporting _live_ version k-1 and _old_ version k-2. Storage providers should aim to switch from _old_ version k-2 to _live_ version k-1 as soon as possible after version k is released. - -You can find various formats of all draft content in the [IETF version tracker](https://datatracker.ietf.org/doc/draft-dejong-remotestorage/). - -### Current versions - -| Version | Status | Published | Breaking changes | -| --- | --- | --- | --- | -| [17](https://tools.ietf.org/html/draft-dejong-remotestorage-17) | New | Jun 2021 | no | -| [16](https://tools.ietf.org/html/draft-dejong-remotestorage-16) | Live | Dec 2020 | no | -| [15](https://tools.ietf.org/html/draft-dejong-remotestorage-15) | Old | Jun 2020 | no | - -### Deprecated versions - -Please visit the [IETF data tracker](https://datatracker.ietf.org/doc/draft-dejong-remotestorage/) to access previous versions of the spec. - -## Useful resources - -- MDN offers [a great collection of articles on all aspects of HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP), including caching and CORS. diff --git a/wiki/wiki.md b/wiki/wiki.md deleted file mode 100644 index 00a29306..00000000 --- a/wiki/wiki.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Wiki -has_children: true ---- - -This page was moved from the old wiki and is in the process of being revised. -{: .fs-5 .ls-10 .code-example } - -# Wiki -{: .no_toc } - -Pages from the wiki -{: .fs-6 .fw-300 }