diff --git a/.devcontainer/compose.yaml b/.devcontainer/compose.yaml index ced5ecfe884..217415c528b 100644 --- a/.devcontainer/compose.yaml +++ b/.devcontainer/compose.yaml @@ -73,7 +73,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.6.2 + image: libretranslate/libretranslate:v1.7.3 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local diff --git a/.env.production.sample b/.env.production.sample index 8ea569fb016..9ff63c49ef1 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -88,21 +88,3 @@ S3_ALIAS_HOST=files.example.com # ----------------------- IP_RETENTION_PERIOD=31556952 SESSION_RETENTION_PERIOD=31556952 - -# Fetch All Replies Behavior -# -------------------------- - -# Period to wait between fetching replies (in minutes) -FETCH_REPLIES_COOLDOWN_MINUTES=15 - -# Period to wait after a post is first created before fetching its replies (in minutes) -FETCH_REPLIES_INITIAL_WAIT_MINUTES=5 - -# Max number of replies to fetch - total, recursively through a whole reply tree -FETCH_REPLIES_MAX_GLOBAL=1000 - -# Max number of replies to fetch - for a single post -FETCH_REPLIES_MAX_SINGLE=500 - -# Max number of replies Collection pages to fetch - total -FETCH_REPLIES_MAX_PAGES=500 diff --git a/.github/actions/setup-javascript/action.yml b/.github/actions/setup-javascript/action.yml index 808adc7de64..0c7ead1c15f 100644 --- a/.github/actions/setup-javascript/action.yml +++ b/.github/actions/setup-javascript/action.yml @@ -9,7 +9,7 @@ runs: using: 'composite' steps: - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version-file: '.nvmrc' diff --git a/.github/renovate.json5 b/.github/renovate.json5 index c1a1c99eb70..2bffaaf27ba 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -23,8 +23,6 @@ // Require Dependency Dashboard Approval for major version bumps of these node packages matchManagers: ['npm'], matchPackageNames: [ - 'tesseract.js', // Requires code changes - // react-router: Requires manual upgrade 'history', 'react-router-dom', diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml index 260730004cc..84b729df434 100644 --- a/.github/workflows/build-container-image.yml +++ b/.github/workflows/build-container-image.yml @@ -35,7 +35,7 @@ jobs: - linux/arm64 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Prepare env: @@ -100,7 +100,7 @@ jobs: - name: Upload digest if: ${{ inputs.push_to_images != '' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: # `hashFiles` is used to disambiguate between streaming and non-streaming images name: digests-${{ hashFiles(inputs.file_to_build) }}-${{ env.PLATFORM_PAIR }} @@ -119,10 +119,10 @@ jobs: PUSH_TO_IMAGES: ${{ inputs.push_to_images }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Download digests - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: path: ${{ runner.temp }}/digests # `hashFiles` is used to disambiguate between streaming and non-streaming images diff --git a/.github/workflows/build-push-pr.yml b/.github/workflows/build-push-pr.yml index 418993475f4..f6ff6521753 100644 --- a/.github/workflows/build-push-pr.yml +++ b/.github/workflows/build-push-pr.yml @@ -18,7 +18,7 @@ jobs: steps: # Repository needs to be cloned so `git rev-parse` below works - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - id: version_vars run: | echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT diff --git a/.github/workflows/build-releases.yml b/.github/workflows/build-releases.yml index db17b2169ca..245b25a9344 100644 --- a/.github/workflows/build-releases.yml +++ b/.github/workflows/build-releases.yml @@ -21,7 +21,7 @@ jobs: # Only tag with latest when ran against the latest stable branch # This needs to be updated after each minor version release flavor: | - latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }} + latest=${{ startsWith(github.ref, 'refs/tags/v4.5.') }} tags: | type=pep440,pattern={{raw}} type=pep440,pattern=v{{major}}.{{minor}} @@ -39,7 +39,7 @@ jobs: # Only tag with latest when ran against the latest stable branch # This needs to be updated after each minor version release flavor: | - latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }} + latest=${{ startsWith(github.ref, 'refs/tags/v4.5.') }} tags: | type=pep440,pattern={{raw}} type=pep440,pattern=v{{major}}.{{minor}} diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index fa28d28f740..9cc49a7f797 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/check-i18n.yml b/.github/workflows/check-i18n.yml index c46090c1b56..9d500ffc44e 100644 --- a/.github/workflows/check-i18n.yml +++ b/.github/workflows/check-i18n.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Ruby environment uses: ./.github/actions/setup-ruby diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 4e6179bc774..e0383b83bcc 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -23,7 +23,7 @@ jobs: if: github.repository == 'mastodon/mastodon' steps: - name: Checkout code - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: fetch-depth: 0 - name: Set up Javascript environment @@ -33,7 +33,7 @@ jobs: run: yarn build-storybook - name: Run Chromatic - uses: chromaui/action@v12 + uses: chromaui/action@v13 with: # ⚠️ Make sure to configure a `CHROMATIC_PROJECT_TOKEN` repository secret projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c864e12d2d8..cf038ae4809 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -31,11 +31,11 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -48,7 +48,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 # ℹ️ Command-line programs to run using the OS shell. # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun @@ -61,6 +61,6 @@ jobs: # ./location_of_script_within_repo/buildscript.sh - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: '/language:${{matrix.language}}' diff --git a/.github/workflows/crowdin-download-stable.yml b/.github/workflows/crowdin-download-stable.yml index 8e18a9d0a0f..8a6ac6df277 100644 --- a/.github/workflows/crowdin-download-stable.yml +++ b/.github/workflows/crowdin-download-stable.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Increase Git http.postBuffer # This is needed due to a bug in Ubuntu's cURL version? diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml index d247a514d92..89125fb2db4 100644 --- a/.github/workflows/crowdin-download.yml +++ b/.github/workflows/crowdin-download.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Increase Git http.postBuffer # This is needed due to a bug in Ubuntu's cURL version? diff --git a/.github/workflows/crowdin-upload.yml b/.github/workflows/crowdin-upload.yml index d0d79d91996..e2764b1ec75 100644 --- a/.github/workflows/crowdin-upload.yml +++ b/.github/workflows/crowdin-upload.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: crowdin action uses: crowdin/github-action@v2 diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml index c10f350a02e..6803686b4ff 100644 --- a/.github/workflows/format-check.yml +++ b/.github/workflows/format-check.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Javascript environment uses: ./.github/actions/setup-javascript diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml index c1385bf789b..51a78d679fc 100644 --- a/.github/workflows/lint-css.yml +++ b/.github/workflows/lint-css.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Javascript environment uses: ./.github/actions/setup-javascript diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml index 499be2010ad..d3452c9ffc2 100644 --- a/.github/workflows/lint-haml.yml +++ b/.github/workflows/lint-haml.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 86e9af23e7e..c9ba1a13f17 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Javascript environment uses: ./.github/actions/setup-javascript diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index 87f8aee24e0..e73617d85da 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml index 0699e6c9ef8..b8e1cc89aaa 100644 --- a/.github/workflows/test-js.yml +++ b/.github/workflows/test-js.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Clone repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Javascript environment uses: ./.github/actions/setup-javascript diff --git a/.github/workflows/test-migrations.yml b/.github/workflows/test-migrations.yml index 7aab34f0cf4..b1b94692f0c 100644 --- a/.github/workflows/test-migrations.yml +++ b/.github/workflows/test-migrations.yml @@ -72,7 +72,7 @@ jobs: BUNDLE_RETRY: 3 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Ruby environment uses: ./.github/actions/setup-ruby diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 63d31725043..8f05812d600 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -32,7 +32,7 @@ jobs: SECRET_KEY_BASE_DUMMY: 1 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Ruby environment uses: ./.github/actions/setup-ruby @@ -65,7 +65,7 @@ jobs: run: | tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs* tmp/cache/vite/last-build*.json - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 if: matrix.mode == 'test' with: path: |- @@ -128,9 +128,9 @@ jobs: - '3.3' - '.ruby-version' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v6 with: path: './' name: ${{ github.sha }} @@ -230,9 +230,9 @@ jobs: - '3.3' - '.ruby-version' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v6 with: path: './' name: ${{ github.sha }} @@ -309,9 +309,9 @@ jobs: - '.ruby-version' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v6 with: path: './' name: ${{ github.sha }} @@ -350,14 +350,14 @@ jobs: - run: bin/rspec spec/system --tag streaming --tag js - name: Archive logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() with: name: e2e-logs-${{ matrix.ruby-version }} path: log/ - name: Archive test screenshots - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() with: name: e2e-screenshots-${{ matrix.ruby-version }} @@ -447,9 +447,9 @@ jobs: search-image: opensearchproject/opensearch:2 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v6 with: path: './' name: ${{ github.sha }} @@ -469,14 +469,14 @@ jobs: - run: bin/rspec --tag search - name: Archive logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() with: name: test-search-logs-${{ matrix.ruby-version }} path: log/ - name: Archive test screenshots - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 if: failure() with: name: test-search-screenshots diff --git a/.gitignore b/.gitignore index db63bc07f0d..4727d9ec27f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ /public/packs /public/packs-dev /public/packs-test +stats.html .env .env.production node_modules/ diff --git a/.nvmrc b/.nvmrc index f666621e500..f88da62e246 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.10 +24.11 diff --git a/.storybook/main.ts b/.storybook/main.ts index bb69f0c6649..c249d1c06dc 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -31,7 +31,7 @@ const config: StorybookConfig = { viteFinal(config) { // For an unknown reason, Storybook does not use the root // from the Vite config so we need to set it manually. - config.root = resolve(__dirname, '../app/javascript'); + config.root = resolve(import.meta.dirname, '../app/javascript'); return config; }, }; diff --git a/CHANGELOG.md b/CHANGELOG.md index f634505428b..f30b502ad14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,45 +2,61 @@ All notable changes to this project will be documented in this file. -## [4.5.0] - UNRELEASED +## [4.5.0] - 2025-11-06 ### Added -- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516 and #36528 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\ +- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516, #36528, #36549, #36550, #36559, #36693, #36704, #36690, #36689, #36696, #36721, #36695 and #36736 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\ This includes a revamp of the composer interface.\ See https://blog.joinmastodon.org/2025/09/introducing-quote-posts/ for a user-centric overview of the feature, and https://docs.joinmastodon.org/client/quotes/ for API documentation. -- **Add support for fetching and refreshing replies to the web UI** (#35210, #35496, #35575, #35500, #35577, #35602, #35603, #35654, #36141, #36237, #36172, #36256, #36271, #36334, #36382, #36239, #36484 and #36481 by @ClearlyClaire, @Gargron, and @diondiondion) +- **Add support for fetching and refreshing replies to the web UI** (#35210, #35496, #35575, #35500, #35577, #35602, #35603, #35654, #36141, #36237, #36172, #36256, #36271, #36334, #36382, #36239, #36484, #36481, #36583, #36627 and #36547 by @ClearlyClaire, @diondiondion, @Gargron and @renchap) - **Add ability to block words in usernames** (#35407, #35655, and #35806 by @ClearlyClaire and @Gargron) +- Add ability to individually disable local or remote feeds for visitors or logged-in users `disabled` value to server setting for live and topic feeds, as well as user permission to bypass that (#36338, #36467, #36497, #36563, #36577, #36585, #36607 and #36703 by @ClearlyClaire)\ + This splits the `timeline_preview` setting into four more granular settings controlling live feeds and topic (hashtag, trending link) feeds.\ + The setting for local topic feeds has 2 values: `public` and `authenticated`. Every other setting has 3 values: `public`, `authenticated`, `disabled`.\ + When `disabled`, users with the “View live and topic feeds” will still be able to view them. - Add support for displaying of quote posts in Moderator UI (#35964 by @ThisIsMissEm) - Add support for displaying link previews for Admin UI (#35958 by @ThisIsMissEm) +- Add a new server setting to choose the server landing page (#36588 and #36602 by @ClearlyClaire and @renchap) +- Add support for `Update` activities on converted object types (#36322 by @ClearlyClaire) - Add support for dynamic viewport height (#36272 by @e1berd) - Add support for numeric-based URIs for new local accounts (#32724, #36304, #36316, and #36365 by @ClearlyClaire) +- Add default visualizer for audio upload without poster (#36734 by @ChaosExAnima) - Add Traditional Mongolian to posting languages (#36196 by @shimon1024) - Add example post with manual quote approval policy to `dev:populate_sample_data` (#36099 by @ClearlyClaire) - Add server-side support for handling posts with a quote policy allowing followers to quote (#36093 and #36127 by @ClearlyClaire) - Add schema.org markup to SEO-enabled posts (#36075 by @Gargron) - Add migration to fill unset default quote policy based on default post privacy (#36041 by @ClearlyClaire) +- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion) +- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima) +- Add feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502, #36532, #36603, #36409, #36638 and #36750 by @ChaosExAnima, @ClearlyClaire and @braddunbar)\ + This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places. - Add support for exposing conversation context for new public conversations according to FEP-7888 (#35959 and #36064 by @ClearlyClaire and @jesseplusplus) - Add digest re-check before removing followers in synchronization mechanism (#34273 by @ClearlyClaire) -- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion) - Add support for displaying Valkey version on admin dashboard (#35785 by @ykzts) - Add delivery failure tracking and handling to FASP jobs (#35625, #35628, and #35723 by @oneiros) - Add example of quote post with a preview card to development sample data (#35616 by @ClearlyClaire) - Add second set of blocked text that applies to accounts regardless of account age for spam-blocking (#35563 by @ClearlyClaire) -- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima) -- Add experimental feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502 and #36532 by @ChaosExAnima and @braddunbar)\ - This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places. ### Changed - Change confirmation dialogs for follow button actions “unfollow”, “unblock”, and “withdraw request” (#36289 by @diondiondion) - Change “Follow” button labels (#36264 by @diondiondion) - Change appearance settings to introduce new Advanced settings section (#36496 and #36506 by @diondiondion) +- Change display of blocked and muted quoted users (#36619 by @ClearlyClaire)\ + This adds `blocked_account`, `blocked_domain` and `muted_account` values to the `state` attribute of `Quote` and `ShallowQuote` REST API entities. +- Change submitting an empty post to show an error rather than failing silently (#36650 by @diondiondion) +- Change "Privacy and reach" settings from "Public profile" to their own top-level category (#27294 by @ChaelCodes) +- Change number of times quote verification is retried to better deal with temporary failures (#36698 by @ClearlyClaire) - Change display of content warnings in Admin UI (#35935 by @ThisIsMissEm) +- Change styling of column banners (#36531 by @ClearlyClaire) +- Change recommended Node version to 24 (LTS) (#36539 by @renchap) +- Change min. characters required for logged-out account search from 5 to 3 (#36487 by @Gargron) +- Change browser target to Vite legacy plugin defaults (#36611 by @larouxn) - Change index on `follows` table to improve performance of some queries (#36374 by @ClearlyClaire) - Change links to accounts in settings and moderation views to link to local view unless account is suspended (#36340 by @diondiondion) - Change redirection for denied registration from web app to sign-in page with error message (#36384 by @ClearlyClaire) -- Change `timeline_preview` setting into four more granular settings (#36338, #36467 and #36497 by @ClearlyClaire) +- Change support for RFC9421 HTTP signatures to be enabled unconditionally (#36610 by @oneiros) - Change wording and design of interaction dialog to simplify it (#36124 by @diondiondion) - Change dropdown menus to allow disabled items to be focused (#36078 by @diondiondion) - Change modal background colours in light mode (#36069 by @diondiondion) @@ -48,7 +64,7 @@ All notable changes to this project will be documented in this file. - Change description of “Quiet public” (#36032 by @ClearlyClaire) - Change “Boost with original visibility” to “Share again with your followers” (#36035 by @ClearlyClaire) - Change handling of push subscriptions to automatically delete invalid ones on delivery (#35987 by @ThisIsMissEm) -- Change design of quote posts in web UI (#35584 and #35834 by @ClearlyClaire and @Gargron) +- Change design of quote posts in web UI (#35584 and #35834 by @Gargron) - Change auditable accounts to be sorted by username in admin action logs interface (#35272 by @breadtk) - Change order of translation restoration and service credit on post card (#33619 by @colindean) - Change position of ‘add more’ to be inside table toolbar on reports (#35963 by @ThisIsMissEm) @@ -59,6 +75,16 @@ All notable changes to this project will be documented in this file. - Fix relationship not being fetched to evaluate whether to show a quote post (#36517 by @ClearlyClaire) - Fix rendering of poll options in status history modal (#35633 by @ThisIsMissEm) - Fix “mute” button being displayed to unauthenticated visitors in hashtag dropdown (#36353 by @mkljczk) +- Fix initially selected language in Rules panel, hide selector when no alternative translations exist (#36672 by @diondiondion) +- Fix URL comparison for mentions in case of empty path (#36613 and #36626 by @ClearlyClaire) +- Fix hashtags not being picked up when full-width hash sign is used (#36103 and #36625 by @ClearlyClaire and @Gargron) +- Fix layout of severed relationships when purged events are listed (#36593 by @mejofi) +- Fix Skeleton placeholders being animated when setting to reduce animations is enabled (#36716 by @ClearlyClaire) +- Fix vacuum tasks being interrupted by a single batch failure (#36606 by @Gargron) +- Fix handling of unreachable network error for search services (#36587 by @mjankowski) +- Fix bookmarks export when a bookmarked status is soft-deleted (#36576 by @ClearlyClaire) +- Fix text overflow alignment for long author names in News (#36562 by @diondiondion) +- Fix discovery preamble missing word in admin settings (#36560 by @belatedly) - Fix overflow handling of `.more-from-author` (#36310 by @edent) - Fix unfortunate action button wrapping in admin area (#36247 by @diondiondion) - Fix translate button width in Safari (#36164 and #36216 by @diondiondion) @@ -81,6 +107,10 @@ All notable changes to this project will be documented in this file. - Fix glitchy status keyboard navigation (#35455 and #35504 by @diondiondion) - Fix post being submitted when pressing “Enter” in the CW field (#35445 by @diondiondion) +### Removed + +- Remove support for PostgreSQL 13 (#36540 by @renchap) + ## [4.4.8] - 2025-10-21 ### Security diff --git a/Dockerfile b/Dockerfile index 1c9c956b72c..c64d529918d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -183,7 +183,7 @@ FROM build AS libvips # libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"] # renovate: datasource=github-releases depName=libvips packageName=libvips/libvips -ARG VIPS_VERSION=8.17.2 +ARG VIPS_VERSION=8.17.3 # libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"] ARG VIPS_URL=https://github.com/libvips/libvips/releases/download diff --git a/Gemfile b/Gemfile index 7d219344b65..e54842fcda0 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,7 @@ gem 'haml-rails', '~>3.0' gem 'pg', '~> 1.5' gem 'pghero' -gem 'aws-sdk-core', '< 3.216.0', require: false # TODO: https://github.com/mastodon/mastodon/pull/34173#issuecomment-2733378873 +gem 'aws-sdk-core', require: false gem 'aws-sdk-s3', '~> 1.123', require: false gem 'blurhash', '~> 0.1' gem 'fog-core', '<= 2.6.0' @@ -114,7 +114,7 @@ group :opentelemetry do gem 'opentelemetry-instrumentation-http', '~> 0.27.0', require: false gem 'opentelemetry-instrumentation-http_client', '~> 0.26.0', require: false gem 'opentelemetry-instrumentation-net_http', '~> 0.26.0', require: false - gem 'opentelemetry-instrumentation-pg', '~> 0.32.0', require: false + gem 'opentelemetry-instrumentation-pg', '~> 0.33.0', require: false gem 'opentelemetry-instrumentation-rack', '~> 0.29.0', require: false gem 'opentelemetry-instrumentation-rails', '~> 0.39.0', require: false gem 'opentelemetry-instrumentation-redis', '~> 0.28.0', require: false @@ -138,7 +138,7 @@ group :test do # Browser integration testing gem 'capybara', '~> 3.39' gem 'capybara-playwright-driver' - gem 'playwright-ruby-client', '1.55.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package + gem 'playwright-ruby-client', '1.56.0', require: false # Pinning the exact version as it needs to be kept in sync with the installed npm package # Used to reset the database between system tests gem 'database_cleaner-active_record' diff --git a/Gemfile.lock b/Gemfile.lock index e36498c3024..251cf771e7c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -90,23 +90,26 @@ GEM public_suffix (>= 2.0.2, < 7.0) aes_key_wrap (1.1.0) android_key_attestation (0.3.0) - annotaterb (4.19.0) + annotaterb (4.20.0) activerecord (>= 6.0.0) activesupport (>= 6.0.0) ast (2.4.3) attr_required (1.0.2) aws-eventstream (1.4.0) - aws-partitions (1.1168.0) - aws-sdk-core (3.215.1) + aws-partitions (1.1180.0) + aws-sdk-core (3.236.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) + base64 + bigdecimal jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.96.0) - aws-sdk-core (~> 3, >= 3.210.0) + logger + aws-sdk-kms (1.116.0) + aws-sdk-core (~> 3, >= 3.234.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.177.0) - aws-sdk-core (~> 3, >= 3.210.0) + aws-sdk-s3 (1.203.0) + aws-sdk-core (~> 3, >= 3.234.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) aws-sigv4 (1.12.1) @@ -116,7 +119,7 @@ GEM base64 (0.3.0) bcp47_spec (0.2.1) bcrypt (3.1.20) - benchmark (0.4.1) + benchmark (0.5.0) better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) @@ -128,7 +131,7 @@ GEM blurhash (0.1.8) bootsnap (1.18.6) msgpack (~> 1.2) - brakeman (7.0.2) + brakeman (7.1.1) racc browser (6.2.0) builder (3.3.0) @@ -168,7 +171,7 @@ GEM cose (1.3.1) cbor (~> 0.5.9) openssl-signature_algorithm (~> 1.0) - crack (1.0.0) + crack (1.0.1) bigdecimal rexml crass (1.0.6) @@ -190,10 +193,10 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-two-factor (6.1.0) - activesupport (>= 7.0, < 8.1) + devise-two-factor (6.2.0) + activesupport (>= 7.0, < 8.2) devise (~> 4.0) - railties (>= 7.0, < 8.1) + railties (>= 7.0, < 8.2) rotp (~> 6.0) devise_pam_authenticatable2 (9.2.0) devise (>= 4.0.0) @@ -224,7 +227,7 @@ GEM mail (~> 2.7) email_validator (2.2.4) activemodel - erb (5.0.2) + erb (5.1.3) erubi (1.13.1) et-orbi (1.4.0) tzinfo @@ -279,7 +282,7 @@ GEM rake (>= 13) googleapis-common-protos-types (1.22.0) google-protobuf (~> 4.26) - haml (6.3.0) + haml (6.4.0) temple (>= 0.8.2) thor tilt @@ -288,7 +291,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.66.0) + haml_lint (0.67.0) haml (>= 5.0) parallel (~> 1.10) rainbow @@ -337,7 +340,7 @@ GEM activesupport (>= 3.0) nokogiri (>= 1.6) io-console (0.8.1) - irb (1.15.2) + irb (1.15.3) pp (>= 0.6.0) rdoc (>= 4.0.0) reline (>= 0.4.2) @@ -346,7 +349,7 @@ GEM azure-blob (~> 0.5.2) hashie (~> 5.0) jmespath (1.6.2) - json (2.15.1) + json (2.15.2) json-canonicalization (1.0.0) json-jwt (1.17.0) activesupport (>= 4.2) @@ -443,7 +446,7 @@ GEM mime-types-data (3.2025.0924) mini_mime (1.1.5) mini_portile2 (2.8.9) - minitest (5.25.5) + minitest (5.26.0) msgpack (1.8.0) multi_json (1.17.0) mutex_m (0.3.0) @@ -465,7 +468,7 @@ GEM nokogiri (1.18.10) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.11) + oj (3.16.12) bigdecimal (>= 3.0) ostruct (>= 0.2) omniauth (2.1.4) @@ -512,9 +515,9 @@ GEM opentelemetry-common (~> 0.20) opentelemetry-sdk (~> 1.10) opentelemetry-semantic_conventions - opentelemetry-helpers-sql (0.2.0) + opentelemetry-helpers-sql (0.3.0) opentelemetry-api (~> 1.7) - opentelemetry-helpers-sql-obfuscation (0.4.0) + opentelemetry-helpers-sql-obfuscation (0.5.0) opentelemetry-common (~> 0.21) opentelemetry-instrumentation-action_mailer (0.6.1) opentelemetry-instrumentation-active_support (~> 0.10) @@ -548,7 +551,7 @@ GEM opentelemetry-instrumentation-base (~> 0.25) opentelemetry-instrumentation-net_http (0.26.0) opentelemetry-instrumentation-base (~> 0.25) - opentelemetry-instrumentation-pg (0.32.0) + opentelemetry-instrumentation-pg (0.33.0) opentelemetry-helpers-sql opentelemetry-helpers-sql-obfuscation opentelemetry-instrumentation-base (~> 0.25) @@ -581,7 +584,7 @@ GEM ox (2.14.23) bigdecimal (>= 3.0) parallel (1.27.0) - parser (3.3.9.0) + parser (3.3.10.0) ast (~> 2.4.1) racc parslet (2.0.0) @@ -590,7 +593,7 @@ GEM pg (1.6.2) pghero (3.7.0) activerecord (>= 7.1) - playwright-ruby-client (1.55.0) + playwright-ruby-client (1.56.0) concurrent-ruby (>= 1.1.6) mime-types (>= 3.0) pp (0.6.3) @@ -604,7 +607,7 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) prettyprint (0.2.0) - prism (1.5.2) + prism (1.6.0) prometheus_exporter (2.3.0) webrick propshaft (1.3.1) @@ -621,7 +624,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (3.2.3) + rack (3.2.4) rack-attack (6.8.0) rack (>= 1.0, < 4) rack-cors (3.0.0) @@ -691,7 +694,7 @@ GEM readline (~> 0.0) rdf-normalize (0.7.0) rdf (~> 3.3) - rdoc (6.15.0) + rdoc (6.15.1) erb psych (>= 4.0.0) tsort @@ -706,9 +709,9 @@ GEM io-console (~> 0.5) request_store (1.7.0) rack (>= 1.4) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) + responders (3.2.0) + actionpack (>= 7.0) + railties (>= 7.0) rexml (3.4.4) rotp (6.3.0) rouge (4.6.1) @@ -745,7 +748,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 9) rspec-support (3.13.6) - rubocop (1.81.6) + rubocop (1.81.7) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -791,7 +794,7 @@ GEM ruby-vips (2.2.5) ffi (~> 1.12) logger - rubyzip (3.2.1) + rubyzip (3.2.2) rufus-scheduler (3.9.2) fugit (~> 1.1, >= 1.11.1) safety_net_attestation (0.5.0) @@ -803,9 +806,9 @@ GEM activerecord (>= 4.0.0) railties (>= 4.0.0) securerandom (0.4.1) - shoulda-matchers (6.5.0) - activesupport (>= 5.2.0) - sidekiq (8.0.8) + shoulda-matchers (7.0.1) + activesupport (>= 7.1) + sidekiq (8.0.9) connection_pool (>= 2.5.0) json (>= 2.9.0) logger (>= 1.6.2) @@ -822,9 +825,9 @@ GEM thor (>= 1.0, < 3.0) simple-navigation (4.4.0) activesupport (>= 2.3.2) - simple_form (5.3.1) - actionpack (>= 5.2) - activemodel (>= 5.2) + simple_form (5.4.0) + actionpack (>= 7.0) + activemodel (>= 7.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -835,7 +838,7 @@ GEM stackprof (0.2.27) starry (0.2.0) base64 - stoplight (5.4.0) + stoplight (5.5.0) zeitwerk stringio (3.1.7) strong_migrations (2.5.1) @@ -883,7 +886,7 @@ GEM unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.1.0) - uri (1.0.4) + uri (1.1.1) useragent (0.16.11) validate_url (1.0.15) activemodel (>= 3.0.0) @@ -911,7 +914,7 @@ GEM activesupport faraday (~> 2.0) faraday-follow_redirects - webmock (3.25.1) + webmock (3.26.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -933,7 +936,7 @@ DEPENDENCIES active_model_serializers (~> 0.10) addressable (~> 2.8) annotaterb (~> 4.13) - aws-sdk-core (< 3.216.0) + aws-sdk-core aws-sdk-s3 (~> 1.123) better_errors (~> 2.9) binding_of_caller (~> 1.0) @@ -1018,7 +1021,7 @@ DEPENDENCIES opentelemetry-instrumentation-http (~> 0.27.0) opentelemetry-instrumentation-http_client (~> 0.26.0) opentelemetry-instrumentation-net_http (~> 0.26.0) - opentelemetry-instrumentation-pg (~> 0.32.0) + opentelemetry-instrumentation-pg (~> 0.33.0) opentelemetry-instrumentation-rack (~> 0.29.0) opentelemetry-instrumentation-rails (~> 0.39.0) opentelemetry-instrumentation-redis (~> 0.28.0) @@ -1028,7 +1031,7 @@ DEPENDENCIES parslet pg (~> 1.5) pghero - playwright-ruby-client (= 1.55.0) + playwright-ruby-client (= 1.56.0) premailer-rails prometheus_exporter (~> 2.2) propshaft diff --git a/SECURITY.md b/SECURITY.md index 19f431fac59..12052652e6c 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -15,7 +15,8 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through | Version | Supported | | ------- | ---------------- | +| 4.5.x | Yes | | 4.4.x | Yes | -| 4.3.x | Yes | +| 4.3.x | Until 2026-05-06 | | 4.2.x | Until 2026-01-08 | | < 4.2 | No | diff --git a/app/controllers/activitypub/quote_authorizations_controller.rb b/app/controllers/activitypub/quote_authorizations_controller.rb index f2f5313e1ad..f4a15055508 100644 --- a/app/controllers/activitypub/quote_authorizations_controller.rb +++ b/app/controllers/activitypub/quote_authorizations_controller.rb @@ -9,7 +9,7 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController before_action :set_quote_authorization def show - expires_in 30.seconds, public: true if @quote.status.distributable? && public_fetch_mode? + expires_in 30.seconds, public: true if @quote.quoted_status.distributable? && public_fetch_mode? render json: @quote, serializer: ActivityPub::QuoteAuthorizationSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json' end @@ -23,7 +23,7 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController @quote = Quote.accepted.where(quoted_account: @account).find(params[:id]) return not_found unless @quote.status.present? && @quote.quoted_status.present? - authorize @quote.status, :show? + authorize @quote.quoted_status, :show? rescue Mastodon::NotPermittedError not_found end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 0627acc30f8..fd7757f2e81 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -66,7 +66,7 @@ class Api::V1::StatusesController < Api::BaseController if async_refresh.running? add_async_refresh_header(async_refresh) elsif !current_account.nil? && @status.should_fetch_replies? - add_async_refresh_header(AsyncRefresh.create(refresh_key)) + add_async_refresh_header(AsyncRefresh.create(refresh_key, count_results: true)) WorkerBatch.new.within do |batch| batch.connect(refresh_key, threshold: 1.0) @@ -126,10 +126,11 @@ class Api::V1::StatusesController < Api::BaseController @status = Status.where(account: current_account).find(params[:id]) authorize @status, :destroy? + json = render_to_body json: @status, serializer: REST::StatusSerializer, source_requested: true + @status.discard_with_reblogs StatusPin.find_by(status: @status)&.destroy @status.account.statuses_count = @status.account.statuses_count - 1 - json = render_to_body json: @status, serializer: REST::StatusSerializer, source_requested: true RemovalWorker.perform_async(@status.id, { 'redraft' => !truthy_param?(:delete_media) }) diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index e9727b756a4..0e0062876a7 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -7,6 +7,7 @@ class FollowerAccountsController < ApplicationController vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' } before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? } + before_action :protect_hidden_collections, if: -> { request.format.json? } skip_around_action :set_locale, if: -> { request.format == :json } skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -18,8 +19,6 @@ class FollowerAccountsController < ApplicationController end format.json do - raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? - expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) render json: collection_presenter, @@ -41,6 +40,10 @@ class FollowerAccountsController < ApplicationController @follows = scope.recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account) end + def protect_hidden_collections + raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? + end + def page_requested? params[:page].present? end diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 803d6e342a9..7a0f37887de 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -7,6 +7,7 @@ class FollowingAccountsController < ApplicationController vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' } before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? } + before_action :protect_hidden_collections, if: -> { request.format.json? } skip_around_action :set_locale, if: -> { request.format == :json } skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -18,11 +19,6 @@ class FollowingAccountsController < ApplicationController end format.json do - if page_requested? && @account.hide_collections? - forbidden - next - end - expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?) render json: collection_presenter, @@ -44,6 +40,10 @@ class FollowingAccountsController < ApplicationController @follows = scope.recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account) end + def protect_hidden_collections + raise Mastodon::NotPermittedError if page_requested? && @account.hide_collections? + end + def page_requested? params[:page].present? end diff --git a/app/javascript/entrypoints/public.tsx b/app/javascript/entrypoints/public.tsx index fea3eb0d792..dd1956446da 100644 --- a/app/javascript/entrypoints/public.tsx +++ b/app/javascript/entrypoints/public.tsx @@ -70,7 +70,7 @@ function loaded() { }; document.querySelectorAll('.emojify').forEach((content) => { - content.innerHTML = emojify(content.innerHTML, {}, true); // Force emojify as public doesn't load the new emoji system. + content.innerHTML = emojify(content.innerHTML); }); document diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index d6de589e903..232c4b1c19c 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -5,6 +5,7 @@ import { throttle } from 'lodash'; import api from 'mastodon/api'; import { browserHistory } from 'mastodon/components/router'; +import { countableText } from 'mastodon/features/compose/util/counter'; import { search as emojiSearch } from 'mastodon/features/emoji/emoji_mart_search_light'; import { tagHistory } from 'mastodon/settings'; @@ -55,7 +56,6 @@ export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT'; export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE'; export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE'; export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE'; -export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE'; export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE'; export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE'; @@ -88,6 +88,7 @@ const messages = defineMessages({ open: { id: 'compose.published.open', defaultMessage: 'Open' }, published: { id: 'compose.published.body', defaultMessage: 'Post published.' }, saved: { id: 'compose.saved.body', defaultMessage: 'Post saved.' }, + blankPostError: { id: 'compose.error.blank_post', defaultMessage: 'Post can\'t be blank.' }, }); export const ensureComposeIsVisible = (getState) => { @@ -197,7 +198,15 @@ export function submitCompose(successCallback) { const hasQuote = !!getState().getIn(['compose', 'quoted_status_id']); const spoiler_text = getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : ''; - if (!(status?.length || media.size !== 0 || (hasQuote && spoiler_text?.length))) { + const fulltext = `${spoiler_text ?? ''}${countableText(status ?? '')}`; + const hasText = fulltext.trim().length > 0; + + if (!(hasText || media.size !== 0 || (hasQuote && spoiler_text?.length))) { + dispatch(showAlert({ + message: messages.blankPostError, + })); + dispatch(focusCompose()); + return; } @@ -784,13 +793,6 @@ export function changeComposeSpoilerText(text) { }; } -export function changeComposeVisibility(value) { - return { - type: COMPOSE_VISIBILITY_CHANGE, - value, - }; -} - export function insertEmojiCompose(position, emoji, needsSpace) { return { type: COMPOSE_EMOJI_INSERT, diff --git a/app/javascript/mastodon/actions/compose_typed.ts b/app/javascript/mastodon/actions/compose_typed.ts index 0f9bf5cfb3c..6b38b25c25c 100644 --- a/app/javascript/mastodon/actions/compose_typed.ts +++ b/app/javascript/mastodon/actions/compose_typed.ts @@ -13,10 +13,11 @@ import { } from 'mastodon/store/typed_functions'; import type { ApiQuotePolicy } from '../api_types/quotes'; -import type { Status } from '../models/status'; +import type { Status, StatusVisibility } from '../models/status'; +import type { RootState } from '../store'; import { showAlert } from './alerts'; -import { focusCompose } from './compose'; +import { changeCompose, focusCompose } from './compose'; import { importFetchedStatuses } from './importer'; import { openModal } from './modal'; @@ -41,6 +42,10 @@ const messages = defineMessages({ id: 'quote_error.unauthorized', defaultMessage: 'You are not authorized to quote this post.', }, + quoteErrorPrivateMention: { + id: 'quote_error.private_mentions', + defaultMessage: 'Quoting is not allowed with direct mentions.', + }, }); type SimulatedMediaAttachmentJSON = ApiMediaAttachmentJSON & { @@ -67,6 +72,39 @@ const simulateModifiedApiResponse = ( return data; }; +export const changeComposeVisibility = createAppThunk( + 'compose/visibility_change', + (visibility: StatusVisibility, { dispatch, getState }) => { + if (visibility !== 'direct') { + return visibility; + } + + const state = getState(); + const quotedStatusId = state.compose.get('quoted_status_id') as + | string + | null; + if (!quotedStatusId) { + return visibility; + } + + // Remove the quoted status + dispatch(quoteComposeCancel()); + const quotedStatus = state.statuses.get(quotedStatusId) as Status | null; + if (!quotedStatus) { + return visibility; + } + + // Append the quoted status URL to the compose text + const url = quotedStatus.get('url') as string; + const text = state.compose.get('text') as string; + if (!text.includes(url)) { + const newText = text.trim() ? `${text}\n\n${url}` : url; + dispatch(changeCompose(newText)); + } + return visibility; + }, +); + export const changeUploadCompose = createDataLoadingThunk( 'compose/changeUpload', async ( @@ -130,6 +168,8 @@ export const quoteComposeByStatus = createAppThunk( if (composeState.get('id')) { dispatch(showAlert({ message: messages.quoteErrorEdit })); + } else if (composeState.get('privacy') === 'direct') { + dispatch(showAlert({ message: messages.quoteErrorPrivateMention })); } else if (composeState.get('poll')) { dispatch(showAlert({ message: messages.quoteErrorPoll })); } else if ( @@ -173,6 +213,17 @@ export const quoteComposeById = createAppThunk( }, ); +const composeStateForbidsLink = (composeState: RootState['compose']) => { + return ( + composeState.get('quoted_status_id') || + composeState.get('is_submitting') || + composeState.get('poll') || + composeState.get('is_uploading') || + composeState.get('id') || + composeState.get('privacy') === 'direct' + ); +}; + export const pasteLinkCompose = createDataLoadingThunk( 'compose/pasteLink', async ({ url }: { url: string }) => { @@ -183,15 +234,12 @@ export const pasteLinkCompose = createDataLoadingThunk( limit: 2, }); }, - (data, { dispatch, getState }) => { + (data, { dispatch, getState, requestId }) => { const composeState = getState().compose; if ( - composeState.get('quoted_status_id') || - composeState.get('is_submitting') || - composeState.get('poll') || - composeState.get('is_uploading') || - composeState.get('id') + composeStateForbidsLink(composeState) || + composeState.get('fetching_link') !== requestId // Request has been cancelled ) return; @@ -207,6 +255,17 @@ export const pasteLinkCompose = createDataLoadingThunk( dispatch(quoteComposeById(data.statuses[0].id)); } }, + { + useLoadingBar: false, + condition: (_, { getState }) => + !getState().compose.get('fetching_link') && + !composeStateForbidsLink(getState().compose), + }, +); + +// Ideally this would cancel the action and the HTTP request, but this is good enough +export const cancelPasteLinkCompose = createAction( + 'compose/cancelPasteLinkCompose', ); export const quoteComposeCancel = createAction('compose/quoteComposeCancel'); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 7723379804c..32c3d766665 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -1,8 +1,5 @@ import escapeTextContentForBrowser from 'escape-html'; -import { makeEmojiMap } from 'mastodon/models/custom_emoji'; - -import emojify from '../../features/emoji/emoji'; import { expandSpoilers } from '../../initial_state'; const domParser = new DOMParser(); @@ -88,11 +85,10 @@ export function normalizeStatus(status, normalOldStatus) { const spoilerText = normalStatus.spoiler_text || ''; const searchContent = ([spoilerText, status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); - const emojiMap = makeEmojiMap(normalStatus.emojis); normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; - normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); - normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap); + normalStatus.contentHtml = normalStatus.content; + normalStatus.spoilerHtml = escapeTextContentForBrowser(spoilerText); normalStatus.hidden = expandSpoilers ? false : spoilerText.length > 0 || normalStatus.sensitive; // Remove quote fallback link from the DOM so it doesn't mess with paragraph margins @@ -128,14 +124,12 @@ export function normalizeStatus(status, normalOldStatus) { } export function normalizeStatusTranslation(translation, status) { - const emojiMap = makeEmojiMap(status.get('emojis').toJS()); - const normalTranslation = { detected_source_language: translation.detected_source_language, language: translation.language, provider: translation.provider, - contentHtml: emojify(translation.content, emojiMap), - spoilerHtml: emojify(escapeTextContentForBrowser(translation.spoiler_text), emojiMap), + contentHtml: translation.content, + spoilerHtml: escapeTextContentForBrowser(translation.spoiler_text), spoiler_text: translation.spoiler_text, }; @@ -149,9 +143,8 @@ export function normalizeStatusTranslation(translation, status) { export function normalizeAnnouncement(announcement) { const normalAnnouncement = { ...announcement }; - const emojiMap = makeEmojiMap(normalAnnouncement.emojis); - normalAnnouncement.contentHtml = emojify(normalAnnouncement.content, emojiMap); + normalAnnouncement.contentHtml = normalAnnouncement.content; return normalAnnouncement; } diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js index 478e0cae453..4299bad5c32 100644 --- a/app/javascript/mastodon/actions/streaming.js +++ b/app/javascript/mastodon/actions/streaming.js @@ -32,13 +32,20 @@ import { const randomUpTo = max => Math.floor(Math.random() * Math.floor(max)); +/** + * @typedef {import('mastodon/store').AppDispatch} Dispatch + * @typedef {import('mastodon/store').GetState} GetState + * @typedef {import('redux').UnknownAction} UnknownAction + * @typedef {function(Dispatch, GetState): Promise} FallbackFunction + */ + /** * @param {string} timelineId * @param {string} channelName * @param {Object.} params * @param {Object} options - * @param {function(Function, Function): Promise} [options.fallback] - * @param {function(): void} [options.fillGaps] + * @param {FallbackFunction} [options.fallback] + * @param {function(): UnknownAction} [options.fillGaps] * @param {function(object): boolean} [options.accept] * @returns {function(): void} */ @@ -46,13 +53,14 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti const { messages } = getLocale(); return connectStream(channelName, params, (dispatch, getState) => { + // @ts-ignore const locale = getState().getIn(['meta', 'locale']); // @ts-expect-error let pollingId; /** - * @param {function(Function, Function): Promise} fallback + * @param {FallbackFunction} fallback */ const useFallback = async fallback => { @@ -132,7 +140,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti }; /** - * @param {Function} dispatch + * @param {Dispatch} dispatch */ async function refreshHomeTimelineAndNotification(dispatch) { await dispatch(expandHomeTimeline({ maxId: undefined })); @@ -151,7 +159,11 @@ async function refreshHomeTimelineAndNotification(dispatch) { * @returns {function(): void} */ export const connectUserStream = () => - connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps }); + connectTimelineStream('home', 'user', {}, { + fallback: refreshHomeTimelineAndNotification, + // @ts-expect-error + fillGaps: fillHomeTimelineGaps + }); /** * @param {Object} options @@ -159,7 +171,10 @@ export const connectUserStream = () => * @returns {function(): void} */ export const connectCommunityStream = ({ onlyMedia } = {}) => - connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`, {}, { fillGaps: () => (fillCommunityTimelineGaps({ onlyMedia })) }); + connectTimelineStream(`community${onlyMedia ? ':media' : ''}`, `public:local${onlyMedia ? ':media' : ''}`, {}, { + // @ts-expect-error + fillGaps: () => (fillCommunityTimelineGaps({ onlyMedia })) + }); /** * @param {Object} options @@ -168,7 +183,10 @@ export const connectCommunityStream = ({ onlyMedia } = {}) => * @returns {function(): void} */ export const connectPublicStream = ({ onlyMedia, onlyRemote } = {}) => - connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, {}, { fillGaps: () => fillPublicTimelineGaps({ onlyMedia, onlyRemote }) }); + connectTimelineStream(`public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, `public${onlyRemote ? ':remote' : ''}${onlyMedia ? ':media' : ''}`, {}, { + // @ts-expect-error + fillGaps: () => fillPublicTimelineGaps({ onlyMedia, onlyRemote }) + }); /** * @param {string} columnId @@ -191,4 +209,7 @@ export const connectDirectStream = () => * @returns {function(): void} */ export const connectListStream = listId => - connectTimelineStream(`list:${listId}`, 'list', { list: listId }, { fillGaps: () => fillListTimelineGaps(listId) }); + connectTimelineStream(`list:${listId}`, 'list', { list: listId }, { + // @ts-expect-error + fillGaps: () => fillListTimelineGaps(listId) + }); diff --git a/app/javascript/mastodon/components/account_bio.tsx b/app/javascript/mastodon/components/account_bio.tsx index e87ae654fdf..6d4ab1ddd49 100644 --- a/app/javascript/mastodon/components/account_bio.tsx +++ b/app/javascript/mastodon/components/account_bio.tsx @@ -1,11 +1,6 @@ -import { useCallback } from 'react'; - import classNames from 'classnames'; -import { useLinks } from 'mastodon/hooks/useLinks'; - import { useAppSelector } from '../store'; -import { isModernEmojiEnabled } from '../utils/environment'; import { EmojiHTML } from './emoji/html'; import { useElementHandledLink } from './status/handled_link'; @@ -21,22 +16,6 @@ export const AccountBio: React.FC = ({ accountId, showDropdown = false, }) => { - const handleClick = useLinks(showDropdown); - const handleNodeChange = useCallback( - (node: HTMLDivElement | null) => { - if ( - !showDropdown || - !node || - node.childNodes.length === 0 || - isModernEmojiEnabled() - ) { - return; - } - addDropdownToHashtags(node, accountId); - }, - [showDropdown, accountId], - ); - const htmlHandlers = useElementHandledLink({ hashtagAccountId: showDropdown ? accountId : undefined, }); @@ -62,30 +41,7 @@ export const AccountBio: React.FC = ({ htmlString={note} extraEmojis={extraEmojis} className={classNames(className, 'translate')} - onClickCapture={handleClick} - ref={handleNodeChange} {...htmlHandlers} /> ); }; - -function addDropdownToHashtags(node: HTMLElement | null, accountId: string) { - if (!node) { - return; - } - for (const childNode of node.childNodes) { - if (!(childNode instanceof HTMLElement)) { - continue; - } - if ( - childNode instanceof HTMLAnchorElement && - (childNode.classList.contains('hashtag') || - childNode.innerText.startsWith('#')) && - !childNode.dataset.menuHashtag - ) { - childNode.dataset.menuHashtag = accountId; - } else if (childNode.childNodes.length > 0) { - addDropdownToHashtags(childNode, accountId); - } - } -} diff --git a/app/javascript/mastodon/components/alert/index.tsx b/app/javascript/mastodon/components/alert/index.tsx index 72fee0a4a30..8bee99130f5 100644 --- a/app/javascript/mastodon/components/alert/index.tsx +++ b/app/javascript/mastodon/components/alert/index.tsx @@ -49,7 +49,11 @@ export const Alert: React.FC<{ {hasAction && ( - )} diff --git a/app/javascript/mastodon/components/alt_text_badge.tsx b/app/javascript/mastodon/components/alt_text_badge.tsx index c7fb0cd81b1..33dd3963d21 100644 --- a/app/javascript/mastodon/components/alt_text_badge.tsx +++ b/app/javascript/mastodon/components/alt_text_badge.tsx @@ -47,7 +47,7 @@ export const AltTextBadge: React.FC<{ description: string }> = ({ rootClose onHide={handleClose} show={open} - target={anchorRef.current} + target={anchorRef} placement='top-end' flip offset={offset} diff --git a/app/javascript/mastodon/components/button/index.tsx b/app/javascript/mastodon/components/button/index.tsx index f940c07d056..ca2da05b703 100644 --- a/app/javascript/mastodon/components/button/index.tsx +++ b/app/javascript/mastodon/components/button/index.tsx @@ -78,6 +78,7 @@ export const Button: React.FC = ({ aria-live={loading !== undefined ? 'polite' : undefined} onClick={handleClick} title={title} + // eslint-disable-next-line react/button-has-type -- set correctly via TS type={type} {...props} > diff --git a/app/javascript/mastodon/components/carousel/carousel.stories.tsx b/app/javascript/mastodon/components/carousel/carousel.stories.tsx new file mode 100644 index 00000000000..5117bc08e35 --- /dev/null +++ b/app/javascript/mastodon/components/carousel/carousel.stories.tsx @@ -0,0 +1,126 @@ +import type { FC } from 'react'; + +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { fn, userEvent, expect } from 'storybook/test'; + +import type { CarouselProps } from './index'; +import { Carousel } from './index'; + +interface TestSlideProps { + id: number; + text: string; + color: string; +} + +const TestSlide: FC = ({ + active, + text, + color, +}) => ( +

+ {text} +
+); + +const slides: TestSlideProps[] = [ + { + id: 1, + text: 'first', + color: 'red', + }, + { + id: 2, + text: 'second', + color: 'pink', + }, + { + id: 3, + text: 'third', + color: 'orange', + }, +]; + +type StoryProps = Pick< + CarouselProps, + 'items' | 'renderItem' | 'emptyFallback' | 'onChangeSlide' +>; + +const meta = { + title: 'Components/Carousel', + args: { + items: slides, + renderItem(item, active) { + return ; + }, + onChangeSlide: fn(), + emptyFallback: 'No slides available', + }, + render(args) { + return ( + <> + + + + ); + }, + argTypes: { + emptyFallback: { + type: 'string', + }, + }, + tags: ['test'], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + async play({ args, canvas }) { + const nextButton = await canvas.findByRole('button', { name: /next/i }); + const slides = await canvas.findAllByRole('group'); + await expect(slides).toHaveLength(slides.length); + + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(1, slides[1]); + + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(2, slides[2]); + + // Wrap around + await userEvent.click(nextButton); + await expect(args.onChangeSlide).toHaveBeenCalledWith(0, slides[0]); + }, +}; + +export const DifferentHeights: Story = { + args: { + items: slides.map((props, index) => ({ + ...props, + styles: { height: 100 + index * 100 }, + })), + }, +}; + +export const NoSlides: Story = { + args: { + items: [], + }, +}; diff --git a/app/javascript/mastodon/components/carousel/index.tsx b/app/javascript/mastodon/components/carousel/index.tsx new file mode 100644 index 00000000000..bc287aa9691 --- /dev/null +++ b/app/javascript/mastodon/components/carousel/index.tsx @@ -0,0 +1,244 @@ +import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; +import type { + ComponentPropsWithoutRef, + ComponentType, + ReactElement, + ReactNode, +} from 'react'; + +import type { MessageDescriptor } from 'react-intl'; +import { defineMessages, useIntl } from 'react-intl'; + +import classNames from 'classnames'; + +import { usePrevious } from '@dnd-kit/utilities'; +import { animated, useSpring } from '@react-spring/web'; +import { useDrag } from '@use-gesture/react'; + +import type { CarouselPaginationProps } from './pagination'; +import { CarouselPagination } from './pagination'; + +import './styles.scss'; + +const defaultMessages = defineMessages({ + previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, + next: { id: 'lightbox.next', defaultMessage: 'Next' }, + current: { + id: 'carousel.current', + defaultMessage: 'Slide {current, number} / {max, number}', + }, + slide: { + id: 'carousel.slide', + defaultMessage: 'Slide {current, number} of {max, number}', + }, +}); + +export type MessageKeys = keyof typeof defaultMessages; + +export interface CarouselSlideProps { + id: string | number; +} + +export type RenderSlideFn< + SlideProps extends CarouselSlideProps = CarouselSlideProps, +> = (item: SlideProps, active: boolean, index: number) => ReactElement; + +export interface CarouselProps< + SlideProps extends CarouselSlideProps = CarouselSlideProps, +> { + items: SlideProps[]; + renderItem: RenderSlideFn; + onChangeSlide?: (index: number, ref: Element) => void; + paginationComponent?: ComponentType | null; + paginationProps?: Partial; + messages?: Record; + emptyFallback?: ReactNode; + classNamePrefix?: string; + slideClassName?: string; +} + +export const Carousel = < + SlideProps extends CarouselSlideProps = CarouselSlideProps, +>({ + items, + renderItem, + onChangeSlide, + paginationComponent: Pagination = CarouselPagination, + paginationProps = {}, + messages = defaultMessages, + children, + emptyFallback = null, + className, + classNamePrefix = 'carousel', + slideClassName, + ...wrapperProps +}: CarouselProps & ComponentPropsWithoutRef<'div'>) => { + // Handle slide change + const [slideIndex, setSlideIndex] = useState(0); + const wrapperRef = useRef(null); + // Handle slide heights + const [currentSlideHeight, setCurrentSlideHeight] = useState( + () => wrapperRef.current?.scrollHeight ?? 0, + ); + const previousSlideHeight = usePrevious(currentSlideHeight); + const handleSlideChange = useCallback( + (direction: number) => { + setSlideIndex((prev) => { + const max = items.length - 1; + let newIndex = prev + direction; + if (newIndex < 0) { + newIndex = max; + } else if (newIndex > max) { + newIndex = 0; + } + + const slide = wrapperRef.current?.children[newIndex]; + if (slide) { + setCurrentSlideHeight(slide.scrollHeight); + if (slide instanceof HTMLElement) { + onChangeSlide?.(newIndex, slide); + } + } + + return newIndex; + }); + }, + [items.length, onChangeSlide], + ); + + const observerRef = useRef(null); + observerRef.current ??= new ResizeObserver(() => { + handleSlideChange(0); + }); + + const wrapperStyles = useSpring({ + x: `-${slideIndex * 100}%`, + height: currentSlideHeight, + // Don't animate from zero to the height of the initial slide + immediate: !previousSlideHeight, + }); + useLayoutEffect(() => { + // Update slide height when the component mounts + if (currentSlideHeight === 0) { + handleSlideChange(0); + } + }, [currentSlideHeight, handleSlideChange]); + + // Handle swiping animations + const bind = useDrag( + ({ swipe: [swipeX] }) => { + handleSlideChange(swipeX * -1); // Invert swipe as swiping left loads the next slide. + }, + { pointer: { capture: false } }, + ); + const handlePrev = useCallback(() => { + handleSlideChange(-1); + // We're focusing on the wrapper as the child slides can potentially be inert. + // Because of that, only the active slide can be focused anyway. + wrapperRef.current?.focus(); + }, [handleSlideChange]); + const handleNext = useCallback(() => { + handleSlideChange(1); + wrapperRef.current?.focus(); + }, [handleSlideChange]); + + const intl = useIntl(); + + if (items.length === 0) { + return emptyFallback; + } + + return ( +
+
+ {children} + {Pagination && items.length > 1 && ( + + )} +
+ + + {items.map((itemsProps, index) => ( + + item={itemsProps} + renderItem={renderItem} + observer={observerRef.current} + index={index} + key={`slide-${itemsProps.id}`} + className={classNames(`${classNamePrefix}__slide`, slideClassName, { + active: index === slideIndex, + })} + active={index === slideIndex} + /> + ))} + +
+ ); +}; + +type CarouselSlideWrapperProps = { + observer: ResizeObserver | null; + className: string; + active: boolean; + item: SlideProps; + index: number; +} & Pick, 'renderItem'>; + +const CarouselSlideWrapper = ({ + observer, + className, + active, + renderItem, + item, + index, +}: CarouselSlideWrapperProps) => { + const handleRef = useCallback( + (instance: HTMLDivElement | null) => { + if (observer && instance) { + observer.observe(instance); + } + }, + [observer], + ); + + const children = useMemo( + () => renderItem(item, active, index), + [renderItem, item, active, index], + ); + + return ( +
+ {children} +
+ ); +}; diff --git a/app/javascript/mastodon/components/carousel/pagination.tsx b/app/javascript/mastodon/components/carousel/pagination.tsx new file mode 100644 index 00000000000..a2666f486fe --- /dev/null +++ b/app/javascript/mastodon/components/carousel/pagination.tsx @@ -0,0 +1,54 @@ +import type { FC, MouseEventHandler } from 'react'; + +import type { MessageDescriptor } from 'react-intl'; +import { useIntl } from 'react-intl'; + +import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; + +import { IconButton } from '../icon_button'; + +import type { MessageKeys } from './index'; + +export interface CarouselPaginationProps { + onNext: MouseEventHandler; + onPrev: MouseEventHandler; + current: number; + max: number; + className?: string; + messages: Record; +} + +export const CarouselPagination: FC = ({ + onNext, + onPrev, + current, + max, + className = '', + messages, +}) => { + const intl = useIntl(); + return ( +
+ + + {intl.formatMessage(messages.current, { + current: current + 1, + max, + sr: (chunk) => {chunk}, + })} + + +
+ ); +}; diff --git a/app/javascript/mastodon/components/carousel/styles.scss b/app/javascript/mastodon/components/carousel/styles.scss new file mode 100644 index 00000000000..bcd0bc7d3af --- /dev/null +++ b/app/javascript/mastodon/components/carousel/styles.scss @@ -0,0 +1,28 @@ +.carousel { + gap: 16px; + overflow: hidden; + touch-action: pan-y; + + &__header { + padding: 8px 16px; + } + + &__pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + } + + &__slides { + display: flex; + flex-wrap: nowrap; + align-items: start; + } + + &__slide { + flex: 0 0 100%; + width: 100%; + overflow: hidden; + } +} diff --git a/app/javascript/mastodon/components/column_back_button.tsx b/app/javascript/mastodon/components/column_back_button.tsx index aad355d710d..8012ba7df69 100644 --- a/app/javascript/mastodon/components/column_back_button.tsx +++ b/app/javascript/mastodon/components/column_back_button.tsx @@ -30,7 +30,7 @@ export const ColumnBackButton: React.FC<{ onClick?: OnClickCallback }> = ({ const handleClick = useHandleClick(onClick); const component = ( - @@ -193,6 +196,7 @@ export const ColumnHeader: React.FC = ({ aria-label={intl.formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={handleMoveRight} + type='button' > @@ -203,6 +207,7 @@ export const ColumnHeader: React.FC = ({ @@ -248,9 +227,7 @@ export const DropdownMenu = ({ target={option.target ?? '_target'} data-method={option.method} rel='noopener' - ref={i === 0 ? handleFocusedItemRef : undefined} onClick={handleItemClick} - onKeyUp={handleItemKeyUp} data-index={i} > @@ -258,13 +235,7 @@ export const DropdownMenu = ({ ); } else { element = ( - + ); @@ -307,15 +278,7 @@ export const DropdownMenu = ({ })} > {items.map((option, i) => - renderItemMethod( - option, - i, - { - onClick: handleItemClick, - onKeyUp: handleItemKeyUp, - }, - i === 0 ? handleFocusedItemRef : undefined, - ), + renderItemMethod(option, i, handleItemClick), )} )} @@ -399,7 +362,7 @@ export const Dropdown = ({ }, [dispatch, currentId]); const handleItemClick = useCallback( - (e: React.MouseEvent | React.KeyboardEvent) => { + (e: React.MouseEvent) => { const i = Number(e.currentTarget.getAttribute('data-index')); const item = items?.[i]; @@ -420,10 +383,20 @@ export const Dropdown = ({ [handleClose, onItemClick, items], ); - const toggleDropdown = useCallback( - (e: React.MouseEvent | React.KeyboardEvent) => { - const { type } = e; + const isKeypressRef = useRef(false); + const handleKeyDown = useCallback((e: React.KeyboardEvent) => { + if (e.key === ' ' || e.key === 'Enter') { + isKeypressRef.current = true; + } + }, []); + + const unsetIsKeypress = useCallback(() => { + isKeypressRef.current = false; + }, []); + + const toggleDropdown = useCallback( + (e: React.MouseEvent) => { if (open) { handleClose(); } else { @@ -450,10 +423,11 @@ export const Dropdown = ({ dispatch( openDropdownMenu({ id: currentId, - keyboard: type !== 'click', + keyboard: isKeypressRef.current, scrollKey, }), ); + isKeypressRef.current = false; } } }, @@ -484,6 +458,9 @@ export const Dropdown = ({ const buttonProps = { disabled, onClick: toggleDropdown, + onKeyDown: handleKeyDown, + onKeyUp: unsetIsKeypress, + onBlur: unsetIsKeypress, 'aria-expanded': open, 'aria-controls': menuId, ref: buttonRef, diff --git a/app/javascript/mastodon/components/edited_timestamp/index.tsx b/app/javascript/mastodon/components/edited_timestamp/index.tsx index 63b21cf5bdf..36f8db8abff 100644 --- a/app/javascript/mastodon/components/edited_timestamp/index.tsx +++ b/app/javascript/mastodon/components/edited_timestamp/index.tsx @@ -58,17 +58,7 @@ export const EditedTimestamp: React.FC<{ }, []); const renderItem = useCallback( - ( - item: HistoryItem, - index: number, - { - onClick, - onKeyUp, - }: { - onClick: React.MouseEventHandler; - onKeyUp: React.KeyboardEventHandler; - }, - ) => { + (item: HistoryItem, index: number, onClick: React.MouseEventHandler) => { const formattedDate = ( - @@ -118,7 +108,7 @@ export const EditedTimestamp: React.FC<{ onItemClick={handleItemClick} forceDropdown > - is focused, + When a is focused, Enter should not trigger open, but o should. diff --git a/app/javascript/mastodon/components/hover_card_account.tsx b/app/javascript/mastodon/components/hover_card_account.tsx index 471d4884157..b51af40e94c 100644 --- a/app/javascript/mastodon/components/hover_card_account.tsx +++ b/app/javascript/mastodon/components/hover_card_account.tsx @@ -23,8 +23,6 @@ import { domain } from 'mastodon/initial_state'; import { getAccountHidden } from 'mastodon/selectors/accounts'; import { useAppSelector, useAppDispatch } from 'mastodon/store'; -import { useLinks } from '../hooks/useLinks'; - export const HoverCardAccount = forwardRef< HTMLDivElement, { accountId?: string } @@ -66,8 +64,6 @@ export const HoverCardAccount = forwardRef< !isMutual && !isFollower; - const handleClick = useLinks(); - return (
-
+
{ const [setLeaveTimeout, cancelLeaveTimeout] = useTimeout(); const [setEnterTimeout, cancelEnterTimeout, delayEnterTimeout] = useTimeout(); const [setScrollTimeout] = useTimeout(); - const location = useLocation(); const handleClose = useCallback(() => { cancelEnterTimeout(); @@ -36,9 +35,12 @@ export const HoverCardController: React.FC = () => { setAnchor(null); }, [cancelEnterTimeout, cancelLeaveTimeout, setOpen, setAnchor]); - useEffect(() => { + const location = useLocation(); + const [previousLocation, setPreviousLocation] = useState(location); + if (location !== previousLocation) { + setPreviousLocation(location); handleClose(); - }, [handleClose, location]); + } useEffect(() => { let isScrolling = false; diff --git a/app/javascript/mastodon/components/html_block/index.tsx b/app/javascript/mastodon/components/html_block/index.tsx index 69fa1d9bf55..ed559269a41 100644 --- a/app/javascript/mastodon/components/html_block/index.tsx +++ b/app/javascript/mastodon/components/html_block/index.tsx @@ -4,7 +4,7 @@ import type { OnElementHandler } from '@/mastodon/utils/html'; import { polymorphicForwardRef } from '@/types/polymorphic'; import type { EmojiHTMLProps } from '../emoji/html'; -import { ModernEmojiHTML } from '../emoji/html'; +import { EmojiHTML } from '../emoji/html'; import { useElementHandledLink } from '../status/handled_link'; export const HTMLBlock = polymorphicForwardRef< @@ -25,6 +25,6 @@ export const HTMLBlock = polymorphicForwardRef< (...args) => onParentElement?.(...args) ?? onLinkElement(...args), [onLinkElement, onParentElement], ); - return ; + return ; }, ); diff --git a/app/javascript/mastodon/components/icon_button.tsx b/app/javascript/mastodon/components/icon_button.tsx index 9d32ab1f528..de9cbc19bb4 100644 --- a/app/javascript/mastodon/components/icon_button.tsx +++ b/app/javascript/mastodon/components/icon_button.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, forwardRef } from 'react'; +import { useCallback, forwardRef } from 'react'; import classNames from 'classnames'; @@ -55,23 +55,6 @@ export const IconButton = forwardRef( }, buttonRef, ) => { - const [activate, setActivate] = useState(false); - const [deactivate, setDeactivate] = useState(false); - - useEffect(() => { - if (!animate) { - return; - } - - if (activate && !active) { - setActivate(false); - setDeactivate(true); - } else if (!activate && active) { - setActivate(true); - setDeactivate(false); - } - }, [setActivate, setDeactivate, animate, active, activate]); - const handleClick: React.MouseEventHandler = useCallback( (e) => { e.preventDefault(); @@ -112,8 +95,8 @@ export const IconButton = forwardRef( active, disabled, inverted, - activate, - deactivate, + activate: animate && active, + deactivate: animate && !active, overlayed: overlay, 'icon-button--with-counter': typeof counter !== 'undefined', }); diff --git a/app/javascript/mastodon/components/learn_more_link.tsx b/app/javascript/mastodon/components/learn_more_link.tsx index b5337794c95..8d22bb7a3ba 100644 --- a/app/javascript/mastodon/components/learn_more_link.tsx +++ b/app/javascript/mastodon/components/learn_more_link.tsx @@ -23,6 +23,7 @@ export const LearnMoreLink: React.FC<{ children: React.ReactNode }> = ({ onClick={handleClick} aria-expanded={open} aria-controls={accessibilityId} + type='button' > = ({
{children}
- )} {!showResults && ( <> - {' '} ·{' '} @@ -187,7 +188,11 @@ export const Poll: React.FC = ({ pollId, disabled, status }) => { )} {showResults && !disabled && ( <> - {' '} ·{' '} @@ -235,12 +240,11 @@ const PollOption: React.FC = (props) => { let titleHtml = option.translation?.titleHtml ?? option.titleHtml; if (!titleHtml) { - const emojiMap = makeEmojiMap(poll.emojis); - titleHtml = emojify(escapeTextContentForBrowser(title), emojiMap); + titleHtml = escapeTextContentForBrowser(title); } return titleHtml; - }, [option, poll, title]); + }, [option, title]); // Handlers const handleOptionChange = useCallback(() => { diff --git a/app/javascript/mastodon/components/status/boost_button.tsx b/app/javascript/mastodon/components/status/boost_button.tsx index cdbe242289d..723fa32aa1b 100644 --- a/app/javascript/mastodon/components/status/boost_button.tsx +++ b/app/javascript/mastodon/components/status/boost_button.tsx @@ -14,7 +14,7 @@ import type { Status } from '@/mastodon/models/status'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import type { SomeRequired } from '@/mastodon/utils/types'; -import type { RenderItemFn, RenderItemFnHandlers } from '../dropdown_menu'; +import type { RenderItemFn } from '../dropdown_menu'; import { Dropdown, DropdownMenuItemContent } from '../dropdown_menu'; import { IconButton } from '../icon_button'; @@ -74,18 +74,12 @@ const StandaloneBoostButton: FC = ({ status, counters }) => { ); }; -const renderMenuItem: RenderItemFn = ( - item, - index, - handlers, - focusRefCallback, -) => ( +const renderMenuItem: RenderItemFn = (item, index, onClick) => ( ); @@ -118,6 +112,18 @@ const BoostOrQuoteMenu: FC = ({ status, counters }) => { const statusId = status.get('id') as string; const wasBoosted = !!status.get('reblogged'); + let count: number | undefined; + if (counters) { + count = 0; + // Ensure count is a valid integer. + if (Number.isInteger(status.get('reblogs_count'))) { + count += status.get('reblogs_count') as number; + } + if (Number.isInteger(status.get('quotes_count'))) { + count += status.get('quotes_count') as number; + } + } + const showLoginPrompt = useCallback(() => { dispatch( openModal({ @@ -193,12 +199,7 @@ const BoostOrQuoteMenu: FC = ({ status, counters }) => { )} icon='retweet' iconComponent={boostIcon} - counter={ - counters - ? (status.get('reblogs_count') as number) + - (status.get('quotes_count') as number) - : undefined - } + counter={count} active={isReblogged} /> @@ -208,16 +209,10 @@ const BoostOrQuoteMenu: FC = ({ status, counters }) => { interface ReblogMenuItemProps { item: ActionMenuItem; index: number; - handlers: RenderItemFnHandlers; - focusRefCallback?: (c: HTMLAnchorElement | HTMLButtonElement | null) => void; + onClick: React.MouseEventHandler; } -const ReblogMenuItem: FC = ({ - index, - item, - handlers, - focusRefCallback, -}) => { +const ReblogMenuItem: FC = ({ index, item, onClick }) => { const { text, highlighted, disabled } = item; return ( @@ -228,10 +223,10 @@ const ReblogMenuItem: FC = ({ key={`${text}-${index}`} > diff --git a/app/javascript/mastodon/components/status/handled_link.tsx b/app/javascript/mastodon/components/status/handled_link.tsx index 59305d57340..be816e98531 100644 --- a/app/javascript/mastodon/components/status/handled_link.tsx +++ b/app/javascript/mastodon/components/status/handled_link.tsx @@ -26,7 +26,12 @@ export const HandledLink: FC> = ({ ...props }) => { // Handle hashtags - if (text.startsWith('#') || prevText?.endsWith('#')) { + if ( + text.startsWith('#') || + prevText?.endsWith('#') || + text.startsWith('#') || + prevText?.endsWith('#') + ) { const hashtag = text.slice(1).trim(); return ( {({ props, placement }) => (
{ const url1 = new URL(href1); const url2 = new URL(href2); - return url1.origin === url2.origin && url1.path === url2.path && url1.search === url2.search; + return url1.origin === url2.origin && url1.pathname === url2.pathname && url1.search === url2.search; } catch { return false; } @@ -131,41 +129,6 @@ class StatusContent extends PureComponent { onCollapsedToggle(collapsed); } - - // Exit if modern emoji is enabled, as it handles links using the HandledLink component. - if (isModernEmojiEnabled()) { - return; - } - - const links = node.querySelectorAll('a'); - - let link, mention; - - for (var i = 0; i < links.length; ++i) { - link = links[i]; - - if (link.classList.contains('status-link')) { - continue; - } - - link.classList.add('status-link'); - - mention = this.props.status.get('mentions').find(item => compareUrls(link, item.get('url'))); - - if (mention) { - link.addEventListener('click', this.onMentionClick.bind(this, mention), false); - link.setAttribute('title', `@${mention.get('acct')}`); - link.setAttribute('href', `/@${mention.get('acct')}`); - link.setAttribute('data-hover-card-account', mention.get('id')); - } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) { - link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false); - link.setAttribute('href', `/tags/${link.text.replace(/^#/, '')}`); - link.setAttribute('data-menu-hashtag', this.props.status.getIn(['account', 'id'])); - } else { - link.setAttribute('title', link.href); - link.classList.add('unhandled-link'); - } - } } async componentDidMount () { @@ -204,22 +167,6 @@ class StatusContent extends PureComponent { this._updateStatusLinks(); } - onMentionClick = (mention, e) => { - if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.history.push(`/@${mention.get('acct')}`); - } - }; - - onHashtagClick = (hashtag, e) => { - hashtag = hashtag.replace(/^#/, ''); - - if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.history.push(`/tags/${hashtag}`); - } - }; - handleMouseDown = (e) => { this.startXY = [e.clientX, e.clientY]; }; @@ -299,7 +246,7 @@ class StatusContent extends PureComponent { {children} ); - } else if (element.classList.contains('quote-inline')) { + } else if (element.classList.contains('quote-inline') && this.props.status.get('quote')) { return null; } return undefined; diff --git a/app/javascript/mastodon/components/status_quoted.tsx b/app/javascript/mastodon/components/status_quoted.tsx index a0024bbf6b2..eac2167294f 100644 --- a/app/javascript/mastodon/components/status_quoted.tsx +++ b/app/javascript/mastodon/components/status_quoted.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useRef } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -73,7 +73,63 @@ const LimitedAccountHint: React.FC<{ accountId: string }> = ({ accountId }) => { defaultMessage='This account has been hidden by the moderators of {domain}.' values={{ domain }} /> - + + ); +}; + +const FilteredQuote: React.FC<{ + reveal: VoidFunction; + quotedAccountId: string; + quoteState: string; +}> = ({ reveal, quotedAccountId, quoteState }) => { + const account = useAppSelector((state) => + quotedAccountId ? state.accounts.get(quotedAccountId) : undefined, + ); + + const quoteAuthorName = account?.acct; + const domain = quoteAuthorName?.split('@')[1]; + + let message; + + switch (quoteState) { + case 'blocked_account': + message = ( + + ); + break; + case 'blocked_domain': + message = ( + + ); + break; + case 'muted_account': + message = ( + + ); + } + + return ( + <> + {message} + @@ -154,6 +155,7 @@ export const DomainPill: React.FC<{ @@ -169,6 +171,7 @@ export const DomainPill: React.FC<{ diff --git a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx index 2bf636d060d..040ca16c720 100644 --- a/app/javascript/mastodon/features/account_timeline/components/account_header.tsx +++ b/app/javascript/mastodon/features/account_timeline/components/account_header.tsx @@ -49,7 +49,6 @@ import { ShortNumber } from 'mastodon/components/short_number'; import { AccountNote } from 'mastodon/features/account/components/account_note'; import { DomainPill } from 'mastodon/features/account/components/domain_pill'; import FollowRequestNoteContainer from 'mastodon/features/account/containers/follow_request_note_container'; -import { useLinks } from 'mastodon/hooks/useLinks'; import { useIdentity } from 'mastodon/identity_context'; import { autoPlayGif, me, domain as localDomain } from 'mastodon/initial_state'; import type { Account } from 'mastodon/models/account'; @@ -198,7 +197,6 @@ export const AccountHeader: React.FC<{ state.relationships.get(accountId), ); const hidden = useAppSelector((state) => getAccountHidden(state, accountId)); - const handleLinkClick = useLinks(); const handleBlock = useCallback(() => { if (!account) { @@ -852,10 +850,7 @@ export const AccountHeader: React.FC<{ {!(suspended || hidden) && (
-
+
{account.id !== me && signedIn && ( )} diff --git a/app/javascript/mastodon/features/alt_text_modal/index.tsx b/app/javascript/mastodon/features/alt_text_modal/index.tsx index f285c35929c..a6b621e6d98 100644 --- a/app/javascript/mastodon/features/alt_text_modal/index.tsx +++ b/app/javascript/mastodon/features/alt_text_modal/index.tsx @@ -101,16 +101,17 @@ const Preview: React.FC<{ position: FocalPoint; onPositionChange: (arg0: FocalPoint) => void; }> = ({ mediaId, position, onPositionChange }) => { - const draggingRef = useRef(false); const nodeRef = useRef(null); + const [dragging, setDragging] = useState<'started' | 'moving' | null>(null); + const [x, y] = position; const style = useSpring({ to: { left: `${x * 100}%`, top: `${y * 100}%`, }, - immediate: draggingRef.current, + immediate: dragging === 'moving', }); const media = useAppSelector((state) => ( @@ -123,8 +124,6 @@ const Preview: React.FC<{ me ? state.accounts.get(me) : undefined, ); - const [dragging, setDragging] = useState(false); - const setRef = useCallback( (e: HTMLImageElement | HTMLVideoElement | null) => { nodeRef.current = e; @@ -140,20 +139,20 @@ const Preview: React.FC<{ const handleMouseMove = (e: MouseEvent) => { const { x, y } = getPointerPosition(nodeRef.current, e); - draggingRef.current = true; // This will disable the animation for quicker feedback, only do this if the mouse actually moves + + setDragging('moving'); // This will disable the animation for quicker feedback, only do this if the mouse actually moves onPositionChange([x, y]); }; const handleMouseUp = () => { - setDragging(false); - draggingRef.current = false; + setDragging(null); document.removeEventListener('mouseup', handleMouseUp); document.removeEventListener('mousemove', handleMouseMove); }; const { x, y } = getPointerPosition(nodeRef.current, e.nativeEvent); - setDragging(true); + setDragging('started'); onPositionChange([x, y]); document.addEventListener('mouseup', handleMouseUp); @@ -489,6 +488,7 @@ export const AltTextModal = forwardRef>( className='link-button' onClick={handleDetectClick} disabled={type !== 'image' || isDetecting} + type='button' > = ({ year }) => { const [response, setResponse] = useState(null); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const currentAccount = useAppSelector((state) => me ? state.accounts.get(me) : undefined, ); const dispatch = useAppDispatch(); useEffect(() => { - setLoading(true); - apiRequestGet(`v1/annual_reports/${year}`) .then((data) => { dispatch(importFetchedStatuses(data.statuses)); diff --git a/app/javascript/mastodon/features/audio/index.tsx b/app/javascript/mastodon/features/audio/index.tsx index a6a131c0d4d..c16fd9eab15 100644 --- a/app/javascript/mastodon/features/audio/index.tsx +++ b/app/javascript/mastodon/features/audio/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useCallback, useState, useId } from 'react'; +import { useEffect, useRef, useCallback, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; @@ -22,6 +22,8 @@ import { useAudioVisualizer } from 'mastodon/hooks/useAudioVisualizer'; import { displayMedia, useBlurhash } from 'mastodon/initial_state'; import { playerSettings } from 'mastodon/settings'; +import { AudioVisualizer } from './visualizer'; + const messages = defineMessages({ play: { id: 'video.play', defaultMessage: 'Play' }, pause: { id: 'video.pause', defaultMessage: 'Pause' }, @@ -116,7 +118,6 @@ export const Audio: React.FC<{ const seekRef = useRef(null); const volumeRef = useRef(null); const hoverTimeoutRef = useRef | null>(); - const accessibilityId = useId(); const { audioContextRef, sourceRef, gainNodeRef, playAudio, pauseAudio } = useAudioContext({ audioElementRef: audioRef }); @@ -538,19 +539,6 @@ export const Audio: React.FC<{ [togglePlay, toggleMute], ); - const springForBand0 = useSpring({ - to: { r: 50 + (frequencyBands[0] ?? 0) * 10 }, - config: config.wobbly, - }); - const springForBand1 = useSpring({ - to: { r: 50 + (frequencyBands[1] ?? 0) * 10 }, - config: config.wobbly, - }); - const springForBand2 = useSpring({ - to: { r: 50 + (frequencyBands[2] ?? 0) * 10 }, - config: config.wobbly, - }); - const progress = Math.min((currentTime / loadedDuration) * 100, 100); const effectivelyMuted = muted || volume === 0; @@ -641,81 +629,7 @@ export const Audio: React.FC<{
- - - - - - - - - - - - - - - - - - - - - - +
@@ -591,6 +609,7 @@ export const Search: React.FC<{ className={classNames('search__popout__menu__item', { selected: selectedOption === i, })} + type='button' > {label} @@ -617,6 +636,7 @@ export const Search: React.FC<{ selectedOption === (quickActions.length || recent.length) + i, })} + type='button' > {label} diff --git a/app/javascript/mastodon/features/compose/components/upload.tsx b/app/javascript/mastodon/features/compose/components/upload.tsx index adc51733d9a..85fed0cbd3b 100644 --- a/app/javascript/mastodon/features/compose/components/upload.tsx +++ b/app/javascript/mastodon/features/compose/components/upload.tsx @@ -10,6 +10,7 @@ import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import CloseIcon from '@/material-icons/400-20px/close.svg?react'; +import SoundIcon from '@/material-icons/400-24px/audio.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import WarningIcon from '@/material-icons/400-24px/warning.svg?react'; import { undoUploadCompose } from 'mastodon/actions/compose'; @@ -17,7 +18,18 @@ import { openModal } from 'mastodon/actions/modal'; import { Blurhash } from 'mastodon/components/blurhash'; import { Icon } from 'mastodon/components/icon'; import type { MediaAttachment } from 'mastodon/models/media_attachment'; -import { useAppDispatch, useAppSelector } from 'mastodon/store'; +import { + createAppSelector, + useAppDispatch, + useAppSelector, +} from 'mastodon/store'; + +import { AudioVisualizer } from '../../audio/visualizer'; + +const selectUserAvatar = createAppSelector( + [(state) => state.accounts, (state) => state.meta.get('me') as string], + (accounts, myId) => accounts.get(myId)?.avatar_static, +); export const Upload: React.FC<{ id: string; @@ -38,6 +50,7 @@ export const Upload: React.FC<{ const sensitive = useAppSelector( (state) => state.compose.get('spoiler') as boolean, ); + const userAvatar = useAppSelector(selectUserAvatar); const handleUndoClick = useCallback(() => { dispatch(undoUploadCompose(id)); @@ -67,6 +80,8 @@ export const Upload: React.FC<{ transform: CSS.Transform.toString(transform), transition, }; + const preview_url = media.get('preview_url') as string | null; + const blurhash = media.get('blurhash') as string | null; return (
- {sensitive && ( - + {sensitive && blurhash && ( + + )} + {!sensitive && !preview_url && ( +
+ + +
)}
diff --git a/app/javascript/mastodon/features/compose/components/visibility_button.tsx b/app/javascript/mastodon/features/compose/components/visibility_button.tsx index 1ea504ab1a3..d9394050207 100644 --- a/app/javascript/mastodon/features/compose/components/visibility_button.tsx +++ b/app/javascript/mastodon/features/compose/components/visibility_button.tsx @@ -5,8 +5,10 @@ import { defineMessages, useIntl } from 'react-intl'; import classNames from 'classnames'; -import { changeComposeVisibility } from '@/mastodon/actions/compose'; -import { setComposeQuotePolicy } from '@/mastodon/actions/compose_typed'; +import { + changeComposeVisibility, + setComposeQuotePolicy, +} from '@/mastodon/actions/compose_typed'; import { openModal } from '@/mastodon/actions/modal'; import type { ApiQuotePolicy } from '@/mastodon/api_types/quotes'; import type { StatusVisibility } from '@/mastodon/api_types/statuses'; diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index 3dad46bc520..15b1c7cc411 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -12,6 +12,7 @@ import { } from 'mastodon/actions/compose'; import { pasteLinkCompose } from 'mastodon/actions/compose_typed'; import { openModal } from 'mastodon/actions/modal'; +import { PRIVATE_QUOTE_MODAL_ID } from 'mastodon/features/ui/components/confirmation_modals/private_quote_notify'; import ComposeForm from '../components/compose_form'; @@ -32,6 +33,10 @@ const mapStateToProps = state => ({ isUploading: state.getIn(['compose', 'is_uploading']), anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, missingAltText: state.getIn(['compose', 'media_attachments']).some(media => ['image', 'gifv'].includes(media.get('type')) && (media.get('description') ?? '').length === 0), + quoteToPrivate: + !!state.getIn(['compose', 'quoted_status_id']) + && state.getIn(['compose', 'privacy']) === 'private' + && !state.getIn(['settings', 'dismissed_banners', PRIVATE_QUOTE_MODAL_ID]), isInReply: state.getIn(['compose', 'in_reply_to']) !== null, lang: state.getIn(['compose', 'language']), maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500), @@ -43,12 +48,17 @@ const mapDispatchToProps = (dispatch, props) => ({ dispatch(changeCompose(text)); }, - onSubmit (missingAltText) { + onSubmit ({ missingAltText, quoteToPrivate }) { if (missingAltText) { dispatch(openModal({ modalType: 'CONFIRM_MISSING_ALT_TEXT', modalProps: {}, })); + } else if (quoteToPrivate) { + dispatch(openModal({ + modalType: 'CONFIRM_PRIVATE_QUOTE_NOTIFY', + modalProps: {}, + })); } else { dispatch(submitCompose((status) => { if (props.redirectOnSuccess) { diff --git a/app/javascript/mastodon/features/compose/containers/privacy_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/privacy_dropdown_container.js index 6d3eef13aa2..803dcb1a4a0 100644 --- a/app/javascript/mastodon/features/compose/containers/privacy_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/privacy_dropdown_container.js @@ -1,8 +1,7 @@ import { connect } from 'react-redux'; -import { changeComposeVisibility } from '../../../actions/compose'; -import { openModal, closeModal } from '../../../actions/modal'; -import { isUserTouching } from '../../../is_mobile'; +import { changeComposeVisibility } from '@/mastodon/actions/compose_typed'; + import PrivacyDropdown from '../components/privacy_dropdown'; const mapStateToProps = state => ({ diff --git a/app/javascript/mastodon/features/domain_blocks/index.tsx b/app/javascript/mastodon/features/domain_blocks/index.tsx index 900aba4745c..2c5860af987 100644 --- a/app/javascript/mastodon/features/domain_blocks/index.tsx +++ b/app/javascript/mastodon/features/domain_blocks/index.tsx @@ -19,14 +19,12 @@ const messages = defineMessages({ const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => { const intl = useIntl(); const [domains, setDomains] = useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); const [next, setNext] = useState(); const hasMore = !!next; const columnRef = useRef(null); useEffect(() => { - setLoading(true); - void apiGetDomainBlocks() .then(({ domains, links }) => { const next = links.refs.find((link) => link.rel === 'next'); @@ -40,7 +38,7 @@ const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => { .catch(() => { setLoading(false); }); - }, [setLoading, setDomains, setNext]); + }, []); const handleLoadMore = useCallback(() => { setLoading(true); diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index cc0d6fe195f..8ca86d16cdf 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -1,6 +1,5 @@ import Trie from 'substring-trie'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import { assetHost } from 'mastodon/utils/config'; import { autoPlayGif } from '../../initial_state'; @@ -153,13 +152,9 @@ const emojifyNode = (node, customEmojis) => { * Legacy emoji processing function. * @param {string} str * @param {object} customEmojis - * @param {boolean} force If true, always emojify even if modern emoji is enabled * @returns {string} */ -const emojify = (str, customEmojis = {}, force = false) => { - if (isModernEmojiEnabled() && !force) { - return str; - } +const emojify = (str, customEmojis = {}) => { const wrapper = document.createElement('div'); wrapper.innerHTML = str; diff --git a/app/javascript/mastodon/features/emoji/emoji_compressed.mjs b/app/javascript/mastodon/features/emoji/emoji_compressed.mjs index db8a4bc122a..c565b861fd7 100644 --- a/app/javascript/mastodon/features/emoji/emoji_compressed.mjs +++ b/app/javascript/mastodon/features/emoji/emoji_compressed.mjs @@ -14,8 +14,7 @@ import { uncompress as emojiMartUncompress } from 'emoji-mart/dist/utils/data'; import data from './emoji_data.json'; import emojiMap from './emoji_map.json'; -import { unicodeToFilename } from './unicode_to_filename'; -import { unicodeToUnifiedName } from './unicode_to_unified_name'; +import { unicodeToFilename, unicodeToUnifiedName } from './unicode_utils'; emojiMartUncompress(data); diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts index 1315518179b..59d995e25ff 100644 --- a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts +++ b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts @@ -9,7 +9,7 @@ import type { ShortCodesToEmojiData, } from 'virtual:mastodon-emoji-compressed'; -import { unicodeToUnifiedName } from './unicode_to_unified_name'; +import { unicodeToUnifiedName } from './unicode_utils'; type Emojis = Record< NonNullable, @@ -23,7 +23,7 @@ type Emojis = Record< const [ shortCodesToEmojiData, - skins, + _skins, categories, short_names, _emojisWithoutShortCodes, @@ -47,4 +47,4 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => { }; }); -export { emojis, skins, categories, short_names }; +export { emojis, categories, short_names }; diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js b/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js index 83e154b0b28..038dd120c9a 100644 --- a/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js +++ b/app/javascript/mastodon/features/emoji/emoji_mart_search_light.js @@ -1,7 +1,7 @@ // This code is largely borrowed from: // https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js -import * as data from './emoji_mart_data_light'; +import { emojis, categories } from './emoji_mart_data_light'; import { getData, getSanitizedData, uniq, intersect } from './emoji_utils'; let originalPool = {}; @@ -10,8 +10,8 @@ let emojisList = {}; let emoticonsList = {}; let customEmojisList = []; -for (let emoji in data.emojis) { - let emojiData = data.emojis[emoji]; +for (let emoji in emojis) { + let emojiData = emojis[emoji]; let { short_names, emoticons } = emojiData; let id = short_names[0]; @@ -84,14 +84,14 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo if (include.length || exclude.length) { pool = {}; - data.categories.forEach(category => { + categories.forEach(category => { let isIncluded = include && include.length ? include.indexOf(category.name.toLowerCase()) > -1 : true; let isExcluded = exclude && exclude.length ? exclude.indexOf(category.name.toLowerCase()) > -1 : false; if (!isIncluded || isExcluded) { return; } - category.emojis.forEach(emojiId => pool[emojiId] = data.emojis[emojiId]); + category.emojis.forEach(emojiId => pool[emojiId] = emojis[emojiId]); }); if (custom.length) { @@ -171,7 +171,7 @@ function search(value, { emojisToShowFilter, maxResults, include, exclude, custo if (results) { if (emojisToShowFilter) { - results = results.filter((result) => emojisToShowFilter(data.emojis[result.id])); + results = results.filter((result) => emojisToShowFilter(emojis[result.id])); } if (results && results.length > maxResults) { diff --git a/app/javascript/mastodon/features/emoji/emoji_picker.tsx b/app/javascript/mastodon/features/emoji/emoji_picker.tsx index 38363d4310b..37fc94dde7a 100644 --- a/app/javascript/mastodon/features/emoji/emoji_picker.tsx +++ b/app/javascript/mastodon/features/emoji/emoji_picker.tsx @@ -2,7 +2,6 @@ import type { EmojiProps, PickerProps } from 'emoji-mart'; import EmojiRaw from 'emoji-mart/dist-es/components/emoji/nimble-emoji'; import PickerRaw from 'emoji-mart/dist-es/components/picker/nimble-picker'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import { assetHost } from 'mastodon/utils/config'; import { EMOJI_MODE_NATIVE } from './constants'; @@ -27,7 +26,7 @@ const Emoji = ({ sheetSize={sheetSize} sheetColumns={sheetColumns} sheetRows={sheetRows} - native={mode === EMOJI_MODE_NATIVE && isModernEmojiEnabled()} + native={mode === EMOJI_MODE_NATIVE} backgroundImageFn={backgroundImageFn} {...props} /> @@ -51,7 +50,7 @@ const Picker = ({ sheetColumns={sheetColumns} sheetRows={sheetRows} backgroundImageFn={backgroundImageFn} - native={mode === EMOJI_MODE_NATIVE && isModernEmojiEnabled()} + native={mode === EMOJI_MODE_NATIVE} {...props} /> ); diff --git a/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts b/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts index a53496be2a8..ecf36e3ea85 100644 --- a/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts +++ b/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts @@ -8,7 +8,7 @@ import type { ShortCodesToEmojiDataKey, } from 'virtual:mastodon-emoji-compressed'; -import { unicodeToFilename } from './unicode_to_filename'; +import { unicodeToFilename } from './unicode_utils'; type UnicodeMapping = Record< FilenameData[number][0], diff --git a/app/javascript/mastodon/features/emoji/emoji_utils.js b/app/javascript/mastodon/features/emoji/emoji_utils.js index c13d2505670..75b2acafa5c 100644 --- a/app/javascript/mastodon/features/emoji/emoji_utils.js +++ b/app/javascript/mastodon/features/emoji/emoji_utils.js @@ -209,50 +209,9 @@ function intersect(a, b) { return uniqA.filter(item => uniqB.indexOf(item) >= 0); } -function deepMerge(a, b) { - let o = {}; - - for (let key in a) { - let originalValue = a[key], - value = originalValue; - - if (Object.hasOwn(b, key)) { - value = b[key]; - } - - if (typeof value === 'object') { - value = deepMerge(originalValue, value); - } - - o[key] = value; - } - - return o; -} - -// https://github.com/sonicdoe/measure-scrollbar -function measureScrollbar() { - const div = document.createElement('div'); - - div.style.width = '100px'; - div.style.height = '100px'; - div.style.overflow = 'scroll'; - div.style.position = 'absolute'; - div.style.top = '-9999px'; - - document.body.appendChild(div); - const scrollbarWidth = div.offsetWidth - div.clientWidth; - document.body.removeChild(div); - - return scrollbarWidth; -} - export { getData, getSanitizedData, uniq, intersect, - deepMerge, - unifiedToNative, - measureScrollbar, }; diff --git a/app/javascript/mastodon/features/emoji/handlers.ts b/app/javascript/mastodon/features/emoji/handlers.ts deleted file mode 100644 index 3b02028f3c3..00000000000 --- a/app/javascript/mastodon/features/emoji/handlers.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { autoPlayGif } from '@/mastodon/initial_state'; - -const PARENT_MAX_DEPTH = 10; - -export function handleAnimateGif(event: MouseEvent) { - // We already check this in ui/index.jsx, but just to be sure. - if (autoPlayGif) { - return; - } - - const { target, type } = event; - const animate = type === 'mouseover'; // Mouse over = animate, mouse out = don't animate. - - if (target instanceof HTMLImageElement) { - setAnimateGif(target, animate); - } else if (!(target instanceof HTMLElement) || target === document.body) { - return; - } - - let parent: HTMLElement | null = null; - let iter = 0; - - if (target.classList.contains('animate-parent')) { - parent = target; - } else { - // Iterate up to PARENT_MAX_DEPTH levels up the DOM tree to find a parent with the class 'animate-parent'. - let current: HTMLElement | null = target; - while (current) { - if (iter >= PARENT_MAX_DEPTH) { - return; // We can just exit right now. - } - current = current.parentElement; - if (current?.classList.contains('animate-parent')) { - parent = current; - break; - } - iter++; - } - } - - // Affect all animated children within the parent. - if (parent) { - const animatedChildren = - parent.querySelectorAll('img.custom-emoji'); - for (const child of animatedChildren) { - setAnimateGif(child, animate); - } - } -} - -function setAnimateGif(image: HTMLImageElement, animate: boolean) { - const { classList, dataset } = image; - if ( - !classList.contains('custom-emoji') || - !dataset.static || - !dataset.original - ) { - return; - } - image.src = animate ? dataset.original : dataset.static; -} diff --git a/app/javascript/mastodon/features/emoji/unicode_to_filename.js b/app/javascript/mastodon/features/emoji/unicode_to_filename.js deleted file mode 100644 index cfe5539c7b9..00000000000 --- a/app/javascript/mastodon/features/emoji/unicode_to_filename.js +++ /dev/null @@ -1,26 +0,0 @@ -// taken from: -// https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866 -export const unicodeToFilename = (str) => { - let result = ''; - let charCode = 0; - let p = 0; - let i = 0; - while (i < str.length) { - charCode = str.charCodeAt(i++); - if (p) { - if (result.length > 0) { - result += '-'; - } - result += (0x10000 + ((p - 0xD800) << 10) + (charCode - 0xDC00)).toString(16); - p = 0; - } else if (0xD800 <= charCode && charCode <= 0xDBFF) { - p = charCode; - } else { - if (result.length > 0) { - result += '-'; - } - result += charCode.toString(16); - } - } - return result; -}; diff --git a/app/javascript/mastodon/features/emoji/unicode_to_unified_name.js b/app/javascript/mastodon/features/emoji/unicode_to_unified_name.js deleted file mode 100644 index 15f60aa7c30..00000000000 --- a/app/javascript/mastodon/features/emoji/unicode_to_unified_name.js +++ /dev/null @@ -1,21 +0,0 @@ -function padLeft(str, num) { - while (str.length < num) { - str = '0' + str; - } - - return str; -} - -export const unicodeToUnifiedName = (str) => { - let output = ''; - - for (let i = 0; i < str.length; i += 2) { - if (i > 0) { - output += '-'; - } - - output += padLeft(str.codePointAt(i).toString(16).toUpperCase(), 4); - } - - return output; -}; diff --git a/app/javascript/mastodon/features/emoji/unicode_utils.ts b/app/javascript/mastodon/features/emoji/unicode_utils.ts new file mode 100644 index 00000000000..04175ee9f90 --- /dev/null +++ b/app/javascript/mastodon/features/emoji/unicode_utils.ts @@ -0,0 +1,43 @@ +// taken from: +// https://github.com/twitter/twemoji/blob/47732c7/twemoji-generator.js#L848-L866 +export function unicodeToFilename(str: string) { + let result = ''; + let charCode = 0; + let p = 0; + let i = 0; + while (i < str.length) { + charCode = str.charCodeAt(i++); + if (p) { + if (result.length > 0) { + result += '-'; + } + result += (0x10000 + ((p - 0xd800) << 10) + (charCode - 0xdc00)).toString( + 16, + ); + p = 0; + } else if (0xd800 <= charCode && charCode <= 0xdbff) { + p = charCode; + } else { + if (result.length > 0) { + result += '-'; + } + result += charCode.toString(16); + } + } + return result; +} + +export function unicodeToUnifiedName(str: string) { + let output = ''; + + for (let i = 0; i < str.length; i += 2) { + if (i > 0) { + output += '-'; + } + + output += + str.codePointAt(i)?.toString(16).toUpperCase().padStart(4, '0') ?? ''; + } + + return output; +} diff --git a/app/javascript/mastodon/features/firehose/index.jsx b/app/javascript/mastodon/features/firehose/index.jsx index 91704f12340..ca3dd7ce38f 100644 --- a/app/javascript/mastodon/features/firehose/index.jsx +++ b/app/javascript/mastodon/features/firehose/index.jsx @@ -24,6 +24,14 @@ import StatusListContainer from '../ui/containers/status_list_container'; const messages = defineMessages({ title: { id: 'column.firehose', defaultMessage: 'Live feeds' }, + title_local: { + id: 'column.firehose_local', + defaultMessage: 'Live feed for this server', + }, + title_singular: { + id: 'column.firehose_singular', + defaultMessage: 'Live feed', + }, }); const ColumnSettings = () => { @@ -161,13 +169,23 @@ const Firehose = ({ feedType, multiColumn }) => { /> ); + let title; + + if (canViewFeed(signedIn, permissions, localLiveFeedAccess) && canViewFeed(signedIn, permissions, remoteLiveFeedAccess)) { + title = messages.title; + } else if (canViewFeed(signedIn, permissions, localLiveFeedAccess)) { + title = messages.title_local; + } else { + title = messages.title_singular; + } + return ( { - this.node = c; - }; - - componentDidMount () { - this._updateLinks(); - } - - componentDidUpdate () { - this._updateLinks(); - } - - _updateLinks () { - const node = this.node; - - if (!node) { - return; - } - - const links = node.querySelectorAll('a'); - - for (var i = 0; i < links.length; ++i) { - let link = links[i]; - - if (link.classList.contains('status-link')) { - continue; - } - - link.classList.add('status-link'); - - let mention = this.props.announcement.get('mentions').find(item => link.href === item.get('url')); - - if (mention) { - link.addEventListener('click', this.onMentionClick.bind(this, mention), false); - link.setAttribute('title', mention.get('acct')); - } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) { - link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false); - } else { - let status = this.props.announcement.get('statuses').find(item => link.href === item.get('url')); - if (status) { - link.addEventListener('click', this.onStatusClick.bind(this, status), false); - } - link.setAttribute('title', link.href); - link.classList.add('unhandled-link'); - } - - link.setAttribute('target', '_blank'); - link.setAttribute('rel', 'noopener'); - } - } - - onMentionClick = (mention, e) => { - if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.history.push(`/@${mention.get('acct')}`); - } - }; - - onHashtagClick = (hashtag, e) => { - hashtag = hashtag.replace(/^#/, ''); - - if (this.props.history&& e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.history.push(`/tags/${hashtag}`); - } - }; - - onStatusClick = (status, e) => { - if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`); - } - }; - - render () { - const { announcement } = this.props; - - return ( -
- ); - } - -} - -const Content = withRouter(ContentWithRouter); - -class Emoji extends PureComponent { - - static propTypes = { - emoji: PropTypes.string.isRequired, - emojiMap: ImmutablePropTypes.map.isRequired, - hovered: PropTypes.bool.isRequired, - }; - - render () { - const { emoji, emojiMap, hovered } = this.props; - - if (unicodeMapping[emoji]) { - const { filename, shortCode } = unicodeMapping[this.props.emoji]; - const title = shortCode ? `:${shortCode}:` : ''; - - return ( - {emoji} - ); - } else if (emojiMap.get(emoji)) { - const filename = (autoPlayGif || hovered) ? emojiMap.getIn([emoji, 'url']) : emojiMap.getIn([emoji, 'static_url']); - const shortCode = `:${emoji}:`; - - return ( - {shortCode} - ); - } else { - return null; - } - } - -} - -class Reaction extends ImmutablePureComponent { - - static propTypes = { - announcementId: PropTypes.string.isRequired, - reaction: ImmutablePropTypes.map.isRequired, - addReaction: PropTypes.func.isRequired, - removeReaction: PropTypes.func.isRequired, - emojiMap: ImmutablePropTypes.map.isRequired, - style: PropTypes.object, - }; - - state = { - hovered: false, - }; - - handleClick = () => { - const { reaction, announcementId, addReaction, removeReaction } = this.props; - - if (reaction.get('me')) { - removeReaction(announcementId, reaction.get('name')); - } else { - addReaction(announcementId, reaction.get('name')); - } - }; - - handleMouseEnter = () => this.setState({ hovered: true }); - - handleMouseLeave = () => this.setState({ hovered: false }); - - render () { - const { reaction } = this.props; - - let shortCode = reaction.get('name'); - - if (unicodeMapping[shortCode]) { - shortCode = unicodeMapping[shortCode].shortCode; - } - - return ( - - - - - - - - - ); - } - -} - -const ReactionsBar = ({ - announcementId, - reactions, - emojiMap, - addReaction, - removeReaction, -}) => { - const visibleReactions = useMemo(() => reactions.filter(x => x.get('count') > 0).toArray(), [reactions]); - - const handleEmojiPick = useCallback((emoji) => { - addReaction(announcementId, emoji.native.replaceAll(/:/g, '')); - }, [addReaction, announcementId]); - - const transitions = useTransition(visibleReactions, { - from: { - scale: 0, - }, - enter: { - scale: 1, - }, - leave: { - scale: 0, - }, - keys: visibleReactions.map(x => x.get('name')), - }); - - return ( -
- {transitions(({ scale }, reaction) => ( - `scale(${s})`) }} - addReaction={addReaction} - removeReaction={removeReaction} - announcementId={announcementId} - emojiMap={emojiMap} - /> - ))} - - {visibleReactions.length < 8 && ( - } - /> - )} -
- ); -}; -ReactionsBar.propTypes = { - announcementId: PropTypes.string.isRequired, - reactions: ImmutablePropTypes.list.isRequired, - addReaction: PropTypes.func.isRequired, - removeReaction: PropTypes.func.isRequired, - emojiMap: ImmutablePropTypes.map.isRequired, -}; - -class Announcement extends ImmutablePureComponent { - - static propTypes = { - announcement: ImmutablePropTypes.map.isRequired, - emojiMap: ImmutablePropTypes.map.isRequired, - addReaction: PropTypes.func.isRequired, - removeReaction: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - selected: PropTypes.bool, - }; - - state = { - unread: !this.props.announcement.get('read'), - }; - - componentDidUpdate () { - const { selected, announcement } = this.props; - if (!selected && this.state.unread !== !announcement.get('read')) { - this.setState({ unread: !announcement.get('read') }); - } - } - - render () { - const { announcement } = this.props; - const { unread } = this.state; - const startsAt = announcement.get('starts_at') && new Date(announcement.get('starts_at')); - const endsAt = announcement.get('ends_at') && new Date(announcement.get('ends_at')); - const now = new Date(); - const hasTimeRange = startsAt && endsAt; - const skipTime = announcement.get('all_day'); - - let timestamp = null; - if (hasTimeRange) { - const skipYear = startsAt.getFullYear() === endsAt.getFullYear() && endsAt.getFullYear() === now.getFullYear(); - const skipEndDate = startsAt.getDate() === endsAt.getDate() && startsAt.getMonth() === endsAt.getMonth() && startsAt.getFullYear() === endsAt.getFullYear(); - timestamp = ( - <> - - - - ); - } else { - const publishedAt = new Date(announcement.get('published_at')); - timestamp = ( - - ); - } - - return ( -
- - - · {timestamp} - - - - - - - {unread && } -
- ); - } - -} - -class Announcements extends ImmutablePureComponent { - - static propTypes = { - announcements: ImmutablePropTypes.list, - emojiMap: ImmutablePropTypes.map.isRequired, - dismissAnnouncement: PropTypes.func.isRequired, - addReaction: PropTypes.func.isRequired, - removeReaction: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - state = { - index: 0, - }; - - static getDerivedStateFromProps(props, state) { - if (props.announcements.size > 0 && state.index >= props.announcements.size) { - return { index: props.announcements.size - 1 }; - } else { - return null; - } - } - - componentDidMount () { - this._markAnnouncementAsRead(); - } - - componentDidUpdate () { - this._markAnnouncementAsRead(); - } - - _markAnnouncementAsRead () { - const { dismissAnnouncement, announcements } = this.props; - const { index } = this.state; - const announcement = announcements.get(announcements.size - 1 - index); - if (!announcement.get('read')) dismissAnnouncement(announcement.get('id')); - } - - handleChangeIndex = index => { - this.setState({ index: index % this.props.announcements.size }); - }; - - handleNextClick = () => { - this.setState({ index: (this.state.index + 1) % this.props.announcements.size }); - }; - - handlePrevClick = () => { - this.setState({ index: (this.props.announcements.size + this.state.index - 1) % this.props.announcements.size }); - }; - - render () { - const { announcements, intl } = this.props; - const { index } = this.state; - - if (announcements.isEmpty()) { - return null; - } - - return ( -
- - -
- - {announcements.map((announcement, idx) => ( - - )).reverse()} - - - {announcements.size > 1 && ( -
- - {index + 1} / {announcements.size} - -
- )} -
-
- ); - } - -} - -export default injectIntl(Announcements); diff --git a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js b/app/javascript/mastodon/features/getting_started/containers/announcements_container.js deleted file mode 100644 index 3bb1b8e8d18..00000000000 --- a/app/javascript/mastodon/features/getting_started/containers/announcements_container.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createSelector } from '@reduxjs/toolkit'; -import { Map as ImmutableMap } from 'immutable'; -import { connect } from 'react-redux'; - - -import { addReaction, removeReaction, dismissAnnouncement } from 'mastodon/actions/announcements'; - -import Announcements from '../components/announcements'; - -const customEmojiMap = createSelector([state => state.get('custom_emojis')], items => items.reduce((map, emoji) => map.set(emoji.get('shortcode'), emoji), ImmutableMap())); - -const mapStateToProps = state => ({ - announcements: state.getIn(['announcements', 'items']), - emojiMap: customEmojiMap(state), -}); - -const mapDispatchToProps = dispatch => ({ - dismissAnnouncement: id => dispatch(dismissAnnouncement(id)), - addReaction: (id, name) => dispatch(addReaction(id, name)), - removeReaction: (id, name) => dispatch(removeReaction(id, name)), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(Announcements); diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx index 8513e6169bd..75be0ffe1b4 100644 --- a/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/announcement.tsx @@ -1,11 +1,13 @@ -import { useEffect, useState } from 'react'; import type { FC } from 'react'; +import { useEffect, useState } from 'react'; import { FormattedDate, FormattedMessage } from 'react-intl'; +import { dismissAnnouncement } from '@/mastodon/actions/announcements'; import type { ApiAnnouncementJSON } from '@/mastodon/api_types/announcements'; import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context'; import { EmojiHTML } from '@/mastodon/components/emoji/html'; +import { useAppDispatch } from '@/mastodon/store'; import { ReactionsBar } from './reactions'; @@ -15,24 +17,39 @@ export interface IAnnouncement extends ApiAnnouncementJSON { interface AnnouncementProps { announcement: IAnnouncement; - selected: boolean; + active?: boolean; } export const Announcement: FC = ({ announcement, - selected, + active, }) => { - const [unread, setUnread] = useState(!announcement.read); + const { read, id } = announcement; + + // Dismiss announcement when it becomes active. + const dispatch = useAppDispatch(); useEffect(() => { - // Only update `unread` marker once the announcement is out of view - if (!selected && unread !== !announcement.read) { - setUnread(!announcement.read); + if (active && !read) { + dispatch(dismissAnnouncement(id)); } - }, [announcement.read, selected, unread]); + }, [active, id, dispatch, read]); + + // But visually show the announcement as read only when it goes out of view. + const [isVisuallyRead, setIsVisuallyRead] = useState(read); + const [previousActive, setPreviousActive] = useState(active); + if (active !== previousActive) { + setPreviousActive(active); + + // This marks the announcement as read in the UI only after it + // went from active to inactive. + if (!active && isVisuallyRead !== read) { + setIsVisuallyRead(read); + } + } return ( - - + + = ({ - {unread && } + {!isVisuallyRead && } ); }; diff --git a/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx index 8c7c704849d..cb44e1d075c 100644 --- a/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/announcements/index.tsx @@ -1,65 +1,50 @@ -import { useCallback, useState } from 'react'; +import { useCallback } from 'react'; import type { FC } from 'react'; -import { defineMessages, useIntl } from 'react-intl'; - import type { Map, List } from 'immutable'; -import ReactSwipeableViews from 'react-swipeable-views'; - import elephantUIPlane from '@/images/elephant_ui_plane.svg'; +import type { RenderSlideFn } from '@/mastodon/components/carousel'; +import { Carousel } from '@/mastodon/components/carousel'; import { CustomEmojiProvider } from '@/mastodon/components/emoji/context'; -import { IconButton } from '@/mastodon/components/icon_button'; -import LegacyAnnouncements from '@/mastodon/features/getting_started/containers/announcements_container'; -import { mascot, reduceMotion } from '@/mastodon/initial_state'; +import { mascot } from '@/mastodon/initial_state'; import { createAppSelector, useAppSelector } from '@/mastodon/store'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; -import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; -import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import type { IAnnouncement } from './announcement'; import { Announcement } from './announcement'; -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, - previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, - next: { id: 'lightbox.next', defaultMessage: 'Next' }, -}); - const announcementSelector = createAppSelector( [(state) => state.announcements as Map>>], (announcements) => - (announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? [], + ((announcements.get('items')?.toJS() as IAnnouncement[] | undefined) ?? []) + .map((announcement) => ({ announcement, id: announcement.id })) + .toReversed(), ); -export const ModernAnnouncements: FC = () => { - const intl = useIntl(); - +export const Announcements: FC = () => { const announcements = useAppSelector(announcementSelector); const emojis = useAppSelector((state) => state.custom_emojis); - const [index, setIndex] = useState(0); - const handleChangeIndex = useCallback( - (idx: number) => { - setIndex(idx % announcements.length); - }, - [announcements.length], + const renderSlide: RenderSlideFn<{ + id: string; + announcement: IAnnouncement; + }> = useCallback( + (item, active) => ( + + ), + [], ); - const handleNextIndex = useCallback(() => { - setIndex((prevIndex) => (prevIndex + 1) % announcements.length); - }, [announcements.length]); - const handlePrevIndex = useCallback(() => { - setIndex((prevIndex) => - prevIndex === 0 ? announcements.length - 1 : prevIndex - 1, - ); - }, [announcements.length]); if (announcements.length === 0) { return null; } return ( -
+
{ src={mascot ?? elephantUIPlane} /> -
- - - {announcements - .map((announcement, idx) => ( - - )) - .reverse()} - - - - {announcements.length > 1 && ( -
- - - {index + 1} / {announcements.length} - - -
- )} -
+ + +
); }; - -export const Announcements = isModernEmojiEnabled() - ? ModernAnnouncements - : LegacyAnnouncements; diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx index 05799ccb824..d297d7cee59 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.tsx @@ -270,7 +270,7 @@ export const InlineFollowSuggestions: React.FC<{ hidden?: boolean }> = ({
- +
+ + ); +}; + +const NewListWrapper: React.FC<{ + multiColumn?: boolean; +}> = ({ multiColumn }) => { + const intl = useIntl(); + const dispatch = useAppDispatch(); + const { id } = useParams<{ id?: string }>(); + const list = useAppSelector((state) => + id ? state.lists.get(id) : undefined, + ); + + useEffect(() => { + if (id) { + dispatch(fetchList(id)); + } + }, [dispatch, id]); + + const isLoading = id && !list; + return (
-
-
-
-
- - -
- -
-
-
-
- -
-
-
- - -
- -
-
-
-
- - {id && ( -
- -
- )} - -
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */} - -
- -
- -
-
+ {isLoading ? : }
@@ -298,4 +306,4 @@ const NewList: React.FC<{ }; // eslint-disable-next-line import/no-default-export -export default NewList; +export default NewListWrapper; diff --git a/app/javascript/mastodon/features/navigation_panel/components/list_panel.tsx b/app/javascript/mastodon/features/navigation_panel/components/list_panel.tsx index 020abf36cfb..56a59d9ccb5 100644 --- a/app/javascript/mastodon/features/navigation_panel/components/list_panel.tsx +++ b/app/javascript/mastodon/features/navigation_panel/components/list_panel.tsx @@ -27,17 +27,15 @@ export const ListPanel: React.FC = () => { const intl = useIntl(); const dispatch = useAppDispatch(); const lists = useAppSelector((state) => getOrderedLists(state)); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); useEffect(() => { - setLoading(true); - void dispatch(fetchLists()).then(() => { setLoading(false); return ''; }); - }, [dispatch, setLoading]); + }, [dispatch]); return ( { return ( - diff --git a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx index 1d1b684b809..9e7f66d112c 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/embedded_status_content.tsx @@ -1,47 +1,17 @@ import { useCallback, useMemo } from 'react'; -import { useHistory } from 'react-router-dom'; - import type { List } from 'immutable'; -import type { History } from 'history'; - -import type { ApiMentionJSON } from '@/mastodon/api_types/statuses'; import { EmojiHTML } from '@/mastodon/components/emoji/html'; import { useElementHandledLink } from '@/mastodon/components/status/handled_link'; import type { Status } from '@/mastodon/models/status'; -import { isModernEmojiEnabled } from '@/mastodon/utils/environment'; import type { Mention } from './embedded_status'; -const handleMentionClick = ( - history: History, - mention: ApiMentionJSON, - e: MouseEvent, -) => { - if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - history.push(`/@${mention.acct}`); - } -}; - -const handleHashtagClick = ( - history: History, - hashtag: string, - e: MouseEvent, -) => { - if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - history.push(`/tags/${hashtag.replace(/^#/, '')}`); - } -}; - export const EmbeddedStatusContent: React.FC<{ status: Status; className?: string; }> = ({ status, className }) => { - const history = useHistory(); - const mentions = useMemo( () => (status.get('mentions') as List).toJS(), [status], @@ -57,55 +27,10 @@ export const EmbeddedStatusContent: React.FC<{ hrefToMention, }); - const handleContentRef = useCallback( - (node: HTMLDivElement | null) => { - if (!node || isModernEmojiEnabled()) { - return; - } - - const links = node.querySelectorAll('a'); - - for (const link of links) { - if (link.classList.contains('status-link')) { - continue; - } - - link.classList.add('status-link'); - - const mention = mentions.find((item) => link.href === item.url); - - if (mention) { - link.addEventListener( - 'click', - handleMentionClick.bind(null, history, mention), - false, - ); - link.setAttribute('title', `@${mention.acct}`); - link.setAttribute('href', `/@${mention.acct}`); - } else if ( - link.textContent.startsWith('#') || - link.previousSibling?.textContent?.endsWith('#') - ) { - link.addEventListener( - 'click', - handleHashtagClick.bind(null, history, link.text), - false, - ); - link.setAttribute('href', `/tags/${link.text.replace(/^#/, '')}`); - } else { - link.setAttribute('title', link.href); - link.classList.add('unhandled-link'); - } - } - }, - [mentions, history], - ); - return ( diff --git a/app/javascript/mastodon/features/notifications_v2/components/notification_annual_report.tsx b/app/javascript/mastodon/features/notifications_v2/components/notification_annual_report.tsx index 8b92f31add5..4541592fbd9 100644 --- a/app/javascript/mastodon/features/notifications_v2/components/notification_annual_report.tsx +++ b/app/javascript/mastodon/features/notifications_v2/components/notification_annual_report.tsx @@ -47,7 +47,7 @@ export const NotificationAnnualReport: React.FC<{ values={{ year }} />

- diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx index 7c73d602fc7..3fca9eb44ee 100644 --- a/app/javascript/mastodon/features/notifications_v2/index.tsx +++ b/app/javascript/mastodon/features/notifications_v2/index.tsx @@ -245,6 +245,7 @@ export const Notifications: React.FC<{ title={intl.formatMessage(messages.markAsRead)} onClick={handleMarkAsRead} className='column-header__button' + type='button' > diff --git a/app/javascript/mastodon/features/search/components/search_section.tsx b/app/javascript/mastodon/features/search/components/search_section.tsx index ae0c1296766..c59d0c2fe4d 100644 --- a/app/javascript/mastodon/features/search/components/search_section.tsx +++ b/app/javascript/mastodon/features/search/components/search_section.tsx @@ -9,7 +9,7 @@ export const SearchSection: React.FC<{

{title}

{onClickMore && ( - + )} /> @@ -625,6 +631,7 @@ class Status extends ImmutablePureComponent { onDelete={this.handleDeleteClick} onRevokeQuote={this.handleRevokeQuoteClick} onQuotePolicyChange={this.handleQuotePolicyChange} + onQuote={this.handleQuote} onEdit={this.handleEditClick} onDirect={this.handleDirectClick} onMention={this.handleMentionClick} diff --git a/app/javascript/mastodon/features/ui/components/actions_modal.tsx b/app/javascript/mastodon/features/ui/components/actions_modal.tsx index 2577b21a17c..13deedcd1a8 100644 --- a/app/javascript/mastodon/features/ui/components/actions_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/actions_modal.tsx @@ -25,7 +25,12 @@ export const ActionsModal: React.FC<{ if (isActionItem(option)) { element = ( - ); diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.tsx b/app/javascript/mastodon/features/ui/components/boost_modal.tsx index 19631891944..a55141167b0 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/boost_modal.tsx @@ -113,7 +113,7 @@ export const BoostModal: React.FC<{
-
- diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modals/private_quote_notify.tsx b/app/javascript/mastodon/features/ui/components/confirmation_modals/private_quote_notify.tsx new file mode 100644 index 00000000000..ef917a10270 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/confirmation_modals/private_quote_notify.tsx @@ -0,0 +1,88 @@ +import { forwardRef, useCallback, useState } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import { submitCompose } from '@/mastodon/actions/compose'; +import { changeSetting } from '@/mastodon/actions/settings'; +import { CheckBox } from '@/mastodon/components/check_box'; +import { useAppDispatch } from '@/mastodon/store'; + +import { ConfirmationModal } from './confirmation_modal'; +import type { BaseConfirmationModalProps } from './confirmation_modal'; +import classes from './styles.module.css'; + +export const PRIVATE_QUOTE_MODAL_ID = 'quote/private_notify'; + +const messages = defineMessages({ + title: { + id: 'confirmations.private_quote_notify.title', + defaultMessage: 'Share with followers and mentioned users?', + }, + message: { + id: 'confirmations.private_quote_notify.message', + defaultMessage: + 'The person you are quoting and other mentions ' + + "will be notified and will be able to view your post, even if they're not following you.", + }, + confirm: { + id: 'confirmations.private_quote_notify.confirm', + defaultMessage: 'Publish post', + }, + cancel: { + id: 'confirmations.private_quote_notify.cancel', + defaultMessage: 'Back to editing', + }, +}); + +export const PrivateQuoteNotify = forwardRef< + HTMLDivElement, + BaseConfirmationModalProps +>( + ( + { onClose }, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _ref, + ) => { + const intl = useIntl(); + + const [dismiss, setDismissed] = useState(false); + const handleDismissToggle = useCallback(() => { + setDismissed((prev) => !prev); + }, []); + + const dispatch = useAppDispatch(); + const handleConfirm = useCallback(() => { + dispatch(submitCompose()); + if (dismiss) { + dispatch( + changeSetting(['dismissed_banners', PRIVATE_QUOTE_MODAL_ID], true), + ); + } + }, [dismiss, dispatch]); + + return ( + + {' '} + + + } + /> + ); + }, +); +PrivateQuoteNotify.displayName = 'PrivateQuoteNotify'; diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modals/styles.module.css b/app/javascript/mastodon/features/ui/components/confirmation_modals/styles.module.css new file mode 100644 index 00000000000..f685c4525f1 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/confirmation_modals/styles.module.css @@ -0,0 +1,7 @@ +.checkbox_wrapper { + display: flex; + align-items: center; + gap: 0.5rem; + margin: 1rem 0; + cursor: pointer; +} diff --git a/app/javascript/mastodon/features/ui/components/domain_block_modal.tsx b/app/javascript/mastodon/features/ui/components/domain_block_modal.tsx index ec089911441..eb2ccbb0352 100644 --- a/app/javascript/mastodon/features/ui/components/domain_block_modal.tsx +++ b/app/javascript/mastodon/features/ui/components/domain_block_modal.tsx @@ -53,8 +53,6 @@ export const DomainBlockModal: React.FC<{ }, [dispatch]); useEffect(() => { - setLoading(true); - apiRequest('GET', 'v1/domain_blocks/preview', { params: { domain }, timeout: 5000, @@ -68,7 +66,7 @@ export const DomainBlockModal: React.FC<{ setPreview('error'); setLoading(false); }); - }, [setPreview, setLoading, domain]); + }, [domain]); return (
@@ -196,7 +194,7 @@ export const DomainBlockModal: React.FC<{
- ; - const rightNav = media.size > 1 && ; - - const content = media.map((image, idx) => { - const width = image.getIn(['meta', 'original', 'width']) || null; - const height = image.getIn(['meta', 'original', 'height']) || null; - const description = image.getIn(['translation', 'description']) || image.get('description'); - - if (image.get('type') === 'image') { - return ( - - ); - } else if (image.get('type') === 'video') { - const { currentTime, autoPlay, volume } = this.props; - - return ( -
+ + {isQuotePost && visibility === 'direct' && ( +
+ + +
+ )}
在社交网络和人们互动。", "domain_pill.who_you_are": "用户名可以表明你的身份和你所在的站点,这样人们就可以通过在社交网络与你互动。", "domain_pill.your_handle": "你的用户名:", - "domain_pill.your_server": "你的数字家园,你的所有嘟文都在此存储。不喜欢这里吗?你可以随时迁移到其它服务器,并带上你的关注者。", + "domain_pill.your_server": "你的数字家园,你的全部嘟文都在此存储。不喜欢这里吗?你可以随时迁移到其它服务器,并带上你的关注者。", "domain_pill.your_username": "你在此服务器上的唯一标识。不同服务器上可能存在相同用户名的用户。", "dropdown.empty": "选项", "embed.instructions": "复制下列代码以在你的网站中嵌入此嘟文。", @@ -333,6 +343,7 @@ "empty_column.bookmarked_statuses": "你还没有给任何嘟文添加书签。添加书签后的嘟文会显示在这里。", "empty_column.community": "本站时间线还没有内容,写点什么并公开发布,让它活跃起来吧!", "empty_column.direct": "你还未使用过私下提及。当你发出或者收到私下提及时,它将显示在此。", + "empty_column.disabled_feed": "此动态已被你的服务器管理员禁用。", "empty_column.domain_blocks": "暂且没有被屏蔽的站点。", "empty_column.explore_statuses": "目前没有热门内容,稍后再来看看吧!", "empty_column.favourited_statuses": "你没有喜欢过任何嘟文。喜欢过的嘟文会显示在这里。", @@ -357,11 +368,9 @@ "explore.trending_links": "新闻", "explore.trending_statuses": "嘟文", "explore.trending_tags": "话题", + "featured_carousel.current": "嘟文 {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {# 条置顶嘟文}}", - "featured_carousel.next": "下一步", - "featured_carousel.post": "发嘟", - "featured_carousel.previous": "上一步", - "featured_carousel.slide": "第 {index} 共 {total}", + "featured_carousel.slide": "第 {current, number} 条嘟文,共 {max, number} 条", "filter_modal.added.context_mismatch_explanation": "这条过滤规则不适用于你当前访问此嘟文的场景。要在此场景下过滤嘟文,你必须编辑此过滤规则。", "filter_modal.added.context_mismatch_title": "场景不匹配!", "filter_modal.added.expired_explanation": "此过滤规则类别已过期,你需要修改到期日期才能应用。", @@ -404,6 +413,7 @@ "follow_suggestions.who_to_follow": "推荐关注", "followed_tags": "已关注话题", "footer.about": "关于", + "footer.about_this_server": "关于本站", "footer.directory": "用户列表", "footer.get_app": "获取应用", "footer.keyboard_shortcuts": "快捷键", @@ -661,9 +671,9 @@ "notifications.column_settings.admin.sign_up": "新注册:", "notifications.column_settings.alert": "桌面通知", "notifications.column_settings.favourite": "喜欢:", - "notifications.column_settings.filter_bar.advanced": "显示所有类别", + "notifications.column_settings.filter_bar.advanced": "显示全部类别", "notifications.column_settings.filter_bar.category": "快速筛选栏", - "notifications.column_settings.follow": "新粉丝:", + "notifications.column_settings.follow": "新关注者:", "notifications.column_settings.follow_request": "新关注请求:", "notifications.column_settings.group": "分组", "notifications.column_settings.mention": "提及:", @@ -755,6 +765,7 @@ "privacy_policy.title": "隐私政策", "quote_error.edit": "编辑嘟文时无法添加引用。", "quote_error.poll": "不允许引用投票嘟文。", + "quote_error.private_mentions": "不允许引用私下提及嘟文。", "quote_error.quote": "一次只能引用一条嘟文。", "quote_error.unauthorized": "你没有权限引用此嘟文。", "quote_error.upload": "不允许引用有媒体附件的嘟文。", @@ -807,9 +818,9 @@ "report.reasons.spam_description": "恶意链接、虚假互动或重复回复", "report.reasons.violation": "违反服务器规则", "report.reasons.violation_description": "你清楚它违反了特定的规则", - "report.rules.subtitle": "选择所有适用选项", + "report.rules.subtitle": "选择全部适用选项", "report.rules.title": "违反了哪些规则?", - "report.statuses.subtitle": "选择所有适用选项", + "report.statuses.subtitle": "选择全部适用选项", "report.statuses.title": "是否有任何嘟文可以支持这一报告?", "report.submit": "提交", "report.target": "举报 {target}", @@ -860,7 +871,7 @@ "server_banner.is_one_of_many": "{domain} 是可用于参与联邦宇宙的众多独立 Mastodon 站点之一。", "server_banner.server_stats": "服务器统计数据:", "sign_in_banner.create_account": "创建账号", - "sign_in_banner.follow_anyone": "关注联邦宇宙中的任何人,并按时间顺序查看所有内容。没有算法、广告或诱导链接。", + "sign_in_banner.follow_anyone": "关注联邦宇宙中的任何人,并按时间顺序查看全部内容。没有算法、广告或诱导链接。", "sign_in_banner.mastodon_is": "Mastodon 是了解最新动态的最佳途径。", "sign_in_banner.sign_in": "登录", "sign_in_banner.sso_redirect": "登录或注册", @@ -908,9 +919,12 @@ "status.pin": "在个人资料页面置顶", "status.quote": "引用", "status.quote.cancel": "取消引用", + "status.quote_error.blocked_account_hint.title": "由于你已屏蔽@{name},此嘟文已隐藏。", + "status.quote_error.blocked_domain_hint.title": "由于你已屏蔽{domain},此嘟文已隐藏。", "status.quote_error.filtered": "已根据你的筛选器过滤", "status.quote_error.limited_account_hint.action": "仍然显示", "status.quote_error.limited_account_hint.title": "此账号已被 {domain} 管理员隐藏。", + "status.quote_error.muted_account_hint.title": "由于你已设置隐藏@{name},此嘟文已隐藏。", "status.quote_error.not_available": "嘟文不可用", "status.quote_error.pending_approval": "嘟文待发布", "status.quote_error.pending_approval_popout.body": "在Mastodon上,你可以控制其他人引用你嘟文的权限。此嘟文在得到原作者的同意后就会发布。", @@ -954,7 +968,7 @@ "status.uncached_media_warning": "预览不可用", "status.unmute_conversation": "恢复此对话的通知提醒", "status.unpin": "在个人资料页面取消置顶", - "subscribed_languages.lead": "更改此选择后,只有选定语言的嘟文才会出现在你的主页和列表时间线上。选择「无」将显示所有语言的嘟文。", + "subscribed_languages.lead": "更改此选择后,只有选定语言的嘟文才会出现在你的主页和列表时间线上。选择「无」将显示全部语言的嘟文。", "subscribed_languages.save": "保存更改", "subscribed_languages.target": "更改 {target} 的订阅语言", "tabs_bar.home": "主页", @@ -1005,13 +1019,15 @@ "video.volume_down": "音量减小", "video.volume_up": "提高音量", "visibility_modal.button_title": "设置可见性", + "visibility_modal.direct_quote_warning.text": "如果你保存当前设置,引用的嘟文将被转换为链接。", + "visibility_modal.direct_quote_warning.title": "引用嘟文无法嵌入到私下提及中", "visibility_modal.header": "可见性和互动", "visibility_modal.helper.direct_quoting": "Mastodon上发布的私下提及无法被他人引用。", "visibility_modal.helper.privacy_editing": "嘟文发布后便无法更改可见性。", "visibility_modal.helper.privacy_private_self_quote": "自我引用的私人嘟文无法设置为公开。", "visibility_modal.helper.private_quoting": "Mastodon上发布的仅限关注者可见的嘟文无法被他人引用。", "visibility_modal.helper.unlisted_quoting": "当其他人引用你时,他们的嘟文也会从热门时间线上隐藏。", - "visibility_modal.instructions": "控制谁可以和此嘟文互动。你也可以前往偏好设置 > 发布默认值将此设置应用到所有未来发布的嘟文。", + "visibility_modal.instructions": "控制谁可以和此嘟文互动。你也可以前往偏好设置 > 发布默认值将此设置应用到全部未来发布的嘟文。", "visibility_modal.privacy_label": "可见性", "visibility_modal.quote_followers": "仅关注者", "visibility_modal.quote_label": "谁可以引用", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 3626f7da54a..fd3eb665ab4 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -28,6 +28,7 @@ "account.disable_notifications": "當 @{name} 發文時不要再通知我", "account.domain_blocking": "封鎖網域", "account.edit_profile": "修改個人檔案", + "account.edit_profile_short": "編輯", "account.enable_notifications": "當 @{name} 發文時通知我", "account.endorse": "在個人檔案中推薦對方", "account.familiar_followers_many": "{name1}、{name2} 及{othersCount, plural, other {你認識的 # 人}}已追蹤", @@ -40,12 +41,18 @@ "account.featured_tags.last_status_never": "暫無文章", "account.follow": "關注", "account.follow_back": "追蹤對方", + "account.follow_back_short": "追蹤對方", + "account.follow_request": "追蹤請求", + "account.follow_request_cancel": "取消請求", + "account.follow_request_cancel_short": "取消", + "account.follow_request_short": "請求", "account.followers": "追蹤者", "account.followers.empty": "尚未有人追蹤這位使用者。", "account.followers_counter": "{count, plural, other {{counter} 個追蹤者}}", "account.followers_you_know_counter": "你認識的 {counter} 人", "account.following": "正在追蹤", "account.follows.empty": "這位使用者尚未追蹤任何人。", + "account.follows_you": "正追蹤你", "account.go_to_profile": "前往個人檔案", "account.hide_reblogs": "隱藏 @{name} 的轉推", "account.in_memoriam": "謹此悼念。", @@ -60,10 +67,13 @@ "account.mute_notifications_short": "靜音通知", "account.mute_short": "靜音", "account.muted": "靜音", + "account.muting": "靜音", + "account.mutual": "你們已互相追蹤", "account.no_bio": "未提供描述。", "account.open_original_page": "打開原始頁面", "account.posts": "帖文", "account.posts_with_replies": "帖文與回覆", + "account.remove_from_followers": "移除追蹤者{name}", "account.report": "檢舉 @{name}", "account.requested_follow": "{name} 要求追蹤你", "account.share": "分享 @{name} 的個人檔案", @@ -130,8 +140,11 @@ "column.direct": "私人提及", "column.directory": "瀏覽個人資料", "column.domain_blocks": "封鎖的服務站", + "column.edit_list": "編輯列表", "column.favourites": "最愛", "column.firehose": "即時動態", + "column.firehose_local": "本伺服器的即時動態", + "column.firehose_singular": "即時動態", "column.follow_requests": "追蹤請求", "column.home": "主頁", "column.lists": "列表", @@ -182,15 +195,28 @@ "confirmations.delete_list.confirm": "刪除", "confirmations.delete_list.message": "你確定要永久刪除這列表嗎?", "confirmations.delete_list.title": "刪除列表?", + "confirmations.discard_draft.post.title": "要捨棄文章的草稿?", "confirmations.discard_edit_media.confirm": "捨棄", "confirmations.discard_edit_media.message": "您在媒體描述或預覽有尚未儲存的變更。確定要捨棄它們嗎?", + "confirmations.follow_to_list.title": "追蹤使用者?", "confirmations.logout.confirm": "登出", "confirmations.logout.message": "確定要登出嗎?", "confirmations.logout.title": "登出?", + "confirmations.missing_alt_text.confirm": "新增替代文字", + "confirmations.missing_alt_text.message": "你的貼文尚未附上替代文字。新增描述有助更多人存取其內容。", "confirmations.mute.confirm": "靜音", + "confirmations.quiet_post_quote_info.dismiss": "不再提醒", + "confirmations.quiet_post_quote_info.got_it": "知道了", "confirmations.redraft.confirm": "刪除並編輯", "confirmations.redraft.message": "你確定要移除並重新起草這篇帖文嗎?你將會失去最愛和轉推,而回覆也會與原始帖文斷開連接。", + "confirmations.revoke_quote.message": "此操作無法還原。", + "confirmations.revoke_quote.title": "移除貼文?", + "confirmations.unblock.confirm": "解除封鎖", + "confirmations.unblock.title": "解除封鎖 {name}?", "confirmations.unfollow.confirm": "取消追蹤", + "confirmations.unfollow.title": "取消追蹤 {name}?", + "confirmations.withdraw_request.confirm": "撤回請求", + "confirmations.withdraw_request.title": "撤回追蹤{name}的請求?", "content_warning.hide": "隱藏嘟文", "content_warning.show": "仍要顯示", "content_warning.show_more": "顯示更多", @@ -432,6 +458,8 @@ "navigation_bar.follows_and_followers": "追蹤及追蹤者", "navigation_bar.import_export": "匯入及匯出", "navigation_bar.lists": "列表", + "navigation_bar.live_feed_local": "即時動態(本地)", + "navigation_bar.live_feed_public": "即時動態(公開)", "navigation_bar.logout": "登出", "navigation_bar.more": "更多", "navigation_bar.mutes": "靜音名單", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 86e231dd494..c75f359a546 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -31,7 +31,7 @@ "account.edit_profile_short": "編輯", "account.enable_notifications": "當 @{name} 嘟文時通知我", "account.endorse": "於個人檔案推薦對方", - "account.familiar_followers_many": "被 {name1}、{name2}、及 {othersCount, plural, other {其他您認識的 # 人}} 跟隨", + "account.familiar_followers_many": "被 {name1}、{name2}、及{othersCount, plural, other {其他您認識的 # 人}} 跟隨", "account.familiar_followers_one": "被 {name1} 跟隨", "account.familiar_followers_two": "被 {name1} 與 {name2} 跟隨", "account.featured": "精選內容", @@ -48,10 +48,10 @@ "account.follow_request_short": "跟隨請求", "account.followers": "跟隨者", "account.followers.empty": "尚未有人跟隨這位使用者。", - "account.followers_counter": "被 {count, plural, other {{count} 人}}跟隨", + "account.followers_counter": "被 {count, plural, other {{counter} 人}}跟隨", "account.followers_you_know_counter": "{counter} 位您知道的跟隨者", "account.following": "跟隨中", - "account.following_counter": "正在跟隨 {count,plural,other {{count} 人}}", + "account.following_counter": "正在跟隨 {count,plural,other {{counter} 人}}", "account.follows.empty": "這位使用者尚未跟隨任何人。", "account.follows_you": "已跟隨您", "account.go_to_profile": "前往個人檔案", @@ -80,7 +80,7 @@ "account.requests_to_follow_you": "要求跟隨您", "account.share": "分享 @{name} 的個人檔案", "account.show_reblogs": "顯示來自 @{name} 的轉嘟", - "account.statuses_counter": "{count, plural, other {{count} 則嘟文}}", + "account.statuses_counter": "{count, plural, other {{counter} 則嘟文}}", "account.unblock": "解除封鎖 @{name}", "account.unblock_domain": "解除封鎖網域 {domain}", "account.unblock_domain_short": "解除封鎖", @@ -104,9 +104,9 @@ "alert.rate_limited.title": "已限速", "alert.unexpected.message": "發生非預期的錯誤。", "alert.unexpected.title": "哎呀!", - "alt_text_badge.title": "ALT 說明文字", - "alt_text_modal.add_alt_text": "新增 ALT 說明文字", - "alt_text_modal.add_text_from_image": "自圖片新增 ALT 說明文字", + "alt_text_badge.title": "替代文字", + "alt_text_modal.add_alt_text": "新增替代文字", + "alt_text_modal.add_text_from_image": "自圖片新增替代文字", "alt_text_modal.cancel": "取消", "alt_text_modal.change_thumbnail": "變更預覽圖", "alt_text_modal.describe_for_people_with_hearing_impairments": "替聽覺障礙人士描述...", @@ -157,6 +157,8 @@ "bundle_modal_error.close": "關閉", "bundle_modal_error.message": "載入此畫面時發生錯誤。", "bundle_modal_error.retry": "重試", + "carousel.current": "頁面 {current, number} / {max, number}", + "carousel.slide": "{max, number} 頁中之第 {current, number} 頁", "closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。", "closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon。", "closed_registrations_modal.find_another_server": "尋找另一個伺服器", @@ -173,6 +175,8 @@ "column.edit_list": "編輯列表", "column.favourites": "最愛", "column.firehose": "即時內容", + "column.firehose_local": "本站伺服器之即時內容", + "column.firehose_singular": "即時內容", "column.follow_requests": "跟隨請求", "column.home": "首頁", "column.list_members": "管理列表成員", @@ -192,6 +196,7 @@ "community.column_settings.local_only": "只顯示本站", "community.column_settings.media_only": "只顯示媒體", "community.column_settings.remote_only": "只顯示遠端", + "compose.error.blank_post": "嘟文無法為空白。", "compose.language.change": "變更語言", "compose.language.search": "搜尋語言...", "compose.published.body": "發嘟成功。", @@ -239,11 +244,16 @@ "confirmations.logout.confirm": "登出", "confirmations.logout.message": "您確定要登出嗎?", "confirmations.logout.title": "您確定要登出嗎?", - "confirmations.missing_alt_text.confirm": "新增 ALT 說明文字", - "confirmations.missing_alt_text.message": "您的嘟文中的多媒體內容未附上 ALT 說明文字。添加說明文字描述能幫助更多人存取您的內容。", + "confirmations.missing_alt_text.confirm": "新增替代文字", + "confirmations.missing_alt_text.message": "您的嘟文中的多媒體內容未附上替代文字。添加描述能幫助更多人存取您的內容。", "confirmations.missing_alt_text.secondary": "仍要發嘟", - "confirmations.missing_alt_text.title": "是否新增 ALT 說明文字?", + "confirmations.missing_alt_text.title": "是否新增替代文字?", "confirmations.mute.confirm": "靜音", + "confirmations.private_quote_notify.cancel": "返回至編輯", + "confirmations.private_quote_notify.confirm": "發表嘟文", + "confirmations.private_quote_notify.do_not_show_again": "不再顯示此訊息", + "confirmations.private_quote_notify.message": "您所引用與提及之使用者將被通知且能檢視您的嘟文,即便他們並無跟隨您。", + "confirmations.private_quote_notify.title": "是否和跟隨者與提及使用者分享此內容?", "confirmations.quiet_post_quote_info.dismiss": "不要再提醒我", "confirmations.quiet_post_quote_info.got_it": "了解", "confirmations.quiet_post_quote_info.message": "當引用不於公開時間軸顯示之嘟文時,您的嘟文將自熱門時間軸隱藏。", @@ -358,11 +368,9 @@ "explore.trending_links": "最新消息", "explore.trending_statuses": "嘟文", "explore.trending_tags": "主題標籤", + "featured_carousel.current": "嘟文 {current, number} / {max, number}", "featured_carousel.header": "{count, plural, other {# 則釘選嘟文}}", - "featured_carousel.next": "下一個", - "featured_carousel.post": "嘟文", - "featured_carousel.previous": "上一個", - "featured_carousel.slide": "{total} 中的 {index}", + "featured_carousel.slide": "{max, number} 則嘟文中之第 {current, number} 則", "filter_modal.added.context_mismatch_explanation": "此過濾器類別不是用您所存取嘟文的情境。若您想要此嘟文被於此情境被過濾,您必須編輯過濾器。", "filter_modal.added.context_mismatch_title": "不符合情境!", "filter_modal.added.expired_explanation": "此過濾器類別已失效,您需要更新過期日期以套用。", @@ -405,6 +413,7 @@ "follow_suggestions.who_to_follow": "推薦跟隨帳號", "followed_tags": "已跟隨主題標籤", "footer.about": "關於", + "footer.about_this_server": "關於", "footer.directory": "個人檔案目錄", "footer.get_app": "取得應用程式", "footer.keyboard_shortcuts": "鍵盤快速鍵", @@ -426,9 +435,9 @@ "hashtag.column_settings.tag_mode.any": "任一", "hashtag.column_settings.tag_mode.none": "全不", "hashtag.column_settings.tag_toggle": "將額外標籤加入到這個欄位", - "hashtag.counter_by_accounts": "{count, plural, one {{counter} 名} other {{counter} 名}}參與者", - "hashtag.counter_by_uses": "{count, plural, one {{counter} 則} other {{counter} 則}}嘟文", - "hashtag.counter_by_uses_today": "本日有 {count, plural, one {{counter} 則} other {{counter} 則}}嘟文", + "hashtag.counter_by_accounts": "{count, plural, other {{counter} 名參與者}}", + "hashtag.counter_by_uses": "{count, plural, other {{counter} 則嘟文}}", + "hashtag.counter_by_uses_today": "本日有 {count, plural, other {{counter} 則嘟文}}", "hashtag.feature": "於個人檔案推薦", "hashtag.follow": "跟隨主題標籤", "hashtag.mute": "靜音 #{hashtag}", @@ -461,7 +470,7 @@ "ignore_notifications_modal.not_following_title": "忽略來自您未跟隨帳號之推播通知?", "ignore_notifications_modal.private_mentions_title": "忽略來自不請自來私訊之推播通知?", "info_button.label": "幫助", - "info_button.what_is_alt_text": "

何謂 ALT 說明文字?

ALT 說明文字為視覺障礙者、低網路頻寬或尋求額外上下文語境的人們提供圖片描述。

您可以透過撰寫清晰、簡潔及客觀的說明文字以替所有人改善無障礙特性與協助理解。

  • 掌握幾個重要元素
  • 替圖片提供文字摘要
  • 使用常規行文結構
  • 避免冗贅資訊
  • 聚焦於趨勢與複雜視覺中之關鍵(如圖表或地圖)
", + "info_button.what_is_alt_text": "

何謂替代文字?

替代文字為視覺障礙者、低網路頻寬或尋求額外上下文語境的人們提供圖片描述。

您可以透過撰寫清晰、簡潔及客觀的替代文字以替所有人改善無障礙特性與協助理解。

  • 掌握幾個重要元素
  • 替圖片提供文字摘要
  • 使用常規行文結構
  • 避免冗贅資訊
  • 聚焦於趨勢與複雜視覺中之關鍵(如圖表或地圖)
", "interaction_modal.action": "若欲與 {name} 之嘟文互動,您必須登入您帳號所註冊之 Mastodon 伺服器。", "interaction_modal.go": "Go!", "interaction_modal.no_account_yet": "仍尚未有帳號嗎?", @@ -520,7 +529,7 @@ "limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。", "link_preview.author": "來自 {name}", "link_preview.more_from_author": "來自 {name} 之更多內容", - "link_preview.shares": "{count, plural, other {{count} 則嘟文}}", + "link_preview.shares": "{count, plural, other {{counter} 則嘟文}}", "lists.add_member": "新增", "lists.add_to_list": "新增至列表", "lists.add_to_lists": "新增 {name} 至列表", @@ -552,7 +561,7 @@ "moved_to_account_banner.text": "您的帳號 {disabledAccount} 目前已停用,因為您已搬家至 {movedToAccount}。", "mute_modal.hide_from_notifications": "於推播通知中隱藏", "mute_modal.hide_options": "隱藏選項", - "mute_modal.indefinite": "直到我解除靜音他們", + "mute_modal.indefinite": "直到我解除靜音", "mute_modal.show_options": "顯示選項", "mute_modal.they_can_mention_and_follow": "他們仍可提及或跟隨您,但您不會見到他們。", "mute_modal.they_wont_know": "他們不會知道他們已被靜音。", @@ -602,8 +611,8 @@ "notification.annual_report.view": "檢視 #Wrapstodon", "notification.favourite": "{name} 已將您的嘟文加入最愛", "notification.favourite.name_and_others_with_link": "{name} 與{count, plural, other {其他 # 個人}}已將您的嘟文加入最愛", - "notification.favourite_pm": "{name} 將您的私人提及加入最愛", - "notification.favourite_pm.name_and_others_with_link": "{name} 與{count, plural, other {其他 # 個人}}已將您的私人提及加入最愛", + "notification.favourite_pm": "{name} 將您的私訊加入最愛", + "notification.favourite_pm.name_and_others_with_link": "{name} 與{count, plural, other {其他 # 個人}}已將您的私訊加入最愛", "notification.follow": "{name} 已跟隨您", "notification.follow.name_and_others": "{name} 與{count, plural, other {其他 # 個人}}已跟隨您", "notification.follow_request": "{name} 要求跟隨您", @@ -640,10 +649,10 @@ "notification_requests.accept_multiple": "{count, plural, other {接受 # 則請求...}}", "notification_requests.confirm_accept_multiple.button": "{count, plural, other {接受請求}}", "notification_requests.confirm_accept_multiple.message": "您將接受 {count, plural, other {# 則推播通知請求}}。您確定要繼續?", - "notification_requests.confirm_accept_multiple.title": "接受推播通知請求?", + "notification_requests.confirm_accept_multiple.title": "是否接受推播通知請求?", "notification_requests.confirm_dismiss_multiple.button": "{count, plural, other {忽略請求}}", "notification_requests.confirm_dismiss_multiple.message": "您將忽略 {count, plural, other {# 則推播通知請求}}。您將不再能輕易存取{count, plural, other {這些}}推播通知。您確定要繼續?", - "notification_requests.confirm_dismiss_multiple.title": "忽略推播通知請求?", + "notification_requests.confirm_dismiss_multiple.title": "是否忽略推播通知請求?", "notification_requests.dismiss": "關閉", "notification_requests.dismiss_multiple": "{count, plural, other {忽略 # 則請求...}}", "notification_requests.edit_selection": "編輯", @@ -701,7 +710,7 @@ "notifications.policy.filter_limited_accounts_title": "受管制帳號", "notifications.policy.filter_new_accounts.hint": "新增於過去 {days, plural, other {# 日}}", "notifications.policy.filter_new_accounts_title": "新帳號", - "notifications.policy.filter_not_followers_hint": "包含最近 {days, plural, other {# 日}} 內跟隨您之使用者", + "notifications.policy.filter_not_followers_hint": "包含最近 {days, plural, other {# 日}}內跟隨您之使用者", "notifications.policy.filter_not_followers_title": "未跟隨您之使用者", "notifications.policy.filter_not_following_hint": "直至您手動核准他們", "notifications.policy.filter_not_following_title": "您未跟隨之使用者", @@ -756,6 +765,7 @@ "privacy_policy.title": "隱私權政策", "quote_error.edit": "編輯嘟文時無法新增引用嘟文。", "quote_error.poll": "無法引用投票嘟文。", + "quote_error.private_mentions": "無法引用私訊嘟文。", "quote_error.quote": "一次僅能引用一則嘟文。", "quote_error.unauthorized": "您不被授權允許引用此嘟文。", "quote_error.upload": "無法引用多媒體內容嘟文。", @@ -820,7 +830,7 @@ "report.thanks.title_actionable": "感謝您的檢舉,我們將會著手處理。", "report.unfollow": "取消跟隨 @{name}", "report.unfollow_explanation": "您正在跟隨此帳號。如不欲於首頁時間軸再見到他們的嘟文,請取消跟隨。", - "report_notification.attached_statuses": "{count, plural, one {{count} 則} other {{count} 則}} 嘟文", + "report_notification.attached_statuses": "已附加 {count, plural, other {{count} 則嘟文}}", "report_notification.categories.legal": "合法性", "report_notification.categories.legal_sentence": "違法內容", "report_notification.categories.other": "其他", @@ -890,7 +900,7 @@ "status.direct_indicator": "私訊", "status.edit": "編輯", "status.edited": "上次編輯於 {date}", - "status.edited_x_times": "已編輯 {count, plural, one {{count} 次} other {{count} 次}}", + "status.edited_x_times": "已編輯 {count, plural, other {{count} 次}}", "status.embed": "取得嵌入程式碼", "status.favourite": "最愛", "status.favourites": "{count, plural, other {則最愛}}", @@ -909,9 +919,12 @@ "status.pin": "釘選至個人檔案頁面", "status.quote": "引用", "status.quote.cancel": "取消引用嘟文", + "status.quote_error.blocked_account_hint.title": "由於您已封鎖 @{name},此嘟文已被隱藏。", + "status.quote_error.blocked_domain_hint.title": "由於您已封鎖 {domain},此嘟文已被隱藏。", "status.quote_error.filtered": "由於您的過濾器,該嘟文被隱藏", "status.quote_error.limited_account_hint.action": "仍要顯示", "status.quote_error.limited_account_hint.title": "此個人檔案已被 {domain} 的管理員隱藏。", + "status.quote_error.muted_account_hint.title": "由於您已靜音 @{name},此嘟文已被隱藏。", "status.quote_error.not_available": "無法取得該嘟文", "status.quote_error.pending_approval": "嘟文正在等候審核中", "status.quote_error.pending_approval_popout.body": "您能於 Mastodon 控制是否允許引用您的嘟文。此嘟文正在等待原始作者審核。", @@ -922,7 +935,7 @@ "status.quote_policy_change": "變更可以引用的人", "status.quote_post_author": "已引用 @{name} 之嘟文", "status.quote_private": "無法引用私人嘟文", - "status.quotes": "{count, plural, other {# 則引用嘟文}}", + "status.quotes": "{count, plural, other {則引用嘟文}}", "status.quotes.empty": "目前尚無人引用此嘟文。當有人引用時,它將於此顯示。", "status.quotes.local_other_disclaimer": "被作者拒絕之引用嘟文將不被顯示。", "status.quotes.remote_other_disclaimer": "僅有來自 {domain} 之引用嘟文保證將於此顯示。被作者拒絕之引用嘟文將不被顯示。", @@ -967,11 +980,11 @@ "terms_of_service.title": "服務條款", "terms_of_service.upcoming_changes_on": "{date} 起即將發生之異動", "time_remaining.days": "剩餘 {number, plural, other {# 天}}", - "time_remaining.hours": "剩餘{number, plural, other {# 小時}}", - "time_remaining.minutes": "剩餘{number, plural, other {# 分鐘}}", + "time_remaining.hours": "剩餘 {number, plural, other {# 小時}}", + "time_remaining.minutes": "剩餘 {number, plural, other {# 分鐘}}", "time_remaining.moments": "剩餘時間", - "time_remaining.seconds": "剩餘{number, plural, other {# 秒}}", - "trends.counter_by_accounts": "{count, plural, one {{counter} 人} other {{counter} 人}}於過去 {days, plural, one {日} other {{days} 日}} 之間", + "time_remaining.seconds": "剩餘 {number, plural, other {# 秒}}", + "trends.counter_by_accounts": "{count, plural, other {{counter} 人}}於過去 {days, plural, other {{days} 日}}之間", "trends.trending_now": "現正熱門趨勢", "ui.beforeunload": "如果離開 Mastodon,您的草稿將會不見。", "units.short.billion": "{count}B", @@ -1002,12 +1015,14 @@ "video.play": "播放", "video.skip_backward": "上一部", "video.skip_forward": "下一部", - "video.unmute": "取消靜音", + "video.unmute": "解除靜音", "video.volume_down": "降低音量", "video.volume_up": "提高音量", "visibility_modal.button_title": "設定可見性", + "visibility_modal.direct_quote_warning.text": "若您儲存目前設定,引用嘟文將被轉為連結。", + "visibility_modal.direct_quote_warning.title": "引用嘟文無法被內嵌於私訊中", "visibility_modal.header": "可見性與互動", - "visibility_modal.helper.direct_quoting": "Mastodon 上發佈之私人提及嘟文無法被其他使用者引用。", + "visibility_modal.helper.direct_quoting": "Mastodon 上發佈之私訊嘟文無法被其他使用者引用。", "visibility_modal.helper.privacy_editing": "嘟文發布後無法變更可見性。", "visibility_modal.helper.privacy_private_self_quote": "自我引用之私嘟無法設為公開可見。", "visibility_modal.helper.private_quoting": "Mastodon 上發佈之僅限跟隨者嘟文無法被其他使用者引用。", diff --git a/app/javascript/mastodon/main.tsx b/app/javascript/mastodon/main.tsx index 456cc21c318..f89baf66cd6 100644 --- a/app/javascript/mastodon/main.tsx +++ b/app/javascript/mastodon/main.tsx @@ -9,11 +9,8 @@ import { me, reduceMotion } from 'mastodon/initial_state'; import ready from 'mastodon/ready'; import { store } from 'mastodon/store'; -import { - isProduction, - isDevelopment, - isModernEmojiEnabled, -} from './utils/environment'; +import { initializeEmoji } from './features/emoji'; +import { isProduction, isDevelopment } from './utils/environment'; function main() { perf.start('main()'); @@ -33,10 +30,7 @@ function main() { }); } - if (isModernEmojiEnabled()) { - const { initializeEmoji } = await import('@/mastodon/features/emoji'); - initializeEmoji(); - } + initializeEmoji(); const root = createRoot(mountNode); root.render(); diff --git a/app/javascript/mastodon/models/account.ts b/app/javascript/mastodon/models/account.ts index 3b0c41be818..8fbc0cdf411 100644 --- a/app/javascript/mastodon/models/account.ts +++ b/app/javascript/mastodon/models/account.ts @@ -8,11 +8,10 @@ import type { ApiAccountRoleJSON, ApiAccountJSON, } from 'mastodon/api_types/accounts'; -import emojify from 'mastodon/features/emoji/emoji'; import { unescapeHTML } from 'mastodon/utils/html'; -import { CustomEmojiFactory, makeEmojiMap } from './custom_emoji'; -import type { CustomEmoji, EmojiMap } from './custom_emoji'; +import { CustomEmojiFactory } from './custom_emoji'; +import type { CustomEmoji } from './custom_emoji'; // AccountField interface AccountFieldShape extends Required { @@ -102,17 +101,11 @@ export const accountDefaultValues: AccountShape = { const AccountFactory = ImmutableRecord(accountDefaultValues); -function createAccountField( - jsonField: ApiAccountFieldJSON, - emojiMap: EmojiMap, -) { +function createAccountField(jsonField: ApiAccountFieldJSON) { return AccountFieldFactory({ ...jsonField, - name_emojified: emojify( - escapeTextContentForBrowser(jsonField.name), - emojiMap, - ), - value_emojified: emojify(jsonField.value, emojiMap), + name_emojified: escapeTextContentForBrowser(jsonField.name), + value_emojified: jsonField.value, value_plain: unescapeHTML(jsonField.value), }); } @@ -120,8 +113,6 @@ function createAccountField( export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { const { moved, ...accountJSON } = serverJSON; - const emojiMap = makeEmojiMap(accountJSON.emojis); - const displayName = accountJSON.display_name.trim().length === 0 ? accountJSON.username @@ -134,7 +125,7 @@ export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { ...accountJSON, moved: moved?.id, fields: ImmutableList( - serverJSON.fields.map((field) => createAccountField(field, emojiMap)), + serverJSON.fields.map((field) => createAccountField(field)), ), emojis: ImmutableList( serverJSON.emojis.map((emoji) => CustomEmojiFactory(emoji)), @@ -142,11 +133,8 @@ export function createAccountFromServerJSON(serverJSON: ApiAccountJSON) { roles: ImmutableList( serverJSON.roles?.map((role) => AccountRoleFactory(role)), ), - display_name_html: emojify( - escapeTextContentForBrowser(displayName), - emojiMap, - ), - note_emojified: emojify(accountNote, emojiMap), + display_name_html: escapeTextContentForBrowser(displayName), + note_emojified: accountNote, note_plain: unescapeHTML(accountNote), url: accountJSON.url?.startsWith('http://') || diff --git a/app/javascript/mastodon/models/poll.ts b/app/javascript/mastodon/models/poll.ts index 6f5655680d6..46cbb1111d1 100644 --- a/app/javascript/mastodon/models/poll.ts +++ b/app/javascript/mastodon/models/poll.ts @@ -1,10 +1,9 @@ import escapeTextContentForBrowser from 'escape-html'; import type { ApiPollJSON, ApiPollOptionJSON } from 'mastodon/api_types/polls'; -import emojify from 'mastodon/features/emoji/emoji'; -import { CustomEmojiFactory, makeEmojiMap } from './custom_emoji'; -import type { CustomEmoji, EmojiMap } from './custom_emoji'; +import { CustomEmojiFactory } from './custom_emoji'; +import type { CustomEmoji } from './custom_emoji'; interface PollOptionTranslation { title: string; @@ -17,16 +16,12 @@ export interface PollOption extends ApiPollOptionJSON { translation: PollOptionTranslation | null; } -export function createPollOptionTranslationFromServerJSON( - translation: { title: string }, - emojiMap: EmojiMap, -) { +export function createPollOptionTranslationFromServerJSON(translation: { + title: string; +}) { return { ...translation, - titleHtml: emojify( - escapeTextContentForBrowser(translation.title), - emojiMap, - ), + titleHtml: escapeTextContentForBrowser(translation.title), } as PollOptionTranslation; } @@ -50,8 +45,6 @@ export function createPollFromServerJSON( serverJSON: ApiPollJSON, previousPoll?: Poll, ) { - const emojiMap = makeEmojiMap(serverJSON.emojis); - return { ...pollDefaultValues, ...serverJSON, @@ -60,20 +53,15 @@ export function createPollFromServerJSON( const option = { ...optionJSON, voted: serverJSON.own_votes?.includes(index) || false, - titleHtml: emojify( - escapeTextContentForBrowser(optionJSON.title), - emojiMap, - ), + titleHtml: escapeTextContentForBrowser(optionJSON.title), } as PollOption; const prevOption = previousPoll?.options[index]; if (prevOption?.translation && prevOption.title === option.title) { const { translation } = prevOption; - option.translation = createPollOptionTranslationFromServerJSON( - translation, - emojiMap, - ); + option.translation = + createPollOptionTranslationFromServerJSON(translation); } return option; diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index f27c3bb06bf..d4ed1bd5059 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -1,11 +1,14 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable'; import { + changeComposeVisibility, changeUploadCompose, quoteCompose, quoteComposeCancel, setComposeQuotePolicy, -} from 'mastodon/actions/compose_typed'; + pasteLinkCompose, + cancelPasteLinkCompose, +} from '@/mastodon/actions/compose_typed'; import { timelineDelete } from 'mastodon/actions/timelines_typed'; import { @@ -38,7 +41,6 @@ import { COMPOSE_SENSITIVITY_CHANGE, COMPOSE_SPOILERNESS_CHANGE, COMPOSE_SPOILER_TEXT_CHANGE, - COMPOSE_VISIBILITY_CHANGE, COMPOSE_LANGUAGE_CHANGE, COMPOSE_COMPOSING_CHANGE, COMPOSE_EMOJI_INSERT, @@ -93,6 +95,7 @@ const initialState = ImmutableMap({ quoted_status_id: null, quote_policy: 'public', default_quote_policy: 'public', // Set in hydration. + fetching_link: null, }); const initialPoll = ImmutableMap({ @@ -315,7 +318,11 @@ const calculateProgress = (loaded, total) => Math.min(Math.round((loaded / total /** @type {import('@reduxjs/toolkit').Reducer} */ export const composeReducer = (state = initialState, action) => { - if (changeUploadCompose.fulfilled.match(action)) { + if (changeComposeVisibility.match(action)) { + return state + .set('privacy', action.payload) + .set('idempotencyKey', uuid()); + } else if (changeUploadCompose.fulfilled.match(action)) { return state .set('is_changing_upload', false) .update('media_attachments', list => list.map(item => { @@ -331,15 +338,27 @@ export const composeReducer = (state = initialState, action) => { return state.set('is_changing_upload', false); } else if (quoteCompose.match(action)) { const status = action.payload; + const isDirect = state.get('privacy') === 'direct'; return state - .set('quoted_status_id', status.get('id')) + .set('quoted_status_id', isDirect ? null : status.get('id')) .set('spoiler', status.get('sensitive')) .set('spoiler_text', status.get('spoiler_text')) - .update('privacy', (visibility) => ['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private' ? 'private' : visibility); + .update('privacy', (visibility) => { + if (['public', 'unlisted'].includes(visibility) && status.get('visibility') === 'private') { + return 'private'; + } + return visibility; + }); } else if (quoteComposeCancel.match(action)) { return state.set('quoted_status_id', null); } else if (setComposeQuotePolicy.match(action)) { return state.set('quote_policy', action.payload); + } else if (pasteLinkCompose.pending.match(action)) { + return state.set('fetching_link', action.meta.requestId); + } else if (pasteLinkCompose.fulfilled.match(action) || pasteLinkCompose.rejected.match(action)) { + return action.meta.requestId === state.get('fetching_link') ? state.set('fetching_link', null) : state; + } else if (cancelPasteLinkCompose.match(action)) { + return state.set('fetching_link', null); } switch(action.type) { @@ -383,10 +402,6 @@ export const composeReducer = (state = initialState, action) => { return state .set('spoiler_text', action.text) .set('idempotencyKey', uuid()); - case COMPOSE_VISIBILITY_CHANGE: - return state - .set('privacy', action.value) - .set('idempotencyKey', uuid()); case COMPOSE_CHANGE: return state .set('text', action.text) @@ -403,6 +418,7 @@ export const composeReducer = (state = initialState, action) => { map.set('caretPosition', null); map.set('preselectDate', new Date()); map.set('idempotencyKey', uuid()); + map.set('quoted_status_id', null); map.update('media_attachments', list => list.filter(media => media.get('unattached'))); diff --git a/app/javascript/mastodon/reducers/polls.ts b/app/javascript/mastodon/reducers/polls.ts index aadf6741c13..ac0917bd201 100644 --- a/app/javascript/mastodon/reducers/polls.ts +++ b/app/javascript/mastodon/reducers/polls.ts @@ -1,7 +1,6 @@ import type { Reducer } from '@reduxjs/toolkit'; import { importPolls } from 'mastodon/actions/importer/polls'; -import { makeEmojiMap } from 'mastodon/models/custom_emoji'; import { createPollOptionTranslationFromServerJSON } from 'mastodon/models/poll'; import type { Poll } from 'mastodon/models/poll'; @@ -20,16 +19,11 @@ const statusTranslateSuccess = (state: PollsState, pollTranslation?: Poll) => { if (!poll) return; - const emojiMap = makeEmojiMap(poll.emojis); - pollTranslation.options.forEach((item, index) => { const option = poll.options[index]; if (!option) return; - option.translation = createPollOptionTranslationFromServerJSON( - item, - emojiMap, - ); + option.translation = createPollOptionTranslationFromServerJSON(item); }); }; diff --git a/app/javascript/mastodon/store/typed_functions.ts b/app/javascript/mastodon/store/typed_functions.ts index 4d7341b0c82..5ceb05909f0 100644 --- a/app/javascript/mastodon/store/typed_functions.ts +++ b/app/javascript/mastodon/store/typed_functions.ts @@ -42,7 +42,7 @@ interface AppThunkConfig { } export type AppThunkApi = Pick< GetThunkAPI, - 'getState' | 'dispatch' + 'getState' | 'dispatch' | 'requestId' >; interface AppThunkOptions { @@ -60,7 +60,7 @@ type AppThunk = ( type AppThunkCreator = ( arg: Arg, - api: AppThunkApi, + api: Pick, extra?: ExtraArg, ) => Returned; @@ -143,10 +143,10 @@ export function createAsyncThunk( name, async ( arg: Arg, - { getState, dispatch, fulfillWithValue, rejectWithValue }, + { getState, dispatch, requestId, fulfillWithValue, rejectWithValue }, ) => { try { - const result = await creator(arg, { dispatch, getState }); + const result = await creator(arg, { dispatch, getState, requestId }); return fulfillWithValue(result, { useLoadingBar: options.useLoadingBar, @@ -280,10 +280,11 @@ export function createDataLoadingThunk< return createAsyncThunk( name, - async (arg, { getState, dispatch }) => { + async (arg, { getState, dispatch, requestId }) => { const data = await loadData(arg, { dispatch, getState, + requestId, }); if (!onData) return data as Returned; @@ -291,6 +292,7 @@ export function createDataLoadingThunk< const result = await onData(data, { dispatch, getState, + requestId, discardLoadData: discardLoadDataInPayload, actionArg: arg, }); diff --git a/app/javascript/mastodon/stream.js b/app/javascript/mastodon/stream.js index 59b2fd75828..27fbc25ba5e 100644 --- a/app/javascript/mastodon/stream.js +++ b/app/javascript/mastodon/stream.js @@ -138,10 +138,15 @@ const channelNameWithInlineParams = (channelName, params) => { return `${channelName}&${Object.keys(params).map(key => `${key}=${params[key]}`).join('&')}`; }; +/** + * @typedef {import('mastodon/store').AppDispatch} Dispatch + * @typedef {import('mastodon/store').GetState} GetState + */ + /** * @param {string} channelName * @param {Object.} params - * @param {function(Function, Function): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks + * @param {function(Dispatch, GetState): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks * @returns {function(): void} */ // @ts-expect-error @@ -229,7 +234,7 @@ const handleEventSourceMessage = (e, received) => { * @param {string} streamingAPIBaseURL * @param {string} accessToken * @param {string} channelName - * @param {{ connected: Function, received: function(StreamEvent): void, disconnected: Function, reconnected: Function }} callbacks + * @param {{ connected: function(): void, received: function(StreamEvent): void, disconnected: function(): void, reconnected: function(): void }} callbacks * @returns {WebSocketClient | EventSource} */ const createConnection = (streamingAPIBaseURL, accessToken, channelName, { connected, received, disconnected, reconnected }) => { @@ -242,12 +247,9 @@ const createConnection = (streamingAPIBaseURL, accessToken, channelName, { conne // @ts-expect-error const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken); - // @ts-expect-error ws.onopen = connected; ws.onmessage = e => received(JSON.parse(e.data)); - // @ts-expect-error ws.onclose = disconnected; - // @ts-expect-error ws.onreconnect = reconnected; return ws; diff --git a/app/javascript/mastodon/utils/environment.ts b/app/javascript/mastodon/utils/environment.ts index aa125b09221..95075454f23 100644 --- a/app/javascript/mastodon/utils/environment.ts +++ b/app/javascript/mastodon/utils/environment.ts @@ -12,16 +12,8 @@ export function isProduction() { else return import.meta.env.PROD; } -export type Features = 'modern_emojis' | 'fasp'; +export type Features = 'fasp' | 'http_message_signatures'; export function isFeatureEnabled(feature: Features) { return initialState?.features.includes(feature) ?? false; } - -export function isModernEmojiEnabled() { - try { - return isFeatureEnabled('modern_emojis'); - } catch { - return false; - } -} diff --git a/app/javascript/material-icons/400-24px/audio.svg b/app/javascript/material-icons/400-24px/audio.svg new file mode 100644 index 00000000000..417e47c18fe --- /dev/null +++ b/app/javascript/material-icons/400-24px/audio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 6a5008909db..b5cb56d4254 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1309,6 +1309,10 @@ a.sparkline { line-height: 1; width: 100%; animation: skeleton 1.2s ease-in-out infinite; + + .reduce-motion & { + animation: none; + } } @keyframes skeleton { diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index d403a33e1e8..238fbe2be32 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -775,16 +775,43 @@ padding: 8px; } - &__preview { + &__preview, + &__visualizer { position: absolute; width: 100%; height: 100%; - border-radius: 6px; z-index: -1; top: 0; + } + + &__preview { + border-radius: 6px; inset-inline-start: 0; } + &__visualizer { + padding: 16px; + box-sizing: border-box; + + .audio-player__visualizer { + margin: 0 auto; + display: block; + height: 100%; + } + + .icon { + position: absolute; + top: 50%; + inset-inline-start: 50%; + transform: translate(-50%, -50%); + opacity: 0.75; + color: var(--player-foreground-color); + filter: var(--overlay-icon-shadow); + width: 48px; + height: 48px; + } + } + &__thumbnail { width: 100%; height: 100%; @@ -1101,7 +1128,8 @@ font-size: inherit; vertical-align: middle; object-fit: contain; - margin: -0.2ex 0.15em 0; + margin: -0.2ex 0.15em 0.2ex; + width: 16px; height: 16px; img { @@ -1143,6 +1171,7 @@ } .emojione { + width: 20px; height: 20px; margin: -3px 0 0; } @@ -1360,11 +1389,12 @@ } } -.announcements__item__content { +.announcements__content { overflow-wrap: break-word; overflow-y: auto; .emojione { + width: 20px; height: 20px; margin: -3px 0 0; } @@ -1791,6 +1821,7 @@ line-height: 24px; .emojione { + width: 24px; height: 24px; margin: -1px 0 0; } @@ -2681,6 +2712,7 @@ a.account__display-name { outline-offset: -1px; border-radius: 8px; touch-action: none; + user-select: none; } &--zoomed-in { @@ -2986,6 +3018,7 @@ a.account__display-name { height: 100%; min-height: 100vh; min-height: 100dvh; + padding-inline: 10px; padding-bottom: env(safe-area-inset-bottom); &__pane { @@ -3148,20 +3181,21 @@ a.account__display-name { } .column__alert { + --alert-height: 54px; + position: sticky; bottom: 0; z-index: 10; box-sizing: border-box; display: grid; + grid-template-rows: minmax(var(--alert-height), max-content); + align-items: end; width: 100%; max-width: 360px; padding: 1rem; margin: auto auto 0; overflow: clip; - - &:empty { - padding: 0; - } + pointer-events: none; @media (max-width: #{$mobile-menu-breakpoint - 1}) { // Compensate for mobile menubar @@ -3172,6 +3206,7 @@ a.account__display-name { // Make all nested alerts occupy the same space // rather than stack grid-area: 1 / 1; + pointer-events: initial; } } @@ -3325,6 +3360,7 @@ a.account__display-name { min-height: 100vh; min-height: 100dvh; gap: 0; + padding-inline: 0; } .columns-area__panels__pane--navigational { @@ -4027,6 +4063,7 @@ a.account__display-name { background: lighten($ui-highlight-color, 5%); } +.follow_requests-unlocked_explanation, .switch-to-advanced { color: $light-text-color; background-color: $ui-base-color; @@ -4037,7 +4074,7 @@ a.account__display-name { font-size: 13px; line-height: 18px; - .switch-to-advanced__toggle { + a { color: $ui-button-tertiary-color; font-weight: bold; } @@ -4449,13 +4486,19 @@ a.status-card { box-sizing: border-box; text-decoration: none; - &:hover { - background: var(--on-surface-color); + &--large { + padding-block: 32px; } - &:focus-visible { - outline: 2px solid $ui-button-focus-outline-color; - outline-offset: -2px; + &:is(button) { + &:hover { + background: var(--on-surface-color); + } + + &:focus-visible { + outline: 2px solid $ui-button-focus-outline-color; + outline-offset: -2px; + } } .icon { @@ -5219,8 +5262,7 @@ a.status-card { } } -.empty-column-indicator, -.follow_requests-unlocked_explanation { +.empty-column-indicator { color: $dark-text-color; text-align: center; padding: 20px; @@ -5259,10 +5301,8 @@ a.status-card { } .follow_requests-unlocked_explanation { - background: var(--surface-background-color); - border-bottom: 1px solid var(--background-border-color); - contain: initial; - flex-grow: 0; + margin: 16px; + margin-bottom: 0; } .error-column { @@ -5741,6 +5781,34 @@ a.status-card { } } +.visibility-modal { + &__quote-warning { + color: var(--nested-card-text); + background: + /* This is a bit of a silly hack for layering two background colours + * since --nested-card-background is too transparent for a tooltip */ + linear-gradient( + var(--nested-card-background), + var(--nested-card-background) + ), + linear-gradient(var(--background-color), var(--background-color)); + border: var(--nested-card-border); + padding: 16px; + border-radius: 4px; + + h3 { + font-weight: 500; + margin-bottom: 4px; + color: $darker-text-color; + } + + p { + font-size: 0.8em; + color: $dark-text-color; + } + } +} + .visibility-dropdown { &__overlay[data-popper-placement] { z-index: 9999; @@ -6094,6 +6162,7 @@ a.status-card { width: 100%; height: 100%; position: relative; + touch-action: pan-y; &__buttons { position: absolute; @@ -6129,11 +6198,19 @@ a.status-card { } .media-modal__closer { + display: flex; position: absolute; top: 0; inset-inline-start: 0; inset-inline-end: 0; bottom: 0; + align-items: center; + justify-content: space-around; // If set to center, the fullscreen image overlay is misaligned. + + > div { + flex-shrink: 0; + overflow: auto; + } } .media-modal__navigation { @@ -7085,6 +7162,7 @@ a.status-card { line-height: 24px; .emojione { + width: 24px; height: 24px; margin: -1px 0 0; } @@ -8416,6 +8494,7 @@ noscript { margin-bottom: 16px; .emojione { + width: 22px; height: 22px; } @@ -8927,10 +9006,25 @@ noscript { } .announcements { - background: lighten($ui-base-color, 8%); - font-size: 13px; - display: flex; - align-items: flex-end; + width: calc(100% - 124px); + flex: 0 0 auto; + position: relative; + overflow: hidden; + + .layout-multiple-columns & { + width: 100%; + } + + @media screen and (max-width: (124px + 300px)) { + width: 100%; + } + + &__root { + background: lighten($ui-base-color, 8%); + font-size: 13px; + display: flex; + align-items: flex-end; + } &__mastodon { width: 124px; @@ -8941,19 +9035,16 @@ noscript { } } - &__container { - width: calc(100% - 124px); - flex: 0 0 auto; - position: relative; - - @media screen and (max-width: (124px + 300px)) { - width: 100%; - } + &__slides { + display: flex; + flex-wrap: nowrap; + align-items: start; } - &__item { + &__slide { box-sizing: border-box; width: 100%; + flex: 0 0 100%; padding: 15px; position: relative; font-size: 15px; @@ -8962,26 +9053,25 @@ noscript { font-weight: 400; max-height: 50vh; overflow: hidden; - display: flex; flex-direction: column; + } - &__range { - display: block; - font-weight: 500; - margin-bottom: 10px; - padding-inline-end: 18px; - } + &__range { + display: block; + font-weight: 500; + margin-bottom: 10px; + padding-inline-end: 18px; + } - &__unread { - position: absolute; - top: 19px; - inset-inline-end: 19px; - display: block; - background: $highlight-text-color; - border-radius: 50%; - width: 0.625rem; - height: 0.625rem; - } + &__unread { + position: absolute; + top: 19px; + inset-inline-end: 19px; + display: block; + background: $highlight-text-color; + border-radius: 50%; + width: 0.625rem; + height: 0.625rem; } &__pagination { @@ -8992,6 +9082,7 @@ noscript { inset-inline-end: 0; display: flex; align-items: center; + z-index: 1; } } @@ -11583,4 +11674,10 @@ noscript { height: 16px; } } + + &__pagination { + display: flex; + align-items: center; + gap: 4px; + } } diff --git a/app/javascript/testing/api.ts b/app/javascript/testing/api.ts index dd45b7e7b6b..096d2ce30ea 100644 --- a/app/javascript/testing/api.ts +++ b/app/javascript/testing/api.ts @@ -53,6 +53,7 @@ export const mockHandlers = { const locale = toSupportedLocale(params.locale); action('fetching emoji data')(locale); const { default: data } = (await import( + /* @vite-ignore */ `emojibase-data/${locale}/compact.json` )) as { default: CompactEmoji[]; diff --git a/app/javascript/types/dom.d.ts b/app/javascript/types/dom.d.ts new file mode 100644 index 00000000000..fcb1b0346fa --- /dev/null +++ b/app/javascript/types/dom.d.ts @@ -0,0 +1,6 @@ +declare namespace React { + interface HTMLAttributes extends AriaAttributes, DOMAttributes { + // Add inert attribute support, which is only in React 19.2. See: https://github.com/facebook/react/pull/24730 + inert?: ''; + } +} diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 3d52c9a56ca..43c7bb1fe71 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class ActivityPub::Activity::Create < ActivityPub::Activity - include FormattingHelper - def perform @account.schedule_refresh_if_stale! @@ -99,9 +97,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity uri: @status_parser.uri, url: @status_parser.url || @status_parser.uri, account: @account, - text: converted_object_type? ? converted_text : (@status_parser.text || ''), + text: @status_parser.processed_text, language: @status_parser.language, - spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''), + spoiler_text: @status_parser.processed_spoiler_text, created_at: @status_parser.created_at, edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil, override_timestamps: @options[:override_timestamps], @@ -405,18 +403,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity value_or_id(@object['inReplyTo']) end - def converted_text - [formatted_title, @status_parser.spoiler_text.presence, formatted_url].compact.join("\n\n") - end - - def formatted_title - "

#{@status_parser.title}

" if @status_parser.title.present? - end - - def formatted_url - linkify(@status_parser.url || @status_parser.uri) - end - def unsupported_media_type?(mime_type) mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type) end diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb index 15025ca5e71..f158626dbbf 100644 --- a/app/lib/activitypub/activity/update.rb +++ b/app/lib/activitypub/activity/update.rb @@ -8,10 +8,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity if equals_or_includes_any?(@object['type'], %w(Application Group Organization Person Service)) update_account - elsif equals_or_includes_any?(@object['type'], %w(Note Question)) + elsif supported_object_type? || converted_object_type? update_status - elsif converted_object_type? - Status.find_by(uri: object_uri, account_id: @account.id) end end diff --git a/app/lib/activitypub/dereferencer.rb b/app/lib/activitypub/dereferencer.rb index eb99842828c..4c4eb3a6090 100644 --- a/app/lib/activitypub/dereferencer.rb +++ b/app/lib/activitypub/dereferencer.rb @@ -44,7 +44,7 @@ class ActivityPub::Dereferencer req = Request.new(:get, uri) - req.add_headers('Accept' => 'application/activity+json, application/ld+json') + req.add_headers('Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/activity+json') req.add_headers(headers) if headers req.on_behalf_of(@signature_actor) if @signature_actor diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index 57e6cb926c4..83f03756ef3 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class ActivityPub::Parser::StatusParser + include FormattingHelper include JsonLdHelper NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze @@ -44,6 +45,16 @@ class ActivityPub::Parser::StatusParser end end + def processed_text + return text || '' unless converted_object_type? + + [ + title.presence && "

#{title}

", + spoiler_text.presence, + linkify(url || uri), + ].compact.join("\n\n") + end + def spoiler_text if @object['summary'].present? @object['summary'] @@ -52,6 +63,12 @@ class ActivityPub::Parser::StatusParser end end + def processed_spoiler_text + return '' if converted_object_type? + + spoiler_text || '' + end + def title if @object['name'].present? @object['name'] @@ -145,6 +162,10 @@ class ActivityPub::Parser::StatusParser as_array(@object['quoteAuthorization']).first end + def converted_object_type? + equals_or_includes_any?(@object['type'], ActivityPub::Activity::CONVERTED_TYPES) + end + private def quote_subpolicy(subpolicy) diff --git a/app/lib/request.rb b/app/lib/request.rb index 4858aa4bc24..dd65b481d88 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -65,6 +65,7 @@ class Request # and 5s timeout on the TLS handshake, meaning the worst case should take # about 15s in total TIMEOUT = { connect_timeout: 5, read_timeout: 10, write_timeout: 10, read_deadline: 30 }.freeze + SAFE_PRESERVED_CHARS = '+,' include RoutingHelper @@ -72,7 +73,7 @@ class Request raise ArgumentError if url.blank? @verb = verb - @url = Addressable::URI.parse(url).normalize + @url = normalize_preserving_url_encodings(url, SAFE_PRESERVED_CHARS) @http_client = options.delete(:http_client) @allow_local = options.delete(:allow_local) @options = { @@ -148,6 +149,34 @@ class Request private + # Using code from https://github.com/sporkmonger/addressable/blob/3450895887d0a1770660d8831d1b6fcfed9bd9d6/lib/addressable/uri.rb#L1609-L1635 + # to preserve some URL Encodings while normalizing + def normalize_preserving_url_encodings(url, preserved_chars = SAFE_PRESERVED_CHARS, *flags) + original_uri = Addressable::URI.parse(url) + normalized_uri = original_uri.normalize + + if original_uri.query + modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup + modified_query_class.sub!('\\&', '').sub!('\\;', '') + + pairs = original_uri.query.split('&', -1) + pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted) + pairs.sort! if flags.include?(:sorted) + + normalized_query = pairs.map do |pair| + Addressable::URI.normalize_component( + pair, + modified_query_class, + preserved_chars + ) + end.join('&') + + normalized_uri.query = normalized_query == '' ? nil : normalized_query + end + + normalized_uri + end + def set_common_headers! @headers['User-Agent'] = Mastodon::Version.user_agent @headers['Host'] = @url.host diff --git a/app/lib/signed_request.rb b/app/lib/signed_request.rb index d8887d9596a..1cea2955f52 100644 --- a/app/lib/signed_request.rb +++ b/app/lib/signed_request.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class SignedRequest - include DomainControlHelper - EXPIRATION_WINDOW_LIMIT = 12.hours CLOCK_SKEW_MARGIN = 1.hour diff --git a/app/lib/status_cache_hydrator.rb b/app/lib/status_cache_hydrator.rb index b6a5e370564..be425e1291c 100644 --- a/app/lib/status_cache_hydrator.rb +++ b/app/lib/status_cache_hydrator.rb @@ -98,12 +98,12 @@ class StatusCacheHydrator if quote.quoted_status.nil? payload[nested ? :quoted_status_id : :quoted_status] = nil payload[:state] = 'deleted' - elsif StatusFilter.new(quote.quoted_status, Account.find_by(id: account_id)).filtered_for_quote? - payload[nested ? :quoted_status_id : :quoted_status] = nil - payload[:state] = 'unauthorized' else - payload[:state] = 'accepted' - if nested + filter_state = StatusFilter.new(quote.quoted_status, Account.find_by(id: account_id)).filter_state_for_quote + payload[:state] = filter_state || 'accepted' + if filter_state == 'unauthorized' + payload[nested ? :quoted_status_id : :quoted_status] = nil + elsif nested payload[:quoted_status_id] = quote.quoted_status_id&.to_s else payload[:quoted_status] = StatusCacheHydrator.new(quote.quoted_status).hydrate(account_id, nested: true) diff --git a/app/lib/status_filter.rb b/app/lib/status_filter.rb index dbf7d28b69c..2313e1407df 100644 --- a/app/lib/status_filter.rb +++ b/app/lib/status_filter.rb @@ -15,10 +15,18 @@ class StatusFilter blocked_by_policy? || (account_present? && filtered_status?) || silenced_account? end - def filtered_for_quote? - return false if !account.nil? && account.id == status.account_id - - blocked_by_policy? || (account_present? && filtered_status?) + def filter_state_for_quote + if !account.nil? && account.id == status.account_id + nil + elsif blocked_by_policy? + 'unauthorized' + elsif account_present? && blocking_domain? + 'blocked_domain' + elsif account_present? && blocking_account? + 'blocked_account' + elsif account_present? && muting_account? + 'muted_account' + end end private diff --git a/app/models/concerns/status/fetch_replies_concern.rb b/app/models/concerns/status/fetch_replies_concern.rb index 7ab46481747..6d65fe41cb8 100644 --- a/app/models/concerns/status/fetch_replies_concern.rb +++ b/app/models/concerns/status/fetch_replies_concern.rb @@ -4,8 +4,10 @@ module Status::FetchRepliesConcern extend ActiveSupport::Concern # debounce fetching all replies to minimize DoS - FETCH_REPLIES_COOLDOWN_MINUTES = (ENV['FETCH_REPLIES_COOLDOWN_MINUTES'] || 15).to_i.minutes - FETCH_REPLIES_INITIAL_WAIT_MINUTES = (ENV['FETCH_REPLIES_INITIAL_WAIT_MINUTES'] || 5).to_i.minutes + # Period to wait between fetching replies + FETCH_REPLIES_COOLDOWN_MINUTES = 15.minutes + # Period to wait after a post is first created before fetching its replies + FETCH_REPLIES_INITIAL_WAIT_MINUTES = 5.minutes included do scope :created_recently, -> { where(created_at: FETCH_REPLIES_INITIAL_WAIT_MINUTES.ago..) } diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 926995f02e3..af4ad38ae94 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -87,6 +87,7 @@ class Form::AdminSettings DOMAIN_BLOCK_AUDIENCES = %w(disabled users all).freeze REGISTRATION_MODES = %w(open approved none).freeze FEED_ACCESS_MODES = %w(public authenticated disabled).freeze + ALTERNATE_FEED_ACCESS_MODES = %w(public authenticated).freeze LANDING_PAGE = %w(trends about local_feed).freeze attr_accessor(*KEYS) @@ -99,7 +100,7 @@ class Form::AdminSettings validates :show_domain_blocks_rationale, inclusion: { in: DOMAIN_BLOCK_AUDIENCES }, if: -> { defined?(@show_domain_blocks_rationale) } validates :local_live_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@local_live_feed_access) } validates :remote_live_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@remote_live_feed_access) } - validates :local_topic_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@local_topic_feed_access) } + validates :local_topic_feed_access, inclusion: { in: ALTERNATE_FEED_ACCESS_MODES }, if: -> { defined?(@local_topic_feed_access) } validates :remote_topic_feed_access, inclusion: { in: FEED_ACCESS_MODES }, if: -> { defined?(@remote_topic_feed_access) } validates :media_cache_retention_period, :content_cache_retention_period, :backups_retention_period, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@media_cache_retention_period) || defined?(@content_cache_retention_period) || defined?(@backups_retention_period) } validates :min_age, numericality: { only_integer: true }, allow_blank: true, if: -> { defined?(@min_age) } diff --git a/app/models/tag.rb b/app/models/tag.rb index 1514a44005f..f9eb6bfd33e 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -41,7 +41,7 @@ class Tag < ApplicationRecord HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)' HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}".freeze - HASHTAG_RE = %r{(? @status.edited_at) @@ -170,8 +169,8 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end def update_immediate_attributes! - @status.text = @status_parser.text || '' - @status.spoiler_text = @status_parser.spoiler_text || '' + @status.text = @status_parser.processed_text + @status.spoiler_text = @status_parser.processed_spoiler_text @status.sensitive = @account.sensitized? || @status_parser.sensitive || false @status.language = @status_parser.language @@ -351,7 +350,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService end def expected_type? - equals_or_includes_any?(@json['type'], %w(Note Question)) + equals_or_includes_any?(@json['type'], ActivityPub::Activity::SUPPORTED_TYPES) || equals_or_includes_any?(@json['type'], ActivityPub::Activity::CONVERTED_TYPES) end def record_previous_edit! diff --git a/app/services/fetch_resource_service.rb b/app/services/fetch_resource_service.rb index 2382e126bd3..666eccb9ce5 100644 --- a/app/services/fetch_resource_service.rb +++ b/app/services/fetch_resource_service.rb @@ -3,7 +3,7 @@ class FetchResourceService < BaseService include JsonLdHelper - ACCEPT_HEADER = 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams", text/html;q=0.1' + ACCEPT_HEADER = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/activity+json, text/html;q=0.1' ACTIVITY_STREAM_LINK_TYPES = ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].freeze attr_reader :response_code diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index c55a54df378..3e4a715225a 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -80,6 +80,7 @@ class PostStatusService < BaseService @status = @account.statuses.new(status_attributes) process_mentions_service.call(@status, save_records: false) safeguard_mentions!(@status) + safeguard_private_mention_quote!(@status) attach_quote!(@status) antispam = Antispam.new(@status) @@ -92,6 +93,16 @@ class PostStatusService < BaseService end end + def safeguard_private_mention_quote!(status) + return if @quoted_status.nil? || @visibility.to_sym != :direct + + # The mentions array test here is awkward because the relationship is not persisted at this time + return if @quoted_status.account_id == @account.id || status.mentions.to_a.any? { |mention| mention.account_id == @quoted_status.account_id && !mention.silent } + + status.errors.add(:base, I18n.t('statuses.errors.quoted_user_not_mentioned')) + raise ActiveRecord::RecordInvalid, status + end + def attach_quote!(status) return if @quoted_status.nil? @@ -114,6 +125,7 @@ class PostStatusService < BaseService def schedule_status! status_for_validation = @account.statuses.build(status_attributes) + safeguard_private_mention_quote!(status_for_validation) antispam = Antispam.new(status_for_validation) antispam.local_preflight_check! diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml index 1f5f81348e2..082f71e69e6 100644 --- a/app/views/accounts/show.html.haml +++ b/app/views/accounts/show.html.haml @@ -6,6 +6,7 @@ %link{ rel: 'alternate', type: 'application/rss+xml', href: rss_url }/ %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@account) }/ + %link{ rel: 'alternate', type: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', href: ActivityPub::TagManager.instance.uri_for(@account) }/ - @account.fields.select(&:verifiable?).each do |field| %link{ rel: 'me', type: 'text/html', href: field.value }/ diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index 1272419c332..04c242597d3 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -43,7 +43,7 @@ .fields-row .fields-row__column.fields-row__column-6.fields-group = f.input :local_topic_feed_access, - collection: f.object.class::FEED_ACCESS_MODES, + collection: f.object.class::ALTERNATE_FEED_ACCESS_MODES, include_blank: false, label_method: ->(mode) { I18n.t("admin.settings.feed_access.modes.#{mode}") }, wrapper: :with_label diff --git a/app/views/settings/migrations/show.html.haml b/app/views/settings/migrations/show.html.haml index 31f7d5e58d7..296075a28ed 100644 --- a/app/views/settings/migrations/show.html.haml +++ b/app/views/settings/migrations/show.html.haml @@ -30,8 +30,8 @@ %ul.hint %li.warning-hint= t('migrations.warning.followers') - %li.warning-hint= t('migrations.warning.redirect') %li.warning-hint= t('migrations.warning.other_data') + %li.warning-hint= t('migrations.warning.redirect') %li.warning-hint= t('migrations.warning.backreference_required') %li.warning-hint= t('migrations.warning.cooldown') %li.warning-hint= t('migrations.warning.disabled_account') diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml index e1ee4ac0b00..e6e96f97d55 100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@ -31,16 +31,15 @@ label: I18n.t('simple_form.labels.defaults.setting_theme'), wrapper: :with_label - - if Mastodon::Feature.modern_emojis_enabled? - .fields-group - = f.simple_fields_for :settings, current_user.settings do |ff| - = ff.input :'web.emoji_style', - collection: %w(auto twemoji native), - include_blank: false, - hint: I18n.t('simple_form.hints.defaults.setting_emoji_style'), - label: I18n.t('simple_form.labels.defaults.setting_emoji_style'), - label_method: ->(emoji_style) { I18n.t("emoji_styles.#{emoji_style}", default: emoji_style) }, - wrapper: :with_label + .fields-group + = f.simple_fields_for :settings, current_user.settings do |ff| + = ff.input :'web.emoji_style', + collection: %w(auto twemoji native), + include_blank: false, + hint: I18n.t('simple_form.hints.defaults.setting_emoji_style'), + label: I18n.t('simple_form.labels.defaults.setting_emoji_style'), + label_method: ->(emoji_style) { I18n.t("emoji_styles.#{emoji_style}", default: emoji_style) }, + wrapper: :with_label - unless I18n.locale == :en .flash-message.translation-prompt diff --git a/app/views/settings/privacy/show.html.haml b/app/views/settings/privacy/show.html.haml index f7241cfb246..553d6e80af4 100644 --- a/app/views/settings/privacy/show.html.haml +++ b/app/views/settings/privacy/show.html.haml @@ -2,8 +2,7 @@ = t('privacy.title') - content_for :heading do - %h2= t('settings.profile') - = render partial: 'settings/shared/profile_navigation' + %h2= t('privacy.title') = simple_form_for @account, url: settings_privacy_path do |f| = render 'shared/error_messages', object: @account diff --git a/app/views/settings/shared/_profile_navigation.html.haml b/app/views/settings/shared/_profile_navigation.html.haml index 2f81cb5cfdc..9da8af9c2ee 100644 --- a/app/views/settings/shared/_profile_navigation.html.haml +++ b/app/views/settings/shared/_profile_navigation.html.haml @@ -2,6 +2,5 @@ = render_navigation renderer: :links do |primary| :ruby primary.item :edit_profile, safe_join([material_symbol('person'), t('settings.edit_profile')]), settings_profile_path - primary.item :privacy_reach, safe_join([material_symbol('lock'), t('privacy.title')]), settings_privacy_path primary.item :verification, safe_join([material_symbol('check'), t('verification.verification')]), settings_verification_path primary.item :featured_tags, safe_join([material_symbol('tag'), t('settings.featured_tags')]), settings_featured_tags_path diff --git a/app/views/statuses/show.html.haml b/app/views/statuses/show.html.haml index c530b77c331..ca2628bbcda 100644 --- a/app/views/statuses/show.html.haml +++ b/app/views/statuses/show.html.haml @@ -8,6 +8,7 @@ %link{ rel: 'alternate', type: 'application/json+oembed', href: api_oembed_url(url: short_account_status_url(@account, @status), format: 'json') }/ %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@status) }/ + %link{ rel: 'alternate', type: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', href: ActivityPub::TagManager.instance.uri_for(@status) }/ = opengraph 'og:site_name', site_title = opengraph 'og:type', 'article' diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml index bce1b4aa4d1..0746e42cbcf 100644 --- a/app/views/tags/show.html.haml +++ b/app/views/tags/show.html.haml @@ -1,6 +1,7 @@ - content_for :header_tags do %link{ rel: :alternate, type: 'application/rss+xml', href: tag_url(@tag) }/ %link{ rel: :alternate, type: 'application/activity+json', href: tag_url(@tag) }/ + %link{ rel: :alternate, type: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', href: tag_url(@tag) }/ %meta{ name: 'robots', content: 'noindex' }/ = render partial: 'shared/og' diff --git a/app/workers/activitypub/fetch_all_replies_worker.rb b/app/workers/activitypub/fetch_all_replies_worker.rb index 128bfe7e8af..2e91a3e95b8 100644 --- a/app/workers/activitypub/fetch_all_replies_worker.rb +++ b/app/workers/activitypub/fetch_all_replies_worker.rb @@ -11,9 +11,10 @@ class ActivityPub::FetchAllRepliesWorker sidekiq_options queue: 'pull', retry: 3 - # Global max replies to fetch per request (all replies, recursively) - MAX_REPLIES = (ENV['FETCH_REPLIES_MAX_GLOBAL'] || 1000).to_i - MAX_PAGES = (ENV['FETCH_REPLIES_MAX_PAGES'] || 500).to_i + # Max number of replies to fetch - total, recursively through a whole reply tree + MAX_REPLIES = 1000 + # Max number of replies Collection pages to fetch - total + MAX_PAGES = 500 def perform(root_status_id, options = {}) @batch = WorkerBatch.new(options['batch_id']) diff --git a/app/workers/activitypub/refetch_and_verify_quote_worker.rb b/app/workers/activitypub/refetch_and_verify_quote_worker.rb index e2df0231030..1a8dd40541e 100644 --- a/app/workers/activitypub/refetch_and_verify_quote_worker.rb +++ b/app/workers/activitypub/refetch_and_verify_quote_worker.rb @@ -5,7 +5,7 @@ class ActivityPub::RefetchAndVerifyQuoteWorker include ExponentialBackoff include JsonLdHelper - sidekiq_options queue: 'pull', retry: 3 + sidekiq_options queue: 'pull', retry: 5 def perform(quote_id, quoted_uri, options = {}) quote = Quote.find(quote_id) diff --git a/config/locales/an.yml b/config/locales/an.yml index ca7d6b8254d..b7806dd17d9 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -1191,7 +1191,6 @@ an: disabled_account: La tuya cuenta actual no será completament utilizable dimpués. Manimenos, tendrás acceso a la exportación de datos asinas como a la reactivación. followers: Esta acción migrará a totz los seguidores d'a cuenta actual a la nueva cuenta only_redirect_html: Alternativament, nomás puetz meter una redirección en o tuyo perfil. - other_data: No se moverán atros datos automaticament redirect: Lo perfil d'a tuya cuenta actual s'actualizará con un aviso de redirección y será excluyiu d'as busquedas moderation: title: Moderación diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 8774b0227ad..25c53fadee1 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1798,7 +1798,6 @@ ar: disabled_account: لن يكون حسابك الحالي قابلا للاستخدام بشكل كامل بعد ذلك، ولكن سيكون لديك حق الوصول إلى تصدير البيانات وكذلك إعادة التنشيط. followers: تقوم هذه العملية بنقل كافة المُتابِعين مِن الحساب الحالي إلى الحساب الجديد only_redirect_html: بدلاً من ذلك، يمكنك أن تضع فقط إعادة توجيه على ملفك الشخصي. - other_data: لن يتم نقل أية بيانات أخرى تلقائيا redirect: سيتم تحديث ملفك التعريفي الحالي مع إشعار إعادة توجيه وسيتم استبعاده من عمليات البحث moderation: title: الإشراف diff --git a/config/locales/be.yml b/config/locales/be.yml index 2a9a61c3472..003902d8ecc 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1750,7 +1750,7 @@ be: disabled_account: Пасля гэтага ваш бягучы ўліковы запіс не будзе цалкам даступны. Аднак у вас будзе доступ да экспарту даных, а таксама да паўторнай актывацыі. followers: Гэтае дзеянне будзе «пераносіць» усіх падпісчыкаў з бягучага ўліковага запісу на новы only_redirect_html: Альбо вы можаце толькі наладзіць перанакіраванне на ваш профіль. - other_data: Ніякія іншыя даныя не будуць перамешчаны аўтаматычна + other_data: Сістэма не будзе аўтаматычна перамяшчаць астатнія даныя (у тым ліку Вашы допісы і спіс уліковых запісаў, на якія Вы падпісаліся) redirect: Профіль вашага бягучага ўліковага запісу будзе абноўлены з паведамленнем аб перанакіраванні і выключаны з пошуку moderation: title: Мадэрацыя @@ -2015,6 +2015,7 @@ be: errors: in_reply_not_found: Здаецца, допіс, на які вы спрабуеце адказаць, не існуе. quoted_status_not_found: Выглядае, што допісу, які Вы спрабуеце цытаваць, не існуе. + quoted_user_not_mentioned: Немагчыма цытаваць незгаданага карыстальніка ў допісе прыватнага згадвання. over_character_limit: перавышаная колькасць сімвалаў у %{max} pin_errors: direct: Допісы, бачныя толькі згаданым карыстальнікам, нельга замацаваць diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 251eef9cb9b..2f77de72628 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1651,7 +1651,6 @@ bg: disabled_account: След това, текущият ви акаунт няма да бъде напълно използваем. Но ще имате достъп до експортиране на данни от него и до повторното му активиране. followers: Това действие ще премести всички последователи от текущия към новия акаунт only_redirect_html: Иначе, можете да просто да оставите пренасочване в своя профил. - other_data: Други данни няма да бъдат автоматично пренасочени redirect: Текущият профил на вашия акаунт ще бъде обновен с бележка за пренасочване и няма да се появява при търсене moderation: title: Mодериране diff --git a/config/locales/ca.yml b/config/locales/ca.yml index caa472fb399..aa1cc97dbb8 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -586,6 +586,7 @@ ca: created_msg: S'ha creat la nota de moderació d'instància. description_html: Mireu i deixeu notes per als altres moderadors i per a un mateix destroyed_msg: S'ha esborrat la nota de moderació d'instància. + placeholder: Informació sobre aquesta instància, accions preses o qualsevol altra cosa que us pugui ajudar a moderar-la en el futur. title: Notes de moderació private_comment: Comentari privat public_comment: Comentari públic @@ -895,6 +896,7 @@ ca: no_status_selected: No s’han canviat els estatus perquè cap no ha estat seleccionat open: Obre la publicació original_status: Publicació original + quotes: Cites reblogs: Impulsos replied_to_html: En resposta a %{acct_link} status_changed: Publicació canviada @@ -902,6 +904,7 @@ ca: title: Publicacions del compte - @%{name} trending: Tendència view_publicly: Vegeu en públic + view_quoted_post: Veure la publicació citada visibility: Visibilitat with_media: Amb contingut multimèdia strikes: @@ -1577,6 +1580,13 @@ ca: expires_at: Caduca uses: Usos title: Convidar persones + link_preview: + author_html: Per %{name} + potentially_sensitive_content: + action: Feu clic per a mostrar + confirm_visit: Esteu segur que voleu obrir aquest enllaç? + hide_button: Amaga + label: Contingut potencialment sensible lists: errors: limit: Has assolit la quantitat màxima de llistes @@ -1641,7 +1651,6 @@ ca: disabled_account: El teu compte actual no serà plenament utilitzable després. Tanmateix, tindràs accés a exportació de dades així com reactivació. followers: Aquesta acció mourà tots els seguidors des de l'actual al compte nou only_redirect_html: Alternativament, pots posar només una redirecció en el teu perfil. - other_data: Cap altre dada serà moguda automàticament redirect: El perfil del teu compte actual serà actualitzat amb un avís de redirecció i serà exclòs de les cerques moderation: title: Moderació @@ -1885,6 +1894,9 @@ ca: other: "%{count} vídeos" boosted_from_html: Impulsat des de %{acct_link} content_warning: 'Avís de contingut: %{warning}' + content_warnings: + hide: Amaga la publicació + show: Mostra'n més default_language: El mateix que a la llengua de la interfície disallowed_hashtags: one: 'conté una etiqueta no permesa: %{tags}' @@ -1899,10 +1911,15 @@ ca: limit: Ja has fixat el màxim nombre de tuts ownership: No es pot fixar el tut d'algú altre reblog: No es pot fixar un impuls + quote_error: + not_available: Publicació no disponible + pending_approval: Publicació pendent + revoked: Publicació eliminada per l'autor quote_policies: followers: Només seguidors nobody: Només jo public: Qualsevol + quote_post_author: S'ha citat una publicació de @%{acct} title: '%{name}: "%{quote}"' visibilities: direct: Menció privada diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 8494e6e46ff..4129efd0459 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -773,7 +773,6 @@ ckb: disabled_account: هەژمارەی ئێستات دوای ئەوە بە تەواوی بەکارناهیێت. هەرچۆنێک بێت، تۆ دەستگەیشتنت دەبێت بۆ ناردنەدەرەوەی داتا و هەروەها دووبارە کاراکردنەوە. followers: ئەم کردارە هەموو شوێنکەوتوانی هەژمارەی ئێستا دەگوازێتەوە بۆ هەژمارەی نوێ only_redirect_html: ئێوە دەتانن هەژمارەکەی خۆتان بیخەنە سەر هەژمارەیەکی دیکە. - other_data: هیچ داتایەکی تر بە خۆکارانە ناگوێزرێتەوە redirect: پرۆفایلی هەژمارەی ئێستات بە ئاگادارییەکی ئاراستەکەراوە نوێ دەکرێتەوە و دووردەکەویت لە گەڕانەکان moderation: title: بەڕێوەبردن diff --git a/config/locales/co.yml b/config/locales/co.yml index 268377d7dd3..e86e96846e3 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -738,7 +738,6 @@ co: disabled_account: U contu attuale ùn puderà più esse utilizatu dop'à st'azzione. Però, puderete accede à a spurtazione di dati o riattivà u contu. followers: St'azzione hà da spiazzà tutti l'abbunati di u contu attuale nant'à u novu contu only_redirect_html: Pudete ancu mette solu una ridirezzione nant'à u vostru prufile. - other_data: L'altri dati ùn saranu micca autumaticamente trasferiti redirect: U prufile di u vostru contu attuale sarà messu à ghjornu cù una nutificazione di ridirezzione è sarà sclusu di e ricerche moderation: title: Muderazione diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 9c69ab84491..e270b500eca 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1750,7 +1750,7 @@ cs: disabled_account: Váš aktuální účet nebude poté zcela použitelný. Budete však mít přístup k datovým exportům a budete ho moci znovu aktivovat. followers: Touto akcí přesunete všechny sledující z aktuálního účtu na nový only_redirect_html: Alternativně můžete nastavit pouze přesměrování na váš profil. - other_data: Žádná další data nebudou přesunuta automaticky + other_data: Žádná další data nebudou automaticky přesunuta (včetně vašich příspěvků a seznamu účtů, které sledujete) redirect: Profil vašeho aktuálního účtu bude aktualizován s oznámením o přesměrování a bude vyloučen z výsledků hledání moderation: title: Moderování @@ -2015,6 +2015,7 @@ cs: errors: in_reply_not_found: Příspěvek, na který se pokoušíte odpovědět, neexistuje. quoted_status_not_found: Zdá se, že příspěvek, který se pokoušíte citovat neexistuje. + quoted_user_not_mentioned: Nelze citovat nezmíněného uživatele v soukromé zmínce. over_character_limit: byl překročen limit %{max} znaků pin_errors: direct: Příspěvky viditelné pouze zmíněným uživatelům nelze připnout diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 4b875b2c02c..ad153fdac31 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -911,6 +911,11 @@ cy: authenticated: Defnyddwyr dilys yn unig disabled: Gofyn am rôl defnyddiwr penodol public: Pawb + landing_page: + values: + about: Ynghylch + local_feed: Ffrwd leol + trends: Trendiau registrations: moderation_recommandation: Gwnewch yn siŵr bod gennych chi dîm cymedroli digonol ac adweithiol cyn i chi agor cofrestriadau i bawb! preamble: Rheoli pwy all greu cyfrif ar eich gweinydd. @@ -1823,7 +1828,7 @@ cy: disabled_account: Ni fydd modd defnyddio'ch cyfrif cyfredol yn llawn wedyn. Fodd bynnag, bydd gennych fynediad i allforio data yn ogystal ag ail agor. followers: Bydd y weithred hon yn symud yr holl ddilynwyr o'r cyfrif cyfredol i'r cyfrif newydd only_redirect_html: Fel arall, dim ond ailgyfeiriad y gallwch chi ei osod ar eich proffil. - other_data: Ni fydd unrhyw data arall yn cael ei symud yn awtomatig + other_data: Bydd dim ddata arall yn cael ei symud yn awtomatig (gan gynnwys eich postiadau a'r rhestr o gyfrifon rydych chi'n eu dilyn) redirect: Bydd proffil eich cyfrif presennol yn cael ei diweddaru gyda hysbysiad ailgyfeirio ac yn cael ei eithrio o chwiliadau moderation: title: Cymedroil @@ -2096,6 +2101,7 @@ cy: errors: in_reply_not_found: Nid yw'n ymddangos bod y postiad rydych chi'n ceisio ei ateb yn bodoli. quoted_status_not_found: Nid yw'n ymddangos bod y postiad rydych chi'n ceisio'i ddyfynnu yn bodoli. + quoted_user_not_mentioned: Does dim modd dyfynnu defnyddiwr heb ei grybwyll mewn postiad Crybwyll Preifat. over_character_limit: wedi mynd y tu hwnt i'r terfyn nodau o %{max} pin_errors: direct: Nid oes modd pinio postiadau sy'n weladwy i ddefnyddwyr a grybwyllwyd yn unig diff --git a/config/locales/da.yml b/config/locales/da.yml index c6a30afaaee..b2a078b4846 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1672,7 +1672,7 @@ da: disabled_account: Efterfølgende er din nuværende konto ikke fuldt funktionsdygtig, der er dog adgang til dataeksport samt genaktivering. followers: Denne handling vil flytte alle følgere fra den aktuelle konto til den nye konto only_redirect_html: Alternativt kan du oprette en omdirigering for din profil alene. - other_data: Ingen øvrige data flyttes automatisk + other_data: Ingen andre data flyttes automatisk (herunder dine indlæg og listen over konti, du følger) redirect: Din nuværende kontoprofil opdateres med en omdirigeringsnotits og ekskluderes fra søgninger moderation: title: Moderation @@ -1929,6 +1929,7 @@ da: errors: in_reply_not_found: Indlægget, der forsøges besvaret, ser ikke ud til at eksistere. quoted_status_not_found: Indlægget, du forsøger at citere, ser ikke ud til at eksistere. + quoted_user_not_mentioned: Kan ikke citere en ikke-omtalt bruger i et privat omtale-indlæg. over_character_limit: grænsen på %{max} tegn overskredet pin_errors: direct: Indlæg, som kun kan ses af omtalte brugere, kan ikke fastgøres diff --git a/config/locales/de.yml b/config/locales/de.yml index e4a579575f1..d5c35ccfa21 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -796,6 +796,8 @@ de: view_dashboard_description: Gewährt Benutzer*innen den Zugriff auf das Dashboard und verschiedene Metriken view_devops: DevOps view_devops_description: Erlaubt es Benutzer*innen, auf die Sidekiq- und pgHero-Dashboards zuzugreifen + view_feeds: Live-Feeds und Hashtags anzeigen + view_feeds_description: Ermöglicht Nutzer*innen unabhängig von den Servereinstellungen den Zugriff auf die Live-Feeds und Hashtags title: Rollen rules: add_new: Regel hinzufügen @@ -851,10 +853,13 @@ de: feed_access: modes: authenticated: Nur authentifizierte Nutzer*innen + disabled: Bestimmte Rolle erforderlich public: Alle landing_page: values: about: Über + local_feed: Lokaler Feed + trends: Trends registrations: moderation_recommandation: Bitte vergewissere dich, dass du ein geeignetes und reaktionsschnelles Moderationsteam hast, bevor du die Registrierungen uneingeschränkt zulässt! preamble: Lege fest, wer auf deinem Server ein Konto erstellen darf. @@ -1193,7 +1198,8 @@ de: appearance: advanced_settings: Erweiterte Einstellungen animations_and_accessibility: Animationen und Barrierefreiheit - boosting_preferences: Teilen-Einstellungen + boosting_preferences: Teilen + boosting_preferences_info_html: "Tipp: Umschalttaste + Klick beim Teilen-Symbol %{icon} wird den Beitrag immer sofort teilen." discovery: Entdecken localization: body: Mastodon wird von Freiwilligen übersetzt. @@ -1666,7 +1672,7 @@ de: disabled_account: Dein altes Konto ist nur noch eingeschränkt verwendbar. Du kannst jedoch deine Daten exportieren und das Konto wieder reaktivieren. followers: Alle Follower werden vom alten zum neuen Konto übertragen only_redirect_html: Alternativ kannst du auch nur eine Weiterleitung zu deinem neuen Konto einrichten, ohne die Follower zu übertragen. - other_data: Keine anderen Daten werden automatisch zum neuen Konto übertragen + other_data: Es werden keine weiteren Daten automatisch übertragen (einschließlich deiner Beiträge und der Liste der Konten, denen du folgst) redirect: Dein altes Konto wird einen Hinweis erhalten, dass du umgezogen bist. Außerdem wird das Profil von Suchanfragen ausgeschlossen moderation: title: Moderation @@ -1756,7 +1762,7 @@ de: too_many_options: darf nicht mehr als %{max} Auswahlfelder enthalten vote: Abstimmen posting_defaults: - explanation: Diese Einstellungen werden standardmäßig für neue Beiträge verwendet. Du kannst sie auch beim Verfassen eines Beitrags individuell anpassen. + explanation: Diese Einstellungen werden standardmäßig für neue Beiträge verwendet, aber du kannst sie für jeden Beitrag individuell anpassen. preferences: other: Erweitert posting_defaults: Standardeinstellungen für Beiträge @@ -1923,6 +1929,7 @@ de: errors: in_reply_not_found: Der Beitrag, auf den du antworten möchtest, scheint nicht zu existieren. quoted_status_not_found: Der Beitrag, den du zitieren möchtest, scheint nicht zu existieren. + quoted_user_not_mentioned: Nur ein erwähntes Profil kann in einer privaten Erwähnung zitiert werden. over_character_limit: Begrenzung von %{max} Zeichen überschritten pin_errors: direct: Beiträge, die nur für erwähnte Profile sichtbar sind, können nicht angeheftet werden diff --git a/config/locales/devise.ca.yml b/config/locales/devise.ca.yml index f228843863e..924c9cf7fdf 100644 --- a/config/locales/devise.ca.yml +++ b/config/locales/devise.ca.yml @@ -9,6 +9,7 @@ ca: Si us plau, verifica la carpeta de la brossa si no l'has rebut. failure: already_authenticated: Ja t'has registrat. + closed_registrations: El vostre intent de registre s'ha blocat per una política de xarxa. Si creieu que és un error, contacteu %{email}. inactive: El teu compte encara no s'ha activat. invalid: "%{authentication_keys} o contrasenya no són vàlids." last_attempt: Tens un intent més abans no es bloqui el teu compte. diff --git a/config/locales/devise.eu.yml b/config/locales/devise.eu.yml index 4b3bbea8c6b..7189901fd18 100644 --- a/config/locales/devise.eu.yml +++ b/config/locales/devise.eu.yml @@ -7,6 +7,7 @@ eu: send_paranoid_instructions: Zure eposta helbidea aurretik gure datu-basean bazegoen, eposta mezu bat jasoko duzu minutu batzuk barru zure eposta helbidea berresteko argibideekin. Begiratu zure spam karpetan ez baduzu mezua jaso. failure: already_authenticated: Saioa hasi duzu jada. + closed_registrations: Zure erregistro saiakera blokeatu egin da, sareko politika baten ondorioz. Erabaki okerra dela uste baduzu, kontaktatu %{email}. inactive: Zure kontua ez dago oraindik aktibo. invalid: Baliogabeko %{authentication_keys} edo pasahitza. last_attempt: Saiakera bat geratzen zaizu zure kontua giltzapetu aurretik. diff --git a/config/locales/devise.fa.yml b/config/locales/devise.fa.yml index 71cd7699fe2..31001d2c1a7 100644 --- a/config/locales/devise.fa.yml +++ b/config/locales/devise.fa.yml @@ -7,6 +7,7 @@ fa: send_paranoid_instructions: اگر نشانی رایانامه‌تان در پایگاه داده‌مان وجود داشته باشد، تا دقایقی دیگر تا دقایقی دیگر رایانامه‌ای با دستورالعمل تأیید نشانی رایانامه‌تان دریافت خواهید کرد. اگر این رایانامه را نگرفتید، لطفاً پوشهٔ هرزنامه‌هایتان را بررسی کنید. failure: already_authenticated: از پیش وارد شده‌اید. + closed_registrations: تلاشتان برا ثبت‌نام به دلیل سیاست شبکه مسدود شد. اگر باور دارید خطایی رخ داده با %{email} تماس بگیرید. inactive: هنوز حسابتان فعّال نشده. invalid: "%{authentication_keys} یا گذرواژه نامعتبر." last_attempt: پیش از آن که حساب شما قفل شود، یک فرصت دیگر دارید. diff --git a/config/locales/devise.fr-CA.yml b/config/locales/devise.fr-CA.yml index fbe549743c9..1acb5d1770f 100644 --- a/config/locales/devise.fr-CA.yml +++ b/config/locales/devise.fr-CA.yml @@ -7,6 +7,7 @@ fr-CA: send_paranoid_instructions: Si votre adresse courriel existe dans notre base de données, vous allez recevoir un courriel contenant les instructions de confirmation de votre adresse. Veuillez vérifier votre dossier de pourriels si vous n'avez pas reçu ce message. failure: already_authenticated: Vous êtes déjà connecté·e. + closed_registrations: Votre tentative d'inscription a été bloquée en raison d'une politique de réseau. Si vous pensez qu'il s'agit d'une erreur, contactez %{email}. inactive: Votre compte n’est pas encore activé. invalid: "%{authentication_keys} ou mot de passe invalide." last_attempt: Vous avez droit à une dernière tentative avant que votre compte ne soit verrouillé. diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml index 10c49b22e66..c2147fcf9fc 100644 --- a/config/locales/devise.fr.yml +++ b/config/locales/devise.fr.yml @@ -7,6 +7,7 @@ fr: send_paranoid_instructions: Si votre adresse électronique existe dans notre base de données, vous allez bientôt recevoir un courriel contenant les instructions de confirmation de votre compte. Veuillez, dans le cas où vous ne recevriez pas ce message, vérifier votre dossier d’indésirables. failure: already_authenticated: Vous êtes déjà connecté⋅e. + closed_registrations: Votre tentative d'inscription a été bloquée en raison d'une politique de réseau. Si vous pensez qu'il s'agit d'une erreur, contactez %{email}. inactive: Votre compte n’est pas encore activé. invalid: "%{authentication_keys} ou mot de passe invalide." last_attempt: Vous avez droit à une dernière tentative avant que votre compte ne soit verrouillé. diff --git a/config/locales/devise.ko.yml b/config/locales/devise.ko.yml index b57ef9684c6..ebdd3ed4499 100644 --- a/config/locales/devise.ko.yml +++ b/config/locales/devise.ko.yml @@ -7,6 +7,7 @@ ko: send_paranoid_instructions: 이메일 주소가 저희 데이터베이스에 있는 경우, 몇 분 내에 이메일 주소를 확인하는 방법에 대한 안내가 포함된 이메일을 받을 수 있습니다. 이 이메일을 받지 못했다면 스팸 폴더를 확인해 주세요. failure: already_authenticated: 이미 로그인 된 상태입니다. + closed_registrations: 네트워크 정책에 의해 가입 시도가 차단되었습니다. 오류라고 생각된다면 %{email}에 문의해주세요. inactive: 계정이 아직 활성화 되지 않았습니다. invalid: 올바르지 않은 %{authentication_keys} 혹은 암호입니다. last_attempt: 계정이 잠기기까지 한 번의 시도가 남았습니다. diff --git a/config/locales/devise.zh-CN.yml b/config/locales/devise.zh-CN.yml index 6fd47ec3564..ffffe0cbf46 100644 --- a/config/locales/devise.zh-CN.yml +++ b/config/locales/devise.zh-CN.yml @@ -7,7 +7,7 @@ zh-CN: send_paranoid_instructions: 如果你的邮箱地址存在于我们的数据库中,你将在几分钟内收到一封邮件,内含如何验证邮箱地址的指引。如果你没有收到这封邮件,请检查你的垃圾邮件文件夹。 failure: already_authenticated: 你已登录。 - closed_registrations: 您的注册因为网络政策已被阻止。若您认为这是错误,请联系 %{email}。 + closed_registrations: 你的注册因为网络政策已被阻止。若您认为这是错误,请联系 %{email}。 inactive: 你还没有激活账号。 invalid: "%{authentication_keys} 无效或密码错误。" last_attempt: 你只有最后一次尝试机会,若未通过,账号将被锁定。 diff --git a/config/locales/doorkeeper.et.yml b/config/locales/doorkeeper.et.yml index b21afa9a791..df10f9a0cec 100644 --- a/config/locales/doorkeeper.et.yml +++ b/config/locales/doorkeeper.et.yml @@ -130,11 +130,11 @@ et: crypto: Otspunktkrüpteerimine favourites: Lemmikud filters: Filtrid - follow: Jälgitavad, Vaigistatud ja Blokeeritud + follow: Jälgitavad, summutamised ja blokeerimised follows: Jälgimised lists: Loetelud media: Lisatud meedia - mutes: Vaigistused + mutes: Summutamised notifications: Teavitused profile: Sinu Mastodoni profiil push: Tõuketeated @@ -177,7 +177,7 @@ et: read:filters: näha su filtreid read:follows: näha su jälgimisi read:lists: näha su loetelusid - read:mutes: näha su vaigistusi + read:mutes: näha su summutamisi read:notifications: näha teateid read:reports: näha teavitusi read:search: otsida sinu nimel @@ -186,13 +186,13 @@ et: write:accounts: muuta profiili write:blocks: kontode ja domeenide blokeerimine write:bookmarks: lisada postitusele järjehoidja - write:conversations: vaigista ja kustuta vestlused + write:conversations: summuta ja kustuta vestlused write:favourites: lisada postitusi lemmikuks write:filters: luua filtreid write:follows: jälgida inimesi write:lists: luua loetelusid write:media: üles laadida meediafaile - write:mutes: vaigista inimesi ja vestluseid + write:mutes: summuta inimesi ja vestluseid write:notifications: tühjendada teateid write:reports: teavitada teistest inimestest write:statuses: avaldada postitusi diff --git a/config/locales/el.yml b/config/locales/el.yml index 0f2339b1cad..397c03b402e 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1672,7 +1672,7 @@ el: disabled_account: Ο τρέχων λογαριασμός σου δε θα είναι πλήρως ενεργός μετά. Πάντως θα έχεις πρόσβαση στην εξαγωγή δεδομένων καθώς και στην επανενεργοποίηση. followers: Αυτή η ενέργεια θα μεταφέρει όλους τους ακόλουθούς σου από τον τρέχοντα λογαριασμό στον νέο λογαριασμό only_redirect_html: Εναλλακτικά, μπορείς απλά να προσθέσεις μια ανακατατεύθυνση στο προφίλ σου. - other_data: Κανένα άλλο δεδομένο δε θα μεταφερθεί αυτόματα + other_data: Δεν θα μετακινηθούν αυτόματα άλλα δεδομένα (συμπεριλαμβανομένου των αναρτήσεων σας και της λίστας των λογαριασμών που ακολουθείτε) redirect: Το προφίλ του τρέχοντος λογαριασμού σου θα ενημερωθεί με μια σημείωση ανακατεύθυνσης και θα εξαιρεθεί από τα αποτελέσματα αναζητήσεων moderation: title: Συντονισμός @@ -1929,6 +1929,7 @@ el: errors: in_reply_not_found: Η ανάρτηση στην οποία προσπαθείς να απαντήσεις δεν φαίνεται να υπάρχει. quoted_status_not_found: Η ανάρτηση την οποία προσπαθείς να παραθέσεις δεν φαίνεται να υπάρχει. + quoted_user_not_mentioned: Δεν είναι δυνατή η παράθεση ενός μη επισημασμένου χρήστη σε μια ανάρτηση Ιδιωτικής επισήμανσης. over_character_limit: υπέρβαση μέγιστου ορίου %{max} χαρακτήρων pin_errors: direct: Αναρτήσεις που είναι ορατές μόνο στους αναφερόμενους χρήστες δεν μπορούν να καρφιτσωθούν diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index eda44eaa904..3da8ee0541a 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1622,7 +1622,6 @@ en-GB: disabled_account: Your current account will not be fully usable afterwards. However, you will have access to data export as well as re-activation. followers: This action will move all followers from the current account to the new account only_redirect_html: Alternatively, you can only put up a redirect on your profile. - other_data: No other data will be moved automatically redirect: Your current account's profile will be updated with a redirect notice and be excluded from searches moderation: title: Moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index b647c5ddffc..ffe6028e729 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1672,7 +1672,7 @@ en: disabled_account: Your current account will not be fully usable afterwards. However, you will have access to data export as well as re-activation. followers: This action will move all followers from the current account to the new account only_redirect_html: Alternatively, you can only put up a redirect on your profile. - other_data: No other data will be moved automatically + other_data: No other data will be moved automatically (including your posts and the list of accounts you follow) redirect: Your current account's profile will be updated with a redirect notice and be excluded from searches moderation: title: Moderation @@ -1930,6 +1930,7 @@ en: errors: in_reply_not_found: The post you are trying to reply to does not appear to exist. quoted_status_not_found: The post you are trying to quote does not appear to exist. + quoted_user_not_mentioned: Cannot quote a non-mentioned user in a Private Mention post. over_character_limit: character limit of %{max} exceeded pin_errors: direct: Posts that are only visible to mentioned users cannot be pinned diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 008a72ecffd..0ae35b55646 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1642,7 +1642,6 @@ eo: disabled_account: Via nuna konto ne estos tute uzebla poste. followers: Ĉi tiu ago translokigos ĉi tiujn sekvantojn de la nuna konto al la nova konto only_redirect_html: Alie, vi povas nur aldoni alidirekton en via profilo. - other_data: Neniu alia datumo estos movita aŭtomate redirect: Via nuna profilo de konto ĝisdatigotas kun alidirektoavizo moderation: title: Moderigado diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 12973554690..a2f3e7dcfd6 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -857,8 +857,8 @@ es-AR: public: Todos landing_page: values: - about: Acerca de - local_feed: Cronología local + about: Información + local_feed: Línea temporal local trends: Tendencias registrations: moderation_recommandation: Por favor, ¡asegurate de tener un equipo de moderación adecuado y reactivo antes de abrir los registros a todos! @@ -1672,7 +1672,7 @@ es-AR: disabled_account: Tu cuenta actual no será completamente utilizable luego de esto. Sin embargo, tendrás acceso a la exportación de datos así como a la reactivación. followers: Esta acción mudará a todos los seguidores de la cuenta actual a la cuenta nueva only_redirect_html: Alternativamente, podés poner solamente un redireccionamiento en tu perfil. - other_data: No se mudarán otros datos automáticamente + other_data: No se mudarán otros datos automáticamente (esto incluye tus mensajes y la lista de cuentas que seguís) redirect: El perfil de tu cuenta actual se actualizará con un aviso de redireccionamiento y será excluido de las búsquedas moderation: title: Moderación @@ -1929,6 +1929,7 @@ es-AR: errors: in_reply_not_found: El mensaje al que intentás responder no existe. quoted_status_not_found: El mensaje al que intentás citar parece que no existe. + quoted_user_not_mentioned: No se puede citar a un usuario no mencionado en un mensaje de mención privada. over_character_limit: se excedió el límite de %{max} caracteres pin_errors: direct: Los mensajes que sólo son visibles para los usuarios mencionados no pueden ser fijados diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index ecfc06836ef..08f1b33c7a0 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1672,7 +1672,7 @@ es-MX: disabled_account: Tu cuenta actual no será completamente utilizable después. Sin embargo, tendrás acceso a la exportación de datos así como a la reactivación. followers: Esta acción migrará a todos los seguidores de la cuenta actual a la nueva cuenta only_redirect_html: Alternativamente, solo puedes poner una redirección en tu perfil. - other_data: No se moverán otros datos automáticamente + other_data: Ningún otro dato se moverá automáticamente (esto incluye tus publicaciones y la lista de cuentas que sigues) redirect: El perfil de tu cuenta actual se actualizará con un aviso de redirección y será excluido de las búsquedas moderation: title: Moderación @@ -1929,6 +1929,7 @@ es-MX: errors: in_reply_not_found: La publicación a la que estás intentando responder no existe. quoted_status_not_found: La publicación que intentas citar no parece existir. + quoted_user_not_mentioned: No se puede citar a un usuario no mencionado en una Mención Privada. over_character_limit: Límite de caracteres de %{max} superado pin_errors: direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse diff --git a/config/locales/es.yml b/config/locales/es.yml index da0d9ac34bb..9dcb73e0061 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -517,13 +517,13 @@ es: title: Fediverse Auxiliary Service Providers (Proveedores de Servicio Auxiliares del Fediverso) title: FASP follow_recommendations: - description_html: "Las recomendaciones de cuentas ayudan a los nuevos usuarios a encontrar rápidamente contenido interesante. Cuando un usuario no ha interactuado con otros lo suficiente como para suscitar recomendaciones personalizadas de cuentas a las que seguir, en su lugar se le recomiendan estas cuentas. Se recalculan diariamente a partir de una mezcla de cuentas con el mayor número de interacciones recientes y con el mayor número de seguidores locales con un idioma determinado." + description_html: "Las recomendaciones de cuentas a las que seguir ayudan a los nuevos usuarios a encontrar rápidamente contenido interesante. Cuando un usuario no ha interactuado con otros lo suficiente como para formar recomendaciones personalizadas de seguimiento, estas cuentas se recomiendan en su lugar. Se recalculan diariamente a partir de una mezcla de cuentas con las interacciones más recientes y el mayor número de seguidores para un idioma determinado." language: Para el idioma status: Estado - suppress: Suprimir recomendación de cuentas + suppress: Eliminar recomendación de cuentas a las que seguir suppressed: Suprimida - title: Recomendaciones de cuentas - unsuppress: Restaurar recomendaciones de cuentas + title: Recomendaciones de cuentas a las que seguir + unsuppress: Restaurar recomendaciones de cuentas a las que seguir instances: audit_log: title: Registros de auditoría recientes @@ -1672,7 +1672,7 @@ es: disabled_account: Tu cuenta actual no será completamente utilizable después. Sin embargo, tendrás acceso a la exportación de datos así como a la reactivación. followers: Esta acción migrará a todos los seguidores de la cuenta actual a la nueva cuenta only_redirect_html: Alternativamente, solo puedes poner una redirección en tu perfil. - other_data: No se moverán otros datos automáticamente + other_data: Ningún otro dato se moverá automáticamente (esto incluye tus publicaciones y la lista de cuentas que sigues) redirect: El perfil de tu cuenta actual se actualizará con un aviso de redirección y será excluido de las búsquedas moderation: title: Moderación @@ -1929,6 +1929,7 @@ es: errors: in_reply_not_found: La publicación a la que intentas responder no existe. quoted_status_not_found: La publicación que estás intentando citar no parece existir. + quoted_user_not_mentioned: No se puede citar a un usuario no mencionado en una Mención Privada. over_character_limit: Límite de caracteres de %{max} superado pin_errors: direct: Las publicaciones que son visibles solo para los usuarios mencionados no pueden fijarse diff --git a/config/locales/et.yml b/config/locales/et.yml index 8f56b20b1af..99643e60859 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -796,6 +796,8 @@ et: view_dashboard_description: Lubab kasutajail pääseda ligi töölauale ja erinevale meetrikale view_devops: DevOps view_devops_description: Lubab kasutajail ligipääsu Sidekiq ja pgHero töölaudadele + view_feeds: Vaata postituste ja teemade voogu reaalajas + view_feeds_description: Sõltumata serveri seadistustest luba kasutajatel vaadata postituste ja teemade voogu reaalajas title: Rollid rules: add_new: Lisa reegel @@ -855,6 +857,8 @@ et: public: Kõik landing_page: values: + about: Teave + local_feed: Kohalik sisuvoog trends: Trendid registrations: moderation_recommandation: Enne kõigi jaoks registreerimise avamist veendu, et oleks olemas adekvaatne ja reageerimisvalmis modereerijaskond! @@ -1419,7 +1423,7 @@ et: csv: CSV domain_blocks: Domeeni blokeeringud lists: Loetelud - mutes: Oled vaigistanud + mutes: Oled summutanud storage: Meedia hoidla featured_tags: add_new: Lisa uus @@ -1524,8 +1528,8 @@ et: one: Oled asendamas oma loetelusid faili %{filename} sisuga. Uutesse loeteludesse lisatakse kuni %{count} konto. other: Oled asendamas oma loetelusid faili %{filename} sisuga. Uutesse loeteludesse lisatakse kuni %{count} kontot. muting_html: - one: Oled asendamas oma vaigistatud kontode loetelu faili %{filename} sisuga, milles on kuni %{count} konto. - other: Oled asendamas oma vaigistatud kontode loetelu faili %{filename} sisuga, milles on kuni %{count} kontot. + one: Oled asendamas oma summutatud kontode loetelu faili %{filename} sisuga, milles on kuni %{count} konto. + other: Oled asendamas oma summutatud kontode loetelu faili %{filename} sisuga, milles on kuni %{count} kontot. preambles: blocking_html: one: Oled blokeerimas kuni %{count} konto failist %{filename}. @@ -1543,8 +1547,8 @@ et: one: Oled lisamas oma loeteludesse failist %{filename} kuni %{count} konto. Kui pole loetelusi, kuhu lisada, luuakse uued loetelud. other: Oled lisamas oma loeteludesse failist %{filename} kuni %{count} kontot. Kui pole loetelusi, kuhu lisada, luuakse uued loetelud. muting_html: - one: Oled vaigistamas kuni %{count} konto failist %{filename}. - other: Oled vaigistamas kuni %{count} kontot failist %{filename}. + one: Oled summutamas kuni %{count} konto failist %{filename}. + other: Oled summutamas kuni %{count} kontot failist %{filename}. preface: Saad importida mistahes andmeid, mis on eksporditud teisest serverist. Näiteks nimekirja inimestest, keda jälgid ja keda blokeerid. recent_imports: Viimati imporditud states: @@ -1561,11 +1565,11 @@ et: domain_blocking: Blokeeritud domeenide importimine following: Jälgitavate kontode importimine lists: Loetelude importimine - muting: Vaigistatud kontode importimine + muting: Summutatud kontode importimine type: Importimise tüüp type_groups: constructive: Jälgimised & Järjehoidjad - destructive: Blokeerimised & Vaigistamised + destructive: Blokeerimised & summutamised types: blocking: Blokeeringute nimekiri bookmarks: Järjehoidjad @@ -1668,13 +1672,13 @@ et: disabled_account: Pärast seda ei ole konto täielik kasutamine võimalik. Säilib andmete eksportimise ja konto taasaktiveerimise võimalus. followers: See käsklus kolib kõik siinse konto jälgijad üle sinu uue konto jälgijateks only_redirect_html: Teine võimalus on märkida konto ümbersuunatuks. - other_data: Muid kontoandmeid, sh postitusi automaatselt üle ei kanta + other_data: Muid andmeid ei teisaldata automaatselt (sealhulgas sinu postitusi ja jälgitavate kasutajakontode loendit) redirect: Konto eemaldatakse avalikust kataloogist ja märgitakse profiilis ümbersuunatuks moderation: title: Modereerimine move_handler: carry_blocks_over_text: See kasutaja kolis kontolt %{acct}, mis oli keelatud. - carry_mutes_over_text: Kasutaja kolis ümber kontolt %{acct}, mis oli vaigistatud. + carry_mutes_over_text: Kasutaja kolis ümber kontolt %{acct}, mis oli summutatud. copy_account_note_text: 'Kasutaja kolis kontolt %{acct}, kus olid eelnevad märkmed tema kohta:' navigation: toggle_menu: Menüü lülimine @@ -1925,6 +1929,7 @@ et: errors: in_reply_not_found: Postitus, millele üritad vastata, ei näi enam eksisteerivat. quoted_status_not_found: Postitus, mida üritad tsiteerida, ei näi enam eksisteerivat. + quoted_user_not_mentioned: Privaatses mainimisega postituses ei saa tsiteerida mittemaninitud kasutajat. over_character_limit: tähtmärkide limiit %{max} ületatud pin_errors: direct: Ei saa kinnitada postitusi, mis on nähtavad vaid mainitud kasutajatele diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 242bfa51ae9..01976436977 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1488,7 +1488,6 @@ eu: disabled_account: Zure uneko kontua ezin izango da gero erabili. Hala ere, datua exporatu ahal izango dituzu, eta berriro aktibatu. followers: Ekintza honek jarraitzaile guztiak eramango ditu uneko kontutik kontu berrira only_redirect_html: Bestela, zure profilean birbideratze bat jar dezakezu. - other_data: Ez da beste daturik migratuko automatikoki redirect: Zure uneko kontuaren profila eguneratuko da birbideratze ohar batekin eta bilaketetatik kenduko da moderation: title: Moderazioa diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 92e305bcee3..85230296b22 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -1,35 +1,35 @@ --- fa: about: - about_mastodon_html: 'شبکه‌ی اجتماعی آینده: بدون تبلیغات، بدون شنود از طرف شرکت‌ها، طراحی اخلاق‌مدار، و معماری غیرمتمرکز! با ماستودون صاحب داده‌های خودتان باشید!' + about_mastodon_html: 'شبکهٔ اجتماعی آینده: بدون تبلیغ، بدون شنود شرکت‌ها، طراحی اخلاق مدار و معماری نامتمرکز! با ماستودون صاحب داده‌های خودتان باشید!' contact_missing: تنظیم نشده contact_unavailable: موجود نیست - hosted_on: ماستودون، میزبانی‌شده روی %{domain} + hosted_on: ماستودون میزبانی شده روی %{domain} title: درباره accounts: followers: - one: پیگیر - other: پیگیر + one: پی‌گیرنده + other: پی‌گیرنده following: پی می‌گیرد - instance_actor_flash: این حساب یک عامل مجازی است که به نمایندگی از خود کارساز استفاده می‌شود و نه هیچ یکی از کاربران. این حساب به منظور اتصال به فدراسیون استفاده می‌شود و نباید معلق شود. - last_active: آخرین فعالیت + instance_actor_flash: این حساب عاملی مجازیست که به نمایندگی از خود کارساز استفاده می‌شود و نه کاربری جداگانه. این حساب به منظور اتصال به فدراسیون استفاده می‌شود و نباید معلق شود. + last_active: آخرین فعّالیت link_verified_on: مالکیت این پیوند در %{date} بررسی شد - nothing_here: این‌جا چیزی نیست! + nothing_here: چیزی این‌جا نیست! pin_errors: following: باید کاربری که می‌خواهید پیشنهاد دهید را دنبال کرده باشید posts: one: فرسته other: فرسته‌ها posts_tab_heading: فرسته‌ها - self_follow_error: دنبال کردن حساب کاربری شما مجاز نیست + self_follow_error: پی‌گیری حساب خودتان مجاز نیست admin: account_actions: action: انجامِ کنش - already_silenced: این جساب از پیش محدود شده. - already_suspended: این جساب از پیش معلّق شده. + already_silenced: این حساب از پیش محدود شده. + already_suspended: این حساب از پیش معلّق شده. title: انجام کنش مدیریتی روی %{acct} account_moderation_notes: - create: افزودن یادداشت + create: گذاشتن یادداشت created_msg: یادداشت مدیر با موفقیت ساخته شد! destroyed_msg: یادداشت نظارتی با موفقیت نابود شد! accounts: @@ -796,6 +796,8 @@ fa: view_dashboard_description: اجازه به کاربران برای دسترسی به داشتبورد و سنجه‌های مختلف view_devops: دواپس view_devops_description: به کاربران امکان دسترسی به داشبورد Sidekiq و pgHero را می دهد + view_feeds: دیدن خوراک‌های موضوع و زنده + view_feeds_description: می‌گذارد کاربران فارغ از تنظیمات کارساز به خوراک‌های موضوع و زنده دسترسی داشته باشند title: نقش‌ها rules: add_new: افزودن قانون @@ -837,6 +839,7 @@ fa: title: درخواست خروج از اندیس‌گذاری پیش‌گزیدهٔ موتور جست‌وجو discovery: follow_recommendations: پیروی از پیشنهادها + preamble: ارائه محتوای جذّاب برای آغاز به کار کاربرانی که شاید کسی را روی ماستودون نشناسند ضروری است. واپایش چگونگی کار کردن ویژگی‌های کشف روی کارسازتان. privacy: محرمانگی profile_directory: شاخهٔ نمایه public_timelines: خط زمانی‌های عمومی @@ -847,6 +850,16 @@ fa: all: برای همه disabled: برای هیچ‌کدام users: برای کاربران محلی واردشده + feed_access: + modes: + authenticated: تنها کاربران تأیید شده + disabled: نیازمند نقش کاربری خاص + public: هرکسی + landing_page: + values: + about: درباره + local_feed: خوراک محلی + trends: داغ‌ها registrations: moderation_recommandation: لطفاً قبل از اینکه ثبت نام را برای همه باز کنید، مطمئن شوید که یک تیم نظارتی مناسب و واکنشی دارید! preamble: کنترل کنید چه کسی می تواند در سرور شما یک حساب ایجاد کند. @@ -900,6 +913,7 @@ fa: no_status_selected: هیچ فرسته‌ای تغییری نکرد زیرا هیچ‌کدام از آن‌ها انتخاب نشده بودند open: گشودن فرسته original_status: فرستهٔ اصلی + quotes: نقل‌ها reblogs: تقویت‌ها replied_to_html: به %{acct_link} پاسخ داد status_changed: فرسته تغییر کرد @@ -907,6 +921,7 @@ fa: title: پست‌های حساب - @%{name} trending: پرطرفدار view_publicly: مشاهده عمومی + view_quoted_post: دیدن فرستهٔ نقل شده visibility: نمایانی with_media: دارای عکس یا ویدیو strikes: @@ -1181,7 +1196,10 @@ fa: hint_html: اگر می‌خواهید از حساب دیگری به این حساب منتقل شوید، این‌جا می‌توانید یک نام مستعار بسازید که برای انتقال از حساب قدیمی به این حساب لازم است. این کار به تنهایی بی‌ضرر و قابل بازگشت است. فرایند انتقال حساب از حساب قدیمی آغاز خواهد شد. remove: حذف ارتباط نام مستعار appearance: + advanced_settings: تنظیمات پیش‌رفته animations_and_accessibility: پویانمایی‌های و دسترسی‌پذیری + boosting_preferences: ترجیحات تقویت + boosting_preferences_info_html: "نکته: فارغ از تنظیمات، تبدیل + کلیک روی %{icon} نقشک تقویت بلافاصله تقویت خواهد کرد." discovery: کاوش localization: body: ماستودون توسط داوطلبان ترجمه شده است. @@ -1583,6 +1601,13 @@ fa: expires_at: تاریخ انقضا uses: استفاده‌ها title: دعوت دیگران + link_preview: + author_html: به دست %{name} + potentially_sensitive_content: + action: زدن برای نمایش + confirm_visit: مطمئنید که می‌خواهید این پیوند را بگشایید؟ + hide_button: نهفتن + label: محتوای بالقوه حسّاس lists: errors: limit: به بیشینهٔ تعداد سیاهه‌ها رسیدید @@ -1647,7 +1672,7 @@ fa: disabled_account: حساب فعلی شما پس از این کار دیگر قابل استفاده نخواهد بود. شما فقط خواهید توانست داده‌های خود را بیرون ببرید یا حساب را دوباره فعال کنید. followers: این کار همهٔ پیگیران شما را از حساب فعلی به حساب تازه منتقل خواهد کرد only_redirect_html: شما همچنین می‌توانید حساب خود را به یک حساب دیگر اشاره دهید. - other_data: هیچ دادهٔ دیگری خودبه‌خود منتقل نخواهد شد + other_data: هیچ دادهٔ دیگری به صورت خودکار جابه‌جا نخواهد شد (از حمله فرسته‌هایتان و سیاههٔ حساب‌هایی که پی می‌گیرید) redirect: نمایهٔ حساب کنونیتان به حساب تازه اشاره خواهد کرد و از جست‌وجوها حذف خواهد شد moderation: title: مدیریت کاربران @@ -1735,6 +1760,9 @@ fa: self_vote: شما نمی توانید در نظرسنجی خودتان رای دهید too_few_options: حتماً باید بیش از یک گزینه داشته باشد too_many_options: نمی‌تواند بیشتر از %{max} گزینه داشته باشد + vote: رأی + posting_defaults: + explanation: این تنظیمات هنگام ایجاد فرسته به عنوان پیش‌گزیده استفاده خواهند شد؛ ولی می‌توانید در نویسنده برای هر فرسته تغییرش دهید. preferences: other: سایر تنظیمات posting_defaults: تنظیمات پیش‌فرض انتشار @@ -1890,6 +1918,9 @@ fa: other: "%{count} ویدیو" boosted_from_html: تقویت شده از طرف %{acct_link} content_warning: 'هشدا محتوا: %{warning}' + content_warnings: + hide: نهفتن فرسته + show: نمایش بیش‌تر default_language: همانند زبان واسط disallowed_hashtags: one: 'دارای برچسبی غیرمجاز: %{tags}' @@ -1898,16 +1929,30 @@ fa: errors: in_reply_not_found: به نظر نمی‌رسد وضعیتی که می‌خواهید به آن پاسخ دهید، وجود داشته باشد. quoted_status_not_found: به نظر نمی‌رسد فرسته‌ای که می‌خواهید نقلش کنید وجود داشته باشد. + quoted_user_not_mentioned: نمی‌توان کاربری اشاره نشده را در فرستهٔ اشارهٔ خصوصی نقل کرد. over_character_limit: از حد مجاز %{max} حرف فراتر رفتید pin_errors: direct: فرسته‌هایی که فقط برای کاربران اشاره شده نمایانند نمی‌توانند سنجاق شوند limit: از این بیشتر نمی‌شود نوشته‌های ثابت داشت ownership: نوشته‌های دیگران را نمی‌توان ثابت کرد reblog: تقویت نمی‌تواند سنجاق شود + quote_error: + not_available: فرسته ناموجود + pending_approval: فرسته منتظر + revoked: فرسته به دست نگارنده برداشته شد + quote_policies: + followers: تنها پی‌گیران + nobody: فقط من + public: هرکسی + quote_post_author: فرسته‌ای از %{acct} را نقل کرد title: "%{name}: «%{quote}»" visibilities: direct: اشاره خصوصی + private: تنها پی‌گیران public: عمومی + public_long: هرکسی داخل و خارج از ماستودون + unlisted: عمومی ساکت + unlisted_long: نهفته از نتیجه‌های جست‌وجوی ماستودون و خط‌های زمانی داغ و عمومی statuses_cleanup: enabled: حذف خودکار فرسته‌های قدیمی enabled_hint: فرسته‌هایتان را هنگام رسیدن به کرانهٔ سن خاصی به صورت خودکار حذف می‌کند، مگر این که با یکی از استثناهای زیر مطابق باشند diff --git a/config/locales/fi.yml b/config/locales/fi.yml index f52c34b082c..93d0b87433c 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -796,6 +796,8 @@ fi: view_dashboard_description: Sallii käyttäjille pääsyn koontinäyttöön ja erilaisiin mittareihin view_devops: DevOps view_devops_description: Sallii käyttäjille pääsyn Sidekiq- ja pgHero-hallintapaneeleihin + view_feeds: Näytä live- ja aihesyötteet + view_feeds_description: Sallii käyttäjien tarkastella live- ja aihesyötteitä palvelimen asetuksista riippumatta title: Roolit rules: add_new: Lisää sääntö @@ -837,11 +839,12 @@ fi: title: Jätä käyttäjät oletusarvoisesti hakukoneindeksoinnin ulkopuolelle discovery: follow_recommendations: Seurantasuositukset + preamble: Mielenkiintoisen sisällön esille tuominen on keskeistä perehdyttäessä uusia käyttäjiä, jotka eivät ehkä tunne ketään Mastodonissa. Hallitse, miten eri löydettävyysominaisuudet toimivat palvelimellasi. privacy: Yksityisyys profile_directory: Profiilihakemisto public_timelines: Julkiset aikajanat publish_statistics: Julkaise tilastot - title: Löytäminen + title: Löydettävyys trends: Trendit domain_blocks: all: Kaikille @@ -850,7 +853,13 @@ fi: feed_access: modes: authenticated: Vain todennetut käyttäjät + disabled: Vaadi tiettyä käyttäjäroolia public: Kaikki + landing_page: + values: + about: Tietoja + local_feed: Paikallinen syöte + trends: Trendit registrations: moderation_recommandation: Varmista, että sinulla on riittävä ja toimintavalmis joukko moderaattoreita, ennen kuin avaat rekisteröitymisen kaikille! preamble: Määritä, kuka voi luoda tilin palvelimellesi. @@ -1191,7 +1200,7 @@ fi: animations_and_accessibility: Animaatiot ja saavutettavuus boosting_preferences: Tehostusasetukset boosting_preferences_info_html: "Vihje: Asetuksista riippumatta Vaihto + napsautus %{icon} Tehosta-kuvakkeeseen tehostaa välittömästi." - discovery: Löytäminen + discovery: Löydettävyys localization: body: Mastodonin ovat kääntäneet vapaaehtoiset. guide_link: https://crowdin.com/project/mastodon @@ -1663,7 +1672,7 @@ fi: disabled_account: Nykyinen tilisi ei ole täysin käytettävissä tämän jälkeen. Sinulla on kuitenkin pääsy tietojen vientiin ja tilin uudelleenaktivointiin. followers: Tämä toiminto siirtää kaikki seuraajasi nykyiseltä tililtä uudelle tilille only_redirect_html: Vaihtoehtoisesti voit asettaa vain ohjauksen profiiliisi. - other_data: Muita tietoja ei siirretä automaattisesti + other_data: Muita tietoja ei siirretä automaattisesti (mukaan lukien julkaisujasi ja seurattavien tilien luettoloa) redirect: Nykyisen tilisi profiili päivitetään uudelleenohjaushuomautuksella ja suljetaan pois hauista moderation: title: Moderointi @@ -1920,6 +1929,7 @@ fi: errors: in_reply_not_found: Julkaisua, johon yrität vastata, ei näytä olevan olemassa. quoted_status_not_found: Julkaisua, jota yrität lainata, ei näytä olevan olemassa. + quoted_user_not_mentioned: Mainitsematonta käyttäjää ei voi lainata yksityismaininnassa. over_character_limit: merkkimäärän rajoitus %{max} ylitetty pin_errors: direct: Vain mainituille käyttäjille näkyviä julkaisuja ei voi kiinnittää @@ -2076,7 +2086,7 @@ fi: disable: Et voi enää käyttää tiliäsi, mutta profiilisi ja muut tiedot pysyvät muuttumattomina. Voit pyytää varmuuskopiota tiedoistasi, vaihtaa tilin asetuksia tai poistaa tilisi. mark_statuses_as_sensitive: Palvelimen %{instance} moderaattorit ovat merkinneet osan julkaisuistasi arkaluonteisiksi. Tämä tarkoittaa sitä, että mediaa täytyy napauttaa ennen kuin sen esikatselu näytetään. Voit merkitä median itse arkaluonteiseksi, kun julkaiset tulevaisuudessa. sensitive: Tästä lähtien kaikki lähetetyt mediatiedostot merkitään arkaluonteisiksi ja piilotetaan napsautusvaroituksen taakse. - silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat käyttäjät näkevät julkaisusi tällä palvelimella ja sinut voidaan sulkea pois eri löytämisominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti. + silence: Voit edelleen käyttää tiliäsi, mutta vain sinua jo seuraavat käyttäjät näkevät julkaisusi tällä palvelimella ja sinut voidaan sulkea pois eri löydettävyysominaisuuksista. Toiset voivat kuitenkin edelleen seurata sinua manuaalisesti. suspend: Et voi enää käyttää tiliäsi, eivätkä profiilisi ja muut tiedot ole enää käytettävissä. Voit silti kirjautua sisään pyytääksesi tietojesi varmuuskopiota, kunnes tiedot on poistettu kokonaan noin 30 päivän kuluttua. Säilytämme kuitenkin joitain perustietoja, jotka estävät sinua kiertämästä jäädytystä. reason: 'Syy:' statuses: 'Julkaisuja lainattu:' diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 3938235eee8..82c21360e64 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1672,7 +1672,7 @@ fo: disabled_account: Tín verandi konta verður ikki fult nýtilig aftaná. Tó so, tú hevur atgongd til at útlesa dátur og tú kanst gera kontuna virkna aftur. followers: Hetta fer at flyta alla fylgjarar frá verandi kontuni til ta nýggju only_redirect_html: Ein annar møguleiki er, at tú setir eina víðaribeining upp á vanga tínum. - other_data: Ongar aðrar dátur verða fluttar sjálvvirkandi + other_data: Ongar aðrar dátur verða fluttar sjálvvirkandi (íroknað postarnir hjá tær og listin av kontum, sum tú fylgir) redirect: Vangin á tíni núverandi kontu verður dagførd við eini viðmerking um víðaribeining og tú verður ikki at finna í leitingum moderation: title: Umsjón @@ -1929,6 +1929,7 @@ fo: errors: in_reply_not_found: Posturin, sum tú roynir at svara, sýnist ikki at finnast. quoted_status_not_found: Posturin, sum tú roynir at sitera, sýnist ikki at finnast. + quoted_user_not_mentioned: Kann ikki sitera ein brúkara, sum ikki er nevndur, í einum posti, sum er ein privat umrøða. over_character_limit: mesta tal av teknum, %{max}, rokkið pin_errors: direct: Postar, sum einans eru sjónligir hjá nevndum brúkarum, kunnu ikki festast diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index b27d53eea8d..7e1c7632255 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -190,6 +190,7 @@ fr-CA: create_relay: Créer un relais create_unavailable_domain: Créer un domaine indisponible create_user_role: Créer le rôle + create_username_block: Créer une règle de nom d'utilisateur demote_user: Rétrograder l’utilisateur·ice destroy_announcement: Supprimer l’annonce destroy_canonical_email_block: Supprimer le blocage de courriel @@ -203,6 +204,7 @@ fr-CA: destroy_status: Supprimer le message destroy_unavailable_domain: Supprimer le domaine indisponible destroy_user_role: Détruire le rôle + destroy_username_block: Supprimer la règle de nom d'utilisateur disable_2fa_user: Désactiver l’A2F disable_custom_emoji: Désactiver les émojis personnalisés disable_relay: Désactiver le relais @@ -237,6 +239,7 @@ fr-CA: update_report: Mettre à jour le rapport update_status: Mettre à jour le message update_user_role: Mettre à jour le rôle + update_username_block: Mettre à jour la règle de nom d'utilisateur actions: approve_appeal_html: "%{name} a approuvé l'appel de la décision de modération émis par %{target}" approve_user_html: "%{name} a approuvé l’inscription de %{target}" @@ -255,6 +258,7 @@ fr-CA: create_relay_html: "%{name} a créé un relais %{target}" create_unavailable_domain_html: "%{name} a arrêté la livraison vers le domaine %{target}" create_user_role_html: "%{name} a créé le rôle %{target}" + create_username_block_html: "%{name} a ajouté une règle pour les noms d'utilisateur contenant %{target}" demote_user_html: "%{name} a rétrogradé l'utilisateur·rice %{target}" destroy_announcement_html: "%{name} a supprimé l'annonce %{target}" destroy_canonical_email_block_html: "%{name} a débloqué l'adresse email avec le hachage %{target}" @@ -268,6 +272,7 @@ fr-CA: destroy_status_html: "%{name} a supprimé le message de %{target}" destroy_unavailable_domain_html: "%{name} a repris la livraison au domaine %{target}" destroy_user_role_html: "%{name} a supprimé le rôle %{target}" + destroy_username_block_html: "%{name} a supprimé une règle pour les noms d'utilisateurs contenant %{target}" disable_2fa_user_html: "%{name} a désactivé l'authentification à deux facteurs pour l'utilisateur·rice %{target}" disable_custom_emoji_html: "%{name} a désactivé l'émoji %{target}" disable_relay_html: "%{name} a désactivé le relais %{target}" @@ -302,6 +307,7 @@ fr-CA: update_report_html: "%{name} a mis à jour le rapport de signalement %{target}" update_status_html: "%{name} a mis à jour le message de %{target}" update_user_role_html: "%{name} a changé le rôle %{target}" + update_username_block_html: "%{name} a mis à jour une règle pour les noms d'utilisateurs contenant %{target}" deleted_account: compte supprimé empty: Aucun journal trouvé. filter_by_action: Filtrer par action @@ -489,9 +495,17 @@ fr-CA: created_at: Créé à delete: Supprimer ip: Adresse IP + request_body: Corps de la demande providers: + active: Activé + base_url: URL de base + callback: Rappel + delete: Supprimer + edit: Modifier un fournisseur + finish_registration: Terminer l'inscription name: Nom providers: Fournisseur + registration_requested: Inscription demandée registrations: confirm: Confirmer description: Vous avez reçu une souscription d'un FSAF. Rejetez-la si vous ne l'avez pas initiée. Si c'est bien votre intention, comparez le nom et l'empreinte de la clé avant de confirmer la souscription. @@ -502,6 +516,7 @@ fr-CA: sign_in: Se connecter status: État title: Fournisseurs de Services Auxiliaire du Fedivers + title: FASP follow_recommendations: description_html: "Les recommandations d'abonnement aident les nouvelles personnes à trouver rapidement du contenu intéressant. Si un·e utilisateur·rice n'a pas assez interagi avec les autres pour avoir des recommandations personnalisées, ces comptes sont alors recommandés. La sélection est mise à jour quotidiennement depuis un mélange de comptes ayant le plus d'interactions récentes et le plus grand nombre d'abonné·e·s locaux pour une langue donnée." language: Pour la langue @@ -571,6 +586,11 @@ fr-CA: limited: Limité title: Modération moderation_notes: + create: Ajouter une note de modération + created_msg: Note de modération de l'instance créée avec succès ! + description_html: Voir et laisser des notes pour les autres modérateurs et pour référence future + destroyed_msg: Note de modération de l'instance supprimée avec succès ! + placeholder: Informations à propos de cette instance, actions entreprises ou de toute autre chose qui vous aidera à modérer cette instance à l'avenir. title: Notes de modération private_comment: Commentaire privé public_comment: Commentaire public @@ -777,6 +797,8 @@ fr-CA: view_dashboard_description: Permet aux utilisateur⋅rice⋅s d'accéder au tableau de bord et à diverses statistiques view_devops: DevOps view_devops_description: Permet aux utilisateur⋅rice⋅s d'accéder aux tableaux de bord Sidekiq et pgHero + view_feeds: Voir les flux en direct et les fils de discussion + view_feeds_description: Permet aux utilisateur·rice·s d'accéder aux flux en direct et de discussion indépendamment des paramètres du serveur title: Rôles rules: add_new: Ajouter une règle @@ -785,9 +807,12 @@ fr-CA: description_html: Bien que la plupart des gens prétende avoir lu les conditions d'utilisation avant de les accepter, généralement les utilisateur·rice·s ne les lisent vraiment que lorsque un problème apparaît. Pour faciliter la visualisation des règles de votre serveur en un seul coup d’œil, présentez-les sous la forme d'une liste à puces ! Essayez de garder chacune des règles simple et concise, mais faites attention à ne pas non plus les diviser en de trop nombreux éléments distincts. edit: Modifier la règle empty: Aucune règle de serveur n'a été définie pour l'instant. + move_down: Déplacer vers le bas + move_up: Déplacer vers le haut title: Règles du serveur translation: Traduction translations: Traductions + translations_explanation: Vous pouvez éventuellement ajouter des traductions pour les règles. La valeur par défaut sera affichée si aucune version traduite n'est disponible. Veuillez toujours vous assurer que toute traduction fournie est synchronisée avec la valeur par défaut. settings: about: manage_rules: Gérer les règles du serveur @@ -812,6 +837,7 @@ fr-CA: title: Par défaut, ne pas indexer les comptes dans les moteurs de recherche discovery: follow_recommendations: Suivre les recommandations + privacy: Vie privée profile_directory: Annuaire des profils public_timelines: Fils publics publish_statistics: Publier les statistiques @@ -821,6 +847,15 @@ fr-CA: all: À tout le monde disabled: À personne users: Aux utilisateur·rice·s connecté·e·s localement + feed_access: + modes: + authenticated: Utilisateurs authentifiés uniquement + public: Tout le monde + landing_page: + values: + about: À propos + local_feed: Fil local + trends: Tendances registrations: moderation_recommandation: Veuillez vous assurer d'avoir une équipe de modération adéquate et réactive avant d'ouvrir les inscriptions à tout le monde! preamble: Affecte qui peut créer un compte sur votre serveur. @@ -874,6 +909,7 @@ fr-CA: no_status_selected: Aucun message n’a été modifié car aucun n’a été sélectionné open: Ouvrir le message original_status: Message original + quotes: Citations reblogs: Partages replied_to_html: Répondu à %{acct_link} status_changed: Publication modifiée @@ -881,6 +917,7 @@ fr-CA: title: Messages du compte - @%{name} trending: Tendances view_publicly: Afficher de manière publique + view_quoted_post: Voir la publication citée visibility: Visibilité with_media: Avec médias strikes: @@ -1062,6 +1099,22 @@ fr-CA: other: Utilisé par %{count} personnes au cours de la dernière semaine title: Recommandations et tendances trending: Tendances + username_blocks: + add_new: Ajouter un nouveau + block_registrations: Bloquer les inscriptions + comparison: + contains: Contient + equals: Est égal à + contains_html: Contient %{string} + created_msg: Règle de nom d'utilisateur créée avec succès + delete: Supprimer + edit: + title: Modifier la règle de nom d'utilisateur + new: + create: Créer une règle + title: Créer une nouvelle règle de nom d'utilisateur + no_username_block_selected: Aucune règle de nom d'utilisateur n'a été modifiée car aucune n'a été sélectionnée + title: Règles de nom d'utilisateur warning_presets: add_new: Ajouter un nouveau delete: Supprimer @@ -1134,7 +1187,9 @@ fr-CA: hint_html: Si vous voulez déménager d’un autre compte vers celui-ci, vous pouvez créer ici un alias, qui est nécessaire avant de pouvoir migrer les abonné·e·s de l’ancien compte vers celui-ci. Cette action en soi est inoffensive et réversible. La migration du compte est initiée à partir de l’ancien compte. remove: Détacher l'alias appearance: + advanced_settings: Paramètres avancés animations_and_accessibility: Animations et accessibilité + boosting_preferences: Préférences de partage discovery: Découverte localization: body: Mastodon est traduit par des volontaires. @@ -1323,6 +1378,10 @@ fr-CA: basic_information: Informations de base hint_html: "Personnalisez ce que les gens voient sur votre profil public et à côté de vos messages. Les autres personnes seront plus susceptibles de vous suivre et d’interagir avec vous lorsque vous avez un profil complet et une photo." other: Autre + emoji_styles: + auto: Auto + native: Natif + twemoji: Twemoji errors: '400': La demande que vous avez soumise est invalide ou mal formée. '403': Vous n’avez pas accès à cette page. @@ -1532,6 +1591,12 @@ fr-CA: expires_at: Expire uses: Utilisations title: Inviter des gens + link_preview: + author_html: Par %{name} + potentially_sensitive_content: + confirm_visit: Voulez-vous vraiment ouvrir ce lien ? + hide_button: Masquer + label: Contenu potentiellement sensible lists: errors: limit: Vous avez atteint le nombre maximum de listes @@ -1596,7 +1661,6 @@ fr-CA: disabled_account: Votre compte actuel ne sera pas entièrement utilisable par la suite. Cependant, vous aurez accès à l'exportation de données et à la réactivation. followers: Cette action va déménager tou·te·s les abonné·e·s du compte actuel vers le nouveau compte only_redirect_html: Alternativement, vous pouvez seulement appliquer une redirection sur votre profil. - other_data: Aucune autre donnée ne sera déplacée automatiquement redirect: Le profil de votre compte actuel sera mis à jour avec un avis de redirection et sera exclu des recherches moderation: title: Modération @@ -1632,6 +1696,10 @@ fr-CA: title: Nouvelle mention poll: subject: Un sondage de %{name} est terminé + quote: + body: 'Votre message a été cité par %{name}:' + subject: "%{name} a cité votre message" + title: Nouvelle citation reblog: body: 'Votre message été partagé par %{name} :' subject: "%{name} a partagé votre message" @@ -1680,6 +1748,9 @@ fr-CA: self_vote: Vous ne pouvez pas voter à vos propres sondages too_few_options: doit avoir plus qu’une proposition too_many_options: ne peut contenir plus de %{max} propositions + vote: Voter + posting_defaults: + explanation: Ces paramètres seront utilisés par défaut lorsque vous créez de nouveaux messages, mais vous pouvez les modifier par message dans le champs de rédaction. preferences: other: Autre posting_defaults: Paramètres de publication par défaut @@ -1835,6 +1906,9 @@ fr-CA: other: "%{count} vidéos" boosted_from_html: Partagé depuis %{acct_link} content_warning: 'Avertissement sur le contenu : %{warning}' + content_warnings: + hide: Masquer le message + show: Afficher plus default_language: Même langue que celle de l’interface disallowed_hashtags: one: 'contient un hashtag désactivé : %{tags}' @@ -1842,15 +1916,29 @@ fr-CA: edited_at_html: Édité le %{date} errors: in_reply_not_found: Le message auquel vous essayez de répondre ne semble pas exister. + quoted_status_not_found: Le message que vous essayez de citer ne semble pas exister. over_character_limit: limite de %{max} caractères dépassée pin_errors: direct: Les messages qui ne sont visibles que pour les utilisateur·rice·s mentionné·e·s ne peuvent pas être épinglés limit: Vous avez déjà épinglé le nombre maximum de messages ownership: Vous ne pouvez pas épingler un message ne vous appartenant pas reblog: Un partage ne peut pas être épinglé + quote_error: + not_available: Message indisponible + pending_approval: Message en attente + revoked: Message supprimé par l'auteur + quote_policies: + followers: Abonné·e·s seulement + nobody: Moi uniquement + public: Tout le monde + quote_post_author: A cité un message de %{acct} title: "%{name} : « %{quote} »" visibilities: + direct: Mention privée + private: Abonné·e·s seulement public: Publique + public_long: Tout le monde sur et en dehors de Mastodon + unlisted: Public discret statuses_cleanup: enabled: Supprimer automatiquement vos anciens messages enabled_hint: Supprime automatiquement vos messages une fois qu'ils ont atteint un seuil d'ancienneté défini, à moins qu'ils ne correspondent à l'une des exceptions ci-dessous diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 6b04aca1afb..4ed43673650 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -190,6 +190,7 @@ fr: create_relay: Créer un relais create_unavailable_domain: Créer un domaine indisponible create_user_role: Créer le rôle + create_username_block: Créer une règle de nom d'utilisateur demote_user: Rétrograder l’utilisateur·ice destroy_announcement: Supprimer l’annonce destroy_canonical_email_block: Supprimer le blocage de courriel @@ -203,6 +204,7 @@ fr: destroy_status: Supprimer le message destroy_unavailable_domain: Supprimer le domaine indisponible destroy_user_role: Détruire le rôle + destroy_username_block: Supprimer la règle de nom d'utilisateur disable_2fa_user: Désactiver l’A2F disable_custom_emoji: Désactiver les émojis personnalisés disable_relay: Désactiver le relais @@ -237,6 +239,7 @@ fr: update_report: Mettre à jour le rapport update_status: Mettre à jour le message update_user_role: Mettre à jour le rôle + update_username_block: Mettre à jour la règle de nom d'utilisateur actions: approve_appeal_html: "%{name} a approuvé l'appel de la décision de modération émis par %{target}" approve_user_html: "%{name} a approuvé l’inscription de %{target}" @@ -255,6 +258,7 @@ fr: create_relay_html: "%{name} a créé un relais %{target}" create_unavailable_domain_html: "%{name} a arrêté la livraison vers le domaine %{target}" create_user_role_html: "%{name} a créé le rôle %{target}" + create_username_block_html: "%{name} a ajouté une règle pour les noms d'utilisateur contenant %{target}" demote_user_html: "%{name} a rétrogradé l'utilisateur·rice %{target}" destroy_announcement_html: "%{name} a supprimé l'annonce %{target}" destroy_canonical_email_block_html: "%{name} a débloqué l'adresse email avec le hachage %{target}" @@ -268,6 +272,7 @@ fr: destroy_status_html: "%{name} a supprimé le message de %{target}" destroy_unavailable_domain_html: "%{name} a repris la livraison au domaine %{target}" destroy_user_role_html: "%{name} a supprimé le rôle %{target}" + destroy_username_block_html: "%{name} a supprimé une règle pour les noms d'utilisateurs contenant %{target}" disable_2fa_user_html: "%{name} a désactivé l'authentification à deux facteurs pour l'utilisateur·rice %{target}" disable_custom_emoji_html: "%{name} a désactivé l'émoji %{target}" disable_relay_html: "%{name} a désactivé le relais %{target}" @@ -302,6 +307,7 @@ fr: update_report_html: "%{name} a mis à jour le rapport de signalement %{target}" update_status_html: "%{name} a mis à jour le message de %{target}" update_user_role_html: "%{name} a changé le rôle %{target}" + update_username_block_html: "%{name} a mis à jour une règle pour les noms d'utilisateurs contenant %{target}" deleted_account: compte supprimé empty: Aucun journal trouvé. filter_by_action: Filtrer par action @@ -489,9 +495,17 @@ fr: created_at: Créé à delete: Supprimer ip: Adresse IP + request_body: Corps de la demande providers: + active: Activé + base_url: URL de base + callback: Rappel + delete: Supprimer + edit: Modifier un fournisseur + finish_registration: Terminer l'inscription name: Nom providers: Fournisseur + registration_requested: Inscription demandée registrations: confirm: Confirmer description: Vous avez reçu une souscription d'un FSAF. Rejetez-la si vous ne l'avez pas initiée. Si c'est bien votre intention, comparez le nom et l'empreinte de la clé avant de confirmer la souscription. @@ -502,6 +516,7 @@ fr: sign_in: Se connecter status: État title: Fournisseurs de Services Auxiliaire du Fedivers + title: FASP follow_recommendations: description_html: "Les recommandations d'abonnement aident les nouvelles personnes à trouver rapidement du contenu intéressant. Si un·e utilisateur·rice n'a pas assez interagi avec les autres pour avoir des recommandations personnalisées, ces comptes sont alors recommandés. La sélection est mise à jour quotidiennement depuis un mélange de comptes ayant le plus d'interactions récentes et le plus grand nombre d'abonné·e·s locaux pour une langue donnée." language: Pour la langue @@ -571,6 +586,11 @@ fr: limited: Limité title: Modération moderation_notes: + create: Ajouter une note de modération + created_msg: Note de modération de l'instance créée avec succès ! + description_html: Voir et laisser des notes pour les autres modérateurs et pour référence future + destroyed_msg: Note de modération de l'instance supprimée avec succès ! + placeholder: Informations à propos de cette instance, actions entreprises ou de toute autre chose qui vous aidera à modérer cette instance à l'avenir. title: Notes de modération private_comment: Commentaire privé public_comment: Commentaire public @@ -777,6 +797,8 @@ fr: view_dashboard_description: Permet aux utilisateur⋅rice⋅s d'accéder au tableau de bord et à diverses statistiques view_devops: DevOps view_devops_description: Permet aux utilisateur⋅rice⋅s d'accéder aux tableaux de bord Sidekiq et pgHero + view_feeds: Voir les flux en direct et les fils de discussion + view_feeds_description: Permet aux utilisateur·rice·s d'accéder aux flux en direct et de discussion indépendamment des paramètres du serveur title: Rôles rules: add_new: Ajouter une règle @@ -785,9 +807,12 @@ fr: description_html: Bien que la plupart des gens prétende avoir lu les conditions d'utilisation avant de les accepter, généralement les utilisateur·rice·s ne les lisent vraiment que lorsque un problème apparaît. Pour faciliter la visualisation des règles de votre serveur en un seul coup d’œil, présentez-les sous la forme d'une liste à puces ! Essayez de garder chacune des règles simple et concise, mais faites attention à ne pas non plus les diviser en de trop nombreux éléments distincts. edit: Modifier la règle empty: Aucune règle de serveur n'a été définie pour l'instant. + move_down: Déplacer vers le bas + move_up: Déplacer vers le haut title: Règles du serveur translation: Traduction translations: Traductions + translations_explanation: Vous pouvez éventuellement ajouter des traductions pour les règles. La valeur par défaut sera affichée si aucune version traduite n'est disponible. Veuillez toujours vous assurer que toute traduction fournie est synchronisée avec la valeur par défaut. settings: about: manage_rules: Gérer les règles du serveur @@ -812,6 +837,7 @@ fr: title: Par défaut, ne pas indexer les comptes dans les moteurs de recherche discovery: follow_recommendations: Suivre les recommandations + privacy: Vie privée profile_directory: Annuaire des profils public_timelines: Fils publics publish_statistics: Publier les statistiques @@ -821,6 +847,15 @@ fr: all: À tout le monde disabled: À personne users: Aux utilisateur·rice·s connecté·e·s localement + feed_access: + modes: + authenticated: Utilisateurs authentifiés uniquement + public: Tout le monde + landing_page: + values: + about: À propos + local_feed: Fil local + trends: Tendances registrations: moderation_recommandation: Veuillez vous assurer d'avoir une équipe de modération adéquate et réactive avant d'ouvrir les inscriptions à tout le monde! preamble: Affecte qui peut créer un compte sur votre serveur. @@ -874,6 +909,7 @@ fr: no_status_selected: Aucun message n’a été modifié car aucun n’a été sélectionné open: Ouvrir le message original_status: Message original + quotes: Citations reblogs: Partages replied_to_html: Répondu à %{acct_link} status_changed: Message modifié @@ -881,6 +917,7 @@ fr: title: Messages du compte - @%{name} trending: Tendances view_publicly: Afficher de manière publique + view_quoted_post: Voir la publication citée visibility: Visibilité with_media: Avec médias strikes: @@ -1062,6 +1099,22 @@ fr: other: Utilisé par %{count} personnes au cours de la dernière semaine title: Recommandations et tendances trending: Tendances + username_blocks: + add_new: Ajouter un nouveau + block_registrations: Bloquer les inscriptions + comparison: + contains: Contient + equals: Est égal à + contains_html: Contient %{string} + created_msg: Règle de nom d'utilisateur créée avec succès + delete: Supprimer + edit: + title: Modifier la règle de nom d'utilisateur + new: + create: Créer une règle + title: Créer une nouvelle règle de nom d'utilisateur + no_username_block_selected: Aucune règle de nom d'utilisateur n'a été modifiée car aucune n'a été sélectionnée + title: Règles de nom d'utilisateur warning_presets: add_new: Ajouter un nouveau delete: Supprimer @@ -1134,7 +1187,9 @@ fr: hint_html: Si vous voulez déménager d’un autre compte vers celui-ci, vous pouvez créer ici un alias, qui est nécessaire avant de pouvoir migrer les abonné·e·s de l’ancien compte vers celui-ci. Cette action en soi est inoffensive et réversible. La migration du compte est initiée à partir de l’ancien compte. remove: Détacher l'alias appearance: + advanced_settings: Paramètres avancés animations_and_accessibility: Animations et accessibilité + boosting_preferences: Préférences de partage discovery: Découverte localization: body: Mastodon est traduit par des volontaires. @@ -1323,6 +1378,10 @@ fr: basic_information: Informations de base hint_html: "Personnalisez ce que les gens voient sur votre profil public et à côté de vos messages. Les autres personnes seront plus susceptibles de vous suivre et d’interagir avec vous lorsque vous avez un profil complet et une photo." other: Autre + emoji_styles: + auto: Auto + native: Natif + twemoji: Twemoji errors: '400': La demande que vous avez soumise est invalide ou mal formée. '403': Vous n’avez pas accès à cette page. @@ -1532,6 +1591,12 @@ fr: expires_at: Expire uses: Utilisations title: Inviter des gens + link_preview: + author_html: Par %{name} + potentially_sensitive_content: + confirm_visit: Voulez-vous vraiment ouvrir ce lien ? + hide_button: Masquer + label: Contenu potentiellement sensible lists: errors: limit: Vous avez atteint le nombre maximum de listes @@ -1596,7 +1661,6 @@ fr: disabled_account: Votre compte actuel ne sera pas entièrement utilisable par la suite. Cependant, vous aurez accès à l'exportation de données et à la réactivation. followers: Cette action va déménager tou·te·s les abonné·e·s du compte actuel vers le nouveau compte only_redirect_html: Alternativement, vous pouvez seulement appliquer une redirection sur votre profil. - other_data: Aucune autre donnée ne sera déplacée automatiquement redirect: Le profil de votre compte actuel sera mis à jour avec un avis de redirection et sera exclu des recherches moderation: title: Modération @@ -1632,6 +1696,10 @@ fr: title: Nouvelle mention poll: subject: Un sondage de %{name} est terminé + quote: + body: 'Votre message a été cité par %{name}:' + subject: "%{name} a cité votre message" + title: Nouvelle citation reblog: body: 'Votre message été partagé par %{name} :' subject: "%{name} a partagé votre message" @@ -1680,6 +1748,9 @@ fr: self_vote: Vous ne pouvez pas voter à vos propres sondages too_few_options: doit avoir plus qu’une proposition too_many_options: ne peut contenir plus de %{max} propositions + vote: Voter + posting_defaults: + explanation: Ces paramètres seront utilisés par défaut lorsque vous créez de nouveaux messages, mais vous pouvez les modifier par message dans le champs de rédaction. preferences: other: Autre posting_defaults: Paramètres de publication par défaut @@ -1835,6 +1906,9 @@ fr: other: "%{count} vidéos" boosted_from_html: Partagé depuis %{acct_link} content_warning: 'Avertissement de contenu : %{warning}' + content_warnings: + hide: Masquer le message + show: Afficher plus default_language: Même langue que celle de l’interface disallowed_hashtags: one: 'contient un hashtag désactivé : %{tags}' @@ -1842,15 +1916,29 @@ fr: edited_at_html: Modifié le %{date} errors: in_reply_not_found: Le message auquel vous essayez de répondre ne semble pas exister. + quoted_status_not_found: Le message que vous essayez de citer ne semble pas exister. over_character_limit: limite de %{max} caractères dépassée pin_errors: direct: Les messages qui ne sont visibles que pour les utilisateur·rice·s mentionné·e·s ne peuvent pas être épinglés limit: Vous avez déjà épinglé le nombre maximum de messages ownership: Vous ne pouvez pas épingler un message ne vous appartenant pas reblog: Un partage ne peut pas être épinglé + quote_error: + not_available: Message indisponible + pending_approval: Message en attente + revoked: Message supprimé par l'auteur + quote_policies: + followers: Abonné·e·s seulement + nobody: Moi uniquement + public: Tout le monde + quote_post_author: A cité un message de %{acct} title: "%{name} : « %{quote} »" visibilities: + direct: Mention privée + private: Abonné·e·s seulement public: Publique + public_long: Tout le monde sur et en dehors de Mastodon + unlisted: Public discret statuses_cleanup: enabled: Supprimer automatiquement vos anciens messages enabled_hint: Supprime automatiquement vos messages une fois qu'ils ont atteint un seuil d'ancienneté défini, à moins qu'ils ne correspondent à l'une des exceptions ci-dessous diff --git a/config/locales/fy.yml b/config/locales/fy.yml index 9c489c03ec4..f96e0f92ecf 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -1647,7 +1647,6 @@ fy: disabled_account: Jo aktuele account is hjirnei net mear folslein brûkber. Jo hawwe echter wol tagong ta it eksportearjen fan jo gegevens en ta it opnij aktivearjen fan jo account. followers: Dizze aksje ferhuzet alle folgers fan de aktuele account ôf nei de nije account only_redirect_html: Jo kinne as alternatyf ek allinnich de trochferwizing op jo profyl sette. - other_data: Oare gegevens wurde net automatysk ferhuze redirect: Jo aktuele accountprofyl wurdt bywurke mei in trochferwizingsmelding en wurdt útsluten fan sykresultaten moderation: title: Moderaasje diff --git a/config/locales/ga.yml b/config/locales/ga.yml index cb27ec1f9e6..aac1e85e88e 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1791,7 +1791,7 @@ ga: disabled_account: Ní bheidh do chuntas reatha inúsáidte go hiomlán ina dhiaidh sin. Mar sin féin, beidh rochtain agat ar onnmhairiú sonraí chomh maith le hathghníomhú. followers: Bogfaidh an gníomh seo gach leantóir ón gcuntas reatha go dtí an cuntas nua only_redirect_html: Nó, ní féidir leat ach atreorú a chur suas ar do phróifíl. - other_data: Ní bhogfar aon sonraí eile go huathoibríoch + other_data: Ní bhogfar aon sonraí eile go huathoibríoch (lena n-áirítear do phoist agus an liosta cuntas a leanann tú) redirect: Déanfar próifíl do chuntais reatha a nuashonrú le fógra atreoraithe agus fágfar as an áireamh é ó chuardaigh moderation: title: Measarthacht @@ -2060,6 +2060,7 @@ ga: errors: in_reply_not_found: Is cosúil nach ann don phostáil a bhfuil tú ag iarraidh freagra a thabhairt air. quoted_status_not_found: Is cosúil nach bhfuil an post atá tú ag iarraidh a lua ann. + quoted_user_not_mentioned: Ní féidir úsáideoir nach luaitear a lua i bpost Lua Príobháideach. over_character_limit: teorainn carachtar %{max} sáraithe pin_errors: direct: Ní féidir postálacha nach bhfuil le feiceáil ach ag úsáideoirí luaite a phinnáil diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 3b1f956fe12..ce62e5261fa 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -824,6 +824,8 @@ gd: view_dashboard_description: Leigidh seo le cleachdaichean an deas-bhòrd agus meatrachdan inntrigeadh view_devops: DevOps view_devops_description: Leigidh seo le cleachdaichean na deas-bhùird aig Sidekiq is pgHero inntrigeadh + view_feeds: Seall loidhnichean-ama beòtha ’s nan cuspairean + view_feeds_description: Leigidh seo le cleachdaichean loidhnichean-ama beòtha ’s nan cuspairean inntrigeadh ge b’ e dè roghainnean an fhrithealaiche title: Dreuchdan rules: add_new: Cuir riaghailt ris @@ -879,7 +881,13 @@ gd: feed_access: modes: authenticated: Cleachdaichean a chlàraich a-steach a-mhàin + disabled: Iarr dreuchd shònraichte a’ chleachdaiche public: A h-uile duine + landing_page: + values: + about: Mu dhèidhinn + local_feed: Loidhne-ama ionadail + trends: Treandaichean registrations: moderation_recommandation: Dèan cinnteach gu bheil sgioba maoir deiseil is deònach agad mus fhosgail thu an clàradh dhan a h-uile duine! preamble: Stiùirich cò dh’fhaodas cunntas a chruthachadh air an fhrithealaiche agad. @@ -1742,7 +1750,7 @@ gd: disabled_account: Cha ghabh an cunntas làithreach agad a chleachdadh gu slàn às a dhèidh. Gidheadh, bidh an dà chuid às-phortadh an dàta is ath-ghnìomhachadh ri fhaighinn dhut. followers: Imrichidh an gnìomh seo a h-uile neach-leantainn on chunntas làithreach dhan chunntas ùr only_redirect_html: Mar roghainn eile, ’s urrainn dhut ath-stiùireadh a-mhàin a chur air a’ phròifil agad. - other_data: Cha dèid dàta sam bith eile imrich gu fèin-obrachail + other_data: Cha dèid dàta sam bith eile imrich gu fèin-obrachail (a’ gabhail a-staigh nam postaichean ’s liosta nan cunntasan a leanas tu) redirect: Thèid pròifil a’ chunntais làithrich agad ùrachadh le brath ath-stiùiridh agus às-dhùnadh on lorg moderation: title: Maorsainneachd @@ -2007,6 +2015,7 @@ gd: errors: in_reply_not_found: Tha coltas nach eil am post dhan a tha thu airson freagairt ann. quoted_status_not_found: Tha coltas nach eil am post dhan a tha thu airson luaidh ann. + quoted_user_not_mentioned: Chan urrainn dhut neach gun iomradh air a luaidh ann am post a tha ’na iomradh prìobhaideach. over_character_limit: chaidh thu thar crìoch charactaran de %{max} pin_errors: direct: Chan urrainn dhut post a phrìneachadh nach fhaic ach na cleachdaichean le iomradh orra @@ -2028,7 +2037,7 @@ gd: private: Luchd-leantainn a-mhàin public: Poblach public_long: Neach sam bith taobh a-staigh no a-muigh Mhastodon - unlisted: Poblach ach sàmhach + unlisted: Sàmhach unlisted_long: Falaichte o na toraidhean-luirg, na treandaichean ’s na loichnichean-ama poblach statuses_cleanup: enabled: Sguab às seann-phostaichean gu fèin-obrachail diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 79f9fafaf5c..87798f8bae3 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -855,6 +855,11 @@ gl: authenticated: Só para usuarias con sesión iniciada disabled: Requerir un rol da usuaria específico public: Para calquera + landing_page: + values: + about: Sobre + local_feed: Cronoloxía Local + trends: Tendencias registrations: moderation_recommandation: Por favor, pon interese en crear un equipo de moderación competente e reactivo antes de permitir que calquera poida crear unha conta! preamble: Xestiona quen pode crear unha conta no teu servidor. @@ -1667,7 +1672,6 @@ gl: disabled_account: Tras o cambio a túa conta actual non será totalmente usable, pero terás acceso a exportar os datos e tamén a reactivación. followers: Esta acción moverá todas as túas seguidoras desde a conta actual a nova conta only_redirect_html: De xeito alternativo, podes simplemente pór unha redirección no perfil. - other_data: Non se moverán outros datos de xeito automático redirect: O perfil da túa conta actualizarase cun aviso de redirección e será excluído das buscas moderation: title: Moderación @@ -1924,6 +1928,7 @@ gl: errors: in_reply_not_found: A publicación á que tentas responder semella que non existe. quoted_status_not_found: Parece que a publicación que intentas citar non existe. + quoted_user_not_mentioned: Non se pode citar a unha usuaria non mencionada nunha Mención Privada. over_character_limit: Excedeu o límite de caracteres %{max} pin_errors: direct: As publicacións que só son visibles para as usuarias mencionadas non se poden fixar @@ -2110,7 +2115,7 @@ gl: edit_profile_action: Personalizar edit_profile_step: Aumenta as túas interaccións grazas a un perfil descriptivo. edit_profile_title: Personaliza o teu perfil - explanation: Aquí tes algunhas endereitas para ir aprendendo + explanation: Aquí tes algúns consellos para ir aprendendo feature_action: Saber máis feature_audience: Mastodon dache a oportunidade de xestionar sen intermediarios as túas relacións. Incluso se usas o teu propio servidor Mastodon poderás seguir e ser seguida desde calquera outro servidor Mastodon conectado á rede e estará baixo o teu control exclusivo. feature_audience_title: Crea a túa audiencia con tranquilidade diff --git a/config/locales/he.yml b/config/locales/he.yml index eebc9000da7..53940fef519 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1750,7 +1750,7 @@ he: disabled_account: חשבונך הנוכחי לא יהיה שמיש לחלוטין לאחר מכן. עם זאת, ניתן יהיה לגשת ליצוא המידע, וכמו כן להפעילו מחדש. followers: פעולה זו תעביר את כל העוקבים מהחשבון הנוכחי לחשבון החדש only_redirect_html: לחילופין, ניתן להסתפק בהכוונה מחדש בפרופילך. - other_data: שום מידע לא יועבר אוטומטית + other_data: אף מידע נוסף לא יועבר אוטומטית (ובכלל זה הודעותיך ורשימת נעקביך) redirect: פרופיל חשבונך הנוכחי יעודכן עם הודעת הכוונה מחדש ויוחרג מחיפושים moderation: title: ניהול קהילה @@ -2015,6 +2015,7 @@ he: errors: in_reply_not_found: נראה שההודעה שנסית להגיב לה לא קיימת. quoted_status_not_found: נראה שההודעה שנסית לצטט לא קיימת. + quoted_user_not_mentioned: לא ניתן לצטט משתמש שאיננו מאוזכר בהודעה פרטית. over_character_limit: חריגה מגבול התווים של %{max} pin_errors: direct: לא ניתן לקבע הודעות שנראותן מוגבלת למכותבים בלבד diff --git a/config/locales/hu.yml b/config/locales/hu.yml index a90e8a5c2ca..c1d20eadeb9 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -855,6 +855,11 @@ hu: authenticated: Csak hitelesített felhasználók disabled: Konkrét felhasználói szerepkör megkövetelése public: Mindenki + landing_page: + values: + about: Névjegy + local_feed: Helyi idővonal + trends: Trendek registrations: moderation_recommandation: Győződj meg arról, hogy megfelelő és gyors reagálású moderátor csapatod van, mielőtt mindenki számára megnyitod a regisztrációt! preamble: Szabályozd, hogy ki hozhat létre fiókot a kiszolgálón. @@ -1667,7 +1672,6 @@ hu: disabled_account: A jelenlegi fiókod nem lesz teljesen használható ezután. Viszont elérhető lesz majd az adatexport funkció, valamint a reaktiválás is. followers: Ez a művelet az összes követődet a jelenlegi fiókról az újra fogja költöztetni only_redirect_html: Az is lehetséges, hogy csak átirányítást raksz a profilodra. - other_data: Más adatot nem fogunk automatikusan mozgatni redirect: A jelenlegi fiókod profiljára átirányításról szóló figyelmeztetést rakunk, valamint már nem fogjuk mutatni a keresésekben moderation: title: Moderáció diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 75220ecb13b..3dc7913784f 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -616,7 +616,6 @@ hy: warning: followers: Այս քայլով քո բոլոր հետեւորդներին այս հաշուից կը տեղափոխես դէպի նորը only_redirect_html: Որպէս այլընտրանք, կարող ես ուղղակի վերահասցէաւորել քո հաշիւը - other_data: Մնացեալ տուեալները ինքնուրոյն չեն փոխադրուի moderation: title: Մոդերացիա notification_mailer: diff --git a/config/locales/ia.yml b/config/locales/ia.yml index b08b01e0ef2..19c938e0f7a 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -1672,7 +1672,6 @@ ia: disabled_account: Tu conto actual non essera plenmente usabile postea. Nonobstante, tu habera accesso al exportation de datos e al reactivation. followers: Iste action transferera tote le sequitores del conto actual al conto nove only_redirect_html: Como alternativa, tu pote poner solmente un redirection sur tu profilo. - other_data: Nulle altere datos essera migrate automaticamente redirect: Le profilo de tu conto actual essera actualisate con un aviso de redirection e excludite de recercas moderation: title: Moderation diff --git a/config/locales/id.yml b/config/locales/id.yml index eea3637e334..a7f21ee3f51 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -1167,7 +1167,6 @@ id: disabled_account: Akun Anda tidak akan dapat dipakai secara penuh. Namun, Anda tetap akan memiliki akses ke ekspor data dan aktivasi ulang. followers: Tindakan ini akan memindah semua pengikut Anda dari akun sekarang ke akun baru only_redirect_html: Secara alternatif, Anda hanya dapat menaruh tulisan mengarahkan ke profil Anda. - other_data: Tidak akan ada data lagi yang dipindahkan secara otomatis redirect: Pemberitahuan peralihan akan dimunculkan pada akun profil Anda dan akun akan dikecualikan dari pencarian moderation: title: Moderasi diff --git a/config/locales/ie.yml b/config/locales/ie.yml index f9289485363..31d1ea27f77 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -1369,7 +1369,6 @@ ie: disabled_account: Tui actual conto ne va esser completmen usabil pos to. Támen, tu va posser accesser li exportation de data, e anc reactivisation. followers: Ti-ci action va mover omni sequitores del actual conto al nov conto only_redirect_html: Alternativmen, tu posse solmen meter un redirection sur tui profil. - other_data: Necun altri data va esser translocat automaticmen redirect: Li profil de tui actual conto va esser actualisat con un anuncie de redirection e va esser excludet de serchas moderation: title: Moderation diff --git a/config/locales/io.yml b/config/locales/io.yml index 924df63c7dd..3036c363be6 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -1503,7 +1503,6 @@ io: disabled_account: Vua nuna konto ne esos tote uzebla pose. followers: Ca ago transferos omna sequanti de nuna konto a nova konto only_redirect_html: Alternative, vu povas nur pozar ridirekto che vua profilo. - other_data: Altra informi ne transferesos automate redirect: Vua nuna profilo di konto novigesos kun ridirektoavizo e neinkluzesos de trovi moderation: title: Jero diff --git a/config/locales/is.yml b/config/locales/is.yml index 104bd638941..ba03643e1db 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1676,7 +1676,7 @@ is: disabled_account: Núverandi aðgangur þinn verður ekki nothæfur að fullu eftir þetta. Hinsvegar muntu geta flutt út gögn af honum og einnig endurvirkjað hann. followers: Þessi aðgerð mun flytja alla fylgjendur af núverandi aðgangi yfir á nýja aðganginn only_redirect_html: Einnig geturðu einungis sett upp endurbeiningu á notandasniðið þitt. - other_data: Engin önnur gögn munu flytjast sjálfvirkt + other_data: Engin önnur gögn verða flutt sjálfkrafa (m.a. færslurnar þínar og listar yfir þá sem þú fylgist með) redirect: Notandasnið aðgangsins verður uppfært með athugasemd um endurbeininguna og verður undanþegið frá leitum moderation: title: Umsjón @@ -1933,6 +1933,7 @@ is: errors: in_reply_not_found: Færslan sem þú ert að reyna að svara að er líklega ekki til. quoted_status_not_found: Færslan sem þú ert að reyna að vitna í virðist ekki vera til. + quoted_user_not_mentioned: Ekki er hægt að vitna í aðila sem ekki er minnst á í einkaspjalli. over_character_limit: hámarksfjölda stafa (%{max}) náð pin_errors: direct: Ekki er hægt að festa færslur sem einungis eru sýnilegar þeim notendum sem minnst er á diff --git a/config/locales/it.yml b/config/locales/it.yml index d1061229023..b3a4fe0db83 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -855,6 +855,11 @@ it: authenticated: Solo utenti autenticati disabled: Richiedi un ruolo utente specifico public: Tutti + landing_page: + values: + about: Info + local_feed: Feed locale + trends: Tendenze registrations: moderation_recommandation: Assicurati di avere un team di moderazione adeguato e reattivo prima di aprire le registrazioni a tutti! preamble: Controlla chi può creare un account sul tuo server. @@ -1667,7 +1672,7 @@ it: disabled_account: Il tuo account attuale non sarà più pienamente utilizzabile. Tuttavia, avrai accesso all'esportazione dei dati e alla riattivazione. followers: Questa azione sposterà tutti i follower dall'account attuale al nuovo account only_redirect_html: In alternativa, puoi solo impostare un reindirizzamento sul tuo profilo. - other_data: Nessun altro dato verrà spostato automaticamente + other_data: Nessun altro dato verrà trasferito automaticamente (compresi i tuoi post e l'elenco degli account che segui) redirect: Il profilo del tuo account corrente sarà aggiornato con un avviso di ridirezione e sarà escluso dalle ricerche moderation: title: Moderazione @@ -1924,6 +1929,7 @@ it: errors: in_reply_not_found: Il post a cui stai tentando di rispondere non sembra esistere. quoted_status_not_found: Il post che stai cercando di citare non sembra esistere. + quoted_user_not_mentioned: Non è possibile citare un utente non menzionato in un post di menzione privata. over_character_limit: Limite caratteri superato di %{max} pin_errors: direct: I messaggi visibili solo agli utenti citati non possono essere fissati in cima diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 1ef3aef00c3..f15f97ee9b5 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -572,6 +572,8 @@ ja: title: モデレーション moderation_notes: create: モデレーションノートを追加 + description_html: 他のモデレーターと将来の自分にメモを残してください + destroyed_msg: インスタンス・モデレーションノートを正常に削除しました! title: モデレーションメモ private_comment: コメント (非公開) public_comment: コメント (公開) @@ -826,6 +828,9 @@ ja: all: 誰にでも許可 disabled: 誰にも許可しない users: ログイン済みローカルユーザーのみ許可 + landing_page: + values: + trends: トレンド registrations: moderation_recommandation: 登録受付を開始する前に、迅速かつ適切にモデレーションを行うチームを編成しましょう! preamble: あなたのサーバー上でアカウントを作成できるユーザーを制御します。 @@ -879,6 +884,7 @@ ja: no_status_selected: 何も選択されていないため、変更されていません open: 投稿を開く original_status: オリジナルの投稿 + quotes: 引用 reblogs: ブースト replied_to_html: "%{acct_link}さんへの返信" status_changed: 投稿を変更しました @@ -886,6 +892,7 @@ ja: title: 投稿一覧 - @%{name} trending: トレンド view_publicly: 元の投稿を開く + view_quoted_post: 引用されている投稿を見る visibility: 公開範囲 with_media: メディアあり strikes: @@ -1078,6 +1085,7 @@ ja: matches_exactly_html: "%{string}に一致" new: create: ルールを作成 + title: ユーザー名ルールを作成 title: ユーザー名ルール warning_presets: add_new: 追加 @@ -1150,7 +1158,10 @@ ja: hint_html: 他のアカウントからこのアカウントにフォロワーを引き継いで引っ越したい場合、ここでエイリアスを作成しておく必要があります。エイリアス自体は無害で、取り消すことができます。引っ越しは以前のアカウント側から開始する必要があります。 remove: エイリアスを削除 appearance: + advanced_settings: 詳細設定 animations_and_accessibility: アニメーションとアクセシビリティー + boosting_preferences: ブースト設定 + boosting_preferences_info_html: "Tip: 設定に関係なく、Shift を押しながら %{icon} Boostアイコンをクリックすると、すぐにブーストされます。" discovery: 見つける localization: body: Mastodonは有志によって翻訳されています。 @@ -1532,6 +1543,9 @@ ja: expires_at: 有効期限 uses: 使用 title: 新規ユーザーの招待 + link_preview: + potentially_sensitive_content: + hide_button: 非表示 lists: errors: limit: リストの上限数に達しています @@ -1596,7 +1610,6 @@ ja: disabled_account: 引っ越した後はデータのエクスポートと再有効化を除きほとんどの機能が利用できなくなります followers: すべてのフォロワーを現在のアカウントから新しいアカウントに引き継ぎます only_redirect_html: または、フォロワーを残したまま引っ越すこともできます。 - other_data: その他のデータは自動的に引き継がれません redirect: プロフィールに引っ越し済みの通知が表示され、検索結果から除外されます moderation: title: モデレーション @@ -1851,6 +1864,7 @@ ja: public: 誰でも title: '%{name}: "%{quote}"' visibilities: + direct: 非公開の返信 private: フォロワーのみ public: 公開 statuses_cleanup: diff --git a/config/locales/kab.yml b/config/locales/kab.yml index a8fd955ee48..62bc46143dc 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -285,6 +285,7 @@ kab: ip: Tansa IP providers: active: D urmid + base_url: URL n taffa delete: Kkes edit: Ẓreg asaǧǧaw finish_registration: Fakk ajerred @@ -393,6 +394,7 @@ kab: resolved: Fran status: Addad title: Ineqqisen + unknown_action_msg: 'Tigawt tarussint: %{action}' unresolved: Ur yefra ara updated_at: Yettwaleqqem view_profile: Wali amaɣnu @@ -438,6 +440,10 @@ kab: all: I medden akk disabled: Ɣef ula yiwen users: Ɣef yimseqdacen idiganen i yeqqnen + landing_page: + values: + about: Ɣef + trends: Inezzaɣ registrations: title: Ajerred registrations_mode: @@ -449,6 +455,7 @@ kab: delete: Kkes afaylu yulin software_updates: documentation_link: Issin ugar + title: Llan ileqman type: Anaw version: Lqem statuses: @@ -462,7 +469,9 @@ kab: language: Tutlayt media: title: Amidya + metadata: Iɣefisefka open: Ldi tasuffeɣt + quotes: Tinebdurin status_title: Tasuffeɣt sɣur @%{name} trending: Inezzaɣ visibility: Abani @@ -489,12 +498,16 @@ kab: terms_of_service: changelog: Amaynut create: Sqedcet ayla-nwen + current: Amiran draft: Arewway generates: action: Sirew + title: Tawila n tewtilin n useqdec history: Amazray live: Srid + notify_users: Selɣu iseqdacen publish: Asuffeɣ + published_on_html: Teffeɣ-d ass n %{date} save_draft: Sekles arewway title: Tiwtilin n useqdec title: Tadbelt @@ -504,6 +517,7 @@ kab: allow: Sireg aseɣwen title: Iseɣwan inezzaɣ statuses: + allow_account: Sireg ameskar title: Tisuffaɣ tinezzaɣ tags: dashboard: @@ -519,11 +533,13 @@ kab: new: create: Rnu alugen title: Rnu alugen n useqdac amaynut + title: Ilugan n yisem n useqdac warning_presets: add_new: Rnu amaynut delete: Kkes webhooks: delete: Kkes + disable: Kkes armad enable: Rmed enabled: D urmid admin_mailer: @@ -538,6 +554,7 @@ kab: new_trending_tags: title: Ihacṭagen inezzaɣ appearance: + advanced_settings: Iɣewwaren leqqayen discovery: Asnirem localization: body: Mastodon suqqlen-t-id yiwiziwen. @@ -545,7 +562,9 @@ kab: guide_link_text: Yal yiwen·t y·tezmer a ttekki. sensitive_content: Agbur amḥulfu application_mailer: + notification_preferences: Snifel imenyafen n imayl salutation: "%{name}," + settings: 'Snifel imenyafen n imayl: %{link}' view: 'Ẓaṛ:' view_profile: Ssken-d amaɣnu view_status: Ssken-d tasuffiɣt @@ -683,6 +702,7 @@ kab: filters: contexts: account: Imeɣna + home: Agejdan akked tebdarin notifications: Ilɣa thread: Idiwenniyen edit: @@ -722,6 +742,9 @@ kab: modes: merge: Smezdi overwrite: Semselsi + states: + finished: Immed + status: Addad types: blocking: Tabdart n yimiḍanen iweḥlen bookmarks: Ticraḍ @@ -751,6 +774,12 @@ kab: table: expires_at: Ad ifat di title: Ɛreḍ-d kra n yimdanen + link_preview: + author_html: S ɣur %{name} + potentially_sensitive_content: + action: Sit i uskan + confirm_visit: Tebɣiḍ s tidet ad teldiḍ aseɣwen-a? + hide_button: Ffer-it login_activities: authentication_methods: password: awal uffir @@ -824,6 +853,8 @@ kab: status: Addad n umiḍan rss: content_warning: 'Alɣu n ugbur :' + self_destruct: + title: Aqeddac-a ad yemdel sessions: activity: Armud aneggaru browser: Iminig @@ -862,6 +893,7 @@ kab: kai_os: KaiOS linux: Linux mac: macOS + unknown_platform: Tiɣeṛɣeṛt tarussint windows: Windows windows_mobile: Windows Mobile windows_phone: Tiliɣri Windows Phone @@ -900,6 +932,10 @@ kab: video: one: "%{count} n tbidyutt" other: "%{count} n tbidyutin" + content_warnings: + hide: Ffer tasuffeɣt + show: Sken-d ugar + default_language: Kif kif am tutlayt n wegrudem edited_at_html: Tettwaẓreg ass n %{date} pin_errors: reblog: Azuzer ur yezmir ara ad yili d unṭiḍ diff --git a/config/locales/ko.yml b/config/locales/ko.yml index e882368872b..7b624f55fb7 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -784,6 +784,8 @@ ko: view_dashboard_description: 사용자가 여러 통계정보를 볼 수 있는 대시보드에 접근할 수 있도록 허용 view_devops: 데브옵스 view_devops_description: Sidekiq과 pgHero 대시보드에 접근할 수 있도록 허용 + view_feeds: 실시간, 해시태그 피드 보기 + view_feeds_description: 서버 설정에 관계 없이 실시간과 해시태그 피드에 접근할 수 있도록 허용 title: 역할 rules: add_new: 규칙 추가 @@ -835,6 +837,16 @@ ko: all: 모두에게 disabled: 아무에게도 안 함 users: 로그인 한 사용자에게 + feed_access: + modes: + authenticated: 로그인한 사용자들만 + disabled: 특정한 사용자 역할 필요 + public: 모두 + landing_page: + values: + about: 정보 + local_feed: 로컬 피드 + trends: 유행 registrations: moderation_recommandation: 모두에게 가입을 열기 전에 적절하고 반응이 빠른 중재 팀을 데리고 있는지 확인해 주세요! preamble: 누가 이 서버에 계정을 만들 수 있는지 제어합니다. @@ -896,6 +908,7 @@ ko: title: 계정 게시물 - @%{name} trending: 유행 중 view_publicly: 공개시점으로 보기 + view_quoted_post: 인용된 게시물 보기 visibility: 공개 설정 with_media: 미디어 있음 strikes: @@ -1165,7 +1178,10 @@ ko: hint_html: 다른 계정에서 이 계정으로 옮기길 원하는 경우, 여기에서 별칭을 만들 수 있습니다, 기존 계정의 팔로워를 이쪽으로 옮기고 싶은 경우 필요한 과정입니다. 이 행동 자체는 해롭지 않고 되돌리기가 가능합니다.계정 이주는 이전 계정에서 착수하게 됩니다 remove: 별칭 연결 끊기 appearance: + advanced_settings: 고급 설정 animations_and_accessibility: 애니메이션과 접근성 + boosting_preferences: 부스팅 설정 + boosting_preferences_info_html: "팁: 설정에 관계 없이 %{icon}을 쉬프트+클릭하여 곧바로 부스트할 수 있습니다." discovery: 발견하기 localization: body: 마스토돈은 자원봉사자들에 의해 번역되었습니다. @@ -1547,6 +1563,13 @@ ko: expires_at: 만료 uses: 이용 수 title: 초대하기 + link_preview: + author_html: "%{name} 작성" + potentially_sensitive_content: + action: 클릭하여 보기 + confirm_visit: 정말로 이 링크를 여시겠습니까? + hide_button: 숨기기 + label: 민감한 컨텐츠일 수 있음 lists: errors: limit: 리스트 최대 개수를 초과합니다 @@ -1611,7 +1634,7 @@ ko: disabled_account: 이 계정은 완전한 사용이 불가능하게 됩니다. 하지만, 데이터 내보내기나 재활성화를 위해 접근할 수 있습니다. followers: 이 행동은 현재 계정의 모든 팔로워를 새 계정으로 이동시킵니다 only_redirect_html: 대신, 프로필에 리디렉션만 표시할 수도 있습니다. - other_data: 다른 어떤 데이터도 자동적으로 옮겨지지 않을 것입니다 + other_data: 다른 데이터는 자동으로 이전되지 않을 것입니다 (게시물, 팔로우 목록 등) redirect: 현재 계정 프로필은 리다이렉트 알림과 함께 업데이트 되며 검색에서 제외 됩니다 moderation: title: 중재 @@ -1854,6 +1877,9 @@ ko: other: "%{count} 개의 영상" boosted_from_html: "%{acct_link}의 글을 부스트" content_warning: '열람 주의: %{warning}' + content_warnings: + hide: 게시물 숨기기 + show: 더 보기 default_language: 화면 표시 언어와 동일하게 disallowed_hashtags: other: '허용되지 않은 해시태그를 포함하고 있습니다: %{tags}' @@ -1861,19 +1887,26 @@ ko: errors: in_reply_not_found: 답장하려는 게시물이 존재하지 않습니다. quoted_status_not_found: 인용하려는 게시물이 존재하지 않습니다. + quoted_user_not_mentioned: 개인 멘션에서 다른 사람의 게시물을 인용할 수 없습니다. over_character_limit: 최대 %{max}자까지 입력할 수 있습니다 pin_errors: direct: 멘션된 사용자들에게만 보이는 게시물은 고정될 수 없습니다 limit: 이미 너무 많은 게시물을 고정했습니다 ownership: 다른 사람의 게시물은 고정될 수 없습니다 reblog: 부스트는 고정될 수 없습니다 + quote_error: + not_available: 게시물 사용 불가 + pending_approval: 계류 중인 게시물 + revoked: 원작성자에 의해 게시물 삭제됨 quote_policies: followers: 팔로워만 nobody: 나만 public: 누구나 + quote_post_author: 인용된 %{acct} 님의 게시물 title: '%{name}: "%{quote}"' visibilities: direct: 개인 멘션 + private: 팔로워만 public: 공개 public_long: 마스토돈 내외 모두 unlisted: 조용한 공개 diff --git a/config/locales/ku.yml b/config/locales/ku.yml index a1b50a2befd..3c3da2ad102 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -1189,7 +1189,6 @@ ku: disabled_account: Ajimêra te ya heyî dê paşê bi tevahî neyê bikaranîn. Lê belê, tu dikarî bigihîje derxistinê daneyan û hem jî ji nû ve çalakkirinê. followers: Ev çalakî dê hemî şopînerên ji ajimêra heyî bar bike ajimêra nû only_redirect_html: Wekî din, tu dikarî tenê beralîkirinekê li ser profîla xwe bicîh bike . - other_data: Daneyên din dê bi xweberî neyên livandin redirect: Profîla ajimêra te ya heyî dê bi nîşeyeke beralîkirinê were nûve kirin û ji lêgerînan were bi dûrxistin moderation: title: Çavdêrî diff --git a/config/locales/lad.yml b/config/locales/lad.yml index c15f513ce22..90b04a78f1f 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -189,6 +189,7 @@ lad: create_relay: Kriya relevo create_unavailable_domain: Kriya domeno no desponivle create_user_role: Kriya rolo + create_username_block: Kriya regla de nombre de utilizador demote_user: Degrada utilizador destroy_announcement: Efasa pregon destroy_canonical_email_block: Efasa bloko de posta elektronika @@ -202,6 +203,7 @@ lad: destroy_status: Efasa publikasyon destroy_unavailable_domain: Efasa domeno no desponivle destroy_user_role: Efasa rolo + destroy_username_block: Suprime regla de nombre de utilizador disable_2fa_user: Inkapasita autentifikasyon en dos pasos disable_custom_emoji: Inkapasita emoji personalizados disable_relay: Dezaktiva relevo @@ -236,6 +238,7 @@ lad: update_report: Aktualiza raporto update_status: Aktualiza publikasyon update_user_role: Aktualiza rolo + update_username_block: Aktualiza regla de nombre de utilizador actions: approve_appeal_html: "%{name} acheto la solisitasyon de moderasyon de %{target}" approve_user_html: "%{name} acheto el enrejistramiento de %{target}" @@ -476,9 +479,12 @@ lad: ip: Adreso IP providers: active: Aktivo + base_url: URL baza delete: Efasa + edit: Edita prokurador finish_registration: Finaliza enrejistrasyon name: Nombre + providers: Prokuradores registration_requested: Enrejistrasyon rekerida registrations: confirm: Konfirma @@ -770,6 +776,8 @@ lad: description_html: Aunke la majorita afirma aver meldado i estar de akodro kon los terminos de servisyo, la djente normalmente no los melda asta dempues de ke surja algun problema. Az ke sea mas kolay ver las normas de tu sirvidor de un vistazo estipulándolas en una lista de puntos. Aprova ke kada norma sea corta i kolay, ama sin estar divididas en munchos puntos. edit: Edita regla empty: Dinguna regla del sirvidor tiene sido definida. + move_down: Mueve verso abasho + move_up: Mueve verso arriva title: Reglas del sirvidor translation: Traduksyon translations: Traduksyones @@ -950,13 +958,17 @@ lad: updated_msg: Konfigurasyon de etiketas aktualizada kon sukseso terms_of_service: changelog: Ke troko + create: Uza los tuyos current: Aktual + generate: Uza modelo generates: action: Djenera + title: Konfigurasyon de terminos de servisyo history: Istorya live: En bivo notify_users: Aviza a los utilizadores publish: Publika + published_on_html: Puvlikado el %{date} title: Terminos de servisyo title: Administrasyon trends: @@ -1028,10 +1040,19 @@ lad: block_registrations: Bloka enrejistrasyones comparison: contains: Kontyene + equals: Es egual a + contains_html: Kontyene %{string} + created_msg: Regla de nombre de utilizador kriyada kon reusho delete: Efasa + edit: + title: Edita regla de nombre de utilizador + matches_exactly_html: Es egual a %{string} new: create: Kriya regla + title: Kriya mueva regla de nombre de utilizador not_permitted: Sin permiso + title: Reglas de nombre de utilizador + updated_msg: Regla de nombre de utilizador aktualizada kon reusho warning_presets: add_new: Adjusta muevo delete: Efasa @@ -1532,7 +1553,6 @@ lad: disabled_account: Tu kuento aktual no sera kompletamente utilizable dempues. Portanto, tendras akseso a la eksportasyon de datos ansi komo a la reaktivasyon. followers: Esta aksion migrara a todos los suivantes del kuento aktual al muevo kuento only_redirect_html: Alternativamente, solo puedes poner un readreso en tu profil. - other_data: No se moveran otros datos otomatikamente redirect: El profil de tu kuento aktual se aktualizara kon un avizo de readreso i sera eskluido de las bushkedas moderation: title: Moderasyon diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 40078ed3264..ba8ec50efca 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -1644,7 +1644,6 @@ lv: disabled_account: Tavs pašreizējais konts pēc tam nebūs pilnībā lietojams. Tomēr tev būs piekļuve datu eksportēšanai, kā arī atkārtotai aktivizēšanai. followers: Veicot šo darbību, visi sekotāji tiks pārvietoti no pašreizējā konta uz jauno kontu only_redirect_html: Citādāk tu vari arī savā profilā ievietot tikai novirzīšanu. - other_data: Nekādi citi dati netiks automātiski pārvietoti redirect: Tava pašreizējā konta profils tiks atjaunināts ar novirzīšanas paziņojumu un tiks izslēgts no meklēšanas moderation: title: Satura pārraudzība diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 76d7bd4d209..a89ae262834 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -1321,7 +1321,6 @@ ms: disabled_account: Akaun semasa anda tidak akan dapat digunakan sepenuhnya selepas itu. Walau bagaimanapun, anda akan mempunyai akses kepada eksport data serta pengaktifan semula. followers: Tindakan ini akan mengalihkan semua pengikut daripada akaun semasa ke akaun baharu only_redirect_html: Sebagai alternatif, anda boleh hanya meletakkan ubah hala pada profil anda. - other_data: Tiada data lain akan dialihkan secara automatik redirect: Profil akaun semasa anda akan dikemas kini dengan notis ubah hala dan dikecualikan daripada carian moderation: title: Penyederhanaan diff --git a/config/locales/my.yml b/config/locales/my.yml index 687c350f3ef..90b0ca0a6d6 100644 --- a/config/locales/my.yml +++ b/config/locales/my.yml @@ -1316,7 +1316,6 @@ my: disabled_account: နောက်ပိုင်းတွင် သင့်လက်ရှိအကောင့်အား အပြည့်အဝအသုံးပြုနိုင်တော့မည်မဟုတ်သော်လည်း အချက်အလက်ထုတ်ယူခြင်းနှင့် ပြန်လည်အတည်ပြုခြင်းတို့ကို ဆောင်ရွက်နိုင်မည်ဖြစ်သည်။ followers: ဤလုပ်ဆောင်ချက်မှာ စောင့်ကြည့်သူအားလုံးကို လက်ရှိအကောင့်မှ အကောင့်အသစ်သို့ ရွှေ့ပြောင်းခြင်းဖြစ်သည် only_redirect_html: တနည်းအားဖြင့် သင်သည် သင့်ပရိုဖိုင်ပေါ်တွင် ပြန်ညွှန်းခြင်းကိုသာ ပြုလုပ်နိုင်သည်။ - other_data: အခြားအချက်အလက်များကို အလိုအလျောက်ရွှေ့မည်မဟုတ်ပါ redirect: သင့်လက်ရှိအကောင့်၏ပရိုဖိုင်ကို ပြန်လည်ညွှန်းပေးသည့်အသိပေးချက်ဖြင့် ပြင်ဆင်ပေးမည်ဖြစ်ပြီး ရှာဖွေမှုများမှ ဖယ်ထုတ်ပေးမည်ဖြစ်သည် moderation: title: စိစစ်ခြင်း diff --git a/config/locales/nan.yml b/config/locales/nan.yml index 8127cc56791..508cc46665d 100644 --- a/config/locales/nan.yml +++ b/config/locales/nan.yml @@ -841,6 +841,11 @@ nan: authenticated: Kan-ta hōo登入ê用者 disabled: 愛特別ê用者角色 public: Ta̍k lâng + landing_page: + values: + about: 關係本站 + local_feed: 本地ê動態 + trends: 趨勢 registrations: moderation_recommandation: 佇開放hōo ta̍k ê lâng註冊進前,請確認lí有夠額koh主動反應ê管理團隊! preamble: 控制ē當佇lí ê服侍器註冊ê人。 @@ -1213,6 +1218,46 @@ nan: redirect_to_app_html: Lí應該受重轉kàu %{app_name}應用程式,若是iáu-buē,試 %{clicking_this_link} á是手動轉去tsit ê應用程式。 registration_complete: Lí佇 %{domain} ê註冊完成ah! welcome_title: 歡迎 %{name}! + wrong_email_hint: Nā是電子phue ê地址無正確,lí ē當tī口座設定kā改。 + delete_account: Thâi掉口座 + delete_account_html: Nā lí behthâi掉lí ê口座,lí ē當ji̍h tsia繼續。Lí著確認動作。 + description: + prefix_invited_by_user: "@%{name} 邀請lí加入tsit ê Mastodon 服侍器!" + prefix_sign_up: Tsit-má註冊Mastodon ê口座! + suffix: 有口座,lí當tuì ta̍k ê Mastodon 服侍器跟tuè lâng、PO更新kap交換訊息等等! + didnt_get_confirmation: Kám無收著確認ê連結? + dont_have_your_security_key: Lí iáu無安全鎖(security key)? + forgot_password: 密碼be記得? + invalid_reset_password_token: 重新設密碼ê token無效á是過期ah。請重頭the̍h新ê。 + link_to_otp: 請tuì lí ê手機á輸入雙因素認證(2FA)ê碼,á是恢復碼。 + link_to_webauth: 用lí ê安全鎖ê裝置 + log_in_with: 登入用 + login: 登入 + logout: 登出 + migrate_account: 轉kàu無kâng ê口座 + migrate_account_html: Nā lí ǹg望引tshuā別人tuè無kâng ê口座,請 kàutsia設定。 + or_log_in_with: Á是登入用 + progress: + confirm: 確認電子phue + details: Lí ê詳細 + review: Lán ê審查 + rules: 接受規則 + providers: + cas: CAS + saml: SAML + register: 註冊 + registration_closed: "%{instance} 無接受新ê成員" + resend_confirmation: 重送確認ê連結 + reset_password: 重設密碼 + rules: + accept: 接受 + back: Tńg去 + invited_by: Lí通用有tuì hia收著ê邀請加入 %{domain}: + preamble: Tsiah-ê hōo %{domain} ê管理員設定kap實施。 + preamble_invited: 佇lí繼續進前,請思考 %{domain} ê管理員設立ê基本規則。 + title: Tsi̍t-kuá基本規定。 + title_invited: Lí受邀請ah。 + security: 安全 scheduled_statuses: too_soon: Tio̍h用未來ê日期。 statuses: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 9179337c6f2..19adee033ff 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1672,7 +1672,7 @@ nl: disabled_account: Jouw huidige account is hierna niet meer volledig bruikbaar. Je hebt echter wel toegang tot het exporteren van je gegevens en tot het opnieuw activeren van je account. followers: Deze actie verhuist alle volgers vanaf het huidige account naar het nieuwe account only_redirect_html: Je kunt als alternatief ook alleen de doorverwijzing op je profiel zetten. - other_data: Geen andere gegevens worden automatisch verhuisd + other_data: Geen andere gegevens worden automatisch verhuisd (inclusief jouw berichten en de lijst met accounts die je volgt) redirect: Jouw huidige accountprofiel wordt bijgewerkt met een doorverwijzingsmelding en wordt uitgesloten van zoekresultaten moderation: title: Moderatie @@ -1929,6 +1929,7 @@ nl: errors: in_reply_not_found: Het bericht waarop je probeert te reageren lijkt niet te bestaan. quoted_status_not_found: Het bericht die je probeert te citeren lijkt niet te bestaan. + quoted_user_not_mentioned: Een niet-vermelde gebruiker kan niet in een privébericht worden geciteerd. over_character_limit: Limiet van %{max} tekens overschreden pin_errors: direct: Berichten die alleen zichtbaar zijn voor vermelde gebruikers, kunnen niet worden vastgezet diff --git a/config/locales/nn.yml b/config/locales/nn.yml index c3e37405c5e..51ba5f6b2fc 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -796,6 +796,8 @@ nn: view_dashboard_description: Gir brukere tilgang til dashbordet og ulike metrikker view_devops: DevOps view_devops_description: Gir brukere tilgang til Sidekiq og pgHero-dashbord + view_feeds: Sjå direktestraumar og emnestraumar + view_feeds_description: La brukarar sjå direkte- og emnestraumane uansett innstillingar på tenaren title: Roller rules: add_new: Legg til regel @@ -843,7 +845,7 @@ nn: public_timelines: Offentlege tidsliner publish_statistics: Publiser statistikk title: Oppdaging - trends: Trender + trends: Populært domain_blocks: all: Til alle disabled: Til ingen @@ -851,7 +853,13 @@ nn: feed_access: modes: authenticated: Berre godkjende brukarar + disabled: Krev ei spesifikk brukarrolle public: Alle + landing_page: + values: + about: Om + local_feed: Lokal tidsline + trends: Populært registrations: moderation_recommandation: Pass på at du har mange og kjappe redaktørar og moderatorar på laget ditt før du opnar for allmenn registrering! preamble: Kontroller kven som kan oppretta konto på tenaren din. @@ -1664,7 +1672,6 @@ nn: disabled_account: Din nåværende konto vil ikke være fullt brukbar etterpå. Men du vil ha tilgang til dataeksportering såvel som reaktivering. followers: Denne handlinga flyttar alle fylgjarar frå denne kontoen til den nye only_redirect_html: Alternativt kan du velge å bare legge ut en omdirigering på profilen din. - other_data: Inkje anna data flyttast av seg sjølve redirect: Profilen til din nåværende konto vil bli oppdatert med en omdirigeringsnotis og bli fjernet fra søk moderation: title: Moderasjon @@ -1921,6 +1928,7 @@ nn: errors: in_reply_not_found: Det ser ut til at tutet du freistar å svara ikkje finst. quoted_status_not_found: Innlegget du prøver å sitera ser ikkje ut til å finnast. + quoted_user_not_mentioned: Kan ikkje sitera ein person som ikkje er nemnd i direktemeldingar. over_character_limit: øvregrensa for teikn, %{max}, er nådd pin_errors: direct: Innlegg som bare er synlige for nevnte brukere kan ikke festes diff --git a/config/locales/no.yml b/config/locales/no.yml index f627c931848..81bdb2467ca 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -1385,7 +1385,6 @@ disabled_account: Din nåværende konto vil ikke være fullt brukbar etterpå. Men du vil ha tilgang til dataeksportering såvel som reaktivering. followers: Denne handlingen vil flytte alle følgere fra den nåværende kontoen til den nye kontoen only_redirect_html: Alternativt kan du velge å bare legge ut en omdirigering på profilen din. - other_data: Ingen andre data vil bli flyttet automatisk redirect: Profilen til din nåværende konto vil bli oppdatert med en omdirigeringsnotis og bli fjernet fra søk moderation: title: Moderasjon diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 1e34dcc6ea4..3d9fbd77453 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -668,7 +668,6 @@ oc: warning: before: 'Abans de contunhar, volgatz legir aquestas nòtas amb atencion :' only_redirect_html: Autrament, podètz solament definir una redireccion sus vòstre perfil. - other_data: Cap d’autra donada serà desplaçada automaticament moderation: title: Moderacion notification_mailer: diff --git a/config/locales/pl.yml b/config/locales/pl.yml index cea6bf5ee4e..5084ccc4cee 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1715,7 +1715,6 @@ pl: disabled_account: Twoje obecne konto nie będzie później całkowicie użyteczne. Możesz jednak uzyskać dostęp do eksportu danych i ponownie aktywować je. followers: To działanie przeniesie wszystkich Twoich obserwujących z obecnego konta na nowe only_redirect_html: Możesz też po prostu skonfigurować przekierowanie na swój profil. - other_data: Żadne inne dane nie zostaną automatycznie przeniesione redirect: Twoje obecne konto zostanie uaktualnione o informację o przeniesieniu i wyłączone z wyszukiwania moderation: title: Moderacja diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 44e6d18311e..1ae00ddc934 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -796,6 +796,8 @@ pt-BR: view_dashboard_description: Permite que os usuários acessem o painel e várias métricas view_devops: DevOps view_devops_description: Permite aos usuários acessar os painéis da Sidekiq e pgHero + view_feeds: Veja transmissões ao vivo e por tópico + view_feeds_description: Permite que os usuários acessem os feeds ao vivo e por tópico, independentemente das configurações do servidor title: Funções rules: add_new: Adicionar regra @@ -837,6 +839,7 @@ pt-BR: title: Optar por excluir usuários da indexação de mecanismos de pesquisa por padrão discovery: follow_recommendations: Seguir recomendações + preamble: A exibição de conteúdo interessante é fundamental para a integração de novos usuários que podem não conhecer ninguém no Mastodon. Controle o funcionamento de vários recursos de descoberta no seu servidor. privacy: Privacidade profile_directory: Diretório de perfis public_timelines: Timelines públicas @@ -1196,6 +1199,7 @@ pt-BR: advanced_settings: Configurações avançadas animations_and_accessibility: Animações e acessibilidade boosting_preferences: Adicionar preferências + boosting_preferences_info_html: "Dica: Independentemente das configurações, Shift + Clique no ícone %{icon} Boost irá impulsionar imediatamente." discovery: Descobrir localization: body: Mastodon é traduzido por voluntários. @@ -1668,7 +1672,6 @@ pt-BR: disabled_account: Sua conta não estará totalmente funcional ao término deste processo. Entretanto, você terá acesso à exportação de dados bem como à reativação. followers: Esta ação moverá todos os seguidores da conta atual para a nova conta only_redirect_html: Alternativamente, você pode apenas colocar um redirecionamento no seu perfil. - other_data: Nenhum outro dado será movido automaticamente redirect: O perfil atual da sua conta será atualizado com um aviso de redirecionamento e também será excluído das pesquisas moderation: title: Moderação diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 24a21f886c5..32afa809e9e 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1672,7 +1672,7 @@ pt-PT: disabled_account: Posteriormente, a tua conta atual não será totalmente utilizável. No entanto, continuarás a ter acesso à exportação de dados, bem como à reativação. followers: Esta ação irá migrar todos os seguidores da conta atual para a nova conta only_redirect_html: Em alternativa, podes apenas colocar um redirecionamento no teu perfil. - other_data: Nenhum outro dado será migrado automaticamente + other_data: Não serão movidos automaticamente mais nenhuns dados (incluindo as suas publicações e a lista de contas que segue) redirect: O perfil da tua conta atual será atualizado com um aviso de redirecionamento e será excluído das pesquisas moderation: title: Moderação @@ -1929,6 +1929,7 @@ pt-PT: errors: in_reply_not_found: A publicação a que estás a tentar responder parece não existir. quoted_status_not_found: A publicação que está a tentar citar parece não existir. + quoted_user_not_mentioned: Um utilizador não mencionado não pode ser citado numa publicação privada. over_character_limit: limite de caracteres %{max} excedido pin_errors: direct: As publicações que só são visíveis para os utilizadores mencionados não podem ser fixadas diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 7ea9083c8fa..b7ca4eed33e 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1706,7 +1706,6 @@ ru: disabled_account: Переезд приведёт к тому, что вашу текущую учётную запись нельзя будет полноценно использовать. Тем не менее у вас останется доступ к экспорту данных и повторной активации учётной записи. followers: В результате переезда все ваши подписчики будут перенесены с текущей учётной записи на новую only_redirect_html: Также вы можете настроить перенаправление без переноса подписчиков. - other_data: Никакие другие данные не будут автоматически перенесены redirect: Профиль текущей учётной записи будет исключён из поиска, а в нём появится объявление о переезде moderation: title: Модерация diff --git a/config/locales/sc.yml b/config/locales/sc.yml index 5757e49077d..55bb21608d4 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -951,7 +951,6 @@ sc: disabled_account: A pustis, su contu atuale tuo no at a èssere prus operativu in manera cumpleta. Sende gasi, as a tènnere atzessu a s'esportatzione de datos e a sa re-ativatzione. followers: Custa atzione at a tramudare totu sa gente chi ti sighit dae su contu atuale a su contu nou only_redirect_html: In alternativa, podes isceti cunfigurare un'indiritzamentu in su profilu tuo. - other_data: Perunu àteru datu at a èssere tramudadu in automàticu redirect: Su profilu de su contu atuale tuo at a èssere atualizadu cun un'avisu de indiritzamentu e at a èssere esclùidu dae is chircas moderation: title: Moderatzione diff --git a/config/locales/sco.yml b/config/locales/sco.yml index 777bd10ef93..8aa4454f0b2 100644 --- a/config/locales/sco.yml +++ b/config/locales/sco.yml @@ -1179,7 +1179,6 @@ sco: disabled_account: Yer current accoont wullnae be fully uisable efterwart. Hou an iver, ye wull hae access tae data export as weil as re-activation. followers: This action wull flit aw follaers fae the current accoont tae the new accoont only_redirect_html: Alternatively, ye kin ainly pit up a redirect on yer profile. - other_data: Nae ither data wull get flittit automatically redirect: Yer current accoont's profile wull get updatit wi a redirect note an be excludit fae seirches moderation: title: Moderation diff --git a/config/locales/si.yml b/config/locales/si.yml index dee5e3bb959..9c3ff9c904d 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -1067,7 +1067,6 @@ si: disabled_account: ඔබගේ ජංගම ගිණුම පසුව සම්පූර්ණයෙන්ම භාවිතා කළ නොහැක. කෙසේ වෙතත්, ඔබට දත්ත අපනයනයට මෙන්ම නැවත සක්‍රිය කිරීමට ප්‍රවේශය ඇත. followers: මෙම ක්‍රියාව සියළුම අනුගාමිකයින් ජංගම ගිණුමේ සිට නව ගිණුමට ගෙන යනු ඇත only_redirect_html: විකල්පයක් ලෙස, ඔබට ඔබගේ පැතිකඩහි යළි-යොමුවීමක් පමණක් තැබිය හැකිය. - other_data: වෙනත් දත්ත කිසිවක් ස්වයංක්‍රීයව ගෙන නොයනු ඇත redirect: ඔබගේ ජංගම ගිණුමේ පැතිකඩ යළි-යොමු කිරීමේ දැන්වීමක් සමඟ යාවත්කාලීන කෙරෙන අතර සෙවුම් වලින් බැහැර කරනු ලැබේ moderation: title: මැදිහත්කරණය diff --git a/config/locales/simple_form.an.yml b/config/locales/simple_form.an.yml index 971ba5851db..b720cc17600 100644 --- a/config/locales/simple_form.an.yml +++ b/config/locales/simple_form.an.yml @@ -60,13 +60,11 @@ an: featured_tag: name: 'Aquí son belunas d''as etiquetas que mas has utilizau recientment:' filters: - action: Triar qué acción realizar quan una publicación coincide con o filtro actions: hide: Amagar completament lo conteniu filtrau, comportando-se como si no existise warn: Amagar lo conteniu filtrau dezaga d'una alvertencia mencionando lo titol d'o filtro form_admin_settings: activity_api_enabled: Conteyo de publicacions locals, usuarios activos y nuevos rechistros en periodos semanals - bootstrap_timeline_accounts: Estas cuentas amaneixerán en a parte superior d'as recomendacions d'os nuevos usuarios. closed_registrations_message: Amostrau quan los rechistros son zarraus custom_css: Puetz aplicar estilos personalizaus a la versión web de Mastodon. mascot: Reemplaza la ilustración en a interficie web abanzada. diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index 75ed51833f6..79d5f033f16 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -73,7 +73,6 @@ ar: featured_tag: name: 'فيما يلي بعض الوسوم التي استخدمتها مؤخراً:' filters: - action: اختر الإجراء الذي سينفذ عند تطابق المشاركة فلتر التصفية actions: blur: إخفاء الوسائط وراء تحذير، دون إخفاء النص نفسه hide: إخفاء المحتويات التي تم تصفيتها، والتصرف كما لو أنها غير موجودة @@ -82,7 +81,6 @@ ar: activity_api_enabled: عدد المنشورات المحلية و المستخدمين الناشطين و التسجيلات الأسبوعية الجديدة app_icon: WEBP أو PNG أو GIF أو JPG. يتجاوز أيقونة التطبيق الافتراضية على الجوالات مع أيقونة مخصصة. backups_retention_period: للمستخدمين القدرة على إنشاء أرشيفات لمنشوراتهم لتحميلها في وقت لاحق. عند التعيين إلى قيمة موجبة، سيتم حذف هذه الأرشيف تلقائياً من وحدة تخزينك بعد عدد الأيام المحدد. - bootstrap_timeline_accounts: سيتم تثبيت هذه الحسابات على قمة التوصيات للمستخدمين الجدد. closed_registrations_message: ما سيعرض عند إغلاق التسجيلات content_cache_retention_period: سيتم حذف جميع المنشورات من الخوادم الأخرى (بما في ذلك التعزيزات والردود) بعد عدد الأيام المحدد، دون أي تفاعل محلي للمستخدم مع هذه المنشورات. وهذا يشمل المنشورات التي قام المستخدم المحلي بوضع علامة عليها كإشارات مرجعية أو المفضلة. وسوف تختفي أيضا الإشارات الخاصة بين المستخدمين من المثيلات المختلفة ويستحيل استعادتها. والغرض من استخدام هذا الإعداد هو مثيلات الغرض الخاص ويفسد الكثير من توقعات المستخدمين عند تنفيذها للاستخدام لأغراض عامة. custom_css: يمكنك تطبيق أساليب مخصصة على نسخة الويب من ماستدون. diff --git a/config/locales/simple_form.be.yml b/config/locales/simple_form.be.yml index c097562a2a2..eac024fa703 100644 --- a/config/locales/simple_form.be.yml +++ b/config/locales/simple_form.be.yml @@ -79,7 +79,7 @@ be: featured_tag: name: 'Вось некаторыя з хэштэгаў, якімі вы нядаўна карысталіся:' filters: - action: Абярыце, што зрабіць, калі допіс падпадае пад умовы фільтру + action: Выберыце, што трэба рабіць, калі допіс супадзе з фільтрам actions: blur: Схавайце медыя за знакам папярэджання, не хаваючы пры гэтым тэкст hide: Поўнасцю схаваць адфільтраванае змесціва, дзейнічаць, нібы яго не існуе @@ -88,7 +88,7 @@ be: activity_api_enabled: Падлік лакальна апублікаваных пастоў, актыўных карыстальнікаў і новых рэгістрацый у тыдзень app_icon: WEBP, PNG, GIF ці JPG. Заменіце прадвызначаны значок праграмы на мабільных прыладах карыстальніцкім значком. backups_retention_period: Карыстальнікі могуць ствараць архівы сваіх допісаў для наступнай запампоўкі. Пры станоўчай колькасці дзён гэтыя архівы будуць аўтаматычна выдаляцца са сховішча пасля заканчэння названай колькасці дзён. - bootstrap_timeline_accounts: Гэтыя ўліковыя запісы будуць замацаваны ў топе рэкамендацый для новых карыстальнікаў. + bootstrap_timeline_accounts: Гэтыя ўліковыя запісы будуць прымацаваныя наверсе рэкамендацый для новых карыстальнікаў. Дайце спіс уліковых запісаў, выкарыстоўваючы коску, каб раздзяліць іх. closed_registrations_message: Паказваецца, калі рэгістрацыя закрытая content_cache_retention_period: Усе допісы з іншых сервераў (разам з пашырэннямі і адказамі) будуць выдалены праз паказаную колькасць дзён, незалежна ад таго, як лакальны карыстальнік узаемадзейнічаў з гэтымі допісамі. Гэта датычыцца і тых допісаў, якія лакальны карыстальнік пазначыў у закладкі або ўпадабанае. Прыватныя згадванні паміж карыстальнікамі з розных экзэмпляраў сервераў таксама будуць страчаны і іх нельга будзе аднавіць. Выкарыстанне гэтай налады прызначана для экзэмпляраў сервераў спецыяльнага прызначэння і парушае многія чаканні карыстальнікаў пры выкарыстанні ў агульных мэтах. custom_css: Вы можаце прымяняць карыстальніцкія стылі ў вэб-версіі Mastodon. diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml index e14b05ed901..2306109b6bd 100644 --- a/config/locales/simple_form.bg.yml +++ b/config/locales/simple_form.bg.yml @@ -74,7 +74,6 @@ bg: featured_tag: name: 'Ето няколко хаштага, които последно сте използвали:' filters: - action: Изберете кое действие да се извърши, прецеждайки съвпаденията на публикацията actions: blur: Скриване на мултимедия зад предупреждение, но без скриване на самия текст hide: Напълно скриване на филтрираното съдържание, сякаш не съществува @@ -83,7 +82,6 @@ bg: activity_api_enabled: Броят на местните публикувани публикации, дейни потребители и нови регистрации в седмични кофи app_icon: WEBP, PNG, GIF или JPG. Заменя подразбиращата се икона на приложението в мобилни устройства с произволна икона. backups_retention_period: Потребителите имат способността да пораждат архиви от публикациите си за по-късно изтегляне. Задавайки положителна стойност, тези архиви самодейно ще се изтрият от хранилището ви след определения брой дни. - bootstrap_timeline_accounts: Тези акаунти ще се закачат в горния край на препоръките за следване на нови потребители. closed_registrations_message: Показва се, когато е затворено за регистрации content_cache_retention_period: Всички публикации от други сървъри, включително подсилвания и отговори, ще се изтрият след посочения брой дни, без да се взема предвид каквото и да е взаимодействие на местния потребител с тези публикации. Това включва публикации, които местния потребител е означил като отметки или любими. Личните споменавания между потребители от различни инстанции също ще се загубят и невъзможно да се възстановят. Употребата на тази настройка е предназначена за случаи със специално предназначение и разбива очакванията на много потребители, когато се изпълнява за употреба с общо предназначение. custom_css: Може да прилагате собствени стилове в уебверсията на Mastodon. diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml index ceca6b0e7fc..776465c62c0 100644 --- a/config/locales/simple_form.ca.yml +++ b/config/locales/simple_form.ca.yml @@ -76,7 +76,7 @@ ca: featured_tag: name: 'Aquí estan algunes de les etiquetes que més has usat recentment:' filters: - action: Tria quina acció cal executar quan un apunt coincideixi amb el filtre + action: Trieu quina acció executar quan una publicació coincideixi amb el filtre actions: blur: Amaga el contingut multimèdia rere un avís, sense amagar el text en si hide: Ocultar completament el contingut filtrat, comportant-se com si no existís @@ -85,7 +85,6 @@ ca: activity_api_enabled: Contador de tuts publicats localment, usuaris actius i registres nous en períodes setmanals app_icon: WEBP, PNG, GIF o JPG. Canvia la icona per defecte de l'app en dispositius mòbils per una de personalitzada. backups_retention_period: Els usuaris poden generar arxius de les seves publicacions per a baixar-los més endavant. Quan tingui un valor positiu, els arxius s'esborraran del vostre emmagatzematge després del nombre donat de dies. - bootstrap_timeline_accounts: Aquests comptes es fixaran en la part superior de les recomanacions de seguiment dels nous usuaris. closed_registrations_message: Es mostra quan el registres estan tancats content_cache_retention_period: S'esborraran totes les publicacions d'altres servidors (impulsos i respostes inclosos) passats els dies indicats, sense tenir en consideració les interaccions d'usuaris locals amb aquestes publicacions. Això inclou les publicacions que un usuari local hagi marcat com a favorites. També es perdran, i no es podran recuperar, les mencions privades entre usuaris d'instàncies diferents. Aquest paràmetre està pensat per a instàncies amb un propòsit especial i trencarà les expectatives dels usuaris si s'utilitza en una instància convencional. custom_css: Pots aplicar estils personalitzats en la versió web de Mastodon. diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml index cd5a51901a7..8570d6ea02b 100644 --- a/config/locales/simple_form.cs.yml +++ b/config/locales/simple_form.cs.yml @@ -79,7 +79,7 @@ cs: featured_tag: name: 'Zde jsou některé z hashtagů, které jste nedávno použili:' filters: - action: Vyberte, jakou akci provést, když příspěvek odpovídá filtru + action: Vyberte, která akce má být provedena, když příspěvek odpovídá filtru actions: blur: Skrýt média za varováním, bez skrytí samotného textu hide: Úplně schovat filtrovaný obsah tak, jako by neexistoval @@ -88,7 +88,7 @@ cs: activity_api_enabled: Počty lokálně zveřejnělých příspěvků, aktivních uživatelů a nových registrací v týdenních intervalech app_icon: WEBP, PNG, GIF nebo JPG. Nahradí výchozí ikonu aplikace v mobilních zařízeních vlastní ikonou. backups_retention_period: Uživatelé mají možnost vytvářet archivy svých příspěvků, které si mohou stáhnout později. Pokud je nastaveno na kladnou hodnotu, budou tyto archivy po zadaném počtu dní automaticky odstraněny z úložiště. - bootstrap_timeline_accounts: Tyto účty budou připnuty na vrchol nových uživatelů podle doporučení. + bootstrap_timeline_accounts: Tyto účty budou připnuty na vrcholu doporučení pro nové uživatele. Napište čárkou oddělený seznam účtů. closed_registrations_message: Zobrazeno při zavření registrace content_cache_retention_period: Všechny příspěvky z jiných serverů (včetně boostů a odpovědí) budou po uplynutí stanoveného počtu dní smazány bez ohledu na interakci místního uživatele s těmito příspěvky. To se týká i příspěvků, které místní uživatel přidal do záložek nebo oblíbených. Soukromé zmínky mezi uživateli z různých instancí budou rovněž ztraceny a nebude možné je obnovit. Použití tohoto nastavení je určeno pro instance pro speciální účely a při implementaci pro obecné použití porušuje mnohá očekávání uživatelů. custom_css: Můžete použít vlastní styly ve verzi Mastodonu. diff --git a/config/locales/simple_form.cy.yml b/config/locales/simple_form.cy.yml index 0f79229caa9..f53e4f16ca9 100644 --- a/config/locales/simple_form.cy.yml +++ b/config/locales/simple_form.cy.yml @@ -79,7 +79,7 @@ cy: featured_tag: name: 'Dyma rai o’r hashnodau a ddefnyddioch chi''n ddiweddar:' filters: - action: Dewiswch pa weithred i'w chyflawni pan fydd postiad yn cyfateb i'r hidlydd + action: Dewiswch pa weithred i'w gyflawni pan fydd postiad yn cyd-fynd â'r hidlydd actions: blur: Cuddio cyfryngau tu ôl i rybudd, heb guddio'r testun ei hun hide: Cuddiwch y cynnwys wedi'i hidlo'n llwyr, gan ymddwyn fel pe na bai'n bodoli @@ -88,11 +88,12 @@ cy: activity_api_enabled: Cyfrif o bostiadau a gyhoeddir yn lleol, defnyddwyr gweithredol, a chofrestriadau newydd mewn bwcedi wythnosol app_icon: WEBP, PNG, GIF neu JPG. Yn diystyru'r eicon ap rhagosodedig ar ddyfeisiau symudol gydag eicon cyfaddas. backups_retention_period: Mae gan ddefnyddwyr y gallu i gynhyrchu archifau o'u postiadau i'w llwytho i lawr yn ddiweddarach. Pan gânt eu gosod i werth positif, bydd yr archifau hyn yn cael eu dileu'n awtomatig o'ch storfa ar ôl y nifer penodedig o ddyddiau. - bootstrap_timeline_accounts: Bydd y cyfrifon hyn yn cael eu pinio i frig argymhellion dilynol defnyddwyr newydd. + bootstrap_timeline_accounts: Bydd y cyfrifon yma'n cael eu pinio i frig argymhellion dilyn defnyddwyr newydd. Darparwch restr cyfrifon wedi'u gwahanu gan gollnod. closed_registrations_message: Yn cael eu dangos pan fydd cofrestriadau wedi cau content_cache_retention_period: Bydd yr holl bostiadau gan weinyddion eraill (gan gynnwys hwb ac atebion) yn cael eu dileu ar ôl y nifer penodedig o ddyddiau, heb ystyried unrhyw ryngweithio defnyddiwr lleol â'r postiadau hynny. Mae hyn yn cynnwys postiadau lle mae defnyddiwr lleol wedi ei farcio fel nodau tudalen neu ffefrynnau. Bydd cyfeiriadau preifat rhwng defnyddwyr o wahanol achosion hefyd yn cael eu colli ac yn amhosibl eu hadfer. Mae'r defnydd o'r gosodiad hwn wedi'i fwriadu ar gyfer achosion pwrpas arbennig ac mae'n torri llawer o ddisgwyliadau defnyddwyr pan gaiff ei weithredu at ddibenion cyffredinol. custom_css: Gallwch gymhwyso arddulliau cyfaddas ar fersiwn gwe Mastodon. favicon: WEBP, PNG, GIF neu JPG. Yn diystyru'r favicon Mastodon rhagosodedig gydag eicon cyfaddas. + landing_page: Yn dewis pa dudalen y mae ymwelwyr newydd yn ei gweld pan fyddan nhw'n cyrraedd eich gweinydd am y tro cyntaf. Os dewiswch "Trendio", yna mae angen galluogi tueddiadau yn y Gosodiadau Darganfod. Os dewiswch "Ffrydiau lleol", yna mae angen gosod "Mynediad i ffrydiau byw sy'n cynnwys postiadau lleol" i "Pawb" yn y Gosodiadau Darganfod. mascot: Yn diystyru'r darlun yn y rhyngwyneb gwe uwch. media_cache_retention_period: Mae ffeiliau cyfryngau o bostiadau a wneir gan ddefnyddwyr o bell yn cael eu storio ar eich gweinydd. Pan gaiff ei osod i werth positif, bydd y cyfryngau yn cael eu dileu ar ôl y nifer penodedig o ddyddiau. Os gofynnir am y data cyfryngau ar ôl iddo gael ei ddileu, caiff ei ail-lwytho i lawr, os yw'r cynnwys ffynhonnell yn dal i fod ar gael. Oherwydd cyfyngiadau ar ba mor aml y mae cardiau rhagolwg cyswllt yn pleidleisio i wefannau trydydd parti, argymhellir gosod y gwerth hwn i o leiaf 14 diwrnod, neu ni fydd cardiau rhagolwg cyswllt yn cael eu diweddaru ar alw cyn yr amser hwnnw. min_age: Mae gofyn i ddefnyddwyr gadarnhau eu dyddiad geni wrth gofrestru @@ -290,6 +291,7 @@ cy: content_cache_retention_period: Cyfnod cadw cynnwys o bell custom_css: CSS cyfaddas favicon: Favicon + landing_page: Tudalen cychwyn ar gyfer ymwelwyr newydd local_live_feed_access: Mynediad i ffrydiau byw sy'n cynnwys postiadau lleol local_topic_feed_access: Mynediad i ffrydiau hashnod a dolenni sy'n cynnwys postiadau lleol mascot: Mascot cyfaddas (hen) diff --git a/config/locales/simple_form.da.yml b/config/locales/simple_form.da.yml index 6c5711aa5fc..c4b539010b6 100644 --- a/config/locales/simple_form.da.yml +++ b/config/locales/simple_form.da.yml @@ -88,7 +88,7 @@ da: activity_api_enabled: Antal lokalt opslåede indlæg, aktive brugere samt nye tilmeldinger i ugentlige opdelinger app_icon: WEBP, PNG, GIF eller JPG. Tilsidesætter standard app-ikonet på mobilenheder med et tilpasset ikon. backups_retention_period: Brugere har mulighed for at generere arkiver af deres indlæg til senere downloade. Når sat til positiv værdi, vil disse arkiver automatisk blive slettet fra lagerpladsen efter det angivne antal dage. - bootstrap_timeline_accounts: Disse konti fastgøres øverst på nye brugeres følg-anbefalinger. + bootstrap_timeline_accounts: Disse konti vil blive fastgjort til toppen af nye brugeres følg-anbefalinger. Angiv en kommasepareret liste over konti. closed_registrations_message: Vises, når tilmeldinger er lukket content_cache_retention_period: Alle indlæg fra andre servere (herunder fremhævelser og besvarelser) slettes efter det angivne antal dage uden hensyn til lokal brugerinteraktion med disse indlæg. Dette omfatter indlæg, hvor en lokal bruger har markeret dem som bogmærker eller favoritter. Private omtaler mellem brugere fra forskellige instanser vil også være tabt og umulige at gendanne. Brugen af denne indstilling er beregnet til særlige formål instanser og bryder mange brugerforventninger ved implementering til almindelig brug. custom_css: Man kan anvende tilpassede stilarter på Mastodon-webversionen. diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index 74b6e5d9ef2..c3539839adc 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -54,8 +54,10 @@ de: password: Verwende mindestens 8 Zeichen phrase: Wird unabhängig von der Groß- und Kleinschreibung im Text oder der Inhaltswarnung eines Beitrags abgeglichen scopes: Welche Schnittstellen der Applikation erlaubt sind. Wenn du einen Top-Level-Scope auswählst, dann musst du nicht jeden einzelnen darunter auswählen. + setting_advanced_layout: Dadurch wird Mastodon in mehrere Spalten aufgeteilt, womit du deine Timeline, Benachrichtigungen und eine dritte Spalte deiner Wahl nebeneinander siehst. Nicht bei einem kleinen Bildschirm empfohlen. setting_aggregate_reblogs: Beiträge, die erst kürzlich geteilt wurden, werden nicht noch einmal angezeigt (betrifft nur zukünftig geteilte Beiträge) setting_always_send_emails: Normalerweise werden Benachrichtigungen nicht per E-Mail versendet, wenn du gerade auf Mastodon aktiv bist + setting_boost_modal: Dadurch wird beim Teilen ein Bestätigungsdialog angezeigt, um die Sichtbarkeit anzupassen. setting_default_quote_policy_private: Beiträge, die nur für deine Follower bestimmt sind und auf Mastodon verfasst wurden, können nicht von anderen zitiert werden. setting_default_quote_policy_unlisted: Sollten dich andere zitieren, werden ihre zitierten Beiträge ebenfalls nicht in den Trends und öffentlichen Timelines angezeigt. setting_default_sensitive: Medien, die mit einer Inhaltswarnung versehen worden sind, werden – je nach Einstellung – erst nach einem zusätzlichen Klick angezeigt @@ -63,6 +65,7 @@ de: setting_display_media_hide_all: Medien immer ausblenden setting_display_media_show_all: Medien mit Inhaltswarnung immer anzeigen setting_emoji_style: 'Wie Emojis dargestellt werden: „Automatisch“ verwendet native Emojis, für veraltete Browser wird jedoch Twemoji verwendet.' + setting_quick_boosting_html: Dadurch wird der Beitrag beim Anklicken des %{boost_icon} Teilen-Symbols sofort geteilt, anstatt das Drop-down-Menü zu öffnen. Die Möglichkeit zum Zitieren wird dabei in %{options_icon} Mehr verschoben. setting_system_scrollbars_ui: Betrifft nur Desktop-Browser, die auf Chrome oder Safari basieren setting_use_blurhash: Der Farbverlauf basiert auf den Farben der ausgeblendeten Medien, verschleiert aber jegliche Details setting_use_pending_items: Neue Beiträge hinter einem Klick verstecken, anstatt automatisch zu scrollen @@ -76,7 +79,7 @@ de: featured_tag: name: 'Hier sind ein paar Hashtags, die du in letzter Zeit am häufigsten verwendet hast:' filters: - action: Gib an, welche Aktion ausgeführt werden soll, wenn ein Beitrag dem Filter entspricht + action: Auswählen, welche Aktion ausgeführt werden soll, wenn ein Beitrag dem Filter entspricht actions: blur: Medien mit einer Warnung ausblenden, ohne den Text selbst auszublenden hide: Den gefilterten Beitrag vollständig ausblenden, als hätte er nie existiert @@ -85,11 +88,12 @@ de: activity_api_enabled: Anzahl der wöchentlichen Beiträge, aktiven Profile und Registrierungen auf diesem Server app_icon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-App-Symbol auf mobilen Geräten mit einem eigenen Symbol. backups_retention_period: Nutzer*innen haben die Möglichkeit, Archive ihrer Beiträge zu erstellen, die sie später herunterladen können. Wenn ein positiver Wert gesetzt ist, werden diese Archive nach der festgelegten Anzahl von Tagen automatisch aus deinem Speicher gelöscht. - bootstrap_timeline_accounts: Diese Konten werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet. + bootstrap_timeline_accounts: Diese Konten werden an den Anfang der Follow-Empfehlungen für neue Nutzer angeheftet. Gib eine durch Kommata getrennte Liste von Konten an. closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Diese Option richtet sich ausschließlich an Server mit speziellen Zwecken und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist. custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. favicon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Symbol. + landing_page: Legt fest, welche Seite neue Besucher*innen sehen, wenn sie zum ersten Mal auf deinem Server ankommen. Für „Trends“ müssen die Trends in den Entdecken-Einstellungen aktiviert sein. Für „Lokaler Feed“ muss „Zugriff auf Live-Feeds, die lokale Beiträge beinhalten“ in den Entdecken-Einstellungen auf „Alle“ gesetzt werden. mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche. media_cache_retention_period: Mediendateien aus Beiträgen von externen Nutzer*innen werden auf deinem Server zwischengespeichert. Wenn ein positiver Wert gesetzt ist, werden die Medien nach der festgelegten Anzahl von Tagen gelöscht. Sollten die Medien nach dem Löschvorgang wieder angefragt werden, werden sie erneut heruntergeladen, sofern der ursprüngliche Inhalt noch vorhanden ist. Es wird empfohlen, diesen Wert auf mindestens 14 Tage festzulegen, da die Häufigkeit der Abfrage von Linkvorschaukarten für Websites von Dritten begrenzt ist und die Linkvorschaukarten sonst nicht vor Ablauf dieser Zeit aktualisiert werden. min_age: Nutzer*innen werden bei der Registrierung aufgefordert, ihr Geburtsdatum zu bestätigen @@ -233,10 +237,12 @@ de: setting_aggregate_reblogs: Geteilte Beiträge in den Timelines gruppieren setting_always_send_emails: Benachrichtigungen immer senden setting_auto_play_gif: Animierte GIFs automatisch abspielen + setting_boost_modal: Sichtbarkeit für geteilte Beiträge anpassen setting_default_language: Beitragssprache setting_default_privacy: Beitragssichtbarkeit - setting_default_quote_policy: Wer zitieren darf + setting_default_quote_policy: Wer darf mich zitieren? setting_default_sensitive: Medien immer mit einer Inhaltswarnung versehen + setting_delete_modal: Vor dem Löschen bestätigen setting_disable_hover_cards: Profilvorschau deaktivieren, wenn die Maus über das Profil bewegt wird setting_disable_swiping: Wischgesten deaktivieren setting_display_media: Darstellung von Medien @@ -246,7 +252,8 @@ de: setting_emoji_style: Emoji-Stil setting_expand_spoilers: Beiträge mit Inhaltswarnung immer ausklappen setting_hide_network: Follower und „Folge ich“ nicht anzeigen - setting_quick_boosting: Schnelles Boosten aktivieren + setting_missing_alt_text_modal: Erinnerung für Bildbeschreibung anzeigen + setting_quick_boosting: Schnelles Teilen aktivieren setting_reduce_motion: Bewegung in Animationen verringern setting_system_font_ui: Standardschriftart des Browsers verwenden setting_system_scrollbars_ui: Bildlaufleiste des Betriebssystems verwenden @@ -280,6 +287,7 @@ de: content_cache_retention_period: Aufbewahrungsfrist für externe Inhalte custom_css: Eigenes CSS favicon: Favicon + landing_page: Landingpage für neue Besucher*innen local_live_feed_access: Zugriff auf Live-Feeds, die lokale Beiträge beinhalten local_topic_feed_access: Zugriff auf Hashtags und Links, die lokale Beiträge beinhalten mascot: Benutzerdefiniertes Maskottchen (Legacy) diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index 03dd292e0fd..a4c600ede2b 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -88,7 +88,7 @@ el: activity_api_enabled: Καταμέτρηση τοπικά δημοσιευμένων δημοσιεύσεων, ενεργών χρηστών και νέων εγγραφών σε εβδομαδιαία πακέτα app_icon: WEBP, PNG, GIF ή JPG. Παρακάμπτει το προεπιλεγμένο εικονίδιο εφαρμογής σε κινητές συσκευές με προσαρμοσμένο εικονίδιο. backups_retention_period: Οι χρήστες έχουν τη δυνατότητα να δημιουργήσουν αρχεία των αναρτήσεων τους για να κατεβάσουν αργότερα. Όταν οριστεί μια θετική τιμή, αυτά τα αρχεία θα διαγράφονται αυτόματα από τον αποθηκευτικό σου χώρο μετά τον καθορισμένο αριθμό ημερών. - bootstrap_timeline_accounts: Αυτοί οι λογαριασμοί θα καρφιτσωθούν στην κορυφή των νέων χρηστών που ακολουθούν τις συστάσεις. + bootstrap_timeline_accounts: Αυτοί οι λογαριασμοί θα καρφιτσωθούν στην κορυφή των προτεινόμενων ακολουθήσεων για νέους χρήστες. Παρέχετε μια λίστα λογαριασμών χωρισμένη με κόμμα. closed_registrations_message: Εμφανίζεται όταν κλείνουν οι εγγραφές content_cache_retention_period: Όλες οι αναρτήσεις από άλλους διακομιστές (συμπεριλαμβανομένων των ενισχύσεων και απαντήσεων) θα διαγραφούν μετά τον καθορισμένο αριθμό ημερών, χωρίς να λαμβάνεται υπόψη οποιαδήποτε αλληλεπίδραση τοπικού χρήστη με αυτές τις αναρτήσεις. Αυτό περιλαμβάνει αναρτήσεις όπου ένας τοπικός χρήστης την έχει χαρακτηρίσει ως σελιδοδείκτη ή αγαπημένη. Θα χαθούν επίσης ιδιωτικές αναφορές μεταξύ χρηστών από διαφορετικές οντότητες και θα είναι αδύνατο να αποκατασταθούν. Η χρήση αυτής της ρύθμισης προορίζεται για οντότητες ειδικού σκοπού και χαλάει πολλές προσδοκίες του χρήστη όταν εφαρμόζεται για χρήση γενική σκοπού. custom_css: Μπορείς να εφαρμόσεις προσαρμοσμένα στυλ στην έκδοση ιστοσελίδας του Mastodon. diff --git a/config/locales/simple_form.en-GB.yml b/config/locales/simple_form.en-GB.yml index 5ef7647c565..7ab3d887e78 100644 --- a/config/locales/simple_form.en-GB.yml +++ b/config/locales/simple_form.en-GB.yml @@ -74,7 +74,6 @@ en-GB: featured_tag: name: 'Here are some of the hashtags you used the most recently:' filters: - action: Chose which action to perform when a post matches the filter actions: blur: Hide media behind a warning, without hiding the text itself hide: Completely hide the filtered content, behaving as if it did not exist @@ -83,7 +82,6 @@ en-GB: activity_api_enabled: Counts of locally published posts, active users, and new registrations in weekly buckets app_icon: WEBP, PNG, GIF or JPG. Overrides the default app icon on mobile devices with a custom icon. backups_retention_period: Users have the ability to generate archives of their posts to download later. When set to a positive value, these archives will be automatically deleted from your storage after the specified number of days. - bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations. closed_registrations_message: Displayed when sign-ups are closed content_cache_retention_period: All posts from other servers (including boosts and replies) will be deleted after the specified number of days, without regard to any local user interaction with those posts. This includes posts where a local user has marked it as bookmarks or favorites. Private mentions between users from different instances will also be lost and impossible to restore. Use of this setting is intended for special purpose instances and breaks many user expectations when implemented for general purpose use. custom_css: You can apply custom styles on the web version of Mastodon. diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 36ae9a4ca57..43d8e55567f 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -79,7 +79,7 @@ en: featured_tag: name: 'Here are some of the hashtags you used the most recently:' filters: - action: Chose which action to perform when a post matches the filter + action: Choose which action to perform when a post matches the filter actions: blur: Hide media behind a warning, without hiding the text itself hide: Completely hide the filtered content, behaving as if it did not exist @@ -88,7 +88,7 @@ en: activity_api_enabled: Counts of locally published posts, active users, and new registrations in weekly buckets app_icon: WEBP, PNG, GIF or JPG. Overrides the default app icon on mobile devices with a custom icon. backups_retention_period: Users have the ability to generate archives of their posts to download later. When set to a positive value, these archives will be automatically deleted from your storage after the specified number of days. - bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations. + bootstrap_timeline_accounts: These accounts will be pinned to the top of new users' follow recommendations. Provide a comma-separated list of accounts. closed_registrations_message: Displayed when sign-ups are closed content_cache_retention_period: All posts from other servers (including boosts and replies) will be deleted after the specified number of days, without regard to any local user interaction with those posts. This includes posts where a local user has marked it as bookmarks or favorites. Private mentions between users from different instances will also be lost and impossible to restore. Use of this setting is intended for special purpose instances and breaks many user expectations when implemented for general purpose use. custom_css: You can apply custom styles on the web version of Mastodon. diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml index eed4671bb78..f2973d7bb36 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -76,7 +76,6 @@ eo: featured_tag: name: 'Jen kelkaj el la kradvortoj, kiujn vi uzis lastatempe:' filters: - action: Elekti ago kiam mesaĝo kongruas la filtrilon actions: blur: Kaŝi amaskomunikilaron malantaŭ averto, sen kaŝi la tekston mem hide: Tute kaŝigi la filtritajn enhavojn, kvazau ĝi ne ekzistis @@ -85,7 +84,6 @@ eo: activity_api_enabled: Nombroj de loke publikigitaj afiŝoj, aktivaj uzantoj kaj novaj registradoj en semajnaj siteloj app_icon: WEBP, PNG, GIF aŭ JPG. Anstataŭigas la defaŭltan aplikaĵan bildsimbolon sur porteblaj aparatoj kun propra bildsimbolo. backups_retention_period: Uzantoj havas la kapablon generi arkivojn de siaj afiŝoj por elŝuti poste. Kiam estas agordita al pozitiva valoro, ĉi tiuj arkivoj estos aŭtomate forigitaj de via stokado post la specifita nombro da tagoj. - bootstrap_timeline_accounts: Ĉi tiuj kontoj pinglitas al la supro de sekvorekomendoj de novaj uzantoj. closed_registrations_message: Montrita kiam registroj fermitas content_cache_retention_period: Ĉiuj afiŝoj de aliaj serviloj (inkluzive de diskonigoj kaj respondoj) estos forigitaj post la specifita nombro da tagoj, sen konsidero al iu ajn loka uzantinterago kun tiuj afiŝoj. Ĉi tio inkluzivas afiŝojn, kie loka uzanto markis ĝin kiel legosignojn aŭ ŝatatajn. Privataj mencioj inter uzantoj de malsamaj nodoj ankaŭ estos perditaj kaj neeble restaŭreblaj. Uzo de ĉi tiu agordo estas celita por specialcelaj okazoj kaj rompas multajn uzantajn atendojn kiam efektivigita por ĝenerala uzo. custom_css: Vi povas meti propajn stilojn en la retversio de Mastodon. diff --git a/config/locales/simple_form.es-AR.yml b/config/locales/simple_form.es-AR.yml index b58d916d643..eb277888afb 100644 --- a/config/locales/simple_form.es-AR.yml +++ b/config/locales/simple_form.es-AR.yml @@ -88,12 +88,12 @@ es-AR: activity_api_enabled: Conteos de mensajes publicados localmente, cuentas activas y nuevos registros en tandas semanales app_icon: WEBP, PNG, GIF o JPG. Reemplaza el ícono de aplicación predeterminado en dispositivos móviles con uno personalizado. backups_retention_period: Los usuarios tienen la capacidad de generar archivos historiales de sus mensajes para descargar más adelante. Cuando se establece un valor positivo, estos archivos se eliminarán automáticamente de su almacenamiento después del número especificado de días. - bootstrap_timeline_accounts: Estas cuentas serán fijadas a la parte superior de las recomendaciones de cuentas a seguir para nuevos usuarios. + bootstrap_timeline_accounts: Estas cuentas se fijarán en la parte superior de las recomendaciones de seguimiento para los nuevos usuarios. Proporcioná una lista de cuentas separadas por comas. closed_registrations_message: Mostrado cuando los registros están cerrados content_cache_retention_period: Todos los mensajes de otros servidores (incluyendo adhesiones y respuestas) se eliminarán después del número de días especificado, sin tener en cuenta la interacción del usuario local con esos mensajes. Esto incluye mensajes que un usuario local haya agregado a marcadores o los haya marcado como favoritos. Las menciones privadas entre usuarios de diferentes servidores también se perderán y también serán imposibles de restaurar. El uso de esta configuración está destinado a servidores de propósito especial y rompe muchas expectativas de los usuarios cuando se implementa para uso general. custom_css: Podés aplicar estilos personalizados a la versión web de Mastodon. favicon: WEBP, PNG, GIF o JPG. Reemplaza el favicón predeterminado de Mastodon con uno personalizado. - landing_page: Selecciona qué página ven los nuevos visitantes cuando llegan por primera vez a tu servidor. Si seleccionas "Tendencias", entonces las tendencias deben estar habilitadas en la Configuración de Descubrimiento. Si selecciona "Cronología local", entonces "Acceso a las cronologías que destacan publicaciones locales" debe configurarse a "Todos" en la Configuración de Descubrimiento. + landing_page: Selecciona qué página se carga para los nuevos visitantes cuando llegan por primera vez a tu servidor. Si seleccionás «Tendencias», entonces las tendencias tienen que estar habilitadas en la configuración de «Descubrimiento». Si seleccionás «Línea temporal local», entonces «Acceso a líneas temporales en vivo, destacando mensajes locales» tiene que estar establecida a «Todos» en la configuración de «Descubrimiento». mascot: Reemplaza la ilustración en la interface web avanzada. media_cache_retention_period: Los archivos de medios de mensajes publicados por usuarios remotos se almacenan en la memoria caché en tu servidor. Cuando se establece un valor positivo, los medios se eliminarán después del número especificado de días. Si los datos multimedia se solicitan después de eliminarse, se volverán a descargar, si es que el contenido fuente todavía está disponible. Debido a restricciones en la frecuencia con la que las tarjetas de previsualización de enlace consultan a sitios web de terceros, se recomienda establecer este valor a, al menos, 14 días, o las tarjetas de previsualización de enlaces no se actualizarán a pedido antes de ese momento. min_age: Se pedirá a los usuarios que confirmen su fecha de nacimiento durante el registro @@ -287,7 +287,7 @@ es-AR: content_cache_retention_period: Período de retención de contenido remoto custom_css: CSS personalizado favicon: Favicón - landing_page: Página de inicio para nuevos visitantes + landing_page: Página de carga para nuevos visitantes local_live_feed_access: Acceso a líneas temporales en vivo, destacando mensajes locales local_topic_feed_access: Acceso a líneas temporales de etiquetas y enlaces, destacando mensajes locales mascot: Mascota personalizada (legado) diff --git a/config/locales/simple_form.es-MX.yml b/config/locales/simple_form.es-MX.yml index 9494a930671..551192480a0 100644 --- a/config/locales/simple_form.es-MX.yml +++ b/config/locales/simple_form.es-MX.yml @@ -79,7 +79,7 @@ es-MX: featured_tag: name: 'Aquí están algunas de las etiquetas que más has usado recientemente:' filters: - action: Elegir qué acción realizar cuando una publicación coincide con el filtro + action: Elige qué acción realizar cuando una publicación coincide con el filtro actions: blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el propio texto hide: Ocultar completamente el contenido filtrado, comportándose como si no existiera @@ -88,7 +88,7 @@ es-MX: activity_api_enabled: Conteo de publicaciones publicadas localmente, usuarios activos, y nuevos registros en periodos semanales app_icon: WEBP, PNG, GIF o JPG. Reemplaza el icono de aplicación predeterminado en dispositivos móviles con un icono personalizado. backups_retention_period: Los usuarios tienen la posibilidad de generar archivos de sus mensajes para descargarlos más adelante. Cuando se establece en un valor positivo, estos archivos se eliminarán automáticamente del almacenamiento después del número especificado de días. - bootstrap_timeline_accounts: Estas cuentas aparecerán en la parte superior de las recomendaciones de los nuevos usuarios. + bootstrap_timeline_accounts: Estas cuentas se colocarán en la parte superior de las recomendaciones de cuentas a las que seguir para los nuevos usuarios. Proporciona una lista de cuentas separadas por comas. closed_registrations_message: Mostrado cuando los registros están cerrados content_cache_retention_period: Todas las publicaciones de otros servidores (incluyendo impuestos y respuestas) serán borrados después del número de días especificado, sin tener en cuenta cualquier interacción del usuario local con esas publicaciones. Esto incluye los mensajes que un usuario local haya marcado como favoritos. Las menciones privadas entre usuarios de diferentes instancias también se perderán y será imposible restaurarlas. El uso de esta configuración está pensado para instancias de propósito especial y rompe muchas expectativas de los usuarios cuando se implementa para uso general. custom_css: Puedes aplicar estilos personalizados a la versión web de Mastodon. @@ -242,7 +242,7 @@ es-MX: setting_default_privacy: Visibilidad de publicación setting_default_quote_policy: Quién puede citar setting_default_sensitive: Marcar siempre imágenes como sensibles - setting_delete_modal: Avisarme antes de borrar una publicación + setting_delete_modal: Avisarme antes de eliminar una publicación setting_disable_hover_cards: Desactivar vista previa del perfil al pasar el cursor setting_disable_swiping: Deshabilitar movimientos de deslizamiento setting_display_media: Visualización multimedia @@ -252,7 +252,7 @@ es-MX: setting_emoji_style: Estilo de emoji setting_expand_spoilers: Siempre expandir las publicaciones marcadas con advertencias de contenido setting_hide_network: Ocultar tu red - setting_missing_alt_text_modal: Avisarme antes de publicar multimedia sin descripción de texto + setting_missing_alt_text_modal: Avisarme antes de publicar contenido multimedia sin descripción de texto setting_quick_boosting: Habilitar impulso rápido setting_reduce_motion: Reducir el movimiento de las animaciones setting_system_font_ui: Usar la fuente por defecto del sistema diff --git a/config/locales/simple_form.es.yml b/config/locales/simple_form.es.yml index 5c431d04632..0dfd10f4071 100644 --- a/config/locales/simple_form.es.yml +++ b/config/locales/simple_form.es.yml @@ -79,7 +79,7 @@ es: featured_tag: name: 'Aquí están algunas de las etiquetas que más has utilizado recientemente:' filters: - action: Elegir qué acción realizar cuando una publicación coincide con el filtro + action: Elige qué acción realizar cuando una publicación coincide con el filtro actions: blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el texto en sí hide: Ocultar completamente el contenido filtrado, comportándose como si no existiera @@ -88,7 +88,7 @@ es: activity_api_enabled: Conteo de publicaciones publicadas localmente, usuarios activos y registros nuevos cada semana app_icon: WEBP, PNG, GIF o JPG. Reemplaza el icono de aplicación predeterminado en dispositivos móviles con un icono personalizado. backups_retention_period: Los usuarios tienen la capacidad de generar archivos de sus mensajes para descargar más adelante. Cuando se establece un valor positivo, estos archivos se eliminarán automáticamente del almacenamiento después del número de días especificado. - bootstrap_timeline_accounts: Estas cuentas aparecerán en la parte superior de las recomendaciones de los nuevos usuarios. + bootstrap_timeline_accounts: Estas cuentas se colocarán en la parte superior de las recomendaciones de cuentas a las que seguir para los nuevos usuarios. Proporciona una lista de cuentas separadas por comas. closed_registrations_message: Mostrado cuando los registros están cerrados content_cache_retention_period: Todas las publicaciones de otros servidores (incluso impulsos y respuestas) se eliminarán después del número de días especificado, sin tener en cuenta la interacción del usuario local con esos mensajes. Esto incluye mensajes donde un usuario local los ha marcado como marcadores o favoritos. Las menciones privadas entre usuarios de diferentes instancias también se perderán sin posibilidad de recuperación. El uso de esta configuración está destinado a instancias de propósito especial, y rompe muchas expectativas de los usuarios cuando se implementa para un uso de propósito general. custom_css: Puedes aplicar estilos personalizados a la versión web de Mastodon. diff --git a/config/locales/simple_form.et.yml b/config/locales/simple_form.et.yml index a7c318f04f3..9cf4a9ad48e 100644 --- a/config/locales/simple_form.et.yml +++ b/config/locales/simple_form.et.yml @@ -54,8 +54,10 @@ et: password: Vajalik on vähemalt 8 märki phrase: Kattub olenemata postituse teksti suurtähtedest või sisuhoiatusest scopes: Milliseid API-sid see rakendus tohib kasutada. Kui valid kõrgeima taseme, ei pea üksikuid eraldi valima. + setting_advanced_layout: Näita Mastodoni mitme veeruga paigutuses, mispuhul näed korraga nii ajajoont, teavitusi, kui sinu valitud kolmandat veergu. Ei sobi kasutamiseks väikeste ekraanide puhul. setting_aggregate_reblogs: Ära kuva uusi postituste jagamisi, mis on hiljuti jagatud (kehtib vaid uutele jagamistele) setting_always_send_emails: Mastodoni aktiivsel kasutamisel sulle tavaliselt meilile teavitusi ei saadeta + setting_boost_modal: Selle eelistuse kasutamisel hooandmise avatakse esmalt kinnitusvaade, kus saad muuta hooandmise nähtavust. setting_default_quote_policy_private: Ainult jälgijatele mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida. setting_default_quote_policy_unlisted: Kui teised kasutajad sind tsiteerivad, siis nende postitused peidetakse ajajoonelt, mis näitavad populaarsust koguvaid postitusi. setting_default_sensitive: Tundlik meedia on vaikimisi peidetud ning seda saab avada sellele klikkides @@ -63,6 +65,7 @@ et: setting_display_media_hide_all: Alati peida kõik meedia setting_display_media_show_all: Alati näita tundlikuks märgistatud meedia setting_emoji_style: See määrab emojide kuvamise viisi. Automaatse valiku puhul üritatakse kasutada platvormi või klientrakenduse oma emojisid, kuid varuvariandina jääb toimima Twemoji (näiteks vanade veebibrauserite puhul). + setting_quick_boosting_html: Selle eelistuse kasutamisel, Hooandmise ikooni %{boost_icon} teeb toimingu kohe ilma avamata Hooandmise/Tsiteerimise menüüvalikut. Sel puhul tsiteerimise link leidub %{options_icon} (Valikud) menüüs. setting_system_scrollbars_ui: Kehtib vaid Safaril ja Chrome'il põhinevatel tavaarvuti veebibrauserite puhul setting_use_blurhash: Värvid põhinevad peidetud visuaalidel, kuid hägustavad igasuguseid detaile setting_use_pending_items: Voo automaatse kerimise asemel peida ajajoone uuendused kliki taha @@ -76,7 +79,7 @@ et: featured_tag: name: 'Siin on mõned nendest siltidest, mida oled viimati kasutanud:' filters: - action: Tegevuse valik, kui postitus vastab filtrile + action: Vali tegevus, kui postitus vastab filtrile actions: blur: Peida meediumifailid hoiatusega, kuid jäta tekst peitmata hide: Filtreeritud sisu täielik peitmine, nagu seda polekski üldse olemas @@ -85,11 +88,12 @@ et: activity_api_enabled: Kohalike postituste, aktiivsete kasutajate ja uute registreerumistr arv nädala kaupa grupeeritult app_icon: WEBP, PNG, GIF või JPG. Asendab mobiilsel seadmel äpi vaikeikooni kohandatud ikooniga. backups_retention_period: Kasutajatel on võimalus genereerida oma postitustest hiljem allalaaditav arhiiv. Kui määrad positiivse arvu, siis kustutatakse need arhiivid serveri andmeruumist määratud arvu päevade järel automaatselt. - bootstrap_timeline_accounts: Need kasutajad kinnitatakse uute kasutajate jälgimissoovituste esiritta. + bootstrap_timeline_accounts: Järgnevad kasutajakontod kinnitatakse vaate ülaossa ning on mõeldud jälgitavate kontode soovituseks uutele kasutajatele. Sisend peab olema komadega eraldatud kasutajakontode loend. closed_registrations_message: Kuvatakse, kui liitumised pole võimalikud content_cache_retention_period: Kõik teiste serverite postitused (sealhulgas jagamised ja vastused) kustutatakse pärast määratud arvu päevade möödumist, sõltumata, kuidas kohalik kasutaja on nende postitustega interakteerunud. Hõlmatud on ka postitused, mille kohalik kasutaja on märkinud järjehoidjaks või lemmikuks. Ka eri instantside kasutajate vahelised privaatsed mainimised kaovad ja neid on võimatu taastada. See seadistus on mõeldud eriotstarbeliste instantside jaoks ja rikub paljude kasutajate ootusi, kui seda rakendatakse üldotstarbelise kasutuse puhul. custom_css: Mastodoni veebiliideses on võimalik kasutada kohandatud stiile. favicon: WEBP, PNG, GIF või JPG. Asendab Mastodoni vaike- favicon ikooni kohandatud ikooniga. + landing_page: Sellega valid lehe, mida uued külastajad sinu serverisse tulles näevad. Kui sa valid „Trendid“, siis peavad nad olema lubatud. Kui sa valid „Kohalike postituste voog“, siis seadistuse „Ligipääs kohalike postituste voole“ väärtus peab olema „Kõik“. mascot: Asendab kohandatud veebiliidese illustratsiooni. media_cache_retention_period: Kaugkasutajate tehtud postituste meediafailid salvestatakse sinu koduserveri vahemällu. Kui see seadistus on seatud positiivsele väärtusele, kustutatakse meediumifailid määratud päevade möödumisel. Kui meediaandmeid küsitakse pärast nende kustutamist, laaditakse need uuesti alla, kui lähtesisu on veel saadaval. Kuna on olemas piirangud, kui tihti tohivad lingikaardid kolmandatelt saitidelt andmeid pärida, on soovitatav määrata väärtuseks vähemalt 14. Vastasel juhul ei uuendata linkide eelvaatekaarte nõudmise korral enne seda aega. min_age: Kasutajad peavad liitumisel kinnitama oma sünnikuupäeva @@ -249,6 +253,7 @@ et: setting_expand_spoilers: Alati näita tundlikuks märgitud postituste sisu setting_hide_network: Peida oma võrk setting_missing_alt_text_modal: Enne postitamist hoiata mind meediumi puuduva selgitusteksti puhul + setting_quick_boosting: Luba kiire hooandmine setting_reduce_motion: Vähenda animatsioonides liikumist setting_system_font_ui: Kasuta süsteemi vaikefonti setting_system_scrollbars_ui: Kasuta süsteemi vaikimisi kerimisriba @@ -282,6 +287,7 @@ et: content_cache_retention_period: Kaugsisu säilitamise aeg custom_css: Kohandatud CSS favicon: Favicon + landing_page: Avaleht uute külastajate jaoks local_live_feed_access: Ligipääs kohalike postituste voole local_topic_feed_access: Ligipääs kohalike postitustele viitavale teemaviidete ja linkide voole mascot: Kohandatud maskott (kunagine) diff --git a/config/locales/simple_form.eu.yml b/config/locales/simple_form.eu.yml index fc7879896bd..3a0a8b6741d 100644 --- a/config/locales/simple_form.eu.yml +++ b/config/locales/simple_form.eu.yml @@ -74,7 +74,6 @@ eu: featured_tag: name: 'Hemen dituzu azkenaldian gehien erabili dituzun traoletako batzuk:' filters: - action: Aukeratu ze ekintza burutu behar den bidalketa bat iragazkiarekin bat datorrenean actions: blur: Ezkutatu edukia ohar baten atzean, testua bera ezkutatu gabe hide: Ezkutatu erabat iragazitako edukia, existituko ez balitz bezala @@ -83,7 +82,6 @@ eu: activity_api_enabled: Lokalki argitaratutako bidalketak, erabiltzaile aktiboak, eta izen-emateen kopuruak astero zenbatzen ditu app_icon: WEBP, PNG, GIF edo JPG. Aplikazioaren ikono lehenetsia gainidazten du ikono pertsonalizatu batekin gailu mugikorretan. backups_retention_period: Erabiltzaileek geroago deskarga dezaketen beren argitalpenen artxiboak sor ditzakete. Balio positibo bat ezartzean, artxibo hauek biltegiratzetik automatikoki ezabatuko dira zehazturiko egunen buruan. - bootstrap_timeline_accounts: Kontu hauek erabiltzaile berrien jarraitzeko gomendioen goiko aldean ainguratuko dira. closed_registrations_message: Izen-ematea itxia dagoenean bistaratua content_cache_retention_period: Beste zerbitzarietako argitalpen guztiak (bultzadak eta erantzunak barne) ezabatuko dira zehazturiko egunen buruan, argitalpen horiek izan ditzaketen erabiltzaile lokalaren interakzioa kontuan izanik gabe. Instantzia desberdinetako erabiltzaileen arteko aipamen pribatuak ere galdu egingo dira eta ezin izango dira berreskuratu. Ezarpen honen erabilera xede berezia duten instantziei zuzendua dago eta erabiltzaileen itxaropena hausten da orotariko erabilerarako inplementatzean. custom_css: Estilo pertsonalizatuak aplikatu ditzakezu Mastodonen web bertsioan. diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index d244cb52834..497c67b4164 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -56,6 +56,8 @@ fa: scopes: واسط‌های برنامه‌نویسی که این برنامه به آن دسترسی دارد. اگر بالاترین سطح دسترسی را انتخاب کنید، دیگر نیازی به انتخاب سطح‌های پایینی ندارید. setting_aggregate_reblogs: برای تقویت‌هایی که به تازگی برایتان نمایش داده شده‌اند، تقویت‌های بیشتر را نمایش نده (فقط روی تقویت‌های اخیر تأثیر می‌گذارد) setting_always_send_emails: در حالت عادی آگاهی‌های رایانامه‌ای هنگامی که فعّالانه از ماستودون استفاده می‌کنید فرستاده نمی‌شوند + setting_default_quote_policy_private: فرسته‌های فقط پی‌گیران روی ماستودون نمی‌توانند به دست دیگران نقل شوند. + setting_default_quote_policy_unlisted: هنگامی که کسی نقلتان می‌کند هم فرسته‌اش از خط زمانی‌های داغ پنهان خواهد بود. setting_default_sensitive: تصاویر حساس به طور پیش‌فرض پنهان هستند و می‌توانند با یک کلیک آشکار شوند setting_display_media_default: تصویرهایی را که به عنوان حساس علامت زده شده‌اند پنهان کن setting_display_media_hide_all: همیشه همهٔ عکس‌ها و ویدیوها را پنهان کن @@ -74,7 +76,6 @@ fa: featured_tag: name: 'این‌ها برخی از برچسب‌هایی هستند که به تازگی استفاده کرده‌اید:' filters: - action: گزینش کنشی که هنگام تطابق فرسته‌ای با پالایه انجام شود actions: blur: نهفتن رسانه پشت هشدار بدون نهفتن خود متن hide: نهفتن کامل محتوای پالوده، گویی وجود ندارد @@ -83,7 +84,6 @@ fa: activity_api_enabled: تعداد بوق‌های منتشرهٔ محلی، کاربران فعال، و کاربران تازه در هر هفته app_icon: WEBP، PNG، GIF یا JPG. با یک نماد سفارشی، نماد برنامه پیش‌فرض را در دستگاه‌های تلفن همراه لغو می‌کند. backups_retention_period: کاربران می توانند بایگانی هایی از پست های خود ایجاد کنند تا بعدا دانلود کنند. وقتی روی مقدار مثبت تنظیم شود، این بایگانی‌ها پس از تعداد روزهای مشخص شده به‌طور خودکار از فضای ذخیره‌سازی شما حذف می‌شوند. - bootstrap_timeline_accounts: سنجاق کردنThese accounts will be pinned to the top of new users' follow recommendations. closed_registrations_message: نمایش داده هنگام بسته بودن ثبت‌نام‌ها content_cache_retention_period: همه پست‌های سرورهای دیگر (از جمله تقویت‌کننده‌ها و پاسخ‌ها) پس از چند روز مشخص شده، بدون توجه به هرگونه تعامل کاربر محلی با آن پست‌ها، حذف خواهند شد. این شامل پست هایی می شود که یک کاربر محلی آن را به عنوان نشانک یا موارد دلخواه علامت گذاری کرده است. ذکر خصوصی بین کاربران از نمونه های مختلف نیز از بین خواهد رفت و بازیابی آنها غیرممکن است. استفاده از این تنظیم برای موارد با هدف خاص در نظر گرفته شده است و بسیاری از انتظارات کاربر را هنگامی که برای استفاده عمومی اجرا می شود، از بین می برد. custom_css: می‌توانیدروی نگارش وب ماستودون سبک‌های سفارشی اعمال کنید. @@ -231,9 +231,12 @@ fa: setting_aggregate_reblogs: تقویت‌ها را در خط‌زمانی گروه‌بندی کن setting_always_send_emails: فرستادن همیشگی آگاهی‌های رایانامه‌ای setting_auto_play_gif: پخش خودکار تصویرهای متحرک + setting_boost_modal: واپایش نمایانی توثیت setting_default_language: زبان نوشته‌های شما + setting_default_privacy: نمایانی فرسته setting_default_quote_policy: افراد مجاز به نقل setting_default_sensitive: همیشه تصاویر را به عنوان حساس علامت بزن + setting_delete_modal: هشدار پیش از حذف کردن فرسته setting_disable_hover_cards: از کار انداختن پیش‌نمایش نمایه هنگام رفتن رویش setting_disable_swiping: از کار انداختن حرکت‌های کشیدنی setting_display_media: نمایش عکس و ویدیو @@ -243,6 +246,8 @@ fa: setting_emoji_style: سبک شکلک setting_expand_spoilers: همیشه فرسته‌هایی را که هشدار محتوا دارند کامل نشان بده setting_hide_network: نهفتن شبکهٔ ارتباطی + setting_missing_alt_text_modal: هشدار پیش از فرستادن رسانه بدون متن جایگزین + setting_quick_boosting: به کار انداختن تقویت سریع setting_reduce_motion: کاستن از حرکت در پویانمایی‌ها setting_system_font_ui: به‌کاربردن قلم پیش‌فرض سیستم setting_system_scrollbars_ui: از نوار اسکرول پیش فرض سیستم استفاده کنید @@ -276,12 +281,17 @@ fa: content_cache_retention_period: دوره نگهداری محتوا از راه دور custom_css: سبک CSS سفارشی favicon: نمادک + landing_page: صفحهٔ فرود برای بینندگان جدید + local_live_feed_access: دسترسی به خوراک‌های زندهٔ نمایانگر فرسته‌های محلی + local_topic_feed_access: دسترسی به خوراک‌های پیوند و برچسب‌های نمایانگر فرسته‌های محلی mascot: نشان سفارشی (قدیمی) media_cache_retention_period: دورهٔ نگه‌داری انبارهٔ رسانه min_age: کمینهٔ سن لازم peers_api_enabled: انتشار سیاههٔ کارسازهای کشف شده در API profile_directory: به کار انداختن شاخهٔ نمایه registrations_mode: چه کسانی می‌توانند ثبت‌نام کنند + remote_live_feed_access: دسترسی به خوراک‌های زندهٔ نمایانگر فرسته‌های دوردست + remote_topic_feed_access: دسترسی به خوراک‌های پیوند و برچسب‌های نمایانگر فرسته‌های دوردست require_invite_text: نیازمند دلیلی برای پیوستن show_domain_blocks: نمایش مسدودیت‌های دامنه show_domain_blocks_rationale: نمایش چرایی مسدودیت دامنه‌ها diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index 4a1cb3998e7..99c1b79bbe0 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -79,7 +79,7 @@ fi: featured_tag: name: 'Tässä muutamia hiljattain käyttämiäsi aihetunnisteita:' filters: - action: Valitse, mikä toiminto suoritetaan, kun julkaisu vastaa suodatinta + action: Valitse, miten toimitaan, kun julkaisu vastaa suodatinta actions: blur: Piilota media varoituksen taakse piilottamatta itse tekstiä hide: Piilota suodatettu sisältö kokonaan, ikään kuin sitä ei olisi olemassa @@ -88,11 +88,12 @@ fi: activity_api_enabled: Paikallisesti julkaistujen julkaisujen, aktiivisten käyttäjien ja rekisteröitymisten viikoittainen määrä app_icon: WEBP, PNG, GIF tai JPG. Korvaa oletusarvoisen mobiililaitteiden sovelluskuvakkeen haluamallasi kuvakkeella. backups_retention_period: Käyttäjillä on mahdollisuus arkistoida julkaisujaan myöhemmin ladattaviksi. Kun kentän arvo on positiivinen, nämä arkistot poistuvat automaattisesti, kun määritetty määrä päiviä on kulunut. - bootstrap_timeline_accounts: Nämä tilit kiinnitetään uusien käyttäjien seurantasuositusten alkuun. + bootstrap_timeline_accounts: Nämä tilit kiinnittyvät uusien käyttäjien seurantasuositusten alkuun. Syötä pilkuin eroteltu luettelo tilejä. closed_registrations_message: Näkyy, kun rekisteröityminen on suljettu content_cache_retention_period: Kaikki muiden palvelinten julkaisut (mukaan lukien tehostukset ja vastaukset) poistuvat, kun määritetty määrä päiviä on kulunut, lukuun ottamatta paikallisen käyttäjän vuorovaikutusta näiden julkaisujen kanssa. Tämä sisältää julkaisut, jotka paikallinen käyttäjä on merkinnyt kirjanmerkiksi tai suosikiksi. Myös yksityismaininnat eri palvelinten käyttäjien välillä menetetään, eikä niitä voi palauttaa. Tämä asetus on tarkoitettu käytettäväksi erityistapauksissa ja rikkoo monia käyttäjien odotuksia, kun sitä sovelletaan yleiskäyttöön. custom_css: Voit käyttää mukautettuja tyylejä Mastodonin selainversiossa. favicon: WEBP, PNG, GIF tai JPG. Korvaa oletusarvoisen Mastodonin sivustokuvakkeen haluamallasi kuvakkeella. + landing_page: Valitsee, minkä sivun uudet kävijät näkevät saapuessaan palvelimellesi. Jos valitset ”Trendit”, trendien tulee olla käytössä Löydettävyys-asetuksissa. Jos valitset ”Paikallinen syöte”, kohta ”Pääsy paikallisia julkaisuja esitteleviin livesyötteisiin” tulee asettaa arvoon ”Kaikki” Löydettävyys-asetuksissa. mascot: Korvaa kuvituksen edistyneessä selainkäyttöliittymässä. media_cache_retention_period: Etäkäyttäjien tekemien julkaisujen mediatiedostot ovat välimuistissa palvelimellasi. Kun kentän arvo on positiivinen, media poistuu, kun määritetty määrä päiviä on kulunut. Jos mediaa pyydetään sen poistamisen jälkeen, se ladataan uudelleen, jos lähdesisältö on vielä saatavilla. Koska linkkien esikatselun kyselyitä kolmansien osapuolien sivustoille on rajoitettu, on suositeltavaa asettaa tämä arvo vähintään 14 päivään, tai linkkien kortteja ei päivitetä pyynnöstä ennen tätä ajankohtaa. min_age: Käyttäjiä pyydetään rekisteröitymisen aikana vahvistamaan syntymäpäivänsä @@ -144,6 +145,7 @@ fi: admin_email: Oikeudellisiin ilmoituksiin kuuluvat vastailmoitukset, oikeuden määräykset, poistopyynnöt ja lainvalvontaviranomaisten pyynnöt. arbitration_address: Voi olla sama kuin edellä mainittu Fyysinen osoite tai ”N/A”, jos käytät sähköpostia. arbitration_website: Voi olla verkkolomake tai ”N/A”, jos käytät sähköpostia. + choice_of_law: Kaupunki, alue, territorio tai valtio, jonka sisäinen aineellinen oikeus säätelee kaikkia vaatimuksia. dmca_address: Yhdysvaltalaisten operaattoreiden on käytettävä DMCA Designated Agent Directory -luetteloon rekisteröityä osoitetta. Postilokeroluettelo on saatavissa suoralla pyynnöllä, joten käytä DMCA Designated Agent Post Office Box Waiver Request -lomaketta lähettääksesi sähköpostia tekijänoikeusvirastolle ja kuvaile, että olet kotona toimiva sisältömoderaattori, joka pelkää kostoa tai rangaistusta toimistaan ja tarvitsee postilokeroa pitääkseen kotiosoitteensa poissa julkisuudesta. dmca_email: Voi olla sama kuin edellä mainittu ”Sähköpostiosoite oikeudellisille ilmoituksille”. domain: Tarjoamasi verkkopalvelun yksilöllinen tunniste. @@ -172,7 +174,7 @@ fi: labels: account: attribution_domains: Verkkosivustot, jotka voivat antaa sinulle tunnustusta - discoverable: Pidä profiiliasi ja julkaisujasi esillä löytämisalgoritmeissa + discoverable: Pidä profiiliasi ja julkaisujasi esillä löydettävyysalgoritmeissa fields: name: Nimike value: Sisältö @@ -285,6 +287,7 @@ fi: content_cache_retention_period: Etäsisällön säilytysaika custom_css: Mukautettu CSS favicon: Sivustokuvake + landing_page: Uusien kävijöiden aloitussivu local_live_feed_access: Pääsy paikallisia julkaisuja esitteleviin livesyötteisiin local_topic_feed_access: Pääsy paikallisia julkaisuja esitteleviin aihetunniste- ja linkkisyötteisiin mascot: Mukautettu maskotti (vanhentunut) diff --git a/config/locales/simple_form.fo.yml b/config/locales/simple_form.fo.yml index 14a97e07bcf..de563ec5279 100644 --- a/config/locales/simple_form.fo.yml +++ b/config/locales/simple_form.fo.yml @@ -88,7 +88,7 @@ fo: activity_api_enabled: Tal av lokalt útgivnum postum, virknum brúkarum og nýggjum skrásetingum býtt vikuliga app_icon: WEBP, PNG, GIF ella JPG. Býtir vanligu ikonina á fartelefoneindum um við eina ser-ikon. backups_retention_period: Brúkarar hava møguleika at gera trygdaravrit av teirra postum, sum tey kunnu taka niður seinni. Tá hetta er sett til eitt virði størri enn 0, so verða hesi trygdaravrit strikaði av sær sjálvum frá tínar goymslu eftir ásetta talið av døgum. - bootstrap_timeline_accounts: Hesar kontur verða festar ovast á listanum yvir brúkarar, sum tey nýggju verða mælt til at fylgja. + bootstrap_timeline_accounts: Hesar konturnar verða festar ovast í fylgjaratilmælunum hjá nýggjum brúkarum. Kom við einum komma-skildum lista av kontum. closed_registrations_message: Víst tá stongt er fyri tilmeldingum content_cache_retention_period: Allir postar frá øðrum ambætarum (íroknað stimbranir og svar) verða strikaði eftir ásetta talið av døgum, óansæð hvussu lokalir brúkarar hava samvirkað við hesar postar. Hetta fevnir eisini um postar, sum lokalir brúkarar hava bókamerkt ella yndismerkt. Privatar umrøður millum brúkarar frá ymiskum ambætarum verða eisini burturmistar og ómøguligar at endurskapa. Brúk av hesi stillingini er einans hugsað til serligar støður og oyðileggur nógv, sum brúkarar vænta av einum vanligum ambætara. custom_css: Tú kanst seta títt egna snið upp í net-útgávuni av Mastodon. diff --git a/config/locales/simple_form.fr-CA.yml b/config/locales/simple_form.fr-CA.yml index b0dae17121e..e064ceeed16 100644 --- a/config/locales/simple_form.fr-CA.yml +++ b/config/locales/simple_form.fr-CA.yml @@ -56,6 +56,7 @@ fr-CA: scopes: À quelles APIs l’application sera autorisée à accéder. Si vous sélectionnez une permission générale, vous n’avez pas besoin de sélectionner les permissions plus précises. setting_aggregate_reblogs: Ne pas afficher les nouveaux partages pour les messages déjà récemment partagés (n’affecte que les partages futurs) setting_always_send_emails: Normalement, les notifications par courriel ne seront pas envoyées lorsque vous utilisez Mastodon activement + setting_default_quote_policy_unlisted: Lorsque des personnes vous citent, leur message sera également masqué des fils des tendances. setting_default_sensitive: Les médias sensibles sont cachés par défaut et peuvent être révélés d’un simple clic setting_display_media_default: Masquer les médias marqués comme sensibles setting_display_media_hide_all: Toujours masquer les médias @@ -73,7 +74,6 @@ fr-CA: featured_tag: name: 'Voici quelques hashtags que vous avez utilisés récemment :' filters: - action: Choisir l'action à effectuer quand un message correspond au filtre actions: blur: Cacher les médias derrière un avertissement, sans cacher le texte hide: Cacher complètement le contenu filtré, faire comme s'il n'existait pas @@ -82,7 +82,6 @@ fr-CA: activity_api_enabled: Nombre de messages publiés localement, de comptes actifs et de nouvelles inscriptions par tranche hebdomadaire app_icon: WEBP, PNG, GIF ou JPG. Remplace la favicon Mastodon par défaut avec une icône personnalisée. backups_retention_period: Les utilisateur·rice·s ont la possibilité de générer des archives de leurs messages pour les télécharger plus tard. Lorsqu'elles sont définies à une valeur positive, ces archives seront automatiquement supprimées de votre stockage après le nombre de jours spécifié. - bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs. closed_registrations_message: Affiché lorsque les inscriptions sont fermées content_cache_retention_period: Tous les messages provenant d'autres serveurs (y compris les partages et les réponses) seront supprimés passé le nombre de jours spécifié, sans tenir compte de l'interaction de l'utilisateur·rice local·e avec ces messages. Cela inclut les messages qu'un·e utilisateur·rice aurait marqué comme signets ou comme favoris. Les mentions privées entre utilisateur·rice·s de différentes instances seront également perdues et impossibles à restaurer. L'utilisation de ce paramètre est destinée à des instances spécifiques et contrevient à de nombreuses attentes des utilisateurs lorsqu'elle est appliquée à des fins d'utilisation ordinaires. custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon. @@ -223,17 +222,23 @@ fr-CA: setting_aggregate_reblogs: Grouper les partages dans les fils d’actualités setting_always_send_emails: Toujours envoyer les notifications par courriel setting_auto_play_gif: Lire automatiquement les GIFs animés + setting_boost_modal: Configurer la visibilité du partage setting_default_language: Langue de publication + setting_default_privacy: Visibilité de la publication setting_default_quote_policy: Autoriser les citations pour setting_default_sensitive: Toujours marquer les médias comme sensibles + setting_delete_modal: M'avertir avant de supprimer un message setting_disable_hover_cards: Désactiver l'aperçu du profil au survol setting_disable_swiping: Désactiver les actions par glissement setting_display_media: Affichage des médias setting_display_media_default: Défaut setting_display_media_hide_all: Masquer tout setting_display_media_show_all: Montrer tout + setting_emoji_style: Style des émojis setting_expand_spoilers: Toujours déplier les messages marqués d’un avertissement de contenu setting_hide_network: Cacher votre réseau + setting_missing_alt_text_modal: M'avertir avant de publier des médias sans texte alternatif + setting_quick_boosting: Activer le partage rapide setting_reduce_motion: Réduire la vitesse des animations setting_system_font_ui: Utiliser la police par défaut du système setting_system_scrollbars_ui: Utiliser la barre de défilement par défaut du système @@ -267,6 +272,7 @@ fr-CA: content_cache_retention_period: Durée de rétention du contenu distant custom_css: CSS personnalisé favicon: Favicon + landing_page: Page d'accueil pour les nouveaux visiteurs mascot: Mascotte personnalisée (héritée) media_cache_retention_period: Durée de rétention des médias dans le cache min_age: Âge minimum requis @@ -311,6 +317,7 @@ fr-CA: follow_request: Quelqu’un demande à me suivre mention: Quelqu’un me mentionne pending_account: Nouveau compte en attente d’approbation + quote: Quelqu'un vous a cité reblog: Quelqu’un a partagé mon message report: Nouveau signalement soumis software_updates: @@ -357,6 +364,10 @@ fr-CA: name: Nom permissions_as_keys: Autorisations position: Priorité + username_block: + allow_with_approval: Autoriser les inscriptions avec approbation + comparison: Méthode de comparaison + username: Mot à faire correspondre webhook: events: Événements activés template: Modèle de charge utile diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index 270a259dec1..dda65ff2886 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -56,6 +56,7 @@ fr: scopes: À quelles APIs l’application sera autorisée à accéder. Si vous sélectionnez une permission générale, vous n’avez pas besoin de sélectionner les permissions plus précises. setting_aggregate_reblogs: Ne pas afficher les nouveaux partages pour les messages déjà récemment partagés (n’affecte que les partages futurs) setting_always_send_emails: Normalement, les notifications par courriel ne seront pas envoyées lorsque vous utilisez Mastodon activement + setting_default_quote_policy_unlisted: Lorsque des personnes vous citent, leur message sera également masqué des fils des tendances. setting_default_sensitive: Les médias sensibles sont cachés par défaut et peuvent être révélés d’un simple clic setting_display_media_default: Masquer les médias marqués comme sensibles setting_display_media_hide_all: Toujours masquer les médias @@ -73,7 +74,6 @@ fr: featured_tag: name: 'Voici quelques hashtags que vous avez utilisés récemment :' filters: - action: Choisir l'action à effectuer quand un message correspond au filtre actions: blur: Cacher les médias derrière un avertissement, sans cacher le texte hide: Cacher complètement le contenu filtré, faire comme s'il n'existait pas @@ -82,7 +82,6 @@ fr: activity_api_enabled: Nombre de messages publiés localement, de comptes actifs et de nouvelles inscriptions par tranche hebdomadaire app_icon: WEBP, PNG, GIF ou JPG. Remplace la favicon Mastodon par défaut avec une icône personnalisée. backups_retention_period: Les utilisateur·rice·s ont la possibilité de générer des archives de leurs messages pour les télécharger plus tard. Lorsqu'elles sont définies à une valeur positive, ces archives seront automatiquement supprimées de votre stockage après le nombre de jours spécifié. - bootstrap_timeline_accounts: Ces comptes seront épinglés en tête de liste des recommandations pour les nouveaux utilisateurs. closed_registrations_message: Affiché lorsque les inscriptions sont fermées content_cache_retention_period: Tous les messages provenant d'autres serveurs (y compris les partages et les réponses) seront supprimés passé le nombre de jours spécifié, sans tenir compte de l'interaction de l'utilisateur·rice local·e avec ces messages. Cela inclut les messages qu'un·e utilisateur·rice aurait marqué comme signets ou comme favoris. Les mentions privées entre utilisateur·rice·s de différentes instances seront également perdues et impossibles à restaurer. L'utilisation de ce paramètre est destinée à des instances spécifiques et contrevient à de nombreuses attentes des utilisateurs lorsqu'elle est appliquée à des fins d'utilisation ordinaires. custom_css: Vous pouvez appliquer des styles personnalisés sur la version Web de Mastodon. @@ -223,17 +222,23 @@ fr: setting_aggregate_reblogs: Grouper les partages dans les fils d’actualités setting_always_send_emails: Toujours envoyer les notifications par courriel setting_auto_play_gif: Lire automatiquement les GIFs animés + setting_boost_modal: Configurer la visibilité du partage setting_default_language: Langue de publication + setting_default_privacy: Visibilité de la publication setting_default_quote_policy: Autoriser les citations pour setting_default_sensitive: Toujours marquer les médias comme sensibles + setting_delete_modal: M'avertir avant de supprimer un message setting_disable_hover_cards: Désactiver l'aperçu du profil au survol setting_disable_swiping: Désactiver les actions par glissement setting_display_media: Affichage des médias setting_display_media_default: Défaut setting_display_media_hide_all: Masquer tout setting_display_media_show_all: Montrer tout + setting_emoji_style: Style des émojis setting_expand_spoilers: Toujours déplier les messages marqués d’un avertissement de contenu setting_hide_network: Cacher votre réseau + setting_missing_alt_text_modal: M'avertir avant de publier des médias sans texte alternatif + setting_quick_boosting: Activer le partage rapide setting_reduce_motion: Réduire la vitesse des animations setting_system_font_ui: Utiliser la police par défaut du système setting_system_scrollbars_ui: Utiliser la barre de défilement par défaut du système @@ -267,6 +272,7 @@ fr: content_cache_retention_period: Durée de rétention du contenu distant custom_css: CSS personnalisé favicon: Favicon + landing_page: Page d'accueil pour les nouveaux visiteurs mascot: Mascotte personnalisée (héritée) media_cache_retention_period: Durée de rétention des médias dans le cache min_age: Âge minimum requis @@ -311,6 +317,7 @@ fr: follow_request: Quelqu’un demande à vous suivre mention: Quelqu’un vous a mentionné⋅e pending_account: Nouveau compte en attente d’approbation + quote: Quelqu'un vous a cité reblog: Quelqu’un a partagé votre message report: Nouveau signalement soumis software_updates: @@ -357,6 +364,10 @@ fr: name: Nom permissions_as_keys: Autorisations position: Priorité + username_block: + allow_with_approval: Autoriser les inscriptions avec approbation + comparison: Méthode de comparaison + username: Mot à faire correspondre webhook: events: Événements activés template: Modèle de payload diff --git a/config/locales/simple_form.fy.yml b/config/locales/simple_form.fy.yml index 9b0be65b3e9..6507b94ab87 100644 --- a/config/locales/simple_form.fy.yml +++ b/config/locales/simple_form.fy.yml @@ -74,7 +74,6 @@ fy: featured_tag: name: 'Hjir binne inkelde fan de hashtags dy’t jo koartlyn brûkt hawwe:' filters: - action: Kies hokker aksjes útfierd wurde moatte, wannear’t in berjocht oerienkomt mei it filter actions: blur: Media ferstopje efter in warskôging, sûnder de tekst sels te ferstopjen hide: Ferstopje de filtere ynhâld folslein, as oft it net bestiet @@ -83,7 +82,6 @@ fy: activity_api_enabled: Tal lokaal publisearre artikelen, aktive brûkers en nije registraasjes yn wyklikse werjefte app_icon: WEBP, PNG, GIF of JPG. Ferfangt op mobile apparaten it standert app-pictogram mei in oanpast piktogram. backups_retention_period: Brûkers hawwe de mooglikheid om argiven fan harren berjochten te generearjen om letter te downloaden. Wannear ynsteld op in positive wearde, wurde dizze argiven automatysk fuortsmiten út jo ûnthâld nei it opjûne oantal dagen. - bootstrap_timeline_accounts: Dizze accounts wurde boppe oan de oanrekommandaasjes oan nije brûkers toand. Meardere brûkersnammen troch komma’s skiede. closed_registrations_message: Werjûn wannear’t registraasje fan nije accounts útskeakele is content_cache_retention_period: Alle berjochten fan oare servers (ynklusyf boosts en reaksjes) wurde fuortsmiten nei it opjûne oantal dagen, nettsjinsteande iennige lokale brûkersynteraksje mei dy berjochten. Dit oanbelanget ek berjochten dy’t in lokale brûker oan harren blêdwizers tafoege hat of as favoryt markearre hat. Priveeberjochten tusken brûkers fan ferskate servers gean ek ferlern en binne ûnmooglik te werstellen. It gebrûk fan dizze ynstelling is bedoeld foar servers dy’t in spesjaal doel tsjinje en oertrêdet in protte brûkersferwachtingen wannear’t dizze foar algemien gebrûk ymplemintearre wurdt. custom_css: Jo kinne oanpaste CSS tapasse op de webferzje fan dizze Mastodon-server. diff --git a/config/locales/simple_form.ga.yml b/config/locales/simple_form.ga.yml index decbe02cecd..d5e70f08929 100644 --- a/config/locales/simple_form.ga.yml +++ b/config/locales/simple_form.ga.yml @@ -79,7 +79,7 @@ ga: featured_tag: name: 'Seo cuid de na hashtags a d’úsáid tú le déanaí:' filters: - action: Roghnaigh an gníomh ba cheart a dhéanamh nuair a mheaitseálann postáil an scagaire + action: Roghnaigh cén gníomh atá le déanamh nuair a mheaitseálann post an scagaire actions: blur: Folaigh na meáin taobh thiar de rabhadh, gan an téacs féin a cheilt hide: Cuir an t-ábhar scagtha i bhfolach go hiomlán, ag iompar amhail is nach raibh sé ann @@ -88,7 +88,7 @@ ga: activity_api_enabled: Áireamh na bpost a foilsíodh go háitiúil, úsáideoirí gníomhacha, agus clárúcháin nua i buicéid seachtainiúla app_icon: WEBP, PNG, GIF nó JPG. Sáraíonn sé an deilbhín réamhshocraithe aipe ar ghléasanna soghluaiste le deilbhín saincheaptha. backups_retention_period: Tá an cumas ag úsáideoirí cartlanna dá gcuid post a ghiniúint le híoslódáil níos déanaí. Nuair a bheidh luach dearfach socraithe, scriosfar na cartlanna seo go huathoibríoch ó do stór tar éis an líon sonraithe laethanta. - bootstrap_timeline_accounts: Cuirfear na cuntais seo ar bharr na moltaí a leanann úsáideoirí nua. + bootstrap_timeline_accounts: Beidh na cuntais seo bioráilte ag barr mholtaí leantacha úsáideoirí nua. Cuir liosta cuntas ar fáil atá scartha le camóga. closed_registrations_message: Ar taispeáint nuair a dhúntar clárúcháin content_cache_retention_period: Scriosfar gach postáil ó fhreastalaithe eile (lena n-áirítear treisithe agus freagraí) tar éis an líon sonraithe laethanta, gan aird ar aon idirghníomhaíocht úsáideora áitiúil leis na postálacha sin. Áirítear leis seo postálacha ina bhfuil úsáideoir áitiúil tar éis é a mharcáil mar leabharmharcanna nó mar cheanáin. Caillfear tagairtí príobháideacha idir úsáideoirí ó chásanna éagsúla freisin agus ní féidir iad a athchóiriú. Tá úsáid an tsocraithe seo beartaithe le haghaidh cásanna sainchuspóra agus sáraítear go leor ionchais úsáideoirí nuair a chuirtear i bhfeidhm é le haghaidh úsáid ghinearálta. custom_css: Is féidir leat stíleanna saincheaptha a chur i bhfeidhm ar an leagan gréasáin de Mastodon. diff --git a/config/locales/simple_form.gd.yml b/config/locales/simple_form.gd.yml index bc4c3b7f0a9..54d1be91b79 100644 --- a/config/locales/simple_form.gd.yml +++ b/config/locales/simple_form.gd.yml @@ -65,7 +65,7 @@ gd: setting_display_media_hide_all: Falaich na meadhanan an-còmhnaidh setting_display_media_show_all: Seall na meadhanan an-còmhnaidh setting_emoji_style: An dòigh air an dèid emojis a shealltainn. Feuchaidh “Fèin-obrachail” ris na h-emojis tùsail a chleachdadh ach thèid Twemoji a chleachdadh ’nan àite air seann-bhrabhsairean. - setting_quick_boosting_html: Ma tha seo an comas, ma nì thu briogadh air ìomhaigheag %{boost_icon} a’ bhrosnachaidh, thèid a bhriosnachadh sa bhad seach a bhith a’ fosgladh clàr-taice teàrnach a’ bhrosnachaidh/luaidh. Thèid gnìomh an luaidh a ghluasad gu clàr-taice nan %{options_icon} (roghainnean). + setting_quick_boosting_html: Ma tha seo an comas, ma nì thu briogadh air ìomhaigheag %{boost_icon} a’ bhrosnachaidh, thèid a bhrosnachadh sa bhad seach a bhith a’ fosgladh clàr-taice teàrnach a’ bhrosnachaidh/luaidh. Thèid gnìomh an luaidh a ghluasad gu clàr-taice %{options_icon} nan roghainnean. setting_system_scrollbars_ui: Chan obraich seo ach air brabhsairean desktop stèidhichte air Safari ’s Chrome setting_use_blurhash: Tha caiseadan stèidhichte air dathan nan nithean lèirsinneach a chaidh fhalach ach chan fhaicear am mion-fhiosrachadh setting_use_pending_items: Falaich ùrachaidhean na loidhne-ama air cùlaibh briogaidh seach a bhith a’ sgroladh nam postaichean gu fèin-obrachail @@ -88,11 +88,11 @@ gd: activity_api_enabled: Cunntasan nam postaichean a chaidh fhoillseachadh gu h-ionadail, nan cleachdaichean gnìomhach ’s nan clàraidhean ùra an am bucaidean seachdaineil app_icon: WEBP, PNG, GIF no JPG. Tar-àithnidh seo ìomhaigheag bhunaiteach na h-aplacaid air uidheaman mobile le ìomhaigheag ghnàthaichte. backups_retention_period: "’S urrainn do chleachdaichean tasg-lannan dhe na postaichean aca a gintinn airson an luchdadh a-nuas an uairsin. Nuair a bhios luach dearbh air, thèid na tasg-lannan a sguabadh às on stòras agad gu fèin-obrachail às dèidh an àireamh de làithean a shònraich thu." - bootstrap_timeline_accounts: Thèid na cunntasan seo a phrìneachadh air bàrr nam molaidhean leantainn dhan luchd-cleachdaidh ùr. closed_registrations_message: Thèid seo a shealltainn nuair a bhios an clàradh dùinte content_cache_retention_period: Thèid a h-uile post o fhrithealaiche sam bith eile (a’ gabhail a-staigh brosnachaidhean is freagairtean) a sguabadh às às dèidh na h-àireimh de làithean a shònraich thu ’s gun diù a chon air eadar-ghabhail ionadail air na postaichean ud. Gabhaidh seo a-steach na postaichean a chuir cleachdaiche ionadail ris na h-annsachdan aca no comharran-lìn riutha. Thèid iomraidhean prìobhaideach eadar cleachdaichean o ionstansan diofraichte air chall cuideachd agus cha ghabh an aiseag idir. Tha an roghainn seo do dh’ionstansan sònraichte a-mhàin agus briseadh e dùilean an luchd-cleachdaidh nuair a rachadh a chleachdadh gu coitcheann. custom_css: "’S urrainn dhut stoidhlean gnàthaichte a chur an sàs air an tionndadh-lìn de Mhastodon." favicon: WEBP, PNG, GIF no JPG. Tar-àithnidh seo favicon bunaiteach Mhastodon le ìomhaigheag ghnàthaichte. + landing_page: Taghaidh seo an duilleag a chì aoighean ùra nuair a thadhlas air an fhrithealaiche agad a’ chiad turas. ma thaghas tu “Treandaichean”, feumaidh tu na treandaichean a chur an comas ann ann roghainnean an rùrachaidh. Ma thaghas tu “Loidhne-ama ionadail”, feumaidh tu “Inntrigeadh dhan t-saoghal bheò sa bheil postaichean ionadail” a shuidheachadh air “A h-uile duine” ann an roghainnean an rùrachaidh. mascot: Tar-àithnidh seo an sgead-dhealbh san eadar-aghaidh-lìn adhartach. media_cache_retention_period: Thèid faidhlichean meadhain o phostaichean a chruthaich cleachdaichean cèine a chur ri tasgadan an fhrithealaiche agad. Nuair a shuidhicheas tu seo air luach dearbh, thèid na meadhanan a sguabadh às às dèidh na h-àireimh de làithean a shònraich thu. Ma tha dàta meadhain ga iarraidh às dèidh a sguabaidh às, thèid a luchdadh a-nuas a-rithist ma tha susbaint an tùis ri fhaighinn fhathast. Ri linn cuingeachaidhean air mar a cheasnaicheas cairtean ro-sheallaidh làraichean threas-phàrtaidhean, mholamaid gun suidhich thu an luach seo air 14 làithean ar a char as giorra no cha dèid an ùrachadh nuair a thèid an iarraidh ron àm sin. min_age: Thèid iarraidh air an luchd-cleachdaidh gun dearbh iad an là-breith rè a’ chlàraidh @@ -288,6 +288,7 @@ gd: content_cache_retention_period: Ùine glèidhidh aig susbaint chèin custom_css: CSS gnàthaichte favicon: Favicon + landing_page: An duilleag-laighe do dh’aoighean ùra local_live_feed_access: Inntrigeadh dhan t-saoghal bheò sa bheil postaichean ionadail local_topic_feed_access: Inntrigeadh dha loidhnichean-ama nan tagaichean hais is ceanglaichean sa bheil postaichean ionadail mascot: Suaichnean gnàthaichte (dìleabach) diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index cb088c9b81d..3a91a26c114 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -88,11 +88,11 @@ gl: activity_api_enabled: Conta do número de publicacións locais, usuarias activas, e novos rexistros en acumulados semanais app_icon: WEBP, PNG, GIF ou JPG. Sobrescribe a icona por defecto da aplicación nos dispositivos móbiles cunha icona personalizada. backups_retention_period: As usuarias poden crear arquivos das súas publicacións para descargalos. Cando se establece un valor positivo, estes arquivos serán borrados automáticamente da túa almacenaxe despois do número de días establecido. - bootstrap_timeline_accounts: Estas contas aparecerán fixas na parte superior das recomendacións para as usuarias. closed_registrations_message: Móstrase cando non se admiten novas usuarias content_cache_retention_period: Todas as publicacións procedentes de outros servidores (incluído promocións e respostas) van ser eliminadas despois do número de días indicado, sen importar as interaccións das usuarias locais con esas publicacións. Esto inclúe publicacións que a usuaria local marcou como favoritas ou incluíu nos marcadores. As mencións privadas entre usuarias de diferentes instancias tamén se eliminarán e non se poderán restablecer. O uso desta ferramenta esta orientado a situacións especiais e estraga moitas das expectativas das usuarias ao implementala cun propósito de uso xeral. custom_css: Podes aplicar deseños personalizados na versión web de Mastodon. favicon: WEBP, PNG, GIF ou JPG. Sobrescribe a icona de favoritos de Mastodon por defecto cunha icona personalizada. + landing_page: Elixe a páxina que verán as persoas que se acheguen por primeira vez ao teu servidor. Se elixes «Tendencias» entón debes activar as tendencias nos Axustes de Descubrimento. Se elixes «Cronoloxía local», hai que configurar nos Axustes de Descubrimento a opción «Acceso das cronoloxías en directo ás publicacións locais» como «Calquera». mascot: Sobrescribe a ilustración na interface web avanzada. media_cache_retention_period: Os ficheiros multimedia de publicacións de usuarias remotas están almacenados no teu servidor. Ao establecer un valor positivo, o multimedia vaise eliminar despois do número de días establecido. Se o multimedia fose requerido após ser eliminado entón descargaríase outra vez, se aínda está dispoñible na orixe. Debido a restricións sobre a frecuencia en que o servizo de vista previa trae recursos de terceiras partes, é recomendable establecer este valor polo menos en 14 días, ou as tarxetas de vista previa non se actualizarán baixo demanda para casos anteriores a ese prazo. min_age: Váiselle pedir ás usuarias que confirmen a súa data de nacemento cando creen a conta @@ -286,6 +286,7 @@ gl: content_cache_retention_period: Período de retención de contido remoto custom_css: CSS personalizado favicon: Favicon + landing_page: Páxina que se mostra ás visitas local_live_feed_access: Acceso a cronoloxías ao vivo que mostran publicacións locais local_topic_feed_access: Acceso a cronoloxías de ligazóns e cancelos que mostran publicacións locais mascot: Mascota propia (herdado) diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index 5f96869d76b..492d27bea0e 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -88,7 +88,7 @@ he: activity_api_enabled: מספר ההודעות שפורסמו מקומית, משתמשים פעילים, והרשמות חדשות בדליים שבועיים app_icon: WEBP, PNG, GIF או JPG. גובר על אייקון ברירת המחדל ביישומון על מכשירים ניידים ומחליף אותו באייקון נבחר. backups_retention_period: למשתמשים יש יכולת לבקש ארכיון של הודעותיהם להורדה מאוחר יותר. כאשר נבחר ערך חיובי, הארכיונים הללו ימחקו מאחסון לאחר מספר הימים שצוינו. - bootstrap_timeline_accounts: חשבונות אלו יוצמדו לראש רשימת המלצות המעקב של משתמשים חדשים. + bootstrap_timeline_accounts: חשבונות אלו יוצמדו בראש הפיד של המלצות המעקב למשתמשים חדשים. נא לספק רשימת חשבונות מופרדים בפסיקים. closed_registrations_message: להציג כאשר הרשמות חדשות אינן מאופשרות content_cache_retention_period: כל ההודעות משרתים אחרים (לרבות הדהודים ותגובות) ימחקו אחרי מספר ימים, ללא קשר לאינטראקציה של משתמשים מקומיים איתם. בכלל זה הודעות שהמתשתמשים המקומיים סימנו בסימניה או חיבוב. איזכורים פרטיים ("דיאם") בין משתמשים בין שרתים שונים יאבדו גם הם ולא תהיה אפשרות לשחזרם. השימוש באפשרות הזו מיועד לשרתים עם ייעוד מיוחד ושובר את ציפיותיהם של רב המשתמשים כאשר האפשרות מופעלת בשרת לשימוש כללי. custom_css: ניתן לבחור ערכות סגנון אישיות בגרסת הדפדפן של מסטודון. diff --git a/config/locales/simple_form.hu.yml b/config/locales/simple_form.hu.yml index 0e41641d61b..f5dcf3b96a5 100644 --- a/config/locales/simple_form.hu.yml +++ b/config/locales/simple_form.hu.yml @@ -79,7 +79,6 @@ hu: featured_tag: name: 'Itt vannak azok a hashtagek, melyeket legutóbb használtál:' filters: - action: A végrehajtandó műveletet, ha a bejegyzés megfelel a szűrőnek actions: blur: Média elrejtése figyelmeztetéssel, a szöveg elrejtése nélkül hide: A szűrt tartalom teljes elrejtése, mintha nem is létezne @@ -88,11 +87,11 @@ hu: activity_api_enabled: Helyi bejegyzések, aktív felhasználók és új regisztrációk száma heti bontásban app_icon: WEBP, PNG, GIF vagy JPG. Mobileszközökön az alkalmazás alapértelmezett ikonját felülírja egy egyéni ikonnal. backups_retention_period: A felhasználók archívumokat állíthatnak elő a bejegyzéseikből, hogy később letöltsék azokat. Ha pozitív értékre van állítva, akkor a megadott számú nap után automatikusan törölve lesznek a tárhelyedről. - bootstrap_timeline_accounts: Ezek a fiókok ki lesznek tűzve az új felhasználók követési javaslatainak élére. closed_registrations_message: Akkor jelenik meg, amikor a regisztráció le van zárva content_cache_retention_period: Minden más kiszolgálóról származó bejegyzés (megtolásokkal és válaszokkal együtt) törölve lesz a megadott számú nap elteltével, függetlenül a helyi felhasználók ezekkel a bejegyzésekkel történő interakcióitól. Ebben azok a bejegyzések is benne vannak, melyeket a helyi felhasználó könyvjelzőzött vagy kedvencnek jelölt. A különböző kiszolgálók felhasználói közötti privát üzenetek is el fognak veszni visszaállíthatatlanul. Ennek a beállításnak a használata különleges felhasználási esetekre javasolt, mert számos felhasználói elvárás fog eltörni, ha általános céllal használják. custom_css: A Mastodon webes verziójában használhatsz egyéni stílusokat. favicon: WEBP, PNG, GIF vagy JPG. Az alapértelmezett Mastodon favicont felülírja egy egyéni ikonnal. + landing_page: Kiválasztja, hogy a webhely új látogatói mit látnak, amikor először érkeznek a kiszolgálóra. Ha a „Trendek” lehetőséget választod, akkor engedélyezni kell a trendeket a Felfedezési beállításokban. Ha a „Helyi hírfolyamot” választod, akkor a „Helyi bejegyzéseket tartalmazó helyi élő idővonalak elérése” lehetőséget „Mindenki” értékre kell állítani a Felfedezési beállításokban. mascot: Felülbírálja a speciális webes felületen található illusztrációt. media_cache_retention_period: A távoli felhasználók bejegyzéseinek médiatartalmait a kiszolgálód gyorsítótárazza. Ha pozitív értékre állítják, ezek a médiatartalmak a megadott számú nap után törölve lesznek. Ha a médiát újra lekérik, miután törlődött, újra le fogjuk tölteni, ha az eredeti még elérhető. A hivatkozások előnézeti kártyáinak harmadik fél weboldalai felé történő hivatkozásaira alkalmazott megkötései miatt javasolt, hogy ezt az értéket legalább 14 napra állítsuk, ellenkező esetben a hivatkozások előnézeti kártyái szükség esetén nem fognak tudni frissülni ezen idő előtt. min_age: A felhasználók a regisztráció során arra lesznek kérve, hogy erősítsek meg a születési dátumukat @@ -286,6 +285,7 @@ hu: content_cache_retention_period: Távoli tartalmak megtartási időszaka custom_css: Egyéni CSS favicon: Könyvjelzőikon + landing_page: Kezdőoldal az új látogatóknak local_live_feed_access: Helyi bejegyzéseket bemutató élő hírfolyamok elérése local_topic_feed_access: Helyi bejegyzéseket bemutató hashtagek és hivatkozásfolyamok elérése mascot: Egyéni kabala (örökölt) diff --git a/config/locales/simple_form.ia.yml b/config/locales/simple_form.ia.yml index b231ff0dedd..b8231e2e14d 100644 --- a/config/locales/simple_form.ia.yml +++ b/config/locales/simple_form.ia.yml @@ -79,7 +79,6 @@ ia: featured_tag: name: 'Ecce alcun del hashtags que tu usava le plus recentemente:' filters: - action: Selige que action exequer quando un message concorda con le filtro actions: blur: Celar contento multimedial detra un advertimento, sin celar le texto mesme hide: Completemente celar le contento filtrate, comportar se como si illo non existerea @@ -88,7 +87,6 @@ ia: activity_api_enabled: Numeros de messages localmente publicate, usatores active, e nove registrationes in gruppos septimanal app_icon: WEBP, PNG, GIF o JPG. Supplanta le icone predefinite sur apparatos mobile con un icone personalisate. backups_retention_period: Le usatores pote generar archivos de lor messages pro discargar los plus tarde. Si iste option es definite a un valor positive, iste archivos essera automaticamente delite de tu immagazinage post le numero specificate de dies. - bootstrap_timeline_accounts: Iste contos essera fixate al initio del recommendationes de sequimento de nove usatores. closed_registrations_message: Monstrate quando le inscriptiones es claudite content_cache_retention_period: Tote le messages de altere servitores (includite impulsos e responsas) essera delite post le numero de dies specificate, independentemente de tote interaction de usatores local con ille messages. Isto include le messages addite al marcapaginas o marcate como favorite per un usator local. Le mentiones private inter usatores de differente instantias tamben essera irrecuperabilemente perdite. Le uso de iste parametro es intendite pro instantias con scopos specific e viola multe expectationes de usatores si es implementate pro uso general. custom_css: Tu pote applicar stilos personalisate sur le version de web de Mastodon. diff --git a/config/locales/simple_form.id.yml b/config/locales/simple_form.id.yml index 79de53b680e..56c9deed9d6 100644 --- a/config/locales/simple_form.id.yml +++ b/config/locales/simple_form.id.yml @@ -61,12 +61,10 @@ id: featured_tag: name: 'Ini adalah beberapa tagar yang sering Anda gunakan:' filters: - action: Pilih tindakan apa yang dilakukan ketika sebuah kiriman cocok dengan saringan actions: hide: Sembunyikan konten yang disaring, seperti itu tidak ada warn: Sembunyikan konten yang disaring di belakang sebuah peringatan menyebutkan judul saringan form_admin_settings: - bootstrap_timeline_accounts: Akun ini akan disematkan di atas rekomendasi ikut pengguna baru. closed_registrations_message: Ditampilkan ketika pendaftaran ditutup custom_css: Anda dapat menerapkan gaya kustom di versi web Mastodon. mascot: Menimpa ilustrasi di antarmuka web tingkat lanjut. diff --git a/config/locales/simple_form.ie.yml b/config/locales/simple_form.ie.yml index 728e9e81b59..73c3bcfa036 100644 --- a/config/locales/simple_form.ie.yml +++ b/config/locales/simple_form.ie.yml @@ -70,7 +70,6 @@ ie: featured_tag: name: 'Vi quelc hashtags usat max recentmen de te:' filters: - action: Selecter quel action a far quande un posta egala un filtre actions: hide: Celar completmen li contenete filtrat, quam si it ne existe warn: Celar li contenete filtrat detra un avise mentionant li titul del filtre @@ -78,7 +77,6 @@ ie: activity_api_enabled: Númeres de postas publicat localmen, activ usatores, e nov adhesiones in periodes semanal app_icon: WEBP, PNG, GIF o JPG. Remplazza li predenifit favicon Mastodon sur mobiles con un icon customisat. backups_retention_period: Usatores posse generar archives de lor postas por adcargar plu tard. Si on specifica un valore positiv, li archives va esser automaticmen deletet de tui magazinage pos li specificat quantitá de dies. - bootstrap_timeline_accounts: Ti-ci contos va esser pinglat al parte superiori del recomandationes por nov usatores. closed_registrations_message: Monstrat quande adhesiones es cludet content_cache_retention_period: Omni postas de altri servitores (includente boosts e responses) va esser deletet pos li specificat quantitá de dies, sin egard a local usator-interactiones con les. To vale anc por postas queles un local usator ha marcat o favoritat it. Anc privat mentiones ínter usatores de diferent instanties va esser perdit e ínrestorabil. Talmen, ti-ci parametre es intentet por scopes special pro que it posse ruptes li expectationes de usatores. custom_css: On posse aplicar customisat stiles al web-version de Mastodon. diff --git a/config/locales/simple_form.io.yml b/config/locales/simple_form.io.yml index 03c0fd24c19..9cd295eb5f9 100644 --- a/config/locales/simple_form.io.yml +++ b/config/locales/simple_form.io.yml @@ -73,7 +73,6 @@ io: featured_tag: name: 'Yen kelka hashtagi quin vu uzis maxim recente:' filters: - action: Selektez ago kande posto parigas filtrilo actions: hide: Komplete celez filtrita kontenajo quale ol ne existas warn: Celez filtrita kontenajo dop avert quo montras titulo di filtrilo @@ -81,7 +80,6 @@ io: activity_api_enabled: Quanto de lokale publikigita posti, aktiva uzanti e nova registri, donita semanope app_icon: WEBP, PNG, GIF o JPG. Ol remplas la originala imajeto di softwaro sur poshaparati kun personaligita imajeto. backups_retention_period: Uzanto povas igar arkivi di sua afishi por deskargar pose. - bootstrap_timeline_accounts: Ca konti adpinglesos ad super sequorekomendi di nova uzanti. closed_registrations_message: Montresas kande registradi klozesas content_cache_retention_period: Omna posti de altra servili efacesos (anke repeti e respondi) pos decidita quanto di dii, sen ye irga lokala uzantointerago kun ti posti. Privata mencioni inter uzanto de dessanta servili anke desganos e neposible riganesos. custom_css: Vu povas pozar kustumizita staili en retverso di Mastodon. diff --git a/config/locales/simple_form.is.yml b/config/locales/simple_form.is.yml index ccaa8dd69da..9795077ca13 100644 --- a/config/locales/simple_form.is.yml +++ b/config/locales/simple_form.is.yml @@ -88,11 +88,12 @@ is: activity_api_enabled: Fjöldi staðværra stöðufærslna, virkra notenda og nýskráninga í vikulegum skömmtum app_icon: WEBP, PNG, GIF eða JPG. Tekur yfir sjálfgefna táknmynd forrits á snjalltækjum með sérsniðinni táknmynd. backups_retention_period: Notendur hafa kost á að útbúa safnskrár með færslunum sínum til að sækja svo síðar. Þegar þetta er stillt á jákvætt gildi, verður þessum safnskrám eytt sjáfkrafa eftir þeim tiltekna fjölda daga. - bootstrap_timeline_accounts: Þessir notendaaðgangar verða festir efst í meðmælum til nýrra notenda um að fylgjast með þeim. + bootstrap_timeline_accounts: Þessi aðgangar verða festir efst á listann yfir þá aðila sem mælt er með að nýir notendur fylgist með. Gefðu upp lista yfir aðganga aðgreindan með kommum. closed_registrations_message: Birtist þegar lokað er á nýskráningar content_cache_retention_period: Öllum færslum af öðrum netþjónum (þar með taldar endurbirtingar og svör) verður eytt eftir uppgefinn fjölda daga, án tillits til gagnvirkni staðværra notenda við þessar færslur. Þetta á einnig við um færslur sem notandinn hefur merkt sem bókamerki eða eftirlæti. Beinar tilvísanir (einkaspjall) milli notenda af mismunandi netþjónum munu einnig tapast og er engin leið til að endurheimta þær. Notkun á þessari stillingu er einungis ætluð sérstilltum netþjónum og mun skemma fyrir notendum ef þetta er sett upp fyrir almenna notkun. custom_css: Þú getur virkjað sérsniðna stíla í vefútgáfu Mastodon. favicon: WEBP, PNG, GIF eða JPG. Tekur yfir sjálfgefna Mastodon favicon-táknmynd með sérsniðinni táknmynd. + landing_page: Þetta ákvarðar hvaða síðu nýir gestir sjá þegar þeir koma fyrst á netþjóninn þinn. Ef þú velur "Vinsælt" þá þurfa vinsælar færslur að vera virkjaðar í stillingum fyrir Uppgötvun. Ef þú velur "Staðbundið streymi" þá þarf "Aðgangur að beinum streymum, þar með töldum staðværum færslum" að vera stillt á "Allir" í stillingum fyrir Uppgötvun. mascot: Þetta tekyr yfir myndskreytinguna í ítarlega vefviðmótinu. media_cache_retention_period: Myndefnisskrár úr færslum sem gerðar eru af fjartengdum notendum eru geymdar á netþjóninum þínum. Þegar þetta er stillt á jákvætt gildi, verður þessum skrám eytt sjáfkrafa eftir þeim tiltekna fjölda daga. Ef beðið er um myndefnið eftir að því er eytt, mun það verða sótt aftur ef frumgögnin eru ennþá aðgengileg. Vegna takmarkana á hversu oft forskoðunarspjöld tengla eru sótt á utanaðkomandi netþjóna, þá er mælt með því að setja þetta gildi á að minnsta kosti 14 daga, annars gæti mistekist að uppfæra forskoðunarspjöld tengla eftir þörfum fyrir þann tíma. min_age: Notendur verða beðnir um að staðfesta fæðingardag sinn við nýskráningu diff --git a/config/locales/simple_form.it.yml b/config/locales/simple_form.it.yml index bc06874e309..8ce108ba960 100644 --- a/config/locales/simple_form.it.yml +++ b/config/locales/simple_form.it.yml @@ -88,11 +88,12 @@ it: activity_api_enabled: Conteggi di post pubblicati localmente, utenti attivi e nuove registrazioni in gruppi settimanali app_icon: WEBP, PNG, GIF o JPG. Sostituisce l'icona dell'app predefinita sui dispositivi mobili con un'icona personalizzata. backups_retention_period: Gli utenti hanno la possibilità di generare archivi dei propri post da scaricare successivamente. Se impostati su un valore positivo, questi archivi verranno automaticamente eliminati dallo spazio di archiviazione dopo il numero di giorni specificato. - bootstrap_timeline_accounts: Questi account verranno aggiunti in cima ai consigli da seguire dei nuovi utenti. + bootstrap_timeline_accounts: Questi account verranno aggiunti in cima ai suggerimenti dei nuovi utenti. Fornisci un elenco di account separati da virgole. closed_registrations_message: Visualizzato alla chiusura delle iscrizioni content_cache_retention_period: Tutti i post da altri server (inclusi booster e risposte) verranno eliminati dopo il numero specificato di giorni, senza tener conto di eventuali interazioni con gli utenti locali con tali post. Questo include i post in cui un utente locale ha contrassegnato come segnalibri o preferiti. Anche le menzioni private tra utenti di diverse istanze andranno perse e impossibile da ripristinare. L'uso di questa impostazione è inteso per casi di scopo speciale e rompe molte aspettative dell'utente quando implementato per uso generale. custom_css: È possibile applicare stili personalizzati sulla versione web di Mastodon. favicon: WEBP, PNG, GIF o JPG. Sostituisce la favicon predefinita di Mastodon con un'icona personalizzata. + landing_page: Seleziona quale pagina vedono i nuovi visitatori al loro primo arrivo sul tuo server. Se selezioni "Tendenze", è necessario abilitare le tendenze nelle Impostazioni di scoperta. Se selezioni "Feed locale", allora è necessario impostare "Accesso ai feed in diretta con post locali" su "Tutti" nelle Impostazioni di scoperta. mascot: Sostituisce l'illustrazione nell'interfaccia web avanzata. media_cache_retention_period: I file multimediali da post fatti da utenti remoti sono memorizzati nella cache sul tuo server. Quando impostato a un valore positivo, i media verranno eliminati dopo il numero specificato di giorni. Se i dati multimediali sono richiesti dopo che sono stati eliminati, saranno nuovamente scaricati, se il contenuto sorgente è ancora disponibile. A causa di restrizioni su quanto spesso link anteprima carte sondaggio siti di terze parti, si consiglia di impostare questo valore ad almeno 14 giorni, o le schede di anteprima link non saranno aggiornate su richiesta prima di quel tempo. min_age: Agli utenti verrà chiesto di confermare la propria data di nascita durante l'iscrizione @@ -286,6 +287,7 @@ it: content_cache_retention_period: Periodo di ritenzione del contenuto remoto custom_css: Personalizza CSS favicon: Favicon + landing_page: Pagina di destinazione per i nuovi visitatori local_live_feed_access: Accesso ai feed dal vivo con post locali local_topic_feed_access: Accesso a feed di hashtag e link con post locali mascot: Personalizza mascotte (legacy) diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index db43b701bc5..3dc39069974 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -73,7 +73,6 @@ ja: featured_tag: name: 最近使用したハッシュタグ filters: - action: 投稿がフィルタに一致したときに実行するアクションを選択 actions: blur: メディアは警告して非表示にするが、テキストは表示する hide: フィルタに一致した投稿を完全に非表示にします @@ -82,7 +81,6 @@ ja: activity_api_enabled: 週単位でローカルで公開された投稿数、アクティブユーザー数、新規登録者数を表示します app_icon: モバイル端末で表示されるデフォルトのアプリアイコンを独自のアイコンで上書きします。WEBP、PNG、GIF、JPGが利用可能です。 backups_retention_period: ユーザーには、後でダウンロードするために投稿のアーカイブを生成する機能があります。正の値に設定すると、これらのアーカイブは指定された日数後に自動的にストレージから削除されます。 - bootstrap_timeline_accounts: これらのアカウントは、新しいユーザー向けのおすすめユーザーの一番上にピン留めされます。 closed_registrations_message: アカウント作成を停止している時に表示されます content_cache_retention_period: 他のサーバーからのすべての投稿(ブーストや返信を含む)は、指定された日数が経過すると、ローカルユーザーとのやりとりに関係なく削除されます。これには、ローカルユーザーがブックマークやお気に入りとして登録した投稿も含まれます。異なるサーバーのユーザー間の非公開な返信も失われ、復元することは不可能です。この設定の使用は特別な目的のインスタンスのためのものであり、一般的な目的のサーバーで使用した場合、多くのユーザーの期待を裏切ることになります。 custom_css: ウェブ版のMastodonでカスタムスタイルを適用できます。 @@ -236,6 +234,7 @@ ja: setting_emoji_style: 絵文字スタイル setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する setting_hide_network: 繋がりを隠す + setting_quick_boosting: クイックブーストの有効化 setting_reduce_motion: アニメーションの動きを減らす setting_system_font_ui: システムのデフォルトフォントを使う setting_system_scrollbars_ui: システムのデフォルトのスクロールバーを使う diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml index 4e06281ece2..6f3acf712b7 100644 --- a/config/locales/simple_form.kab.yml +++ b/config/locales/simple_form.kab.yml @@ -29,6 +29,7 @@ kab: name: 'Ha-t-an kra seg ihacṭagen i tesseqdaceḍ ussan-a ineggura maḍi :' form_admin_settings: min_age: Ad ttwasutren yiseqdacen ad sentemen azemz-nsen n tlalit deg ujerred + site_contact_username: Amek i zemren ad ak·em-id-afen medden ɣef Mastodon. form_challenge: current_password: Tkecmeḍ ɣer temnaḍt taɣellsant imports: @@ -152,6 +153,7 @@ kab: tag: name: Ahacṭag terms_of_service: + changelog: Amaynut? text: Tiwtilin n useqdec terms_of_service_generator: domain: Taɣult diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml index a1a9d895401..be7a506333e 100644 --- a/config/locales/simple_form.ko.yml +++ b/config/locales/simple_form.ko.yml @@ -56,11 +56,15 @@ ko: scopes: 애플리케이션에 허용할 API들입니다. 최상위 스코프를 선택하면 개별적인 것은 선택하지 않아도 됩니다. setting_aggregate_reblogs: 최근에 부스트 됐던 게시물은 새로 부스트 되어도 보여주지 않기 (새로 받은 부스트에만 적용됩니다) setting_always_send_emails: 기본적으로 마스토돈을 활동적으로 사용하고 있을 때에는 이메일 알림이 보내지지 않습니다 + setting_boost_modal: 활성화하면 부스트하기 전에 부스트의 공개설정을 바꿀 수 있는 확인창이 먼저 뜨게 됩니다. + setting_default_quote_policy_private: 마스토돈에서 작성된 팔로워 전용 게시물은 다른 사용자가 인용할 수 없습니다. + setting_default_quote_policy_unlisted: 사람들에게 인용된 경우, 인용한 게시물도 유행 타임라인에서 감추게 됩니다. setting_default_sensitive: 민감한 미디어는 기본적으로 가려져 있으며 클릭해서 볼 수 있습니다 setting_display_media_default: 민감함으로 표시된 미디어 가리기 setting_display_media_hide_all: 모든 미디어를 가리기 setting_display_media_show_all: 모든 미디어를 보이기 setting_emoji_style: 에모지 표현 방식. "자동"은 시스템 기본 에모지를 적용하고 그렇지 못하는 오래된 브라우저의 경우 트웨모지를 사용합니다. + setting_quick_boosting_html: 활성화하면 %{boost_icon}부스트 아이콘을 클릭했을 때 부스트/인용 드롭다운 메뉴가 뜨지 않고 바로 부스트하게 됩니다. 인용은 %{options_icon} (옵션) 메뉴 안으로 이동합니다. setting_system_scrollbars_ui: 사파리와 크롬 기반의 데스크탑 브라우저만 적용됩니다 setting_use_blurhash: 그라디언트는 숨겨진 내용의 색상을 기반으로 하지만 상세 내용은 보이지 않게 합니다 setting_use_pending_items: 타임라인의 새 게시물을 자동으로 보여 주는 대신, 클릭해서 나타내도록 합니다 @@ -74,7 +78,6 @@ ko: featured_tag: name: '이것들은 최근에 많이 쓰인 해시태그들입니다:' filters: - action: 게시물이 필터에 걸러질 때 어떤 동작을 수행할 지 고르세요 actions: blur: 텍스트는 숨기지 않고 그대로 둔 채 경고 뒤에 미디어를 숨김니다 hide: 필터에 걸러진 글을 처음부터 없었던 것처럼 완전히 가리기 @@ -83,9 +86,8 @@ ko: activity_api_enabled: 주별 로컬에 게시된 글, 활성 사용자 및 새로운 가입자 수 app_icon: WEBP, PNG, GIF 또는 JPG. 모바일 기기에 쓰이는 기본 아이콘을 대체합니다. backups_retention_period: 사용자들은 나중에 다운로드하기 위해 게시물 아카이브를 생성할 수 있습니다. 양수로 설정된 경우 이 아카이브들은 지정된 일수가 지난 후에 저장소에서 자동으로 삭제될 것입니다. - bootstrap_timeline_accounts: 이 계정들은 팔로우 추천 목록 상단에 고정됩니다. closed_registrations_message: 새 가입을 차단했을 때 표시됩니다 - content_cache_retention_period: 다른 서버의 모든 게시물(부스트 및 답글 포함)은 해당 게시물에 대한 로컬 사용자의 상호 작용과 관계없이 지정된 일수가 지나면 삭제됩니다. 여기에는 로컬 사용자가 북마크 또는 즐겨찾기로 표시한 게시물도 포함됩니다. 다른 인스턴스 사용자와 주고 받은 비공개 멘션도 손실되며 복원할 수 없습니다. 이 설정은 특수 목적의 인스턴스를 위한 것이며 일반적인 용도의 많은 사용자의 예상이 빗나가게 됩니다. + content_cache_retention_period: "(부스트 및 답글 포함) 다른 서버의 모든 게시물은 해당 게시물에 대한 로컬 사용자의 상호 작용과 관계없이 지정된 일수가 지나면 삭제됩니다. 여기에는 로컬 사용자가 북마크 또는 즐겨찾기로 표시한 게시물도 포함됩니다. 다른 인스턴스 사용자와 주고 받은 개인 멘션도 손실되며 복원할 수 없습니다. 이 설정은 특수 목적의 인스턴스를 위한 것이며 일반적인 용도의 많은 사용자의 예상이 빗나가게 됩니다." custom_css: 사용자 지정 스타일을 웹 버전의 마스토돈에 지정할 수 있습니다. favicon: WEBP, PNG, GIF 또는 JPG. 기본 파비콘을 대체합니다. mascot: 고급 웹 인터페이스의 그림을 대체합니다. @@ -229,10 +231,12 @@ ko: setting_aggregate_reblogs: 타임라인의 부스트를 그룹화 setting_always_send_emails: 항상 이메일 알림 보내기 setting_auto_play_gif: 애니메이션 GIF를 자동 재생 + setting_boost_modal: 부스트 공개범위 제어 setting_default_language: 게시물 언어 setting_default_privacy: 게시물 공개 범위 setting_default_quote_policy: 인용할 수 있는 사람 setting_default_sensitive: 미디어를 언제나 민감한 콘텐츠로 설정 + setting_delete_modal: 게시물을 삭제하기 전 경고하기 setting_disable_hover_cards: 호버시 프로필 미리보기를 비활성화 setting_disable_swiping: 스와이프 모션 비활성화 setting_display_media: 미디어 표시 @@ -242,6 +246,8 @@ ko: setting_emoji_style: 에모지 스타일 setting_expand_spoilers: 내용 경고로 표시된 게시물을 항상 펼치기 setting_hide_network: 내 인맥 숨기기 + setting_missing_alt_text_modal: 대체텍스트가 없는 미디어를 포함하여 게시하기 전 경고 + setting_quick_boosting: 빠른 부스트 활성화 setting_reduce_motion: 애니메이션 줄이기 setting_system_font_ui: 시스템의 기본 글꼴을 사용 setting_system_scrollbars_ui: 시스템 기본 스크롤바 사용 @@ -275,12 +281,17 @@ ko: content_cache_retention_period: 리모트 콘텐츠 보유 기간 custom_css: 사용자 정의 CSS favicon: 파비콘 + landing_page: 새 방문자를 위한 랜딩 페이지 + local_live_feed_access: 로컬 게시물에 대한 실시간 피드 접근 + local_topic_feed_access: 로컬 게시물에 대한 해시태그와 링크 피드 접근 mascot: 사용자 정의 마스코트 (legacy) media_cache_retention_period: 미디어 캐시 유지 기한 min_age: 최소 연령 제한 peers_api_enabled: API에 발견 된 서버들의 목록 발행 profile_directory: 프로필 책자 활성화 registrations_mode: 누가 가입할 수 있는지 + remote_live_feed_access: 리모트 게시물에 대한 실시간 피드 접근 + remote_topic_feed_access: 리모트 게시물에 대한 해시태그와 링크 피드 접근 require_invite_text: 가입 하는 이유를 필수로 입력하게 하기 show_domain_blocks: 도메인 차단 보여주기 show_domain_blocks_rationale: 왜 도메인이 차단되었는지 보여주기 diff --git a/config/locales/simple_form.ku.yml b/config/locales/simple_form.ku.yml index dda4baf7ac5..52e9d6b234c 100644 --- a/config/locales/simple_form.ku.yml +++ b/config/locales/simple_form.ku.yml @@ -60,12 +60,10 @@ ku: featured_tag: name: 'Li virê çend haştag hene ku te demên dawî bi kar anîne:' filters: - action: Hilbijêre ku dema şandiyek bi parzûnê re lihevhatî be bila kîjan çalakî were pêkanîn actions: hide: Naveroka parzûnkirî bi tevahî veşêre, mîna ku ew tune be tevbigere warn: Naveroka parzûnkirî li pişt hişyariyek ku sernavê parzûnê qal dike veşêre form_admin_settings: - bootstrap_timeline_accounts: Ev ajimêr wê di pêşnîyarên şopandina bikarhênerên nû de werin derzîkirin. closed_registrations_message: Dema ku tomarkirin girtî bin têne xuyakirin custom_css: Tu dikarî awayên kesane li ser guhertoya malperê ya Mastodon bicîh bikî. mascot: Îlustrasyona navrûyê webê yê pêşketî bêbandor dike. diff --git a/config/locales/simple_form.lad.yml b/config/locales/simple_form.lad.yml index a04bf89f953..604f5173b88 100644 --- a/config/locales/simple_form.lad.yml +++ b/config/locales/simple_form.lad.yml @@ -71,13 +71,11 @@ lad: featured_tag: name: 'Aki estan algunas de las etiketas ke mas tienes utilizado resientemente:' filters: - action: Eskoje kuala aksyon realizar kuando una publikasyon koensida kon el filtro actions: hide: Eskonde kompletamente el kontenido filtrado komo si no existiera warn: Eskonde el kontenido filtrado detras de una avertensya enmentando el titolo del filtro form_admin_settings: activity_api_enabled: Numero de publikasyones publikadas lokalmente, utilizadores activos i enrejistrasyones muevas kada semana - bootstrap_timeline_accounts: Estos kuentos apareseran en la parte superior de las rekomendasiones de los muevos utilizadores. closed_registrations_message: Amostrado kuando las enrejistrasyones estan serrados custom_css: Puedes aplikar estilos personalizados a la version web de Mastodon. mascot: Reemplaza la ilustrasyon en la enterfaz web avanzada. @@ -244,6 +242,7 @@ lad: favicon: Ikona de favoritos mascot: Maskota personalizada (legado) media_cache_retention_period: Periodo de retensyon de kashe multimedia + min_age: Edad minima rekerida peers_api_enabled: Publika lista de sirvidores diskuviertos en la API profile_directory: Kapasita katalogo de profiles registrations_mode: Ken puede enrejistrarse diff --git a/config/locales/simple_form.lt.yml b/config/locales/simple_form.lt.yml index bd510a3ebd4..f5f7b582c28 100644 --- a/config/locales/simple_form.lt.yml +++ b/config/locales/simple_form.lt.yml @@ -71,7 +71,6 @@ lt: featured_tag: name: 'Štai keletas pastaruoju metu dažniausiai saitažodžių, kurių tu naudojai:' filters: - action: Pasirink, kokį veiksmą atlikti, kai įrašas atitinka filtrą actions: blur: Slėpti mediją po įspėjimu, neslepiant paties teksto hide: Visiškai paslėpti filtruotą turinį ir elgtis taip, tarsi jo neegzistuotų diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml index d43d89e0340..41d879a3743 100644 --- a/config/locales/simple_form.lv.yml +++ b/config/locales/simple_form.lv.yml @@ -73,7 +73,6 @@ lv: featured_tag: name: 'Šeit ir daži no pēdējiem lietotajiem tēmturiem:' filters: - action: Izvēlies, kuru darbību veikt, ja ziņa atbilst filtram actions: blur: Paslēpt informācijas nesējus aiz brīdinājuma, nepaslēpjot tekstu hide: Paslēp filtrēto saturu pilnībā, izturoties tā, it kā tas neeksistētu @@ -82,7 +81,6 @@ lv: activity_api_enabled: Vietēji publicēto ziņu, aktīvo lietotāju un jauno reģistrāciju skaits nedēļas kopās app_icon: WEBP, PNG, GIF vai JPG. Mobilajās ierīcēs aizstāj noklusējuma lietotnes ikonu ar pielāgotu. backups_retention_period: Lietotājiem ir iespēja izveidot savu ierakstu arhīvu lejupielādēšanai vēlāk. Kad iestatīta pozitīva vērtība, šie arhīvi tiks automātiski izdzēsti no krātuves pēc norādītā dienu skaita. - bootstrap_timeline_accounts: Šie konti tiks piesprausti jauno lietotāju sekošanas ieteikumu augšdaļā. closed_registrations_message: Tiek rādīts, kad reģistrēšanās ir slēgta content_cache_retention_period: Visi ieraksti no citiem serveriem (tajā skaitā pastiprinājumi un atbildes) tiks izdzēsti pēc norādītā dienu skaita, neņemot vērā vietēja lietotāja mijiedarbību ar šādiem ierakstiem. Tas ietver ierakstus, kurus vietējs lietotājs ir atzīmējis kā grāmatzīmi vai pievienojis izlasē. Tiks zaudēti arī privāti pieminējumi starp lietotājiem no dažādiem serveriem, un tos nebūs iespējams atgūt. Šī iestatījuma izmantošana ir paredzēta īpašam nolūkam paredzētiem serveriem un neatbilst tam, ko sagaida vairums lietotāju, kad pielietots vispārējas izmantošanas serveros. custom_css: Vari lietot pielāgotus stilus Mastodon tīmekļa versijā. diff --git a/config/locales/simple_form.ms.yml b/config/locales/simple_form.ms.yml index e4ed284c362..c35989fb815 100644 --- a/config/locales/simple_form.ms.yml +++ b/config/locales/simple_form.ms.yml @@ -68,13 +68,11 @@ ms: featured_tag: name: 'Berikut ialah beberapa hashtag yang paling anda gunakan baru-baru ini:' filters: - action: Pilih tindakan yang hendak dilakukan apabila siaran sepadan dengan penapis actions: hide: Sembunyikan sepenuhnya kandungan yang ditapis, berkelakuan seolah-olah ia tidak wujud warn: Sembunyikan kandungan yang ditapis di sebalik amaran yang menyebut tajuk penapis form_admin_settings: activity_api_enabled: Kiraan siaran tempatan yang diterbitkan, pengguna aktif dan pendaftaran baharu dalam baldi mingguan - bootstrap_timeline_accounts: Akaun ini akan disematkan pada bahagian atas cadangan ikutan pengguna baharu. closed_registrations_message: Dipaparkan semasa pendaftaran ditutup custom_css: Anda boleh menggunakan gaya tersuai pada versi web Mastodon. favicon: WEBP, PNG, GIF, atau JPG. Arca tersuai diutamakan dari arca kegemaran Mastodon lalai. diff --git a/config/locales/simple_form.my.yml b/config/locales/simple_form.my.yml index 6f45a51eba0..0dd04a92183 100644 --- a/config/locales/simple_form.my.yml +++ b/config/locales/simple_form.my.yml @@ -68,13 +68,11 @@ my: featured_tag: name: ဤသည်မှာ သင်မကြာသေးမီက အသုံးပြုခဲ့သော hashtag အချို့ဖြစ်သည် - filters: - action: ပို့စ်တစ်ခုသည် စစ်ထုတ်မှုနှင့် ကိုက်ညီချိန်တွင် မည်သည့်လုပ်ဆောင်ချက် ဆောင်ရွက်မည်ကို ရွေးချယ်ပါ actions: hide: စစ်ထုတ်ထားသော အကြောင်းအရာကို လုံးဝဖျောက်ထားပြီး မရှိသကဲ့သို့ ပြပါ warn: စစ်ထုတ်မှုခေါင်းစဉ်ကိုဖော်ပြသည့်သတိပေးချက်နောက်တွင် စစ်ထုတ်ထားသောအကြောင်းအရာကို ဖျောက်ထားပါ form_admin_settings: activity_api_enabled: အပတ်စဉ် စာရင်းများတွင် ဒေသတွင်းတင်ထားသောပို့စ်များ၊ လက်ရှိအသုံးပြုသူများနှင့် စာရင်းသွင်းမှုအသစ်များ - bootstrap_timeline_accounts: ဤအကောင့်များကို အသုံးပြုသူအသစ်များ၏ စောင့်ကြည့်မှု အကြံပြုချက်များ၏ထိပ်ဆုံးတွင် ပင်ချိတ်ထားပါမည်။ closed_registrations_message: အကောင့်ဖွင့်ခြင်းများကို ပိတ်ထားသည့်အခါတွင် ပြသထားသည် custom_css: Mastodon ဝဘ်ဗားရှင်းတွင် စိတ်ကြိုက်စတိုင်များကို အသုံးပြုနိုင်ပါသည်။ mascot: အဆင့်မြင့် ဝဘ်ပုံစံတွင်တွင် ရုပ်ပုံဖြင့်ဖော်ပြထားသည်။ diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index 36522a66954..5f1cc115e95 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -79,7 +79,7 @@ nl: featured_tag: name: 'Hier zijn enkele van de hashtags die je onlangs hebt gebruikt:' filters: - action: Kies welke acties uitgevoerd moeten wanneer een bericht overeenkomt met het filter + action: Kies welke acties uitgevoerd moeten wanneer een bericht met het filter overeenkomt actions: blur: Media verbergen achter een waarschuwing, zonder de tekst zelf te verbergen hide: Verberg de gefilterde inhoud volledig, alsof het niet bestaat @@ -88,7 +88,7 @@ nl: activity_api_enabled: Aantallen lokaal gepubliceerde berichten, actieve gebruikers en nieuwe registraties per week app_icon: WEBP, PNG, GIF of JPG. Vervangt op mobiele apparaten het standaard app-pictogram met een aangepast pictogram. backups_retention_period: Gebruikers hebben de mogelijkheid om archieven van hun berichten te genereren om later te downloaden. Indien ingesteld op een positieve waarde, worden deze archieven automatisch verwijderd uit jouw opslag na het opgegeven aantal dagen. - bootstrap_timeline_accounts: Deze accounts worden bovenaan de aanbevelingen aan nieuwe gebruikers getoond. Meerdere gebruikersnamen met komma's scheiden. + bootstrap_timeline_accounts: Deze accounts worden bovenaan de lijst aanbevolen om te volgen van nieuwe gebruikers vastgezet. Geef een komma gescheiden lijst van accounts. closed_registrations_message: Weergegeven wanneer registratie van nieuwe accounts is uitgeschakeld content_cache_retention_period: Alle berichten van andere servers (inclusief boosts en reacties) worden verwijderd na het opgegeven aantal dagen, ongeacht enige lokale gebruikersinteractie met die berichten. Dit betreft ook berichten die een lokale gebruiker aan diens bladwijzers heeft toegevoegd of als favoriet heeft gemarkeerd. Privéberichten tussen gebruikers van verschillende servers gaan ook verloren en zijn onmogelijk te herstellen. Het gebruik van deze instelling is bedoeld voor servers die een speciaal doel dienen en overtreedt veel gebruikersverwachtingen wanneer deze voor algemeen gebruik wordt geïmplementeerd. custom_css: Je kunt aangepaste CSS toepassen op de webversie van deze Mastodon-server. diff --git a/config/locales/simple_form.nn.yml b/config/locales/simple_form.nn.yml index f6916c35475..6af7f43de3a 100644 --- a/config/locales/simple_form.nn.yml +++ b/config/locales/simple_form.nn.yml @@ -88,11 +88,11 @@ nn: activity_api_enabled: Tal på lokale innlegg, aktive brukarar og nyregistreringar kvar veke app_icon: WEBP, PNG, GIF eller JPG. Overstyrer standard-app-ikonet på mobile einingar med eit eigendefinert ikon. backups_retention_period: Brukarar har moglegheit til å generere arkiv av sine innlegg for å laste ned seinare. Når sett til ein positiv verdi, blir desse arkiva automatisk sletta frå lagringa etter eit gitt antal dagar. - bootstrap_timeline_accounts: Desse kontoane vil bli festa øverst på fylgjaranbefalingane til nye brukarar. closed_registrations_message: Vist når det er stengt for registrering content_cache_retention_period: Alle innlegg frå andre tenarar (inkludert framhevingar og svar) vil bli sletta etter talet på dagar du skriv inn, uansett om nokon har samhandla med desse innlegga. Dette inkluderer innlegg der ein lokal brukar har merka det som bokmerke eller som favoritt. Private omtalar mellom brukarar frå ulike nettstader vil gå tapt og vera umogleg å gjenskapa. Bruk av denne innstillinga er meint for spesielle nettstader og bryt med det mange forventar av ein vanleg nettstad. custom_css: Du kan bruka eigendefinerte stilar på nettversjonen av Mastodon. favicon: WEBP, PNG, GIF eller JPG. Overstyrer det standarde Mastodon-favikonet med eit eigendefinert ikon. + landing_page: Vel kva side nye lesarar ser når dei kjem til tenaren din. Viss du vel «Populært», må du ha skrudd på dette i innstillingane for oppdaging. Viss du vel «Lokalstraum», må du la alle få sjå lokale straumar i innstillingane for oppdaging. mascot: Overstyrer illustrasjonen i det avanserte webgrensesnittet. media_cache_retention_period: Mediafiler frå innlegg laga av eksterne brukarar blir bufra på serveren din. Når sett til ein positiv verdi, slettast media etter eit gitt antal dagar. Viss mediedata blir førespurt etter det er sletta, vil dei bli lasta ned på nytt viss kjelda sitt innhald framleis er tilgjengeleg. På grunn av restriksjonar på kor ofte lenkeførehandsvisningskort lastar tredjepart-nettstadar, rådast det til å setje denne verdien til minst 14 dagar, eller at førehandsvisningskort ikkje blir oppdatert på førespurnad før det tidspunktet. min_age: Brukarane vil bli bedne om å stadfesta fødselsdatoen sin når dei registrerer seg @@ -286,6 +286,7 @@ nn: content_cache_retention_period: Oppbevaringstid for eksternt innhald custom_css: Egendefinert CSS favicon: Favorittikon + landing_page: Startside for nye lesarar local_live_feed_access: Tilgang til direktestraumar med lokale innlegg local_topic_feed_access: Tilgang til merkelapp- og lenkestraumar med lokale innlegg mascot: Eigendefinert maskot (eldre funksjon) diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index b1afd7e8010..94d8cc2c552 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -70,13 +70,11 @@ featured_tag: name: 'Her er noen av emneknaggene du har brukt i det siste:' filters: - action: Velg hvilken handling som skal utføres når et innlegg samsvarer med filteret actions: hide: Skjul filtrert innhold fullstendig, som om det ikke eksisterte warn: Skjul det filtrerte innholdet bak et varsel som omtaler filterets tittel form_admin_settings: activity_api_enabled: Teller med lokale publiserte innlegg, aktive brukere og nye registreringer i ukentlige bøtter - bootstrap_timeline_accounts: Disse kontoene vil bli festet til toppen av nye brukeres følge-anbefalinger. closed_registrations_message: Vises når det er stengt for registrering custom_css: Du kan bruke egendefinerte stiler på nettversjonen av Mastodon. mascot: Overstyrer illustrasjonen i det avanserte webgrensesnittet. diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index 5cc3c85ce2d..a8518eecc20 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -79,7 +79,6 @@ pl: featured_tag: name: 'Oto niektóre hasztagi, których były ostatnio przez ciebie użyte:' filters: - action: Wybierz akcję do wykonania, gdy post pasuje do filtra actions: blur: Ukryj media za ostrzeżeniem, bez ukrywania samego tekstu hide: Całkowicie ukryj przefiltrowaną zawartość, jakby nie istniała @@ -88,7 +87,6 @@ pl: activity_api_enabled: Liczby opublikowanych lokalnych postów, aktywnych użytkowników i nowych rejestracji w tygodniowych przedziałach app_icon: WEBP, PNG, GIF, albo JPEG. Nadpisuje domyślną ikonę aplikacji na urządzeniach mobilnych. backups_retention_period: Użytkownicy mogą generować archiwa wpisów do późniejszego pobrania. Jeżeli ta wartość jest dodatnia, te archiwa zostaną automatycznie usunięte z twojego serwera po danej liczbie dni. - bootstrap_timeline_accounts: Te konta zostaną przypięte na górze rekomendacji obserwacji nowych użytkowników. closed_registrations_message: Wyświetlane po zamknięciu rejestracji content_cache_retention_period: Wszystkie wpisy z innych serwerów (w tym podbicia i odpowiedzi) zostaną usunięte po danej liczbie dni, bez względu na interakcje z nimi twoich użytkowników. Zawierają się w tym wpisy, które twoi użytkownicy dodali do zakładek lub ulubionych. Prywatne wzmianki od innych instancji zostaną utracone i będą nieprzywracalne. To ustawienie jest przeznaczone dla instancji zastosowania specjalnego i jest niezgodne z wieloma oczekiwaniami użytkowników. custom_css: Możesz zastosować niestandardowe style w internetowej wersji Mastodon. diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 605bcf8d98c..1d3bd5eb1d9 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -54,8 +54,10 @@ pt-BR: password: Use pelo menos 8 caracteres phrase: Corresponderá independente de maiúsculas ou minúsculas, no texto ou no Aviso de Conteúdo de um toot scopes: Quais APIs o aplicativo vai ter permissão de acessar. Se você selecionar uma autorização de alto nível, você não precisa selecionar individualmente os outros. + setting_advanced_layout: Exiba o Mastodon em um layout de várias colunas, permitindo que você visualize a linha do tempo, as notificações e uma terceira coluna de sua escolha. Não recomendado para telas menores. setting_aggregate_reblogs: Não mostrar novos impulsos para publicações que já foram impulsionadas recentemente (afeta somente os impulsos mais recentes) setting_always_send_emails: Normalmente, as notificações por e-mail não serão enviadas enquanto você estiver usando ativamente o Mastodon + setting_boost_modal: Quando ativada, a função de impulsionar primeiro abrirá uma caixa de diálogo de confirmação na qual você poderá alterar a visibilidade do seu impulsionamento. setting_default_quote_policy_private: Publicações exclusivas de seguidores criadas no Mastodon não podem ser citadas por outras pessoas. setting_default_quote_policy_unlisted: Quando as pessoas citarem você, suas publicações também ficarão ocultas da linha do tempo. setting_default_sensitive: Mídia sensível está oculta por padrão e pode ser revelada com um clique @@ -63,6 +65,7 @@ pt-BR: setting_display_media_hide_all: Sempre ocultar todas as mídias setting_display_media_show_all: Sempre mostrar mídia sensível setting_emoji_style: Como exibir emojis. "Automáticos" tentará usar emojis nativos, mas voltará para o Twemoji para navegadores legados. + setting_quick_boosting_html: Quando ativado, clicar no ícone de impulsionamento %{boost_icon} impulsionará imediatamente o texto, em vez de abrir o menu suspenso de impulsionamento/cotação. Move a ação de cotação para o menu %{options_icon} (Opções). setting_system_scrollbars_ui: Se aplica apenas para navegadores de computador baseado no Safari e Chrome setting_use_blurhash: O blur é baseado nas cores da imagem oculta, ofusca a maioria dos detalhes setting_use_pending_items: Ocultar atualizações da linha do tempo atrás de um clique ao invés de rolar automaticamente @@ -76,7 +79,6 @@ pt-BR: featured_tag: name: 'Aqui estão algumas hashtags usadas recentemente:' filters: - action: Escolher qual ação executar quando uma publicação corresponder ao filtro actions: blur: Oculte a mídia com um aviso, porém mantenha o texto visível hide: Esconder completamente o conteúdo filtrado, comportando-se como se ele não existisse @@ -85,11 +87,11 @@ pt-BR: activity_api_enabled: Contagem de publicações locais, usuários ativos e novos usuários semanais app_icon: WEBP, PNG, GIF ou JPG. Sobrescrever o ícone padrão do aplicativo em dispositivos móveis com um ícone personalizado. backups_retention_period: Os usuários podem gerar arquivos de suas postagens para baixar mais tarde. Quando definido como um valor positivo, esses arquivos serão automaticamente excluídos do seu armazenamento após o número especificado de dias. - bootstrap_timeline_accounts: Estas contas serão fixadas no topo das recomendações de novos usuários para seguir. closed_registrations_message: Exibido quando as inscrições estiverem fechadas content_cache_retention_period: Todas as postagens de outros servidores (incluindo boosts e respostas) serão excluídas após o número especificado de dias, sem levar a qualquer interação do usuário local com esses posts. Isto inclui postagens onde um usuário local o marcou como favorito ou favoritos. Menções privadas entre usuários de diferentes instâncias também serão perdidas e impossíveis de restaurar. O uso desta configuração destina-se a instâncias especiais de propósitos e quebra muitas expectativas dos usuários quando implementadas para uso de propósito geral. custom_css: Você pode aplicar estilos personalizados na versão da web do Mastodon. favicon: WEBP, PNG, GIF ou JPG. Sobrescreve o favicon padrão do Mastodon com um ícone personalizado. + landing_page: Seleciona a página que os novos visitantes veem ao acessar seu servidor pela primeira vez. Se você selecionar "Tendências", as tendências precisam estar ativadas nas Configurações de Descoberta. Se você selecionar "Feed local", o "Acesso a feeds ao vivo com publicações locais" precisa estar definido como "Todos" nas Configurações de Descoberta. mascot: Substitui a ilustração na interface web avançada. media_cache_retention_period: Arquivos de mídia de mensagens de usuários remotos são armazenados em cache no seu servidor. Quando definido como valor positivo, a mídia será excluída após o número especificado de dias. Se os dados da mídia forem solicitados depois de excluídos, eles serão baixados novamente, se o conteúdo fonte ainda estiver disponível. Devido a restrições de quantas vezes os cartões de visualização de links sondam sites de terceiros, é recomendado definir este valor em pelo menos 14 dias, ou pré-visualização de links não serão atualizados a pedido antes desse tempo. min_age: Os usuários precisarão confirmar sua data de nascimento no cadastro @@ -233,6 +235,7 @@ pt-BR: setting_aggregate_reblogs: Agrupar boosts nas linhas setting_always_send_emails: Sempre enviar notificações por e-mail setting_auto_play_gif: Reproduzir GIFs automaticamente + setting_boost_modal: Controle que aumenta a visibilidade setting_default_language: Idioma dos toots setting_default_privacy: Visibilidade da publicação setting_default_quote_policy: Quem pode citar @@ -248,6 +251,7 @@ pt-BR: setting_expand_spoilers: Sempre expandir toots com Aviso de Conteúdo setting_hide_network: Ocultar suas relações setting_missing_alt_text_modal: Avise-me antes de publicar mídia sem texto alternado + setting_quick_boosting: Ativar aceleração rápida setting_reduce_motion: Reduzir animações setting_system_font_ui: Usar fonte padrão do sistema setting_system_scrollbars_ui: Usar barra de rolagem padrão do sistema diff --git a/config/locales/simple_form.pt-PT.yml b/config/locales/simple_form.pt-PT.yml index e8aa2692eca..a11d63bfa15 100644 --- a/config/locales/simple_form.pt-PT.yml +++ b/config/locales/simple_form.pt-PT.yml @@ -79,7 +79,7 @@ pt-PT: featured_tag: name: 'Eis algumas das etiquetas que utilizou recentemente:' filters: - action: Escolha qual a ação a executar quando uma publicação corresponde ao filtro + action: Escolha que ação executar quando uma publicação corresponder ao filtro actions: blur: Esconder multimédia com um aviso à frente, sem esconder o texto hide: Ocultar completamente o conteúdo filtrado, comportando-se como se não existisse @@ -88,7 +88,7 @@ pt-PT: activity_api_enabled: Contagem, em blocos semanais, de publicações locais, utilizadores ativos e novos registos app_icon: WEBP, PNG, GIF ou JPG. Substitui o ícone padrão da aplicação em dispositivos móveis por um ícone personalizado. backups_retention_period: Os utilizadores têm a possibilidade de gerar arquivos das suas publicações para descarregar mais tarde. Quando definido para um valor positivo, estes arquivos serão automaticamente eliminados do seu armazenamento após o número de dias especificado. - bootstrap_timeline_accounts: Estas contas serão destacadas no topo das recomendações aos novos utilizadores. + bootstrap_timeline_accounts: Essas contas serão colocadas no topo das recomendações de seguidores para os novos utilizadores. Forneça uma lista de contas separadas por vírgulas. closed_registrations_message: Apresentado quando as inscrições estiverem encerradas content_cache_retention_period: Todas as publicações de outros servidores (incluindo partilhas e respostas) serão eliminadas após o número de dias especificado, independentemente de qualquer interação do utilizador local com essas publicações. Isto inclui mensagens em que um utilizador local as tenha salvo ou adicionado aos favoritos. As menções privadas entre utilizadores de instâncias diferentes também se perderão e serão impossíveis de recuperar. A utilização desta definição destina-se a instâncias para fins especiais e quebra muitas expectativas dos utilizadores quando implementada para utilização geral. custom_css: Pode aplicar estilos personalizados na versão web do Mastodon. diff --git a/config/locales/simple_form.ro.yml b/config/locales/simple_form.ro.yml index fe86121f242..020285edc9b 100644 --- a/config/locales/simple_form.ro.yml +++ b/config/locales/simple_form.ro.yml @@ -71,7 +71,6 @@ ro: featured_tag: name: 'Iată câteva dintre hashtag-urile pe care le-ai folosit cel mai recent:' filters: - action: Alege ce acţiune va fi efectuată atunci când o postare corespunde filtrului actions: hide: Ascunde complet conținutul filtrat, ca și cum nu ar exista warn: Ascunde conținutul filtrat în spatele unui avertisment care menționează titlul filtrului @@ -79,7 +78,6 @@ ro: activity_api_enabled: Numărul de postări publicate local, utilizatori activi și înregistrări noi în grupe săptămânale app_icon: WEBP, PNG, GIF sau JPG. Înlocuiește pictograma implicită a aplicației pe dispozitivele mobile cu o pictogramă personalizată. backups_retention_period: Utilizatorii au posibilitatea de a genera arhive ale postărilor lor pentru a le descărca mai târziu. Când este setat la o valoare pozitivă, aceste arhive vor fi șterse automat din spațiul dvs. de stocare după numărul de zile specificat. - bootstrap_timeline_accounts: Aceste conturi vor fi fixate în partea de sus a recomandărilor de urmărire ale noilor utilizatori. closed_registrations_message: Afișat când înscrierile sunt închise content_cache_retention_period: Toate postările de pe alte servere (inclusiv amplificarea și răspunsurile) vor fi șterse după numărul specificat de zile, fără a ține cont de interacțiunea utilizatorului local cu acele postări. Aceasta include postările în care un utilizator local le-a marcat ca marcaje sau favorite. Mențiunile private între utilizatorii din diferite instanțe se vor pierde și vor fi imposibil de restaurat. Utilizarea acestei setări este destinată cazurilor cu scop special și încalcă multe așteptări ale utilizatorilor atunci când este implementată pentru uz general. custom_css: Puteți aplica stiluri personalizate pe versiunea web a Mastodon. diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml index 5798dd25bcf..2f1f8e03e4b 100644 --- a/config/locales/simple_form.ru.yml +++ b/config/locales/simple_form.ru.yml @@ -73,7 +73,6 @@ ru: featured_tag: name: 'Вот некоторые хештеги, которые вы использовали чаще других в последнее время:' filters: - action: Выберите действие, которое нужно применить к постам, соответствующим фильтру actions: blur: Скрыть медиа за предупреждением, не скрывая сам текст поста hide: Полностью скрыть отфильтрованный пост, будто бы его не существует @@ -82,7 +81,6 @@ ru: activity_api_enabled: Подсчёт количества локальных постов, активных пользователей и новых регистраций на еженедельной основе app_icon: WEBP, PNG, GIF или JPG. Замените значок приложения по умолчанию на мобильных устройствах пользовательским значком. backups_retention_period: Пользователи могут создавать архивы своих постов, чтобы потом их забрать. Если задать положительное значение, эти архивы автоматически удалятся с вашего хранилища через указанное число дней. - bootstrap_timeline_accounts: Эти аккаунты будут рекомендованы для подписки новым пользователям. closed_registrations_message: Отображается, когда регистрация закрыта content_cache_retention_period: Все сообщения с других серверов (включая бусты и ответы) будут удалены через указанное количество дней, независимо от того, как локальный пользователь взаимодействовал с этими сообщениями. Это касается и тех сообщений, которые локальный пользователь пометил в закладки или избранное. Приватные упоминания между пользователями из разных инстансов также будут потеряны и не смогут быть восстановлены. Использование этой настройки предназначено для экземпляров специального назначения и нарушает многие ожидания пользователей при использовании в общих целях. custom_css: Вы можете применять пользовательские стили в веб-версии Mastodon. diff --git a/config/locales/simple_form.sco.yml b/config/locales/simple_form.sco.yml index f95812a7ad0..6b800525c7f 100644 --- a/config/locales/simple_form.sco.yml +++ b/config/locales/simple_form.sco.yml @@ -58,12 +58,10 @@ sco: featured_tag: name: 'Here some o the hashtags ye uised the maist o late:' filters: - action: Pick whit action tae dae whan a post matches the filter actions: hide: Totally plank the filtert content, ackin as if it didnae exist warn: Plank the filtert content ahin a warnin menshiein the filter's title form_admin_settings: - bootstrap_timeline_accounts: Thir accoonts wull get preenit tae the tap o new uisers' follae recommendations. closed_registrations_message: Displayit whan sign-ups is shut custom_css: Ye kin pit custom styles on tae the web version o Mastodon. mascot: Owerrides the illustration in the advanced web interface. diff --git a/config/locales/simple_form.si.yml b/config/locales/simple_form.si.yml index 28d434225ea..c012ded9900 100644 --- a/config/locales/simple_form.si.yml +++ b/config/locales/simple_form.si.yml @@ -73,7 +73,6 @@ si: featured_tag: name: 'ඔබ මෑතකදී භාවිතා කළ හැෂ් ටැග් කිහිපයක් මෙන්න:' filters: - action: ලිපියක් පෙරහනට ගැළපෙන විට ඉටු විය යුතු ක්‍රියාමාර්ගය තෝරන්න actions: blur: පෙළම සඟවා නොගෙන, අනතුරු ඇඟවීමක් පිටුපස මාධ්‍ය සඟවන්න. hide: පෙරහන් කළ අන්තර්ගතය සම්පූර්ණයෙන්ම සඟවන්න, එය නොපවතින ලෙස හැසිරෙන්න @@ -82,7 +81,6 @@ si: activity_api_enabled: සතිපතා බාල්දිවල දේශීයව ප්‍රකාශයට පත් කරන ලද සටහන්, ක්‍රියාකාරී පරිශීලකයින් සහ නව ලියාපදිංචි කිරීම් ගණන app_icon: WEBP, PNG, GIF හෝ JPG. අභිරුචි නිරූපකයක් සමඟ ජංගම උපාංගවල පෙරනිමි යෙදුම් නිරූපකය අභිබවා යයි. backups_retention_period: පරිශීලකයින්ට පසුව බාගත කිරීම සඳහා ඔවුන්ගේ සටහන් වල ලේඛනාගාර ජනනය කිරීමේ හැකියාව ඇත. ධනාත්මක අගයකට සකසා ඇති විට, නිශ්චිත දින ගණනකට පසු මෙම ලේඛනාගාර ඔබගේ ගබඩාවෙන් ස්වයංක්‍රීයව මකා දැමෙනු ඇත. - bootstrap_timeline_accounts: මෙම ගිණුම් නව පරිශීලකයින්ගේ අනුගමනය කිරීමේ නිර්දේශවල ඉහළට අමුණා ඇත. closed_registrations_message: ලියාපදිංචි කිරීම් වසා දැමූ විට පෙන්වනු ලැබේ content_cache_retention_period: අනෙකුත් සේවාදායකයන්ගෙන් ලැබෙන සියලුම පළ කිරීම් (බූස්ට් සහ පිළිතුරු ඇතුළුව) නිශ්චිත දින ගණනකට පසු මකා දැමෙනු ඇත, එම පළ කිරීම් සමඟ කිසිදු දේශීය පරිශීලක අන්තර්ක්‍රියාවක් නොසලකා. මෙයට දේශීය පරිශීලකයෙකු එය පිටු සලකුණු හෝ ප්‍රියතමයන් ලෙස සලකුණු කර ඇති පළ කිරීම් ඇතුළත් වේ. විවිධ අවස්ථා වලින් පරිශීලකයින් අතර පුද්ගලික සඳහන් කිරීම් ද නැති වී යන අතර ප්‍රතිසාධනය කිරීමට නොහැකි වනු ඇත. මෙම සැකසුම භාවිතා කිරීම විශේෂ අරමුණු අවස්ථා සඳහා අදහස් කරන අතර පොදු අරමුණු භාවිතය සඳහා ක්‍රියාත්මක කළ විට බොහෝ පරිශීලක අපේක්ෂාවන් බිඳ දමයි. custom_css: ඔබට Mastodon හි වෙබ් අනුවාදයේ අභිරුචි මෝස්තර යෙදිය හැකිය. diff --git a/config/locales/simple_form.sl.yml b/config/locales/simple_form.sl.yml index 97196e9a00a..55cd67b6f04 100644 --- a/config/locales/simple_form.sl.yml +++ b/config/locales/simple_form.sl.yml @@ -73,7 +73,6 @@ sl: featured_tag: name: 'Tukaj je nekaj ključnikov, ki ste jih nedavno uporabili:' filters: - action: Izberite, kako naj se program vede, ko se objava sklada s filtrom actions: hide: Povsem skrij filtrirano vsebino, kot da ne bi obstajala warn: Skrij filtrirano vsebino za opozorilom, ki pomenja naslov filtra @@ -81,7 +80,6 @@ sl: activity_api_enabled: Številke krajevno objavljenih objav, dejavnih uporabnikov in novih registracij na tedenskih seznamih app_icon: WEBP, PNG, GIF ali JPG. Zamenja privzeto ikono programa na mobilnih napravah z ikono po meri. backups_retention_period: Uporabniki lahko ustvarijo arhive svojih objav za kasnejši prenos k sebi. Ko je nastavljeno na pozitivno vrednost, bodo ti arhivi po nastavljenem številu dni samodejno izbrisani. - bootstrap_timeline_accounts: Ti računi bodo pripeti na vrh priporočenih sledenj za nove uporabnike. closed_registrations_message: Prikazano, ko so registracije zaprte content_cache_retention_period: Vse objave z drugih strežnikov (vključno z izpostavitvami in odgovori) bodo izbrisani po nastavljenem številu dni, ne glede na krajevne interakcije s temi objavami. To vključuje objave, ki jih je krajevni uporabnik dodal med zaznamke ali priljubljene. Zasebne omembe med uporabniki na različnih strežnikih bodo prav tako izgubljene in jih ne bo moč obnoviti. Uporaba te nastavitve je namenjena strežnikom s posebnim namenom in nasprotuje mnogim pričakovanjem uporabnikov na strežnikih za splošni namen. custom_css: Spletni različici Mastodona lahko uveljavite sloge po meri. diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index 9df506083b9..2d155cf2a23 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -78,7 +78,7 @@ sq: featured_tag: name: 'Ja disa nga hashtag-ët që përdorët tani afër:' filters: - action: Zgjidhni cili veprim të kryhet, kur një postim ka përputhje me një filtër + action: Zgjidhni cili veprim të kryhet, kur një postim ka përkim me një filtër actions: blur: Fshihe median pas një sinjalizimi, pa fshehur vetë tekstin hide: Fshihe plotësisht lëndën e filtruar, duke u sjellë sikur të mos ekzistonte @@ -87,7 +87,7 @@ sq: activity_api_enabled: Numër postimesh të botuar lokalisht, përdoruesish aktiv dhe regjistrimesh të reja sipas matjesh javore app_icon: WEBP, PNG, GIF, ose JPG. Anashkalon ikonë parazgjedhje aplikacioni në pajisje celulare me një ikonë vetjake. backups_retention_period: Përdorues kanë aftësinë të prodhojnë arkiva të postimeve të tyre për t’i shkarkuar më vonë. Kur i jepet një vlerë pozitive, këto arkiva do të fshihen automatikisht prej depozitës tuaj pas numrit të dhënë të ditëve. - bootstrap_timeline_accounts: Këto llogari do të fiksohen në krye të rekomandimeve për ndjekje nga përdorues të rinj. + bootstrap_timeline_accounts: Këto llogari do të fiksohen në krye të rekomandimeve për ndjekje për përdoruesin e ri. Jepni një listë llogarish ndarë me presje. closed_registrations_message: Shfaqur kur mbyllen dritare regjistrimesh content_cache_retention_period: Krejt postimet prej shërbyesve të tjerë (përfshi përforcime dhe përgjigje) do të fshihen pas numrit të caktuar të ditëve, pa marrë parasysh çfarëdo ndërveprimi përdoruesi me këto postime. Kjo përfshin postime kur një përdorues vendor u ka vënë shenjë si faqerojtës, ose të parapëlqyer. Do të humbin gjithashtu dhe përmendje private mes përdoruesish nga instanca të ndryshme dhe s’do të jetë e mundshme të rikthehen. Përdorimi i këtij rregullimi është menduar për instanca me qëllim të caktuar dhe ndërhyn në çka presin mjaft përdorues, kur sendërtohet për përdorim të përgjithshëm. custom_css: Stile vetjakë mund të aplikoni në versionin web të Mastodon-it. diff --git a/config/locales/simple_form.sr-Latn.yml b/config/locales/simple_form.sr-Latn.yml index e444f45ca60..1be4c6f2891 100644 --- a/config/locales/simple_form.sr-Latn.yml +++ b/config/locales/simple_form.sr-Latn.yml @@ -70,7 +70,6 @@ sr-Latn: featured_tag: name: 'Evo nekih od heš oznaka koje ste u prethodnom periodu često koristili:' filters: - action: Izaberite koju radnju izvršiti kada objava odgovara filteru actions: hide: Potpuno sakrij filtrirani sadržaj, ponašajući se kao da ne postoji warn: Sakrij filtrirani sadržaj iza upozorenja u kome se navodi naziv filtera @@ -78,7 +77,6 @@ sr-Latn: activity_api_enabled: Brojevi lokalno postavljenih objava, aktivnih korisnika i novih registracija na nedeljnoj bazi app_icon: WEBP, PNG, GIF ili JPG. Zamenjuje podrazumevanu ikonicu aplikacije na mobilnim uređajima prilagođenom ikonicom. backups_retention_period: Korisnici imaju mogućnost da generišu arhive svojih objava za kasnije preuzimanje. Kada se podese na pozitivnu vrednost, ove arhive će se automatski izbrisati iz vašeg skladišta nakon navedenog broja dana. - bootstrap_timeline_accounts: Ovi nalozi će biti zakačeni na vrh preporuka za praćenje novih korisnika. closed_registrations_message: Prikazuje se kada su registracije zatvorene content_cache_retention_period: Sve objave sa drugih servera (uključujući podržavanja i odgovore) će biti izbrisane nakon navedenog broja dana, bez obzira na bilo kakvu interakciju lokalnog korisnika sa tim objavama. Ovo uključuje objave u kojima ih je lokalni korisnik označio kao obeleživače ili omiljene. Privatna pominjanja između korisnika sa različitih instanci će takođe biti izgubljena i nemoguće ih je vratiti. Korišćenje ove postavke je namenjeno za slučajeve posebne namene i krši mnoga očekivanja korisnika kada se primeni za upotrebu opšte namene. custom_css: Možete da primenite prilagođene stilove na veb verziji Mastodon-a. diff --git a/config/locales/simple_form.sr.yml b/config/locales/simple_form.sr.yml index 1f5e9d51701..2fe3d79c3af 100644 --- a/config/locales/simple_form.sr.yml +++ b/config/locales/simple_form.sr.yml @@ -70,7 +70,6 @@ sr: featured_tag: name: 'Ево неких од хеш ознака које сте у претходном периоду често користили:' filters: - action: Изаберите коју радњу извршити када објава одговара филтеру actions: hide: Потпуно сакриј филтрирани садржај, понашајући се као да не постоји warn: Сакриј филтрирани садржај иза упозорења у коме се наводи назив филтера @@ -78,7 +77,6 @@ sr: activity_api_enabled: Бројеви локално постављених објава, активних корисника и нових регистрација на недељној бази app_icon: WEBP, PNG, GIF или JPG. Замењује подразумевану иконицу апликације на мобилним уређајима прилагођеном иконицом. backups_retention_period: Корисници имају могућност да генеришу архиве својих објава за касније преузимање. Када се подесе на позитивну вредност, ове архиве ће се аутоматски избрисати из вашег складишта након наведеног броја дана. - bootstrap_timeline_accounts: Ови налози ће бити закачени на врх препорука за праћење нових корисника. closed_registrations_message: Приказује се када су регистрације затворене content_cache_retention_period: Све објаве са других сервера (укључујући подржавања и одговоре) ће бити избрисане након наведеног броја дана, без обзира на било какву интеракцију локалног корисника са тим објавама. Ово укључује објаве у којима их је локални корисник означио као обележиваче или омиљене. Приватна помињања између корисника са различитих инстанци ће такође бити изгубљена и немогуће их је вратити. Коришћење ове поставке је намењено за случајеве посебне намене и крши многа очекивања корисника када се примени за употребу опште намене. custom_css: Можете да примените прилагођене стилове на веб верзији Mastodon-а. diff --git a/config/locales/simple_form.sv.yml b/config/locales/simple_form.sv.yml index 5f08efa3ff1..2af0a51be4c 100644 --- a/config/locales/simple_form.sv.yml +++ b/config/locales/simple_form.sv.yml @@ -74,7 +74,6 @@ sv: featured_tag: name: 'Här är några av de hashtaggar du använt nyligen:' filters: - action: Välj vilken åtgärd som ska utföras när ett inlägg matchar filtret actions: blur: Dölj media bakom en varning utan att dölja själva texten hide: Dölj det filtrerade innehållet helt, beter sig som om det inte fanns @@ -83,7 +82,6 @@ sv: activity_api_enabled: Antalet lokalt publicerade inlägg, aktiva användare och nya registrerade konton per vecka app_icon: WEBP, PNG, GIF eller JPG. Använd istället för appens egna ikon på mobila enheter. backups_retention_period: Användare har möjlighet att generera arkiv av sina inlägg för att ladda ned senare. När det sätts till ett positivt värde raderas dessa arkiv automatiskt från din lagring efter det angivna antalet dagar. - bootstrap_timeline_accounts: Dessa konton kommer fästas högst upp i nya användares följrekommendationer. closed_registrations_message: Visas när nyregistreringar är avstängda content_cache_retention_period: Alla inlägg från andra servrar (inklusive booster och svar) kommer att raderas efter det angivna antalet dagar, utan hänsyn till någon lokal användarinteraktion med dessa inlägg. Detta inkluderar inlägg där en lokal användare har markerat det som bokmärke eller favoriter. Privata omnämnanden mellan användare från olika instanser kommer också att gå förlorade och blir omöjliga att återställa. Användningen av denna inställning är avsedd för specialfall och bryter många användarförväntningar när de implementeras för allmänt bruk. custom_css: Du kan använda anpassade stilar på webbversionen av Mastodon. diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index 85df9148042..71eea7a46b1 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -72,7 +72,6 @@ th: featured_tag: name: 'นี่คือแฮชแท็กบางส่วนที่คุณได้ใช้ล่าสุด:' filters: - action: เลือกว่าการกระทำใดที่จะทำเมื่อโพสต์ตรงกับตัวกรอง actions: hide: ซ่อนเนื้อหาที่กรองอยู่อย่างสมบูรณ์ ทำเสมือนว่าไม่มีเนื้อหาอยู่ warn: ซ่อนเนื้อหาที่กรองอยู่หลังคำเตือนที่กล่าวถึงชื่อเรื่องของตัวกรอง @@ -80,7 +79,6 @@ th: activity_api_enabled: จำนวนโพสต์ที่เผยแพร่ในเซิร์ฟเวอร์, ผู้ใช้ที่ใช้งานอยู่ และการลงทะเบียนใหม่ในบักเก็ตรายสัปดาห์ app_icon: WEBP, PNG, GIF หรือ JPG เขียนทับไอคอนแอปเริ่มต้นในอุปกรณ์มือถือด้วยไอคอนที่กำหนดเอง backups_retention_period: ผู้ใช้มีความสามารถในการสร้างการเก็บถาวรของโพสต์ของเขาเพื่อดาวน์โหลดในภายหลัง เมื่อตั้งเป็นค่าบวก จะลบการเก็บถาวรเหล่านี้ออกจากที่เก็บข้อมูลของคุณโดยอัตโนมัติหลังจากจำนวนวันที่ระบุ - bootstrap_timeline_accounts: จะปักหมุดบัญชีเหล่านี้ไว้ด้านบนสุดของคำแนะนำการติดตามของผู้ใช้ใหม่ closed_registrations_message: แสดงเมื่อมีการปิดการลงทะเบียน content_cache_retention_period: จะลบโพสต์ทั้งหมดจากเซิร์ฟเวอร์อื่น ๆ (รวมถึงการดันและการตอบกลับ) หลังจากจำนวนวันที่ระบุ โดยไม่คำนึงถึงการโต้ตอบใด ๆ ของผู้ใช้ในเซิร์ฟเวอร์กับโพสต์เหล่านั้น สิ่งนี้รวมถึงโพสต์ที่ผู้ใช้ในเซิร์ฟเวอร์ได้ทำเครื่องหมายโพสต์ว่าเป็นที่คั่นหน้าหรือรายการโปรด การกล่าวถึงแบบส่วนตัวระหว่างผู้ใช้จากอินสแตนซ์ที่แตกต่างกันจะหายไปและไม่สามารถคืนค่าได้เช่นกัน การใช้การตั้งค่านี้มีไว้สำหรับอินสแตนซ์ที่มีวัตถุประสงค์พิเศษและทำลายความคาดหวังของผู้ใช้จำนวนมากเมื่อนำไปใช้สำหรับการใช้งานที่มีวัตถุประสงค์ทั่วไป custom_css: คุณสามารถนำไปใช้ลักษณะที่กำหนดเองใน Mastodon รุ่นเว็บ diff --git a/config/locales/simple_form.tr.yml b/config/locales/simple_form.tr.yml index f64c12cf907..4a5cad50870 100644 --- a/config/locales/simple_form.tr.yml +++ b/config/locales/simple_form.tr.yml @@ -88,7 +88,7 @@ tr: activity_api_enabled: Yerel olarak yayınlanan gönderi, etkin kullanıcı ve yeni kayıtların haftalık sayıları app_icon: WEBP, PNG, GIF veya JPG. Mobil aygıtlarda varsayılan uygulama simgesini isteğe bağlı bir simgeyle değiştirir. backups_retention_period: Kullanıcılar, gönderilerinin arşivlerini daha sonra indirmek üzere oluşturabilirler. Pozitif bir değer verdilğinde bu arşivler verilmiş olan gün sonunda deponuzdan otomatik olarak silinecektir. - bootstrap_timeline_accounts: Bu hesaplar, yeni kullanıcıların takip önerilerinin tepesinde sabitlenecektir. + bootstrap_timeline_accounts: Bu hesaplar, yeni kullanıcıların takip önerilerinin en üstüne sabitlenecektir. Hesapların virgülle ayrılmış bir listesini girin. closed_registrations_message: Kayıt olma kapalıyken görüntülenir content_cache_retention_period: Diğer sunuculardaki (öne çıkarma ve yanıtlar da dahil olmak üzere) tüm gönderiler belirlenen gün sonunda, yerel bir kullanıcının etkileşimine bakılmadan, silinecektir. Yerel bir kullanıcının yerimlerine veya favorilerine eklediği gönderiler de dahildir. Farklı sunuculardaki kullanıcılar arasındaki özel bahsetmeler de kaybolacak ve geri getirilmeleri mümkün olmayacaktır. Bu ayarın kullanımı özel amaçlı sunucular içindir ve genel amaçlı kullanımda etkinleştirildiğinde kullanıcı beklentilerini karşılamayabilir. custom_css: Mastodon'un web sürümüne özel biçimler uygulayabilirsiniz. diff --git a/config/locales/simple_form.uk.yml b/config/locales/simple_form.uk.yml index 40be33811a5..a22ebf28834 100644 --- a/config/locales/simple_form.uk.yml +++ b/config/locales/simple_form.uk.yml @@ -73,7 +73,6 @@ uk: featured_tag: name: 'Ось деякі використані останнім часом хештеґи:' filters: - action: Виберіть дію для виконання коли допис збігається з фільтром actions: blur: Приховати медіа за попередженням, не приховуючи сам текст hide: Повністю сховати фільтрований вміст, ніби його не існує @@ -82,7 +81,6 @@ uk: activity_api_enabled: Кількість локальних опублікованих дописів, активних і нових користувачів у тижневих розрізах app_icon: WEBP, PNG, GIF або JPG. Замінює типову піктограму застосунку на мобільних пристроях на власну. backups_retention_period: Користувачі мають можливість створювати архіви своїх дописів, щоб завантажити їх пізніше. Якщо встановлено додатне значення, ці архіви будуть автоматично видалені з вашого сховища через вказану кількість днів. - bootstrap_timeline_accounts: Ці облікові записи будуть закріплені в топі пропозицій для нових користувачів. closed_registrations_message: Показується, коли реєстрація закрита content_cache_retention_period: Усі дописи з інших серверів (включно з коментарями та відповідями) будуть видалені через певну кількість днів, незважаючи на будь-яку локальну взаємодію користувачів з цими дописами. Сюди входять дописи, які локальний користувач позначив як закладки або вибране. Приватні згадки між користувачами з різних інстанцій також будуть втрачені і не підлягатимуть відновленню. Використання цього параметра призначено для екземплярів спеціального призначення і порушує багато очікувань користувачів, якщо його застосовано для загального використання. custom_css: Ви можете застосувати користувацькі стилі у вебверсії Mastodon. diff --git a/config/locales/simple_form.vi.yml b/config/locales/simple_form.vi.yml index 8432ded89d2..b4506722624 100644 --- a/config/locales/simple_form.vi.yml +++ b/config/locales/simple_form.vi.yml @@ -88,7 +88,7 @@ vi: activity_api_enabled: Số lượng tút được đăng trong máy chủ, người dùng đang hoạt động và đăng ký mới hàng tuần app_icon: WEBP, PNG, GIF hoặc JPG. Dùng biểu tượng tùy chỉnh trên thiết bị di động. backups_retention_period: Người dùng có khả năng tạo bản sao lưu các tút của họ để tải xuống sau. Các bản sao lưu này sẽ tự động bị xóa khỏi bộ nhớ của bạn sau số ngày được chỉ định. - bootstrap_timeline_accounts: Những người này sẽ được ghim vào đầu các gợi ý theo dõi của người mới. + bootstrap_timeline_accounts: Những tài khoản này sẽ được ghim lên đầu danh sách đề xuất theo dõi của người dùng mới. Hãy cung cấp danh sách các tài khoản được phân tách bằng dấu phẩy. closed_registrations_message: Được hiển thị khi đóng đăng ký content_cache_retention_period: Tất cả tút từ các máy chủ khác (bao gồm cả đăng lại và trả lời) sẽ bị xóa sau số ngày được chỉ định mà không tính đến bất kỳ tương tác nào của người dùng cục bộ với các tút đó. Điều này bao gồm các tút mà người dùng cục bộ đã đánh dấu nó là dấu trang hoặc mục yêu thích. Những lượt nhắc riêng tư giữa những người dùng từ các máy chủ khác nhau cũng sẽ bị mất và không thể khôi phục. Việc sử dụng cài đặt này dành cho các trường hợp có mục đích đặc biệt và phá vỡ nhiều kỳ vọng của người dùng khi được triển khai cho mục đích sử dụng chung. custom_css: Bạn có thể tùy chỉnh phong cách trên bản web của Mastodon. diff --git a/config/locales/simple_form.zh-CN.yml b/config/locales/simple_form.zh-CN.yml index c740aba19f6..d6069a43d3b 100644 --- a/config/locales/simple_form.zh-CN.yml +++ b/config/locales/simple_form.zh-CN.yml @@ -26,9 +26,9 @@ zh-CN: types: disable: 禁止用户使用账号,但不会删除或隐藏账号内容。 none: 用它来向用户发送警告,不会触发其他操作。 - sensitive: 强制将此用户的所有媒体文件标记为敏感内容。 - silence: 阻止用户发送公开嘟文,除了关注者以外,其他人都无法看到他的嘟文和通知。关闭针对此账号的所有举报。 - suspend: 阻止此账号的任何交互并删除其内容。30天内可以撤销操作。关闭针对此账号的所有举报。 + sensitive: 强制将此用户的全部媒体文件标记为敏感内容。 + silence: 阻止用户发送公开嘟文,除了关注者以外,其他人都无法看到他的嘟文和通知。关闭针对此账号的全部举报。 + suspend: 阻止此账号的任何交互并删除其内容。30天内可以撤销操作。关闭针对此账号的全部举报。 warning_preset_id: 可选。你可以在预置文本末尾添加自定义文本 announcement: all_day: 如果选中,只有该时间段内的日期会显示。 @@ -54,7 +54,7 @@ zh-CN: password: 至少需要8个字符 phrase: 匹配将忽略嘟文或内容警告里的字母大小写 scopes: 哪些 API 被允许使用。如果你勾选了更高一级的范围,就不用单独选中子项目了。 - setting_advanced_layout: 将Mastodon的界面显示为多列布局,允许您同时查看时间线、通知及可自主选择的第三列。屏幕尺寸较小的情况下不推荐使用。 + setting_advanced_layout: 将 Mastodon 的界面显示为多列布局,允许你同时查看时间线、通知及可自主选择的第三列。屏幕尺寸较小的情况下不推荐使用。 setting_aggregate_reblogs: 不显示最近已经被转嘟过的嘟文(只会影响新收到的转嘟) setting_always_send_emails: 一般情况下,如果你活跃使用 Mastodon,我们不会向你发送电子邮件通知 setting_boost_modal: 如果启用,转嘟前会先打开确认对话框,以便更改转嘟的可见性。 @@ -79,7 +79,7 @@ zh-CN: featured_tag: name: 以下是你最近使用过的标签: filters: - action: 选择在嘟文命中过滤规则时要执行的操作 + action: 请选择在嘟文命中过滤规则时要执行的操作 actions: blur: 将媒体隐藏在警告之后,且不隐藏文字 hide: 选择在嘟文命中过滤规则时要执行的操作 @@ -88,7 +88,7 @@ zh-CN: activity_api_enabled: 本站每周的嘟文数、活跃用户数和新注册用户数 app_icon: WEBP、PNG、GIF 或 JPG。使用自定义图标覆盖移动设备上的默认应用图标。 backups_retention_period: 用户可以生成其嘟文存档以供之后下载。当该值被设为正值时,这些存档将在指定的天数后自动从你的存储中删除。 - bootstrap_timeline_accounts: 这些账号将在新用户关注推荐中置顶显示。 + bootstrap_timeline_accounts: 这些账号将在新用户关注推荐中置顶显示。请提供以逗号分隔的账号列表。 closed_registrations_message: 在关闭注册时显示 content_cache_retention_period: 来自其它实例的所有嘟文(包括转嘟与回复)都将在指定天数后被删除,不论本实例用户是否与这些嘟文产生过交互。这包括被本实例用户喜欢和收藏的嘟文。实例间用户的私下提及也将丢失并无法恢复。此设置针对的是特殊用途的实例,用于一般用途时会打破许多用户的期望。 custom_css: 你可以为网页版 Mastodon 应用自定义样式。 @@ -97,7 +97,7 @@ zh-CN: mascot: 覆盖高级网页界面中的绘图形象。 media_cache_retention_period: 来自外站用户嘟文的媒体文件将被缓存到你的实例上。当该值被设为正值时,缓存的媒体文件将在指定天数后被清除。如果媒体文件在被清除后重新被请求,且源站内容仍然可用,它将被重新下载。由于链接预览卡拉取第三方站点的频率受到限制,建议将此值设置为至少 14 天,如果小于该值,链接预览卡将不会按需更新。 min_age: 用户注册时必须确认出生日期 - peers_api_enabled: 本站在联邦宇宙中遇到的站点列表。 此处不包含关于您是否与给定站点联合的数据,只是您的实例知道它。 这由收集一般意义上的联合统计信息的服务使用。 + peers_api_enabled: 本站在联邦宇宙中遇到的站点列表。 此处不包含关于你是否与给定站点联合的数据,只是你的实例知道它。 这由收集一般意义上的联合统计信息的服务使用。 profile_directory: 个人资料目录会列出所有选择可被发现的用户。 require_invite_text: 当注册需要手动批准时,将“你为什么想要加入?”设为必填项 site_contact_email: 他人需要询恰法务或支持信息时的联络方式 @@ -139,22 +139,22 @@ zh-CN: name: 你只能改变字母的大小写,让它更易读 terms_of_service: changelog: 可以使用 Markdown 语法。 - effective_date: 合理的时间范围可以是从您通知用户之日起 10 到 30 天。 + effective_date: 合理的时间范围可以是从你通知用户之日起 10 到 30 天。 text: 可以使用 Markdown 语法。 terms_of_service_generator: admin_email: 法务通知包括反通知、法院命令、内容下架要求与执法机关的要求。 arbitration_address: 可以与上面的实际地址相同,如果使用电子邮件则为“N/A”。 arbitration_website: 可以是网页表单,如果使用电子邮件则为“N/A”。 - choice_of_law: 适用内部实质法律以管辖任何及所有索赔的城市、地区、领土或州。 + choice_of_law: 适用内部实质法律以管辖任何及全部索赔的城市、地区、领土或州。 dmca_address: 如果你是位于美国的运营者,请使用在 DMCA 指定代表名录中注册的地址。如果你需要使用邮政信箱,可以直接申请。请使用 DMCA 指定代表邮政信箱豁免申请表,通过电子邮件联系版权办公室,并声明你是居家内容审核员,因担心审核操作会招致报复或打击报复,需要使用邮政信箱以避免公开家庭住址。 dmca_email: 可以与上面“法律声明的电子邮件地址”使用相同的电子邮件地址。 domain: 你所提供的在线服务的唯一标识。 jurisdiction: 请列出支付运营费用者所在的国家/地区。如果为公司或其他实体,请列出其注册的国家/地区以及相应的城市、地区、领地或州。 - min_age: 不应低于您所在地法律管辖权要求的最低年龄。 + min_age: 不应低于你所在地法律管辖权要求的最低年龄。 user: chosen_languages: 仅选中语言的嘟文会出现在公共时间线上(全不选则显示所有语言的嘟文) date_of_birth: - other: 我们必须确保您至少年满 %{count} 岁才能使用 %{domain}。我们不会存储此信息。 + other: 我们必须确保你至少年满 %{count} 岁才能使用 %{domain}。我们不会存储此信息。 role: 角色用于控制用户拥有的权限。 user_role: color: 在界面各处用于标记该角色的颜色,以十六进制 RGB 格式表示 @@ -339,7 +339,7 @@ zh-CN: reblog: 有人转嘟了我的嘟文 report: 有人提交了新举报 software_updates: - all: 通知所有更新 + all: 通知全部更新 critical: 仅在有关键更新时通知 label: 有新的 Mastodon 版本可用 none: 从不通知更新(不推荐) diff --git a/config/locales/simple_form.zh-HK.yml b/config/locales/simple_form.zh-HK.yml index 08358ff8c45..a92d7bcd959 100644 --- a/config/locales/simple_form.zh-HK.yml +++ b/config/locales/simple_form.zh-HK.yml @@ -70,14 +70,12 @@ zh-HK: featured_tag: name: 以下是你最近常用的標籤: filters: - action: 選擇當帖文符合篩選器時要執行的動作 actions: hide: 完全隱藏被篩選的內容,猶如它不存在般。 warn: 將已篩選的內容隱藏在篩選器標題的警告後面。 form_admin_settings: activity_api_enabled: 每週本站發佈的帖文、活躍使用者及新註冊的數量 backups_retention_period: 使用者可以生成帖文存檔,以便日後下載。如果設定為正值,這些存檔將在指定天數後自動從你的儲存空間中刪除。 - bootstrap_timeline_accounts: 這些帳號會被置頂在新使用者的追蹤建議上。 closed_registrations_message: 關閉註冊時顯示 content_cache_retention_period: 所有來自其他伺服器的帖文(包括轉推和回覆),不論本站使用者有否與這些帖文互動,帖文都將在指定天數後被刪除。這包括本地使用者標記為書籤或加入最愛的帖文。不同站點之間的私人提及也將丟失,並且無法恢復。此設定適用於有特殊用途的站點,一般使用可能會破壞使用者體驗。 custom_css: 你可以在 Mastodon 網頁版套用自訂樣式。 diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index 181965d514b..274ed20284a 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -88,7 +88,7 @@ zh-TW: activity_api_enabled: 本站使用者的嘟文數量,以及本站的活躍使用者與一週內新使用者數量 app_icon: WEBP、PNG、GIF、或 JPG。於行動裝置上使用自訂圖示替代預設應用程式圖示。 backups_retention_period: 使用者能產生他們嘟文的備份以便日後下載。當設定為正值時,這些嘟文備份將於指定之天數後自您的儲存空間中自動刪除。 - bootstrap_timeline_accounts: 這些帳號將被釘選於新帳號跟隨推薦之上。 + bootstrap_timeline_accounts: 這些帳號將被釘選於新帳號跟隨建議之上。請提供以逗號分隔之帳號列表。 closed_registrations_message: 於註冊關閉時顯示 content_cache_retention_period: 所有來自其他伺服器之嘟文(包括轉嘟與回嘟)將於指定之天數後自動刪除,不論這些嘟文與本地使用者間的任何互動。這將包含本地使用者已標記為書籤或最愛之嘟文。不同站點使用者間之私訊亦將遺失且不可回復。此設定應適用於特殊情況,若常規使用將超乎多數使用者預期。 custom_css: 您於 Mastodon 網頁版本中能套用客製化風格。 diff --git a/config/locales/sk.yml b/config/locales/sk.yml index ac3d5d8ee96..beabe30ba53 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -1121,7 +1121,6 @@ sk: disabled_account: Tvoj súčasný účet už po tomto nebude plne použiteľný. Stále ale budeš mať prístup ku stiahnutiu dát a možnosti znovu-aktivácie. followers: Tento úkon presunie všetkých následovateľov zo súčasného účtu na nový účet only_redirect_html: Ako alternatívu, môžeš iba nastaviť presmerovanie na tvoj profil. - other_data: Žiadne iné dáta nebudú presunuté automaticky redirect: Tvoj súčastný účet bude aktualizovaný s oznamom o presunutí a bude vylúčený z vyhľadávania moderation: title: Moderovanie diff --git a/config/locales/sl.yml b/config/locales/sl.yml index e77132a8840..6bb4a193bc5 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -1646,7 +1646,6 @@ sl: disabled_account: Vaš trenutni račun zatem ne bo polno uporaben. Vendar pa boste imeli dostop do izvoza podatkov kot tudi do ponovne aktivacije. followers: S tem dejanjem boste preselili vse sledilce iz trenutnega računa na novi račun only_redirect_html: Namesto tega lahko na svojem profilu zgolj vzpostavite preusmeritev. - other_data: Nobeni drugi podatki se ne bodo preselili samodejno redirect: Profil vašega trenutnega računa bo posodobljen z obvestilom o preusmeritvi in bo izključen iz iskanj moderation: title: Moderiranje diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 6aa95821d46..6b251a77790 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1657,7 +1657,7 @@ sq: disabled_account: Llogaria juaj e tanishme s’do të jetë plotësisht e përdorshme, pas kësaj. Megjithatë, do të mund të bëni eksportim të dhënash, si dhe riaktivizim. followers: Ky veprim do të kalojë krejt ndjekësit prej llogarisë së tanishme te llogaria e re only_redirect_html: Ndryshe, mund të ujdisni një ridrejtim vetëm te profili juaj. - other_data: S’do të lëvizen të dhëna të tjera automatikisht + other_data: S’do të lëvizen automatikisht të dhëna të tjera (përfshi postimet tuaja dhe listën e llogarive që ndiqni) redirect: Profili i llogarisë tuaj të tanishme do të përditësohet me një shënim ridrejtimi dhe do të përjashtohet prej kërkimesh moderation: title: Moderim @@ -1914,6 +1914,7 @@ sq: errors: in_reply_not_found: Gjendja të cilës po provoni t’i përgjigjeni s’duket se ekziston. quoted_status_not_found: Postimi që po rrekeni të citoni nuk duket se ekziston. + quoted_user_not_mentioned: S’mund të citohet një përdorues që s’është përmendur në një postim Përmendje Private. over_character_limit: u tejkalua kufi shenjash prej %{max} pin_errors: direct: Postimet që janë të dukshme vetëm për përdoruesit e përmendur s’mund të fiksohen diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 7d75fe3bd13..3ea914a016f 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1398,7 +1398,6 @@ sr-Latn: disabled_account: Vaš trenutni nalog više neće biti upotrebljiv. Međutim, imaćete pristup izvozu podataka kao i reaktivaciji. followers: Ova radnja će premestiti sve pratioce sa trenutnog naloga na novi nalog only_redirect_html: Umesto preseljenja, možete samo dodati preusmeravajući link na svoj profil.. - other_data: Ostali podaci neće biti automatski prebačeni redirect: Profil Vašeg sadašnjeg naloga će biti ažuriran sa obaveštenjem o preusmerenju i biće isključen iz pretrage moderation: title: Moderacija diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 25b3728186a..22ba9f0791d 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1428,7 +1428,6 @@ sr: disabled_account: Ваш тренутни налог више неће бити употребљив. Међутим, имаћете приступ извозу података као и реактивацији. followers: Ова радња ће преместити све пратиоце са тренутног налога на нови налог only_redirect_html: Уместо пресељења, можете само додати преусмеравајући линк на свој профил.. - other_data: Остали подаци неће бити аутоматски пребачени redirect: Профил Вашег садашњег налога ће бити ажуриран са обавештењем о преусмерењу и биће искључен из претраге moderation: title: Модерација diff --git a/config/locales/sv.yml b/config/locales/sv.yml index ad1e36bc860..7503b1548b5 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1647,7 +1647,6 @@ sv: disabled_account: Ditt nuvarande konto kommer inte att kunna användas fullt ut efteråt. Du kommer dock att ha tillgång till dataexport samt återaktivering. followers: Den här åtgärden kommer att flytta alla följare från det nuvarande kontot till det nya kontot only_redirect_html: Alternativt kan du bara sätta upp en omdirigering på din profil. - other_data: Ingen annan data kommer att flyttas automatiskt redirect: Ditt nuvarande kontos profil kommer att uppdateras med ett meddelande om omdirigering och uteslutas från sökningar moderation: title: Moderera diff --git a/config/locales/th.yml b/config/locales/th.yml index 202e2c0035a..c207fec0bb3 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -187,6 +187,7 @@ th: create_relay: สร้างรีเลย์ create_unavailable_domain: สร้างโดเมนที่ไม่พร้อมใช้งาน create_user_role: สร้างบทบาท + create_username_block: สร้างกฎชื่อผู้ใช้ demote_user: ลดขั้นผู้ใช้ destroy_announcement: ลบประกาศ destroy_canonical_email_block: ลบการปิดกั้นอีเมล @@ -200,6 +201,7 @@ th: destroy_status: ลบโพสต์ destroy_unavailable_domain: ลบโดเมนที่ไม่พร้อมใช้งาน destroy_user_role: ทำลายบทบาท + destroy_username_block: ลบกฎชื่อผู้ใช้ disable_2fa_user: ปิดใช้งาน 2FA disable_custom_emoji: ปิดใช้งานอีโมจิที่กำหนดเอง disable_relay: ปิดใช้งานรีเลย์ @@ -234,6 +236,7 @@ th: update_report: อัปเดตรายงาน update_status: อัปเดตโพสต์ update_user_role: อัปเดตบทบาท + update_username_block: อัปเดตกฎชื่อผู้ใช้ actions: approve_appeal_html: "%{name} ได้อนุมัติการอุทธรณ์การตัดสินใจในการกลั่นกรองจาก %{target}" approve_user_html: "%{name} ได้อนุมัติการลงทะเบียนจาก %{target}" @@ -481,6 +484,7 @@ th: save: บันทึก sign_in: ลงชื่อเข้า status: สถานะ + title: FASP follow_recommendations: description_html: "คำแนะนำการติดตามช่วยให้ผู้ใช้ใหม่ค้นหาเนื้อหาที่น่าสนใจได้อย่างรวดเร็ว เมื่อผู้ใช้ไม่ได้โต้ตอบกับผู้อื่นมากพอที่จะสร้างคำแนะนำการติดตามเฉพาะบุคคล จะแนะนำบัญชีเหล่านี้แทน จะคำนวณคำแนะนำใหม่เป็นประจำทุกวันจากบัญชีต่าง ๆ ที่มีการมีส่วนร่วมล่าสุดสูงสุดและจำนวนผู้ติดตามในเซิร์ฟเวอร์สูงสุดสำหรับภาษาที่กำหนด" language: สำหรับภาษา @@ -792,6 +796,9 @@ th: all: ให้กับทุกคน disabled: ให้กับไม่มีใคร users: ให้กับผู้ใช้ในเซิร์ฟเวอร์ที่เข้าสู่ระบบ + landing_page: + values: + about: เกี่ยวกับ registrations: moderation_recommandation: โปรดตรวจสอบให้แน่ใจว่าคุณมีทีมการกลั่นกรองที่เพียงพอและมีปฏิกิริยาตอบสนองก่อนที่คุณจะเปิดการลงทะเบียนให้กับทุกคน! preamble: ควบคุมผู้ที่สามารถสร้างบัญชีในเซิร์ฟเวอร์ของคุณ @@ -1019,6 +1026,14 @@ th: other: ใช้โดย %{count} คนในช่วงสัปดาห์ที่ผ่านมา title: คำแนะนำและแนวโน้ม trending: กำลังนิยม + username_blocks: + delete: ลบ + edit: + title: แก้ไขกฎชื่อผู้ใช้ + new: + create: สร้างกฎ + title: สร้างกฎชื่อผู้ใช้ใหม่ + title: กฎชื่อผู้ใช้ warning_presets: add_new: เพิ่มใหม่ delete: ลบ @@ -1090,6 +1105,7 @@ th: hint_html: หากคุณต้องการย้ายจากบัญชีอื่นไปยังบัญชีนี้ ที่นี่คุณสามารถสร้างนามแฝง ซึ่งจำเป็นก่อนที่คุณจะสามารถดำเนินการต่อด้วยการย้ายผู้ติดตามจากบัญชีเก่าไปยังบัญชีนี้ การกระทำนี้โดยตัวการกระทำเอง ไม่เป็นอันตรายและย้อนกลับได้ การโยกย้ายบัญชีเริ่มต้นจากบัญชีเก่า remove: เลิกเชื่อมโยงนามแฝง appearance: + advanced_settings: การตั้งค่าขั้นสูง animations_and_accessibility: ภาพเคลื่อนไหวและการช่วยการเข้าถึง discovery: การค้นพบ localization: @@ -1465,6 +1481,11 @@ th: expires_at: หมดอายุเมื่อ uses: การใช้งาน title: เชิญผู้คน + link_preview: + author_html: โดย %{name} + potentially_sensitive_content: + action: คลิกเพื่อแสดง + hide_button: ซ่อน lists: errors: limit: คุณมีรายการถึงจำนวนสูงสุดแล้ว @@ -1529,7 +1550,6 @@ th: disabled_account: บัญชีปัจจุบันของคุณจะไม่สามารถใช้งานได้อย่างเต็มที่หลังจากนั้น อย่างไรก็ตาม คุณจะสามารถเข้าถึงการส่งออกข้อมูลเช่นเดียวกับการเปิดใช้งานใหม่ followers: การกระทำนี้จะย้ายผู้ติดตามทั้งหมดจากบัญชีปัจจุบันไปยังบัญชีใหม่ only_redirect_html: หรืออีกวิธีหนึ่ง คุณสามารถ ตั้งเพียงการเปลี่ยนเส้นทางในโปรไฟล์ของคุณเท่านั้น - other_data: จะไม่ย้ายข้อมูลอื่น ๆ โดยอัตโนมัติ redirect: จะอัปเดตโปรไฟล์ของบัญชีปัจจุบันของคุณด้วยข้อสังเกตการเปลี่ยนเส้นทางและจะไม่รวมอยู่ในการค้นหา moderation: title: การกลั่นกรอง @@ -1765,6 +1785,9 @@ th: other: "%{count} วิดีโอ" boosted_from_html: ดันจาก %{acct_link} content_warning: 'คำเตือนเนื้อหา: %{warning}' + content_warnings: + hide: ซ่อนโพสต์ + show: แสดงเพิ่มเติม default_language: เหมือนกับภาษาส่วนติดต่อ disallowed_hashtags: other: 'มีแฮชแท็กที่ไม่อนุญาต: %{tags}' diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 3cedf77bbe3..b56ba5d9ac4 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1672,7 +1672,7 @@ tr: disabled_account: Sonrasında, mevcut hesabınız tamamen kullanılabilir olmayacaktır. Ancak, yeniden etkinleştirme işleminin yanı sıra veri dışa aktarma erişimine sahip olacaksınız. followers: Bu eylem tüm takipçileri şu anki hesaptan yeni hesaba taşıyacaktır only_redirect_html: Alternatif olarak, sadece profilinize bir yönlendirme koyabilirsiniz. - other_data: Başka bir veri otomatik olarak taşınmayacaktır + other_data: Başka (gönderileriniz ve takip ettiğiniz hesapların listesi dahil) hiçbir veri otomatik olarak taşınmayacaktır redirect: Mevcut hesabınızın profili bir yönlendirme bildirimi ile güncellenecek ve aramaların dışında tutulacaktır moderation: title: Denetim @@ -1929,6 +1929,7 @@ tr: errors: in_reply_not_found: Yanıtlamaya çalıştığınız durum yok gibi görünüyor. quoted_status_not_found: Alıntılamaya çalıştığınız gönderi mevcut görünmüyor. + quoted_user_not_mentioned: Özel Bahsetme gönderisinde bahsedilmeyen bir kullanıcıyı alıntılamak mümkün değildir. over_character_limit: "%{max} karakter limiti aşıldı" pin_errors: direct: Sadece değinilen kullanıcıların görebileceği gönderiler üstte tutulamaz diff --git a/config/locales/uk.yml b/config/locales/uk.yml index bd94e9da3f1..6af5cada4b4 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -1602,7 +1602,6 @@ uk: disabled_account: Поточний обліковий запис не буде повністю придатний до використання. Проте ви матимете доступ до експорту даних та повторної активації. followers: Ця дія призведе до переміщення всіх підписників з поточного облікового запису до нового облікового запису only_redirect_html: Або ж ви можете просто налаштувати перенаправлення у ваш профіль. - other_data: Ніякі інші дані не будуть переміщені автоматично redirect: Профіль цього облікового запису буде оновлено з заміткою про перенаправлення, а також виключений з пошуку moderation: title: Модерація diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 0d3866f6520..a46e08a6cf7 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1633,7 +1633,7 @@ vi: disabled_account: Tài khoản này sẽ không thể tiếp tục dùng nữa. Tuy nhiên, bạn có quyền truy cập để xuất dữ liệu cũng như kích hoạt lại. followers: Hành động này sẽ chuyển tất cả người theo dõi từ tài khoản hiện tại sang tài khoản mới only_redirect_html: Ngoài ra, bạn có thể đặt chuyển hướng trên trang hồ sơ của bạn. - other_data: Dữ liệu khác sẽ không được di chuyển tự động + other_data: Không có dữ liệu nào khác sẽ được tự động di chuyển (bao gồm tút của bạn và danh sách tài khoản bạn theo dõi) redirect: Trang hồ sơ hiện tại của bạn sẽ hiển thị thông báo chuyển hướng và bị loại khỏi kết quả tìm kiếm moderation: title: Kiểm duyệt @@ -1886,6 +1886,7 @@ vi: errors: in_reply_not_found: Bạn đang trả lời một tút không còn tồn tại. quoted_status_not_found: Bạn đang trích dẫn một tút không còn tồn tại. + quoted_user_not_mentioned: Không thể trích dẫn người dùng không được nhắc đến trong tút Nhắn riêng. over_character_limit: vượt quá giới hạn %{max} ký tự pin_errors: direct: Không thể ghim những tút nhắn riêng diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index e7385e392e8..f4b6dcd837c 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -71,7 +71,7 @@ zh-CN: enable_sign_in_token_auth: 启用邮件令牌身份验证 enabled: 已启用 enabled_msg: 成功解冻 %{username} 的账号 - followers: 粉丝 + followers: 关注者 follows: 关注 header: 封面图 inbox_url: 收件箱(Inbox)URL @@ -118,7 +118,7 @@ zh-CN: reject: 拒绝 rejected_msg: 已拒绝 %{username} 的注册申请 remote_suspension_irreversible: 此账号的数据已被不可逆转地删除。 - remote_suspension_reversible_hint_html: 账号已在他们的服务器上封禁,数据将在 %{date} 完全删除。 在此之前,远程服务器仍可恢复此账号,并且没有任何不良影响。 如果你想立即移除该账号的所有数据,可以在下面进行。 + remote_suspension_reversible_hint_html: 账号已在他们的服务器上封禁,数据将在 %{date} 完全删除。 在此之前,远程服务器仍可恢复此账号,并且没有任何不良影响。 如果你想立即移除该账号的全部数据,可以在下面进行。 remove_avatar: 删除头像 remove_header: 移除封面图 removed_avatar_msg: 成功删除 %{username} 的头像 @@ -536,7 +536,7 @@ zh-CN: confirm_purge: 确定要删除此站点的全部数据吗? content_policies: comment: 内部备注 - description_html: 你可以设置应用于此域名所有账号和其所有子域名的内容策略。 + description_html: 你可以设置应用于此域名全部账号和其全部子域名的内容策略。 limited_federation_mode_description_html: 你可以选择是否允许与此实例联合。 policies: reject_media: 拒收媒体 @@ -578,12 +578,12 @@ zh-CN: created_msg: 实例管理员备注创建成功! description_html: 查看备注或向其他管理员留言 destroyed_msg: 实例管理员备注删除成功! - placeholder: 有关此实例的信息、已采取的行动,或任何能帮助您将来管理此实例的事项。 + placeholder: 有关此实例的信息、已采取的行动,或任何能帮助你将来管理此实例的事项。 title: 审核注意事项 private_comment: 私密评论 public_comment: 公开评论 purge: 清除 - purge_description_html: 如果你确认此域名已永久离线,可以从存储中删除此域名的所有账号记录和相关数据。这将会需要一段时间。 + purge_description_html: 如果你确认此域名已永久离线,可以从存储中删除此域名的全部账号记录和相关数据。这将会需要一段时间。 title: 联合 total_blocked_by_us: 被本站屏蔽的 total_followed_by_them: 被对方关注的 @@ -624,7 +624,7 @@ zh-CN: disable: 禁用 disabled: 已禁用 enable: 启用 - enable_hint: 启用此功能后,你的实例会订阅此中继站的所有公开嘟文,并同时向其推送本服务器的公开嘟文。 + enable_hint: 启用此功能后,你的实例会订阅此中继站的全部公开嘟文,并同时向其推送本服务器的公开嘟文。 enabled: 已启用 inbox_url: 中继站 URL pending: 等待中继站的确认 @@ -647,8 +647,8 @@ zh-CN: mark_as_sensitive_description_html: 被举报的嘟文将被标记为敏感,同时该账号将被标记一次处罚,以供未来同一账号再次违规时参考。 other_description_html: 查看更多控制该账号行为的选项,并自定义编写与被举报账号的通信。 resolve_description_html: 不会对被举报账号采取任何动作,举报将被关闭,也不会留下处罚记录。 - silence_description_html: 只有关注或手工搜索此账号才能查看其资料,将严重限制其触达范围。可随时撤销。关闭针对此账号的所有举报。 - suspend_description_html: 该账号及其所有内容将无法访问并最终被删除,且无法与该账号进行互动。 在 30 天内可随时撤销。关闭针对此账号的所有举报。 + silence_description_html: 只有关注或手工搜索此账号才能查看其资料,将严重限制其触达范围。可随时撤销。关闭针对此账号的全部举报。 + suspend_description_html: 该账号及其全部内容将无法访问并最终被删除,且无法与该账号进行互动。 在 30 天内可随时撤销。关闭针对此账号的全部举报。 actions_description_html: 决定采取何种措施处理此举报。如果对被举报账号采取惩罚性措施,将向其发送一封电子邮件通知。但若选中垃圾信息类别则不会发送通知。 actions_description_remote_html: 决定采取何种行动来解决此举报。 这只会影响你的服务器如何与该远程账号的通信并处理其内容。 actions_no_posts: 该举报没有相关嘟文可供删除 @@ -711,7 +711,7 @@ zh-CN: silence_html: 严格限制 @%{acct} 的影响力,方法是让他们的个人资料和内容仅对已经关注他们的人可见,或手动查找其个人资料时 suspend_html: 暂停 @%{acct},使他们的个人资料和内容无法访问,也无法与之互动 close_report: '将举报 #%{id} 标记为已解决' - close_reports_html: 将针对 @%{acct}所有举报标记为已解决 + close_reports_html: 将针对 @%{acct}全部举报标记为已解决 delete_data_html: 从现在起 30 天后删除 @%{acct} 的个人资料和内容,除非他们同时解除暂停。 preview_preamble_html: "@%{acct} 将收到包含以下内容的警告:" record_strike_html: 记录一次针对 @%{acct} 的警示,以帮助你在这个账号上的未来违规事件中得到重视。 @@ -738,7 +738,7 @@ zh-CN: description_html: 使用 用户角色,你可以自定义你的用户可以访问的 Mastodon 功能和区域。 edit: 编辑角色 '%{name}' everyone: 默认权限 - everyone_full_description_html: 该角色是基础角色,会影响所有用户,包括未指定角色的用户。 其他所有的角色都继承该角色的权限。 + everyone_full_description_html: 该角色是基础角色,会影响全部用户,包括未指定角色的用户。 其他全部的角色都继承该角色的权限。 permissions_count: other: "%{count} 个权限" privileges: @@ -782,6 +782,8 @@ zh-CN: view_dashboard_description: 允许用户访问信息面板和各种指标 view_devops: 开发运维 view_devops_description: 允许用户访问 Sidekiq 和 pgHero 控制面板 + view_feeds: 查看实时动态和话题 + view_feeds_description: 允许用户无视服务器设置访问实时动态和话题 title: 角色 rules: add_new: 添加规则 @@ -803,8 +805,8 @@ zh-CN: rules_hint: 有一个专门区域用于显示用户需要遵守的规则。 title: 关于本站 allow_referrer_origin: - desc: 当您的用户点击指向外部网站的链接时,他们的浏览器可能会将您的 Mastodon 服务器地址作为referrer发送。如果这会唯一地识别出您的用户(例如,如果这是一个私人 Mastodon 服务器),请禁用此功能。 - title: 允许外部网站将您的 Mastodon 服务器视为流量来源 + desc: 当你的用户点击指向外部网站的链接时,他们的浏览器可能会将你的 Mastodon 服务器地址作为 referrer 发送。如果这会唯一地识别出你的用户,例如,如果这是一个私人 Mastodon 服务器,请禁用此功能。 + title: 允许外部网站将你的 Mastodon 服务器视为流量来源 appearance: preamble: 自定义 Mastodon 的网页界面。 title: 外观 @@ -819,7 +821,7 @@ zh-CN: preamble: 控制用户生成的内容在 Mastodon 中如何存储。 title: 内容保留 default_noindex: - desc_html: 影响所有尚未更改此设置的用户 + desc_html: 影响全部尚未更改此设置的用户 title: 默认不让用户被搜索引擎索引 discovery: follow_recommendations: 关注推荐 @@ -831,20 +833,21 @@ zh-CN: title: 发现 trends: 热门 domain_blocks: - all: 对所有人 + all: 对每个人 disabled: 不对任何人 users: 对已登录的本站用户 feed_access: modes: authenticated: 仅已登录用户 - public: 所有人 + disabled: 需要特定的用户角色 + public: 每个人 landing_page: values: about: 关于 local_feed: 本站动态 trends: 热门 registrations: - moderation_recommandation: 在向所有人开放注册之前,请确保你拥有一个人手足够且反应迅速的管理团队! + moderation_recommandation: 在向每个人开放注册之前,请确保你拥有一个人手足够且反应迅速的管理团队! preamble: 控制谁可以在你的服务器上创建账号。 title: 注册 registrations_mode: @@ -959,10 +962,10 @@ zh-CN: message_html: 有一个Mastodon错误修复更新可用。 upload_check_privacy_error: action: 点击这里查看更多信息 - message_html: "您的网站服务器配置错误,您用户的隐私处于危险中。" + message_html: "你的网站服务器配置错误,你的用户的隐私处于危险中。" upload_check_privacy_error_object_storage: action: 点击这里查看更多信息 - message_html: "您的对象存储空间配置错误,您用户的隐私处于危险中。" + message_html: "你的对象存储空间配置错误,你的用户的隐私处于危险中。" tags: moderation: not_trendable: 不在热门中显示 @@ -1452,7 +1455,7 @@ zh-CN: all_items_on_page_selected_html: other: 此页面上的所有 %{count} 项目已被选中。 all_matching_items_selected_html: - other: 所有 %{count} 匹配你搜索的项目都已被选中。 + other: 全部 %{count} 匹配你搜索的项目都已被选中。 cancel: 取消 changes_saved_msg: 更改保存成功! confirm: 确认 @@ -1463,7 +1466,7 @@ zh-CN: order_by: 排序方式 save_changes: 保存更改 select_all_matching_items: - other: 选择匹配你搜索的所有 %{count} 个项目。 + other: 选择匹配你搜索的全部 %{count} 个项目。 today: 今天 validation_errors: other: 出错啦!检查一下下面 %{count} 处出错的地方吧 @@ -1490,7 +1493,7 @@ zh-CN: domain_blocking_html: other: 你即将使用来自 %{filename} 的最多 %{count} 个站点域名替换你的站点屏蔽列表。 following_html: - other: 你即将关注来自 %{filename} 的最多 %{count} 个账号,并停止关注其他所有人。 + other: 你即将关注来自 %{filename} 的最多 %{count} 个账号,并停止关注其他任何人。 lists_html: other: 你即将使用来自 %{filename} 的内容替换你的列表。最多将会有 %{count} 个账号 被添加到新列表。 muting_html: @@ -1563,7 +1566,7 @@ zh-CN: author_html: 来自 %{name} potentially_sensitive_content: action: 点击查看 - confirm_visit: 您确定要打开此链接吗? + confirm_visit: 你确定要打开此链接吗? hide_button: 隐藏 label: 可能为敏感内容 lists: @@ -1628,9 +1631,9 @@ zh-CN: before: 在继续前,请仔细阅读下列说明: cooldown: 移动后会有一个冷却期,在此期间你将无法再次移动 disabled_account: 此后,你的当前账号将无法使用。但是,你仍然有权导出数据或者重新激活。 - followers: 这步操作将把所有关注者从当前账号移动到新账号 + followers: 这步操作将把全部关注者从当前账号移动到新账号 only_redirect_html: 或者,你可以只在你的账号资料上设置一个跳转。 - other_data: 不会自动移动其它数据 + other_data: 其他数据不会自动移动(包括您的嘟文及您关注的账号列表) redirect: 在收到一个跳转通知后,你当前的账号资料将会更新,并被排除在搜索范围外 moderation: title: 审核 @@ -1720,7 +1723,7 @@ zh-CN: too_many_options: 不能超过 %{max} 项 vote: 投票 posting_defaults: - explanation: 这些设置会在您撰写新嘟文时作为默认值应用,但每篇嘟文的设置也可以在编辑器处单独修改。 + explanation: 这些设置会在你撰写新嘟文时作为默认值应用,但每篇嘟文的设置也可以在编辑器处单独修改。 preferences: other: 其他 posting_defaults: 发布默认值 @@ -1730,7 +1733,7 @@ zh-CN: privacy: 隐私 privacy_hint_html: 控制你愿意向他人透露多少信息。通过浏览他人的关注列表和查看他们发嘟所用的应用,人们可以发现有趣的用户和酷炫的应用,但你可能更喜欢将其隐藏起来。 reach: 范围 - reach_hint_html: 控制你是否希望被新人发现和关注。你是否希望你的嘟文出现在“探索”页面上?你是否希望其他人在关注推荐中看到你?你是想自动接受所有新粉丝,还是对每个粉丝都进行仔细的筛选? + reach_hint_html: 控制你是否希望被新人发现和关注。你是否希望你的嘟文出现在“探索”页面上?你是否希望其他人在关注推荐中看到你?你是想自动接受全部新关注者,还是对每个关注者都进行仔细的筛选? search: 搜索 search_hint_html: 控制你希望被找到的方式。你想让人们通过你公开发布的内容来找到你吗?当在网络上搜索时,你是否希望Mastodon之外的人能够找到你的个人资料?请注意,我们无法保证完全排除所有搜索引擎对公开信息的索引。 title: 隐私与可达性 @@ -1747,7 +1750,7 @@ zh-CN: activity: 账号活动 confirm_follow_selected_followers: 你确定想要关注所选的关注者吗? confirm_remove_selected_followers: 你确定想要取关所选的关注者吗? - confirm_remove_selected_follows: 您确定要删除选定的关注者吗? + confirm_remove_selected_follows: 你确定要删除选定的关注者吗? dormant: 休眠 follow_failure: 无法关注选中的部分账号。 follow_selected_followers: 关注选中的关注者 @@ -1760,7 +1763,7 @@ zh-CN: mutual: 互相关注 primary: 主要 relationship: 关系 - remove_selected_domains: 删除在选定站点中的所有关注者 + remove_selected_domains: 删除在选定站点中的全部关注者 remove_selected_followers: 移除选中的关注者 remove_selected_follows: 取消关注所选用户 status: 账号状态 @@ -1882,7 +1885,8 @@ zh-CN: edited_at_html: 编辑于 %{date} errors: in_reply_not_found: 你回复的嘟文似乎不存在 - quoted_status_not_found: 您尝试引用的嘟文似乎不存在。 + quoted_status_not_found: 你尝试引用的嘟文似乎不存在。 + quoted_user_not_mentioned: 无法在私下提及嘟文中引用未提及的用户。 over_character_limit: 超过了 %{max} 字的限制 pin_errors: direct: 仅对被提及的用户可见的帖子不能被置顶 @@ -1951,7 +1955,7 @@ zh-CN: terms_of_service: title: 服务条款 terms_of_service_interstitial: - future_preamble_html: 我们将更改部分服务条款,这些更改将在%{date}生效。我们建议您查看更新后的条款。 + future_preamble_html: 我们将更改部分服务条款,这些更改将在%{date}生效。我们建议你查看更新后的条款。 past_preamble_html: 自你上次访问起,我们更改了一些服务条款。我们建议你查看更新后的条款。 review_link: 查看服务条款 title: "%{domain} 更新了服务条款" @@ -2038,7 +2042,7 @@ zh-CN: delete_statuses: 你的一些嘟文被发现违反了一条或多条社区准则,并已被 %{instance} 的管理员删除。 disable: 你不能再使用你的账号,但你的个人资料和其他数据保持不变。你可以请求数据备份,更改账号设置或删除账号。 mark_statuses_as_sensitive: 你的一些嘟文已经被 %{instance} 管理员标记为敏感内容。这意味着别人需要在嘟文中点击媒体,才能显示媒体预览。你可以在今后发布嘟文时自行将媒体标记为敏感内容。 - sensitive: 即刻起,你上传的所有媒体文件都将被标记为敏感内容并隐藏,在点击警告后才能查看。 + sensitive: 即刻起,你上传的全部媒体文件都将被标记为敏感内容并隐藏,在点击警告后才能查看。 silence: 你可以继续使用你的账号,但只有已关注你的人才能在看到你在此服务器上的嘟文,并且你会被排除在各类公共列表之外。其他用户仍可以手动关注你。 suspend: 你不能再使用你的账号,并且你的个人资料和其他数据都将无法访问。在大约30天内,你仍可以登录并请求数据备份,之后相关数据将被完全删除。我们会保留一些基础数据以避免封禁失效。 reason: 理由: @@ -2100,9 +2104,9 @@ zh-CN: title: "%{name},欢迎你的加入!" users: follow_limit_reached: 你不能关注超过 %{limit} 个人 - go_to_sso_account_settings: 转到您的身份提供商进行账号设置 + go_to_sso_account_settings: 转到你的身份提供商进行账号设置 invalid_otp_token: 输入的双因素认证代码无效 - otp_lost_help_html: 如果你不慎丢失了所有的代码,请联系 %{email} 寻求帮助 + otp_lost_help_html: 如果你不慎丢失了全部的代码,请联系 %{email} 寻求帮助 rate_limited: 验证尝试次数过多,请稍后再试。 seamless_external_login: 你通过外部服务登录,因此密码和邮件设置不可用。 signed_in_as: 当前登录的账号: diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index d565d3604c8..039a89bce6c 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -1382,7 +1382,6 @@ zh-HK: disabled_account: 你的當前帳號將不能完整地運作。但你將會有權力匯出你的數據和重新啟用你的帳號。 followers: 此操作將會由當前帳號轉移所有追隨者至新帳號 only_redirect_html: 另外,你亦可只在你的個人資料頁面放上重新定向標記. - other_data: 並不會自動轉移其他數據 redirect: 你的當前帳號的個人資料頁面將會加上一個重新定向公告,並會在搜尋結果中被剔除。 moderation: title: 營運 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 6c56aaf90f7..bc12e97ac5b 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1635,7 +1635,7 @@ zh-TW: disabled_account: 之後您的目前帳號將完全無法使用。但您可以存取資料匯出與重新啟用。 followers: 此動作將會將目前帳號的所有跟隨者轉移至新帳號 only_redirect_html: 或者,您也可以僅於您的個人檔案中設定重新導向。 - other_data: 其他資料並不會自動轉移 + other_data: 不會自動移動其他資料(包括您的嘟文和您跟隨之帳號列表) redirect: 您目前的帳號將於個人檔案頁面新增重新導向公告,並會被排除於搜尋結果之外 moderation: title: 站務 @@ -1888,6 +1888,7 @@ zh-TW: errors: in_reply_not_found: 您嘗試回覆之嘟文似乎不存在。 quoted_status_not_found: 您嘗試引用之嘟文似乎不存在。 + quoted_user_not_mentioned: 無法於私訊嘟文中引用無提及之使用者。 over_character_limit: 已超過 %{max} 字的限制 pin_errors: direct: 無法釘選只有僅提及使用者可見之嘟文 diff --git a/config/navigation.rb b/config/navigation.rb index 4829f9efd2d..66fdfdfe585 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -12,7 +12,8 @@ SimpleNavigation::Configuration.run do |navigation| if: -> { Rails.configuration.x.mastodon.software_update_url.present? && current_user.can?(:view_devops) && SoftwareUpdate.urgent_pending? }, html: { class: 'warning' } - n.item :profile, safe_join([material_symbol('person'), t('settings.profile')]), settings_profile_path, if: -> { current_user.functional? && !self_destruct }, highlights_on: %r{/settings/profile|/settings/featured_tags|/settings/verification|/settings/privacy} + n.item :profile, safe_join([material_symbol('person'), t('settings.profile')]), settings_profile_path, if: -> { current_user.functional? && !self_destruct }, highlights_on: %r{/settings/profile|/settings/featured_tags|/settings/verification} + n.item :privacy, safe_join([material_symbol('globe'), t('privacy.title')]), settings_privacy_path, if: -> { current_user.functional? && !self_destruct }, highlights_on: %r{/settings/privacy} n.item :preferences, safe_join([material_symbol('settings'), t('settings.preferences')]), settings_preferences_path, if: -> { current_user.functional? && !self_destruct } do |s| s.item :appearance, safe_join([material_symbol('computer'), t('settings.appearance')]), settings_preferences_appearance_path diff --git a/config/puma.rb b/config/puma.rb index d34c14b425d..50f791b0440 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -12,8 +12,7 @@ else bind "tcp://#{ENV.fetch('BIND', '127.0.0.1')}:#{ENV.fetch('PORT', 3000)}" end -environment ENV.fetch('RAILS_ENV') { 'development' } -workers ENV.fetch('WEB_CONCURRENCY') { 2 }.to_i +workers ENV.fetch('WEB_CONCURRENCY') { 2 }.to_i preload_app! @@ -44,12 +43,6 @@ if ENV['MASTODON_PROMETHEUS_EXPORTER_ENABLED'] == 'true' end end -before_worker_boot do - ActiveSupport.on_load(:active_record) do - ActiveRecord::Base.establish_connection - end -end - plugin :tmp_restart set_remote_address(proxy_protocol: :v1) if ENV['PROXY_PROTO_V1'] == 'true' diff --git a/dist/mastodon-prometheus-exporter.service b/dist/mastodon-prometheus-exporter.service new file mode 100644 index 00000000000..28691b05757 --- /dev/null +++ b/dist/mastodon-prometheus-exporter.service @@ -0,0 +1,52 @@ +[Unit] +Description=Prometheus Metrics Exporter Server for Mastodon +Documentation="https://docs.joinmastodon.org/admin/config/#prometheus https://github.com/discourse/prometheus_exporter/?tab=readme-ov-file#exporter-process-configuration" +After=network.target + +[Service] +Type=simple +User=mastodon +WorkingDirectory=/home/mastodon/live +Environment="LD_PRELOAD=libjemalloc.so" +ExecStart=/home/mastodon/.rbenv/shims/bundle exec bin/prometheus_exporter -p 9394 -b 127.0.0.1 --prefix 'mastodon_' +ExecReload=/bin/kill -SIGUSR1 $MAINPID +TimeoutSec=15 +Restart=always +# Proc filesystem +ProcSubset=pid +ProtectProc=invisible +# Capabilities +CapabilityBoundingSet= +# Security +NoNewPrivileges=true +# Sandboxing +ProtectSystem=strict +PrivateTmp=true +PrivateDevices=true +PrivateUsers=true +ProtectHostname=true +ProtectKernelLogs=true +ProtectKernelModules=true +ProtectKernelTunables=true +ProtectControlGroups=true +RestrictAddressFamilies=AF_INET +RestrictAddressFamilies=AF_INET6 +RestrictAddressFamilies=AF_NETLINK +RestrictAddressFamilies=AF_UNIX +RestrictNamespaces=true +LockPersonality=true +RestrictRealtime=true +RestrictSUIDSGID=true +RemoveIPC=true +PrivateMounts=true +ProtectClock=true +# System Call Filtering +SystemCallArchitectures=native +SystemCallFilter=~@cpu-emulation @debug @keyring @ipc @mount @obsolete @privileged @setuid +SystemCallFilter=@chown +SystemCallFilter=pipe +SystemCallFilter=pipe2 +ReadWritePaths=/home/mastodon/live + +[Install] +WantedBy=multi-user.target diff --git a/dist/nginx.conf b/dist/nginx.conf index 8b7c68d2872..a421e000060 100644 --- a/dist/nginx.conf +++ b/dist/nginx.conf @@ -52,6 +52,7 @@ server { keepalive_timeout 70; sendfile on; client_max_body_size 99m; + proxy_read_timeout 120; ## Increase if you experience 504 errors uploading media root /home/mastodon/live/public; @@ -66,65 +67,53 @@ server { gzip_static on; location / { - try_files $uri @proxy; + add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; + try_files $uri @mastodon; } # If Docker is used for deployment and Rails serves static files, - # then needed must replace line `try_files $uri =404;` with `try_files $uri @proxy;`. - location = /sw.js { - add_header Cache-Control "public, max-age=604800, must-revalidate"; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; - } - - location ~ ^/assets/ { + # then needed uncomment line with `try_files $uri @mastodon;`. + location ^~ /assets/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; + # try_files $uri @mastodon; } - location ~ ^/avatars/ { + location ^~ /avatars/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/emoji/ { + location ^~ /emoji/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/headers/ { + location ^~ /headers/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/packs/ { + location ^~ /ocr/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/shortcuts/ { + location ^~ /packs/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/sounds/ { + location ^~ /sounds/ { add_header Cache-Control "public, max-age=2419200, must-revalidate"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - try_files $uri =404; } - location ~ ^/system/ { + location ^~ /system/ { add_header Cache-Control "public, max-age=2419200, immutable"; add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; add_header X-Content-Type-Options nosniff; add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; - try_files $uri =404; } location ^~ /api/v1/streaming { @@ -141,12 +130,10 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; - add_header Strict-Transport-Security "max-age=63072000; includeSubDomains"; - tcp_nodelay on; } - location @proxy { + location @mastodon { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/docker-compose.yml b/docker-compose.yml index 58d7704e415..3725010c13d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -59,7 +59,7 @@ services: web: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.8 + image: ghcr.io/mastodon/mastodon:v4.5.0 restart: always env_file: .env.production command: bundle exec puma -C config/puma.rb @@ -83,7 +83,7 @@ services: # build: # dockerfile: ./streaming/Dockerfile # context: . - image: ghcr.io/mastodon/mastodon-streaming:v4.4.8 + image: ghcr.io/mastodon/mastodon-streaming:v4.5.0 restart: always env_file: .env.production command: node ./streaming/index.js @@ -102,7 +102,7 @@ services: sidekiq: # You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes # build: . - image: ghcr.io/mastodon/mastodon:v4.4.8 + image: ghcr.io/mastodon/mastodon:v4.5.0 restart: always env_file: .env.production command: bundle exec sidekiq diff --git a/eslint.config.mjs b/eslint.config.mjs index 5942219cedc..a9dc9732bfc 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -180,10 +180,11 @@ export default tseslint.config([ 'vendor/**/*', 'streaming/**/*', '.bundle/**/*', + 'storybook-static/**/*', ]), react.configs.flat.recommended, react.configs.flat['jsx-runtime'], - reactHooks.configs['recommended-latest'], + reactHooks.configs.flat.recommended, jsxA11Y.flatConfigs.recommended, importPlugin.flatConfigs.react, // @ts-expect-error -- For some reason the formatjs package exports an empty object? @@ -290,6 +291,7 @@ export default tseslint.config([ 'react/jsx-tag-spacing': 'error', 'react/jsx-wrap-multilines': 'error', 'react/self-closing-comp': 'error', + 'react/button-has-type': 'error', }, }, { @@ -327,7 +329,7 @@ export default tseslint.config([ tseslint.configs.stylisticTypeChecked, react.configs.flat.recommended, react.configs.flat['jsx-runtime'], - reactHooks.configs['recommended-latest'], + reactHooks.configs.flat.recommended, jsxA11Y.flatConfigs.recommended, importPlugin.flatConfigs.react, importPlugin.flatConfigs.typescript, diff --git a/lib/mastodon/email_configuration_helper.rb b/lib/mastodon/email_configuration_helper.rb index af86472786a..be017a4a1ff 100644 --- a/lib/mastodon/email_configuration_helper.rb +++ b/lib/mastodon/email_configuration_helper.rb @@ -8,25 +8,23 @@ module Mastodon # `config/email.yml`) into the format that `ActionMailer` understands def convert_smtp_settings(config) enable_starttls = nil - enable_starttls_auto = nil case config[:enable_starttls] when 'always' - enable_starttls = true - when 'never' + enable_starttls = :always + when 'never', 'false' enable_starttls = false when 'auto' - enable_starttls_auto = true + enable_starttls = :auto else - enable_starttls_auto = config[:enable_starttls_auto] != 'false' + enable_starttls = config[:enable_starttls_auto] ? :auto : false unless config[:tls] || config[:ssl] end authentication = config[:authentication] == 'none' ? nil : (config[:authentication] || 'plain') - config.merge( + config.without(:enable_starttls_auto).merge( authentication:, - enable_starttls:, - enable_starttls_auto: + enable_starttls: ) end end diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index ae88b535170..9ac54d1b7c1 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,7 +9,7 @@ module Mastodon end def minor - 5 + 6 end def patch @@ -17,7 +17,7 @@ module Mastodon end def default_prerelease - 'beta.2' + 'alpha.1' end def prerelease diff --git a/package.json b/package.json index 16095441d87..3c50f111cdb 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@gamestdio/websocket": "^0.3.2", "@github/webauthn-json": "^2.1.1", "@optimize-lodash/rollup-plugin": "^5.0.2", - "@rails/ujs": "7.1.502", + "@rails/ujs": "7.1.600", "@react-spring/web": "^9.7.5", "@reduxjs/toolkit": "^2.0.1", "@use-gesture/react": "^10.3.1", @@ -101,7 +101,6 @@ "react-router-dom": "^5.3.4", "react-select": "^5.7.3", "react-sparklines": "^1.7.0", - "react-swipeable-views": "^0.14.0", "react-textarea-autosize": "^8.4.1", "react-toggle": "^4.1.3", "redux-immutable": "^4.0.0", @@ -133,10 +132,10 @@ "devDependencies": { "@eslint/js": "^9.23.0", "@formatjs/cli": "^6.1.1", - "@storybook/addon-a11y": "^9.1.1", - "@storybook/addon-docs": "^9.1.1", - "@storybook/addon-vitest": "^9.1.1", - "@storybook/react-vite": "^9.1.1", + "@storybook/addon-a11y": "^10.0.2", + "@storybook/addon-docs": "^10.0.2", + "@storybook/addon-vitest": "^10.0.2", + "@storybook/react-vite": "^10.0.2", "@testing-library/dom": "^10.4.1", "@testing-library/react": "^16.3.0", "@types/debug": "^4", @@ -158,41 +157,42 @@ "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", "@types/react-sparklines": "^1.7.2", - "@types/react-swipeable-views": "^0.13.1", "@types/react-test-renderer": "^18.0.0", "@types/react-toggle": "^4.0.3", "@types/redux-immutable": "^4.0.3", "@types/requestidlecallback": "^0.3.5", - "@vitest/browser": "^3.2.4", - "@vitest/coverage-v8": "^3.2.4", - "@vitest/ui": "^3.2.4", + "@vitest/browser": "^4.0.5", + "@vitest/browser-playwright": "^4.0.5", + "@vitest/coverage-v8": "^4.0.5", + "@vitest/ui": "^4.0.5", "chromatic": "^13.1.3", "eslint": "^9.23.0", "eslint-import-resolver-typescript": "^4.2.5", "eslint-plugin-formatjs": "^5.3.1", "eslint-plugin-import": "~2.32.0", - "eslint-plugin-jsdoc": "^54.0.0", + "eslint-plugin-jsdoc": "^61.1.11", "eslint-plugin-jsx-a11y": "~6.10.2", "eslint-plugin-promise": "~7.2.1", "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-storybook": "^9.0.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-storybook": "^10.0.2", "fake-indexeddb": "^6.0.1", "globals": "^16.0.0", "husky": "^9.0.11", - "lint-staged": "^16.0.0", + "lint-staged": "^16.2.6", "msw": "^2.10.2", "msw-storybook-addon": "^2.0.5", - "playwright": "^1.54.1", + "playwright": "^1.56.1", "prettier": "^3.3.3", "react-test-renderer": "^18.2.0", - "storybook": "^9.1.1", + "storybook": "^10.0.2", "stylelint": "^16.19.1", "stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-standard-scss": "^16.0.0", "typescript": "~5.9.0", "typescript-eslint": "^8.45.0", - "vitest": "^3.2.4" + "typescript-plugin-css-modules": "^5.2.0", + "vitest": "^4.0.5" }, "resolutions": { "@types/react": "^18.2.7", diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index dab6aadbaab..d9967611692 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -57,6 +57,17 @@ RSpec.describe FollowerAccountsController do ) end + context 'when account hides their network' do + before { alice.update(hide_collections: true) } + + it 'returns forbidden response' do + expect(response) + .to have_http_status(403) + expect(response.parsed_body) + .to include(error: /forbidden/i) + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index 666c655d743..576d25d93c8 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -57,6 +57,17 @@ RSpec.describe FollowingAccountsController do ) end + context 'when account hides their network' do + before { alice.update(hide_collections: true) } + + it 'returns forbidden response' do + expect(response) + .to have_http_status(403) + expect(response.parsed_body) + .to include(error: /forbidden/i) + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index b829f3a5ad6..d905f68d8f1 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -149,18 +149,17 @@ RSpec.describe ActivityPub::Activity::Update do shared_examples 'updates counts' do it 'updates the reblog count' do - expect(status.untrusted_reblogs_count).to eq reblogs + expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs) end it 'updates the favourites count' do - expect(status.untrusted_favourites_count).to eq favourites + expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites) end end context 'with an implicit update' do before do status.update!(uri: ActivityPub::TagManager.instance.uri_for(status)) - subject.perform end it_behaves_like 'updates counts' @@ -173,11 +172,89 @@ RSpec.describe ActivityPub::Activity::Update do before do status.update!(uri: ActivityPub::TagManager.instance.uri_for(status)) - subject.perform end it_behaves_like 'updates counts' end end + + context 'with an Article object' do + let(:updated) { nil } + let(:favourites) { 50 } + let(:reblogs) { 100 } + + let!(:status) do + Fabricate( + :status, + uri: 'https://example.com/statuses/article', + account: sender, + text: "

Future of the Fediverse

\n\n

Guest article by John Mastodon

The fediverse is great reading this you will find out why!

" + ) + end + + let(:json) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'foo', + type: 'Update', + actor: sender.uri, + object: { + type: 'Article', + id: status.uri, + name: 'Future of the Fediverse', + summary: '

Guest article by Jane Mastodon

The fediverse is great reading this you will find out why!

', + content: 'Foo', + updated: updated, + likes: { + id: "#{status.uri}/likes", + type: 'Collection', + totalItems: favourites, + }, + shares: { + id: "#{status.uri}/shares", + type: 'Collection', + totalItems: reblogs, + }, + }, + }.with_indifferent_access + end + + shared_examples 'updates counts' do + it 'updates the reblog count' do + expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs) + end + + it 'updates the favourites count' do + expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites) + end + end + + context 'with an implicit update' do + before do + status.update!(uri: ActivityPub::TagManager.instance.uri_for(status)) + end + + it_behaves_like 'updates counts' + end + + context 'with an explicit update' do + let(:favourites) { 150 } + let(:reblogs) { 200 } + let(:updated) { Time.now.utc.iso8601 } + + before do + status.update!(uri: ActivityPub::TagManager.instance.uri_for(status)) + end + + it_behaves_like 'updates counts' + + it 'changes the contents as expected' do + expect { subject.perform } + .to(change { status.reload.text }) + + expect(status.text).to start_with("

Future of the Fediverse

\n\n

Guest article by Jane Mastodon

The fediverse is great reading this you will find out why!

") + end + end + end end end diff --git a/spec/lib/mastodon/email_configuration_helper_spec.rb b/spec/lib/mastodon/email_configuration_helper_spec.rb index db513672f06..2894699d057 100644 --- a/spec/lib/mastodon/email_configuration_helper_spec.rb +++ b/spec/lib/mastodon/email_configuration_helper_spec.rb @@ -21,8 +21,9 @@ RSpec.describe Mastodon::EmailConfigurationHelper do base_configuration.merge({ enable_starttls: 'always' }) end - it 'converts this to `true`' do - expect(converted_settings[:enable_starttls]).to be true + it 'converts this to `:always`' do + expect(converted_settings[:enable_starttls]).to eq :always + expect(converted_settings[:enable_starttls_auto]).to be_nil end end @@ -33,6 +34,7 @@ RSpec.describe Mastodon::EmailConfigurationHelper do it 'converts this to `false`' do expect(converted_settings[:enable_starttls]).to be false + expect(converted_settings[:enable_starttls_auto]).to be_nil end end @@ -41,28 +43,43 @@ RSpec.describe Mastodon::EmailConfigurationHelper do base_configuration.merge({ enable_starttls: 'auto' }) end - it 'sets `enable_starttls_auto` instead' do - expect(converted_settings[:enable_starttls]).to be_nil - expect(converted_settings[:enable_starttls_auto]).to be true + it 'sets `enable_starttls` to `:auto`' do + expect(converted_settings[:enable_starttls]).to eq :auto + expect(converted_settings[:enable_starttls_auto]).to be_nil end end context 'when `enable_starttls` is unset' do - context 'when `enable_starttls_auto` is unset' do - let(:configuration) { base_configuration } + context 'when `enable_starttls_auto` is true' do + let(:configuration) do + base_configuration.merge({ enable_starttls_auto: true }) + end - it 'sets `enable_starttls_auto` to `true`' do - expect(converted_settings[:enable_starttls_auto]).to be true + it 'sets `enable_starttls` to `:auto`' do + expect(converted_settings[:enable_starttls]).to eq :auto + expect(converted_settings[:enable_starttls_auto]).to be_nil end end - context 'when `enable_starttls_auto` is set to "false"' do + context 'when `tls` is set to true' do let(:configuration) do - base_configuration.merge({ enable_starttls_auto: 'false' }) + base_configuration.merge({ tls: true }) end - it 'sets `enable_starttls_auto` to `false`' do - expect(converted_settings[:enable_starttls_auto]).to be false + it 'sets `enable_starttls` to `nil`' do + expect(converted_settings[:enable_starttls]).to be_nil + expect(converted_settings[:enable_starttls_auto]).to be_nil + end + end + + context 'when `enable_starttls_auto` is set to false' do + let(:configuration) do + base_configuration.merge({ enable_starttls_auto: false }) + end + + it 'sets `enable_starttls` to `false`' do + expect(converted_settings[:enable_starttls]).to be false + expect(converted_settings[:enable_starttls_auto]).to be_nil end end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 82021cd3d02..153de1ef1c8 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -27,6 +27,7 @@ RSpec.describe UserMailer do address: 'localhost', port: 25, authentication: 'none', + enable_starttls_auto: true, } end @@ -44,8 +45,7 @@ RSpec.describe UserMailer do address: 'localhost', port: 25, authentication: nil, - enable_starttls: nil, - enable_starttls_auto: true, + enable_starttls: :auto, }) end end diff --git a/spec/requests/api/v1/statuses/pins_spec.rb b/spec/requests/api/v1/statuses/pins_spec.rb index 05d8f570cc8..66ed1510a48 100644 --- a/spec/requests/api/v1/statuses/pins_spec.rb +++ b/spec/requests/api/v1/statuses/pins_spec.rb @@ -57,6 +57,21 @@ RSpec.describe 'Pins' do end end + context 'when the account is already at MAX status pins' do + before { StatusPinValidator::PIN_LIMIT.times { Fabricate(:status_pin, account: user.account) } } + + it 'returns http unprocessable entity' do + subject + + expect(response) + .to have_http_status(422) + expect(response.media_type) + .to eq('application/json') + expect(response.parsed_body) + .to include(error: /already pinned the maximum/) + end + end + context 'when the status does not exist' do it 'returns http not found' do post '/api/v1/statuses/-1/pin', headers: headers diff --git a/spec/requests/api/v1/statuses/translations_spec.rb b/spec/requests/api/v1/statuses/translations_spec.rb index e316bd451b0..e95ec1b101a 100644 --- a/spec/requests/api/v1/statuses/translations_spec.rb +++ b/spec/requests/api/v1/statuses/translations_spec.rb @@ -28,20 +28,41 @@ RSpec.describe 'API V1 Statuses Translations' do context 'with an oauth token' do describe 'POST /api/v1/statuses/:status_id/translate' do - let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') } + subject { post "/api/v1/statuses/#{status.id}/translate", headers: headers } before do translation = TranslationService::Translation.new(text: 'Hello') service = instance_double(TranslationService::DeepL, translate: [translation]) allow(TranslationService).to receive_messages(configured?: true, configured: service) Rails.cache.write('translation_service/languages', { 'es' => ['en'] }) - post "/api/v1/statuses/#{status.id}/translate", headers: headers end - it 'returns http success' do - expect(response).to have_http_status(200) - expect(response.content_type) - .to start_with('application/json') + context 'with a public status' do + let(:status) { Fabricate(:status, account: user.account, text: 'Hola', language: 'es') } + + it 'returns http success' do + subject + + expect(response) + .to have_http_status(200) + expect(response.media_type) + .to eq('application/json') + end + end + + context 'with a private status' do + let(:status) { Fabricate(:status, visibility: :private, account: user.account, text: 'Hola', language: 'es') } + + it 'returns http forbidden' do + subject + + expect(response) + .to have_http_status(403) + expect(response.media_type) + .to eq('application/json') + expect(response.parsed_body) + .to include(error: /not allowed/) + end end end end diff --git a/spec/requests/api/v1/statuses_spec.rb b/spec/requests/api/v1/statuses_spec.rb index ed41e54206f..1f431f79d85 100644 --- a/spec/requests/api/v1/statuses_spec.rb +++ b/spec/requests/api/v1/statuses_spec.rb @@ -133,6 +133,21 @@ RSpec.describe '/api/v1/statuses' do expect(response).to have_http_status(200) expect(response.content_type) .to start_with('application/json') + expect(response.headers['Mastodon-Async-Refresh']).to be_nil + end + + context 'with a remote status' do + let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), created_at: 1.hour.ago, updated_at: 1.hour.ago) } + + it 'returns http success and queues discovery of new posts' do + expect { get "/api/v1/statuses/#{status.id}/context", headers: headers } + .to enqueue_sidekiq_job(ActivityPub::FetchAllRepliesWorker) + + expect(response).to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + expect(response.headers['Mastodon-Async-Refresh']).to match(/result_count=0/) + end end end @@ -228,7 +243,7 @@ RSpec.describe '/api/v1/statuses' do end context 'with a self-quote post' do - let(:quoted_status) { Fabricate(:status, account: user.account) } + let!(:quoted_status) { Fabricate(:status, account: user.account) } let(:params) do { status: 'Hello world, this is a self-quote', @@ -237,7 +252,48 @@ RSpec.describe '/api/v1/statuses' do end it 'returns a quote post, as well as rate limit headers', :aggregate_failures do - subject + expect { subject }.to change(user.account.statuses, :count).by(1) + + expect(response).to have_http_status(200) + expect(response.content_type) + .to start_with('application/json') + expect(response.parsed_body[:quote]).to be_present + expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s + expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s + end + end + + context 'with a quote to a non-mentioned user in a Private Mention' do + let!(:quoted_status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let(:params) do + { + status: 'Hello, this is a quote', + quoted_status_id: quoted_status.id, + visibility: :direct, + } + end + + it 'returns an error and does not create a post', :aggregate_failures do + expect { subject }.to_not change(user.account.statuses, :count) + + expect(response).to have_http_status(422) + expect(response.content_type) + .to start_with('application/json') + end + end + + context 'with a quote to a mentioned user in a Private Mention' do + let!(:quoted_status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16) } + let(:params) do + { + status: "Hello @#{quoted_status.account.acct}, this is a quote", + quoted_status_id: quoted_status.id, + visibility: :direct, + } + end + + it 'returns a quote post, as well as rate limit headers', :aggregate_failures do + expect { subject }.to change(user.account.statuses, :count).by(1) expect(response).to have_http_status(200) expect(response.content_type) diff --git a/streaming/database.js b/streaming/database.js index 553c9149cc0..9dd7a97cfe7 100644 --- a/streaming/database.js +++ b/streaming/database.js @@ -65,7 +65,7 @@ export function configFromEnv(env, environment) { if (typeof parsedUrl.ssl === 'boolean') { baseConfig.ssl = parsedUrl.ssl; } else if (typeof parsedUrl.ssl === 'object' && !Array.isArray(parsedUrl.ssl) && parsedUrl.ssl !== null) { - /** @type {Record} */ + /** @type {Record} */ const sslOptions = parsedUrl.ssl; baseConfig.ssl = {}; diff --git a/streaming/index.js b/streaming/index.js index 952b4584ab9..42c6bd8471b 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -19,6 +19,7 @@ import * as Redis from './redis.js'; import { isTruthy, normalizeHashtag, firstParam } from './utils.js'; const environment = process.env.NODE_ENV || 'development'; +const PERMISSION_VIEW_FEEDS = 0x0000000000100000; // Correctly detect and load .env or .env.production file based on environment: const dotenvFile = environment === 'production' ? '.env.production' : '.env'; @@ -44,6 +45,18 @@ initializeLogLevel(process.env, environment); * @property {string[]} scopes * @property {string} accountId * @property {string[]} chosenLanguages + * @property {number} permissions + */ + +/** + * @typedef {http.IncomingMessage & ResolvedAccount & { + * path: string + * query: Record + * remoteAddress?: string + * cachedFilters: unknown + * scopes: string[] + * necessaryScopes: string[] + * }} Request */ @@ -52,8 +65,8 @@ initializeLogLevel(process.env, environment); * from redis and when receiving a message from a client over a websocket * connection, this is why it accepts a `req` argument. * @param {string} json - * @param {any?} req - * @returns {Object.|null} + * @param {Request?} req + * @returns {Object.|null} */ const parseJSON = (json, req) => { try { @@ -170,6 +183,7 @@ const startServer = async () => { let resolvedAccount; try { + // @ts-expect-error resolvedAccount = await accountFromRequest(request); } catch (err) { // Unfortunately for using the on('upgrade') setup, we need to manually @@ -220,7 +234,7 @@ const startServer = async () => { }); /** - * @type {Object.): void>>} + * @type {Object.): void>>} */ const subs = {}; @@ -338,7 +352,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {string[]} necessaryScopes * @returns {boolean} */ @@ -347,11 +361,11 @@ const startServer = async () => { /** * @param {string} token - * @param {any} req + * @param {Request} req * @returns {Promise} */ const accountFromToken = async (token, req) => { - const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id INNER JOIN accounts ON accounts.id = users.account_id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE AND accounts.suspended_at IS NULL LIMIT 1', [token]); + const result = await pgPool.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes, COALESCE(user_roles.permissions, 0) AS permissions FROM oauth_access_tokens INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id INNER JOIN accounts ON accounts.id = users.account_id LEFT OUTER JOIN user_roles ON user_roles.id = users.role_id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL AND users.disabled IS FALSE AND accounts.suspended_at IS NULL LIMIT 1', [token]); if (result.rows.length === 0) { throw new AuthenticationError('Invalid access token'); @@ -367,17 +381,18 @@ const startServer = async () => { scopes: result.rows[0].scopes.split(' '), accountId: result.rows[0].account_id, chosenLanguages: result.rows[0].chosen_languages, + permissions: result.rows[0].permissions, }; }; /** - * @param {any} req + * @param {Request} req * @returns {Promise} */ const accountFromRequest = (req) => new Promise((resolve, reject) => { const authorization = req.headers.authorization; - const location = url.parse(req.url, true); - const accessToken = location.query.access_token || req.headers['sec-websocket-protocol']; + const location = req.url ? url.parse(req.url, true) : undefined; + const accessToken = location?.query.access_token || req.headers['sec-websocket-protocol']; if (!authorization && !accessToken) { reject(new AuthenticationError('Missing access token')); @@ -386,11 +401,12 @@ const startServer = async () => { const token = authorization ? authorization.replace(/^Bearer /, '') : accessToken; + // @ts-expect-error resolve(accountFromToken(token, req)); }); /** - * @param {any} req + * @param {Request} req * @returns {string|undefined} */ const channelNameFromPath = req => { @@ -422,7 +438,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} logger * @param {string|undefined} channelName * @returns {Promise.} @@ -460,7 +476,7 @@ const startServer = async () => { */ /** - * @param {any} req + * @param {Request} req * @param {SystemMessageHandlers} eventHandlers * @returns {SubscriptionListener} */ @@ -485,7 +501,7 @@ const startServer = async () => { }; /** - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {http.OutgoingMessage} res */ const subscribeHttpToSystemChannel = (req, res) => { @@ -512,8 +528,8 @@ const startServer = async () => { }; /** - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @param {function(Error=): void} next */ const authenticationMiddleware = (req, res, next) => { @@ -542,8 +558,8 @@ const startServer = async () => { /** * @param {Error} err - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @param {function(Error=): void} next */ const errorMiddleware = (err, req, res, next) => { @@ -561,16 +577,15 @@ const startServer = async () => { }; /** - * @param {any[]} arr + * @param {string[]} arr * @param {number=} shift * @returns {string} */ - // @ts-ignore const placeholders = (arr, shift = 0) => arr.map((_, i) => `$${i + 1 + shift}`).join(', '); /** * @param {string} listId - * @param {any} req + * @param {Request} req * @returns {Promise.} */ const authorizeListAccess = async (listId, req) => { @@ -583,17 +598,55 @@ const startServer = async () => { } }; + /** + * @param {string} kind + * @param {ResolvedAccount} account + * @returns {Promise.<{ localAccess: boolean, remoteAccess: boolean }>} + */ + const getFeedAccessSettings = async (kind, account) => { + const access = { localAccess: true, remoteAccess: true }; + + if (account.permissions & PERMISSION_VIEW_FEEDS) { + return access; + } + + let localAccessVar, remoteAccessVar; + + if (kind === 'hashtag') { + localAccessVar = 'local_topic_feed_access'; + remoteAccessVar = 'remote_topic_feed_access'; + } else { + localAccessVar = 'local_live_feed_access'; + remoteAccessVar = 'remote_live_feed_access'; + } + + const result = await pgPool.query('SELECT var, value FROM settings WHERE var IN ($1, $2)', [localAccessVar, remoteAccessVar]); + + result.rows.forEach((row) => { + if (row.var === localAccessVar) { + access.localAccess = row.value !== "--- disabled\n"; + } else { + access.remoteAccess = row.value !== "--- disabled\n"; + } + }); + + return access; + }; + /** * @param {string[]} channelIds - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} log * @param {function(string, string): void} output * @param {undefined | function(string[], SubscriptionListener): void} attachCloseHandler * @param {'websocket' | 'eventsource'} destinationType - * @param {boolean=} needsFiltering + * @param {Object} options + * @param {boolean} options.needsFiltering + * @param {boolean=} options.filterLocal + * @param {boolean=} options.filterRemote * @returns {SubscriptionListener} */ - const streamFrom = (channelIds, req, log, output, attachCloseHandler, destinationType, needsFiltering = false) => { + const streamFrom = (channelIds, req, log, output, attachCloseHandler, destinationType, { needsFiltering, filterLocal, filterRemote } = { needsFiltering: false, filterLocal: false, filterRemote: false }) => { log.info({ channelIds }, `Starting stream`); /** @@ -634,6 +687,7 @@ const startServer = async () => { // The channels that need filtering are determined in the function // `channelNameToIds` defined below: if (!needsFiltering || (event !== 'update' && event !== 'status.update')) { + // @ts-expect-error transmit(event, payload); return; } @@ -641,8 +695,16 @@ const startServer = async () => { // The rest of the logic from here on in this function is to handle // filtering of statuses: + const localPayload = payload.account.username === payload.account.acct; + if (localPayload ? filterLocal : filterRemote) { + log.debug(`Message ${payload.id} filtered by feed settings`); + return; + } + // Filter based on language: + // @ts-expect-error if (Array.isArray(req.chosenLanguages) && req.chosenLanguages.indexOf(payload.language) === -1) { + // @ts-expect-error log.debug(`Message ${payload.id} filtered by language (${payload.language})`); return; } @@ -654,8 +716,9 @@ const startServer = async () => { } // Filter based on domain blocks, blocks, mutes, or custom filters: - // @ts-ignore + // @ts-expect-error const targetAccountIds = [payload.account.id].concat(payload.mentions.map(item => item.id)); + // @ts-expect-error const accountDomain = payload.account.acct.split('@')[1]; // TODO: Move this logic out of the message handling loop @@ -666,7 +729,7 @@ const startServer = async () => { } const queries = [ - // @ts-ignore + // @ts-expect-error client.query(`SELECT 1 FROM blocks WHERE (account_id = $1 AND target_account_id IN (${placeholders(targetAccountIds, 2)})) @@ -675,17 +738,19 @@ const startServer = async () => { SELECT 1 FROM mutes WHERE account_id = $1 - AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, payload.account.id].concat(targetAccountIds)), + AND target_account_id IN (${placeholders(targetAccountIds, 2)})`, [req.accountId, payload. + // @ts-expect-error + account.id].concat(targetAccountIds)), ]; if (accountDomain) { - // @ts-ignore + // @ts-expect-error queries.push(client.query('SELECT 1 FROM account_domain_blocks WHERE account_id = $1 AND domain = $2', [req.accountId, accountDomain])); } - // @ts-ignore + // @ts-expect-error if (!payload.filtered && !req.cachedFilters) { - // @ts-ignore + // @ts-expect-error queries.push(client.query('SELECT filter.id AS id, filter.phrase AS title, filter.context AS context, filter.expires_at AS expires_at, filter.action AS filter_action, keyword.keyword AS keyword, keyword.whole_word AS whole_word FROM custom_filter_keywords keyword JOIN custom_filters filter ON keyword.custom_filter_id = filter.id WHERE filter.account_id = $1 AND (filter.expires_at IS NULL OR filter.expires_at > NOW())', [req.accountId])); } @@ -694,6 +759,7 @@ const startServer = async () => { // Handling blocks & mutes and domain blocks: If one of those applies, // then we don't transmit the payload of the event to the client + // @ts-expect-error if (values[0].rows.length > 0 || (accountDomain && values[1].rows.length > 0)) { return; } @@ -710,9 +776,9 @@ const startServer = async () => { // TODO: Move this logic out of the message handling lifecycle // @ts-ignore if (!req.cachedFilters) { + // @ts-expect-error const filterRows = values[accountDomain ? 2 : 1].rows; - // @ts-ignore req.cachedFilters = filterRows.reduce((cache, filter) => { if (cache[filter.id]) { cache[filter.id].keywords.push([filter.keyword, filter.whole_word]); @@ -742,9 +808,9 @@ const startServer = async () => { // needs to be done in a separate loop as the database returns one // filterRow per keyword, so we need all the keywords before // constructing the regular expression - // @ts-ignore + // @ts-expect-error Object.keys(req.cachedFilters).forEach((key) => { - // @ts-ignore + // @ts-expect-error req.cachedFilters[key].regexp = new RegExp(req.cachedFilters[key].keywords.map(([keyword, whole_word]) => { let expr = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); @@ -765,16 +831,14 @@ const startServer = async () => { // Apply cachedFilters against the payload, constructing a // `filter_results` array of FilterResult entities - // @ts-ignore if (req.cachedFilters) { const status = payload; // TODO: Calculate searchableContent in Ruby on Rails: - // @ts-ignore + // @ts-expect-error const searchableContent = ([status.spoiler_text || '', status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(//g, '\n').replace(/<\/p>

/g, '\n\n'); const searchableTextContent = JSDOM.fragment(searchableContent).textContent; const now = new Date(); - // @ts-ignore const filter_results = Object.values(req.cachedFilters).reduce((results, cachedFilter) => { // Check the filter hasn't expired before applying: if (cachedFilter.expires_at !== null && cachedFilter.expires_at < now) { @@ -834,8 +898,8 @@ const startServer = async () => { }; /** - * @param {any} req - * @param {any} res + * @param {Request} req + * @param {http.ServerResponse} res * @returns {function(string, string): void} */ const streamToHttp = (req, res) => { @@ -877,7 +941,7 @@ const startServer = async () => { }; /** - * @param {any} req + * @param {Request} req * @param {function(): void} [closeHandler] * @returns {function(string[], SubscriptionListener): void} */ @@ -927,10 +991,13 @@ const startServer = async () => { app.use(api); + // @ts-expect-error api.use(authenticationMiddleware); + // @ts-expect-error api.use(errorMiddleware); - api.get('/api/v1/streaming/*', (req, res) => { + api.get('/api/v1/streaming/*splat', (req, res) => { + // @ts-expect-error const channelName = channelNameFromPath(req); // FIXME: In theory we'd never actually reach here due to @@ -941,12 +1008,15 @@ const startServer = async () => { return; } + // @ts-expect-error channelNameToIds(req, channelName, req.query).then(({ channelIds, options }) => { + // @ts-expect-error const onSend = streamToHttp(req, res); + // @ts-expect-error const onEnd = streamHttpEnd(req, subscriptionHeartbeat(channelIds)); // @ts-ignore - streamFrom(channelIds, req, req.log, onSend, onEnd, 'eventsource', options.needsFiltering); + streamFrom(channelIds, req, req.log, onSend, onEnd, 'eventsource', options); }).catch(err => { const {statusCode, errorMessage } = extractErrorStatusAndMessage(err); @@ -965,7 +1035,7 @@ const startServer = async () => { */ /** - * @param {any} req + * @param {Request} req * @returns {string[]} */ const channelsForUserStream = req => { @@ -979,12 +1049,28 @@ const startServer = async () => { }; /** - * @param {any} req + * @param {Request} req * @param {string} name * @param {StreamParams} params - * @returns {Promise.<{ channelIds: string[], options: { needsFiltering: boolean } }>} + * @returns {Promise.<{ channelIds: string[], options: { needsFiltering: boolean, filterLocal?: boolean, filterRemote?: boolean } }>} */ const channelNameToIds = (req, name, params) => new Promise((resolve, reject) => { + /** + * @param {string} feedKind + * @param {string} channelId + * @param {{ needsFiltering: boolean }} options + */ + const resolveFeed = (feedKind, channelId, options) => { + getFeedAccessSettings(feedKind, req).then(({ localAccess, remoteAccess }) => { + resolve({ + channelIds: [channelId], + options: { ...options, filterLocal: !localAccess, filterRemote: !remoteAccess }, + }); + }).catch(() => { + reject(new Error('Error getting feed access settings')); + }); + }; + switch (name) { case 'user': resolve({ @@ -1001,46 +1087,22 @@ const startServer = async () => { break; case 'public': - resolve({ - channelIds: ['timeline:public'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public', { needsFiltering: true }); break; case 'public:local': - resolve({ - channelIds: ['timeline:public:local'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public:local', { needsFiltering: true }); break; case 'public:remote': - resolve({ - channelIds: ['timeline:public:remote'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public:remote', { needsFiltering: true }); break; case 'public:media': - resolve({ - channelIds: ['timeline:public:media'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public:media', { needsFiltering: true }); break; case 'public:local:media': - resolve({ - channelIds: ['timeline:public:local:media'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public:local:media', { needsFiltering: true }); break; case 'public:remote:media': - resolve({ - channelIds: ['timeline:public:remote:media'], - options: { needsFiltering: true }, - }); - + resolveFeed('public', 'timeline:public:remote:media', { needsFiltering: true }); break; case 'direct': resolve({ @@ -1052,24 +1114,20 @@ const startServer = async () => { case 'hashtag': if (!params.tag) { reject(new RequestError('Missing tag name parameter')); - } else { - resolve({ - channelIds: [`timeline:hashtag:${normalizeHashtag(params.tag)}`], - options: { needsFiltering: true }, - }); + return; } + resolveFeed('hashtag', `timeline:hashtag:${normalizeHashtag(params.tag)}`, { needsFiltering: true }); + break; case 'hashtag:local': if (!params.tag) { reject(new RequestError('Missing tag name parameter')); - } else { - resolve({ - channelIds: [`timeline:hashtag:${normalizeHashtag(params.tag)}:local`], - options: { needsFiltering: true }, - }); + return; } + resolveFeed('hashtag', `timeline:hashtag:${normalizeHashtag(params.tag)}:local`, { needsFiltering: true }); + break; case 'list': if (!params.list) { @@ -1110,7 +1168,7 @@ const startServer = async () => { /** * @typedef WebSocketSession * @property {import('ws').WebSocket & { isAlive: boolean}} websocket - * @property {http.IncomingMessage & ResolvedAccount} request + * @property {Request} request * @property {import('pino').Logger} logger * @property {Object.} subscriptions */ @@ -1132,7 +1190,7 @@ const startServer = async () => { const onSend = streamToWs(request, websocket, streamNameFromChannelName(channelName, params)); const stopHeartbeat = subscriptionHeartbeat(channelIds); - const listener = streamFrom(channelIds, request, logger, onSend, undefined, 'websocket', options.needsFiltering); + const listener = streamFrom(channelIds, request, logger, onSend, undefined, 'websocket', options); metrics.connectedChannels.labels({ type: 'websocket', channel: channelName }).inc(); @@ -1236,7 +1294,7 @@ const startServer = async () => { /** * @param {import('ws').WebSocket & { isAlive: boolean }} ws - * @param {http.IncomingMessage & ResolvedAccount} req + * @param {Request} req * @param {import('pino').Logger} log */ function onConnection(ws, req, log) { @@ -1303,9 +1361,19 @@ const startServer = async () => { const { type, stream, ...params } = json; if (type === 'subscribe') { - subscribeWebsocketToChannel(session, firstParam(stream), params); + subscribeWebsocketToChannel( + session, + // @ts-expect-error + firstParam(stream), + params + ); } else if (type === 'unsubscribe') { - unsubscribeWebsocketFromChannel(session, firstParam(stream), params); + unsubscribeWebsocketFromChannel( + session, + // @ts-expect-error + firstParam(stream), + params + ); } else { // Unknown action type } @@ -1325,13 +1393,13 @@ const startServer = async () => { setInterval(() => { wss.clients.forEach(ws => { - // @ts-ignore + // @ts-expect-error if (ws.isAlive === false) { ws.terminate(); return; } - // @ts-ignore + // @ts-expect-error ws.isAlive = false; ws.ping('', false); }); @@ -1361,14 +1429,16 @@ const startServer = async () => { }; /** - * @param {any} server + * @param {http.Server} server * @param {function(string): void} [onSuccess] */ const attachServerWithConfig = (server, onSuccess) => { if (process.env.SOCKET) { server.listen(process.env.SOCKET, () => { if (onSuccess) { + // @ts-expect-error fs.chmodSync(server.address(), 0o666); + // @ts-expect-error onSuccess(server.address()); } }); @@ -1383,6 +1453,7 @@ const attachServerWithConfig = (server, onSuccess) => { server.listen(port, bind, () => { if (onSuccess) { + // @ts-expect-error onSuccess(`${server.address().address}:${server.address().port}`); } }); diff --git a/streaming/logging.js b/streaming/logging.js index e1c552c22ed..61946b622c3 100644 --- a/streaming/logging.js +++ b/streaming/logging.js @@ -100,7 +100,7 @@ export function createWebsocketLogger(request, resolvedAccount) { /** * Initializes the log level based on the environment - * @param {Object} env + * @param {Object} env * @param {string} environment */ export function initializeLogLevel(env, environment) { diff --git a/streaming/metrics.js b/streaming/metrics.js index 263339a1caf..d84aa0c28db 100644 --- a/streaming/metrics.js +++ b/streaming/metrics.js @@ -9,7 +9,7 @@ import metrics from 'prom-client'; * @property {metrics.Gauge} redisSubscriptions * @property {metrics.Counter} redisMessagesReceived * @property {metrics.Counter<"type">} messagesSent - * @property {import('express').RequestHandler<{}>} requestHandler + * @property {import('express').RequestHandler} requestHandler */ /** @@ -93,7 +93,7 @@ export function setupMetrics(channels, pgPool) { messagesSent.inc({ type: 'eventsource' }, 0); /** - * @type {import('express').RequestHandler<{}>} + * @type {import('express').RequestHandler} */ const requestHandler = (req, res) => { metrics.register.metrics().then((output) => { diff --git a/streaming/package.json b/streaming/package.json index 7df035d6e7e..90dd5dd0cf3 100644 --- a/streaming/package.json +++ b/streaming/package.json @@ -19,13 +19,13 @@ "dependencies": { "cors": "^2.8.5", "dotenv": "^16.0.3", - "express": "^4.18.2", + "express": "^5.1.0", "ioredis": "^5.3.2", "jsdom": "^27.0.0", "pg": "^8.5.0", "pg-connection-string": "^2.6.0", - "pino": "^9.0.0", - "pino-http": "^10.0.0", + "pino": "^10.0.0", + "pino-http": "^11.0.0", "prom-client": "^15.0.0", "uuid": "^13.0.0", "ws": "^8.12.1" @@ -33,7 +33,7 @@ "devDependencies": { "@eslint/js": "^9.23.0", "@types/cors": "^2.8.16", - "@types/express": "^4.17.17", + "@types/express": "^5.0.5", "@types/pg": "^8.6.6", "@types/ws": "^8.5.9", "globals": "^16.0.0", diff --git a/streaming/redis.js b/streaming/redis.js index 040246fda93..e8f28c0f90c 100644 --- a/streaming/redis.js +++ b/streaming/redis.js @@ -6,6 +6,7 @@ import { parseIntFromEnvValue } from './utils.js'; * @typedef RedisConfiguration * @property {string|undefined} url * @property {import('ioredis').RedisOptions} options + * @property {string|undefined} namespace */ /** diff --git a/streaming/utils.js b/streaming/utils.js index 47c63dd4cae..dd5e82c67ca 100644 --- a/streaming/utils.js +++ b/streaming/utils.js @@ -13,11 +13,15 @@ const FALSE_VALUES = [ ]; /** - * @param {any} value + * @typedef {typeof FALSE_VALUES[number]} FalseValue + */ + +/** + * @param {unknown} value * @returns {boolean} */ export function isTruthy(value) { - return value && !FALSE_VALUES.includes(value); + return !!value && !FALSE_VALUES.includes(/** @type {FalseValue} */ (value)); } /** diff --git a/tsconfig.json b/tsconfig.json index 2b981b67abe..db727baf185 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,8 @@ "mastodon/*": ["app/javascript/mastodon/*"], "images/*": ["app/javascript/images/*"], "styles/*": ["app/javascript/styles/*"] - } + }, + "plugins": [{ "name": "typescript-plugin-css-modules" }] }, "include": [ "vite.config.mts", diff --git a/vite.config.mts b/vite.config.mts index 6876302dd90..f2a0ec05976 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -27,6 +27,8 @@ import { MastodonAssetsManifest } from './config/vite/plugin-assets-manifest'; const jsRoot = path.resolve(__dirname, 'app/javascript'); +const cssAliasClasses: ReadonlyArray = ['components', 'features']; + export const config: UserConfigFnPromise = async ({ mode, command }) => { const isProdBuild = mode === 'production' && command === 'build'; @@ -49,6 +51,45 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => { }, }, css: { + modules: { + generateScopedName(name, filename) { + let prefix = ''; + + // Use the top two segments of the path as the prefix. + const [parentDirName, dirName] = path + .dirname(filename) + .split(path.sep) + .slice(-2) + .map((dir) => dir.toLowerCase()); + + // If the parent directory is in the cssAliasClasses list, use + // the first four letters of it as the prefix, otherwise use the full name. + if (parentDirName) { + if (cssAliasClasses.includes(parentDirName)) { + prefix = parentDirName.slice(0, 4); + } else { + prefix = parentDirName; + } + } + + // If we have a directory name, append it to the prefix. + if (dirName) { + prefix = `${prefix}_${dirName}`; + } + + // If the file is not styles.module.scss or style.module.scss, + // append the file base name to the prefix. + const baseName = path.basename( + filename, + `.module${path.extname(filename)}`, + ); + if (baseName !== 'styles' && baseName !== 'style') { + prefix = `${prefix}_${baseName}`; + } + + return `_${prefix}__${name}`; + }, + }, postcss: { plugins: [ postcssPresetEnv({ @@ -73,7 +114,6 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => { port: 3036, }, build: { - target: 'modules', commonjsOptions: { transformMixedEsModules: true }, chunkSizeWarningLimit: 1 * 1024 * 1024, // 1MB sourcemap: true, diff --git a/vitest.config.mts b/vitest.config.mts index b129c293f4c..16c1ba2e9ef 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,6 +1,7 @@ import { resolve } from 'node:path'; import { storybookTest } from '@storybook/addon-vitest/vitest-plugin'; +import { playwright } from '@vitest/browser-playwright'; import { configDefaults, defineConfig, @@ -23,7 +24,7 @@ const storybookTests: TestProjectInlineConfiguration = { browser: { enabled: true, headless: true, - provider: 'playwright', + provider: playwright(), instances: [{ browser: 'chromium' }], }, setupFiles: [resolve(__dirname, '.storybook/vitest.setup.ts')], diff --git a/yarn.lock b/yarn.lock index de2d35becbe..c27a442ec3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,6 +12,13 @@ __metadata: languageName: node linkType: hard +"@acemir/cssom@npm:^0.9.19": + version: 0.9.19 + resolution: "@acemir/cssom@npm:0.9.19" + checksum: 10c0/baef216086b4c6d32ac02fff6621e5343969710d8262be3a84494564754424f60d3add8313c05a76465310e02bf72faa65abcb9febee15c2dc01d9b08c044d5a + languageName: node + linkType: hard + "@adobe/css-tools@npm:^4.4.0": version: 4.4.3 resolution: "@adobe/css-tools@npm:4.4.3" @@ -19,13 +26,10 @@ __metadata: languageName: node linkType: hard -"@ampproject/remapping@npm:^2.3.0": - version: 2.3.0 - resolution: "@ampproject/remapping@npm:2.3.0" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/81d63cca5443e0f0c72ae18b544cc28c7c0ec2cea46e7cb888bb0e0f411a1191d0d6b7af798d54e30777d8d1488b2ec0732aac2be342d3d7d3ffd271c6f489ed +"@adobe/css-tools@npm:~4.3.1": + version: 4.3.3 + resolution: "@adobe/css-tools@npm:4.3.3" + checksum: 10c0/e76e712df713964b87cdf2aca1f0477f19bebd845484d5fcba726d3ec7782366e2f26ec8cb2dcfaf47081a5c891987d8a9f5c3f30d11e1eb3c1848adc27fcb24 languageName: node linkType: hard @@ -55,16 +59,16 @@ __metadata: languageName: node linkType: hard -"@asamuzakjp/dom-selector@npm:^6.7.2": - version: 6.7.2 - resolution: "@asamuzakjp/dom-selector@npm:6.7.2" +"@asamuzakjp/dom-selector@npm:^6.7.3": + version: 6.7.3 + resolution: "@asamuzakjp/dom-selector@npm:6.7.3" dependencies: "@asamuzakjp/nwsapi": "npm:^2.3.9" bidi-js: "npm:^1.0.3" css-tree: "npm:^3.1.0" is-potential-custom-element-name: "npm:^1.0.1" lru-cache: "npm:^11.2.2" - checksum: 10c0/b0cb6a5540dc70c9ace3fa91bdd84cf12be7817451d8522d8aaa19f806edc52f500647055ac2b806a93213b9756cd8cae9958fac8dcffbaecaef5dadabf1674f + checksum: 10c0/14af5b239e7c28db9a0378316da8b40669b29287c17a25119e34aa0b24336f7ed2b9b76b4fcf50c5221ffa0c6800d19ba3f5fa422786e3495af2dd64767cf741 languageName: node linkType: hard @@ -295,10 +299,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.27.1": - version: 7.27.1 - resolution: "@babel/helper-validator-identifier@npm:7.27.1" - checksum: 10c0/c558f11c4871d526498e49d07a84752d1800bf72ac0d3dad100309a2eaba24efbf56ea59af5137ff15e3a00280ebe588560534b0e894a4750f8b1411d8f78b84 +"@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847 languageName: node linkType: hard @@ -330,14 +334,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": - version: 7.28.4 - resolution: "@babel/parser@npm:7.28.4" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.25.4, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" dependencies: - "@babel/types": "npm:^7.28.4" + "@babel/types": "npm:^7.28.5" bin: parser: ./bin/babel-parser.js - checksum: 10c0/58b239a5b1477ac7ed7e29d86d675cc81075ca055424eba6485872626db2dc556ce63c45043e5a679cd925e999471dba8a3ed4864e7ab1dbf64306ab72c52707 + checksum: 10c0/5bbe48bf2c79594ac02b490a41ffde7ef5aa22a9a88ad6bcc78432a6ba8a9d638d531d868bd1f104633f1f6bba9905746e15185b8276a3756c42b765d131b1ef languageName: node linkType: hard @@ -1170,16 +1174,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.0.0": - version: 7.0.0 - resolution: "@babel/runtime@npm:7.0.0" - dependencies: - regenerator-runtime: "npm:^0.12.0" - checksum: 10c0/fbbdf86380a1cfa6ce32a743549f4e4c8b8eb06a18be5054441cc0f66e75a747ae43b042d8989f4657027e1be3b9a82069865ccc5080838f004abd1161093742 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.27.0 resolution: "@babel/runtime@npm:7.27.0" dependencies: @@ -1214,13 +1209,13 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.4.4": - version: 7.28.4 - resolution: "@babel/types@npm:7.28.4" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.25.4, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.28.5, @babel/types@npm:^7.4.4": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" dependencies: "@babel/helper-string-parser": "npm:^7.27.1" - "@babel/helper-validator-identifier": "npm:^7.27.1" - checksum: 10c0/ac6f909d6191319e08c80efbfac7bd9a25f80cc83b43cd6d82e7233f7a6b9d6e7b90236f3af7400a3f83b576895bcab9188a22b584eb0f224e80e6d4e95f4517 + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/a5a483d2100befbf125793640dec26b90b95fd233a94c19573325898a5ce1e52cdfa96e495c7dcc31b5eca5b66ce3e6d4a0f5a4a62daec271455959f208ab08a languageName: node linkType: hard @@ -1895,10 +1890,10 @@ __metadata: languageName: node linkType: hard -"@dual-bundle/import-meta-resolve@npm:^4.1.0": - version: 4.1.0 - resolution: "@dual-bundle/import-meta-resolve@npm:4.1.0" - checksum: 10c0/55069e550ee2710e738dd8bbd34aba796cede456287454b50c3be46fbef8695d00625677f3f41f5ffbec1174c0f57f314da9a908388bc9f8ad41a8438db884d9 +"@dual-bundle/import-meta-resolve@npm:^4.2.1": + version: 4.2.1 + resolution: "@dual-bundle/import-meta-resolve@npm:4.2.1" + checksum: 10c0/8f1e572c14c4d20ea35734635085213abd13bd440c251309cf8ae5ed1082f6759cefa1c2c52a631f76859c57e26062f78a8cee4acc239c0edc87cd316a5d3b5b languageName: node linkType: hard @@ -2054,16 +2049,23 @@ __metadata: languageName: node linkType: hard -"@es-joy/jsdoccomment@npm:~0.52.0": - version: 0.52.0 - resolution: "@es-joy/jsdoccomment@npm:0.52.0" +"@es-joy/jsdoccomment@npm:~0.76.0": + version: 0.76.0 + resolution: "@es-joy/jsdoccomment@npm:0.76.0" dependencies: "@types/estree": "npm:^1.0.8" - "@typescript-eslint/types": "npm:^8.34.1" + "@typescript-eslint/types": "npm:^8.46.0" comment-parser: "npm:1.4.1" esquery: "npm:^1.6.0" - jsdoc-type-pratt-parser: "npm:~4.1.0" - checksum: 10c0/4def78060ef58859f31757b9d30c4939fc33e7d9ee85637a7f568c1d209c33aa0abd2cf5a3a4f3662ec5b12b85ecff2f2035d809dc93b9382a31a6dfb200d83c + jsdoc-type-pratt-parser: "npm:~6.10.0" + checksum: 10c0/8fe4edec7d60562787ea8c77193ebe8737a9e28ec3143d383506b63890d0ffd45a2813e913ad1f00f227cb10e3a1fb913e5a696b33d499dc564272ff1a6f3fdb + languageName: node + linkType: hard + +"@es-joy/resolve.exports@npm:1.2.0": + version: 1.2.0 + resolution: "@es-joy/resolve.exports@npm:1.2.0" + checksum: 10c0/7e4713471f5eccb17a925a12415a2d9e372a42376813a19f6abd9c35e8d01ab1403777265817da67c6150cffd4f558d9ad51e26a8de6911dad89d9cb7eedacd8 languageName: node linkType: hard @@ -2242,14 +2244,14 @@ __metadata: languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0": - version: 4.7.0 - resolution: "@eslint-community/eslint-utils@npm:4.7.0" +"@eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0": + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" dependencies: eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10c0/c0f4f2bd73b7b7a9de74b716a664873d08ab71ab439e51befe77d61915af41a81ecec93b408778b3a7856185244c34c2c8ee28912072ec14def84ba2dec70adf + checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817 languageName: node linkType: hard @@ -2260,30 +2262,32 @@ __metadata: languageName: node linkType: hard -"@eslint/config-array@npm:^0.21.0": - version: 0.21.0 - resolution: "@eslint/config-array@npm:0.21.0" +"@eslint/config-array@npm:^0.21.1": + version: 0.21.1 + resolution: "@eslint/config-array@npm:0.21.1" dependencies: - "@eslint/object-schema": "npm:^2.1.6" + "@eslint/object-schema": "npm:^2.1.7" debug: "npm:^4.3.1" minimatch: "npm:^3.1.2" - checksum: 10c0/0ea801139166c4aa56465b309af512ef9b2d3c68f9198751bbc3e21894fe70f25fbf26e1b0e9fffff41857bc21bfddeee58649ae6d79aadcd747db0c5dca771f + checksum: 10c0/2f657d4edd6ddcb920579b72e7a5b127865d4c3fb4dda24f11d5c4f445a93ca481aebdbd6bf3291c536f5d034458dbcbb298ee3b698bc6c9dd02900fe87eec3c languageName: node linkType: hard -"@eslint/config-helpers@npm:^0.3.0": - version: 0.3.0 - resolution: "@eslint/config-helpers@npm:0.3.0" - checksum: 10c0/013ae7b189eeae8b30cc2ee87bc5c9c091a9cd615579003290eb28bebad5d78806a478e74ba10b3fe08ed66975b52af7d2cd4b4b43990376412b14e5664878c8 +"@eslint/config-helpers@npm:^0.4.2": + version: 0.4.2 + resolution: "@eslint/config-helpers@npm:0.4.2" + dependencies: + "@eslint/core": "npm:^0.17.0" + checksum: 10c0/92efd7a527b2d17eb1a148409d71d80f9ac160b565ac73ee092252e8bf08ecd08670699f46b306b94f13d22e88ac88a612120e7847570dd7cdc72f234d50dcb4 languageName: node linkType: hard -"@eslint/core@npm:^0.15.0, @eslint/core@npm:^0.15.1": - version: 0.15.1 - resolution: "@eslint/core@npm:0.15.1" +"@eslint/core@npm:^0.17.0": + version: 0.17.0 + resolution: "@eslint/core@npm:0.17.0" dependencies: "@types/json-schema": "npm:^7.0.15" - checksum: 10c0/abaf641940776638b8c15a38d99ce0dac551a8939310ec81b9acd15836a574cf362588eaab03ab11919bc2a0f9648b19ea8dee33bf12675eb5b6fd38bda6f25e + checksum: 10c0/9a580f2246633bc752298e7440dd942ec421860d1946d0801f0423830e67887e4aeba10ab9a23d281727a978eb93d053d1922a587d502942a713607f40ed704e languageName: node linkType: hard @@ -2304,27 +2308,27 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:9.32.0, @eslint/js@npm:^9.23.0": - version: 9.32.0 - resolution: "@eslint/js@npm:9.32.0" - checksum: 10c0/f71e8f9146638d11fb15238279feff98801120a4d4130f1c587c4f09b024ff5ec01af1ba88e97ba6b7013488868898a668f77091300cc3d4394c7a8ed32d2667 +"@eslint/js@npm:9.39.1, @eslint/js@npm:^9.23.0": + version: 9.39.1 + resolution: "@eslint/js@npm:9.39.1" + checksum: 10c0/6f7f26f8cdb7ad6327bbf9741973b6278eb946f18f70e35406e88194b0d5c522d0547a34a02f2a208eec95c5d1388cdf7ccb20039efd2e4cb6655615247a50f1 languageName: node linkType: hard -"@eslint/object-schema@npm:^2.1.6": - version: 2.1.6 - resolution: "@eslint/object-schema@npm:2.1.6" - checksum: 10c0/b8cdb7edea5bc5f6a96173f8d768d3554a628327af536da2fc6967a93b040f2557114d98dbcdbf389d5a7b290985ad6a9ce5babc547f36fc1fde42e674d11a56 +"@eslint/object-schema@npm:^2.1.7": + version: 2.1.7 + resolution: "@eslint/object-schema@npm:2.1.7" + checksum: 10c0/936b6e499853d1335803f556d526c86f5fe2259ed241bc665000e1d6353828edd913feed43120d150adb75570cae162cf000b5b0dfc9596726761c36b82f4e87 languageName: node linkType: hard -"@eslint/plugin-kit@npm:^0.3.4": - version: 0.3.4 - resolution: "@eslint/plugin-kit@npm:0.3.4" +"@eslint/plugin-kit@npm:^0.4.1": + version: 0.4.1 + resolution: "@eslint/plugin-kit@npm:0.4.1" dependencies: - "@eslint/core": "npm:^0.15.1" + "@eslint/core": "npm:^0.17.0" levn: "npm:^0.4.1" - checksum: 10c0/64331ca100f62a0115d10419a28059d0f377e390192163b867b9019517433d5073d10b4ec21f754fa01faf832aceb34178745924baab2957486f8bf95fd628d2 + checksum: 10c0/51600f78b798f172a9915dffb295e2ffb44840d583427bc732baf12ecb963eb841b253300e657da91d890f4b323d10a1bd12934bf293e3018d8bb66fdce5217b languageName: node linkType: hard @@ -2355,10 +2359,10 @@ __metadata: linkType: hard "@formatjs/cli@npm:^6.1.1": - version: 6.7.2 - resolution: "@formatjs/cli@npm:6.7.2" + version: 6.7.4 + resolution: "@formatjs/cli@npm:6.7.4" peerDependencies: - "@glimmer/syntax": ^0.94.9 + "@glimmer/syntax": ^0.95.0 "@vue/compiler-core": ^3.5.12 content-tag: ^3.0.0 ember-template-recast: ^6.1.5 @@ -2382,19 +2386,7 @@ __metadata: optional: true bin: formatjs: bin/formatjs - checksum: 10c0/fbcb1d35915a5b1542e4fa3f3f79e23fa5988681e6c238d7e8a3d4d32e18df3e5c36cebe01b04e011bb5c91f96f4d08d36af750259aa799d3e81943084e2f0c2 - languageName: node - linkType: hard - -"@formatjs/ecma402-abstract@npm:2.3.4": - version: 2.3.4 - resolution: "@formatjs/ecma402-abstract@npm:2.3.4" - dependencies: - "@formatjs/fast-memoize": "npm:2.2.7" - "@formatjs/intl-localematcher": "npm:0.6.1" - decimal.js: "npm:^10.4.3" - tslib: "npm:^2.8.0" - checksum: 10c0/2644bc618a34dc610ef9691281eeb45ae6175e6982cf19f1bd140672fc95c748747ce3c85b934649ea7e4a304f7ae0060625fd53d5df76f92ca3acf743e1eb0a + checksum: 10c0/11ff474cd79bef464a2aa50d0a5145542aaf414445399f3eb6d5693c0f3ebed1fdb90b58a5f88a5c834a3344624baf7b457d622a4697534ada271ad97532eac9 languageName: node linkType: hard @@ -2419,17 +2411,6 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.11.2": - version: 2.11.2 - resolution: "@formatjs/icu-messageformat-parser@npm:2.11.2" - dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.4" - "@formatjs/icu-skeleton-parser": "npm:1.8.14" - tslib: "npm:^2.8.0" - checksum: 10c0/a121f2d2c6b36a1632ffd64c3545e2500c8ee0f7fee5db090318c035d635c430ab123faedb5d000f18d9423a7b55fbf670b84e2e2dd72cc307a38aed61d3b2e0 - languageName: node - linkType: hard - "@formatjs/icu-messageformat-parser@npm:2.11.4": version: 2.11.4 resolution: "@formatjs/icu-messageformat-parser@npm:2.11.4" @@ -2441,16 +2422,6 @@ __metadata: languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.8.14": - version: 1.8.14 - resolution: "@formatjs/icu-skeleton-parser@npm:1.8.14" - dependencies: - "@formatjs/ecma402-abstract": "npm:2.3.4" - tslib: "npm:^2.8.0" - checksum: 10c0/a1807ed6e90b8a2e8d0e5b5125e6f9a2c057d3cff377fb031d2333af7cfaa6de4ed3a15c23da7294d4c3557f8b28b2163246434a19720f26b5db0497d97e9b58 - languageName: node - linkType: hard - "@formatjs/icu-skeleton-parser@npm:1.8.16": version: 1.8.16 resolution: "@formatjs/icu-skeleton-parser@npm:1.8.16" @@ -2461,15 +2432,6 @@ __metadata: languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.6.1": - version: 0.6.1 - resolution: "@formatjs/intl-localematcher@npm:0.6.1" - dependencies: - tslib: "npm:^2.8.0" - checksum: 10c0/bacbedd508519c1bb5ca2620e89dc38f12101be59439aa14aa472b222915b462cb7d679726640f6dcf52a05dd218b5aa27ccd60f2e5010bb96f1d4929848cde0 - languageName: node - linkType: hard - "@formatjs/intl-localematcher@npm:0.6.2": version: 0.6.2 resolution: "@formatjs/intl-localematcher@npm:0.6.2" @@ -2509,26 +2471,6 @@ __metadata: languageName: node linkType: hard -"@formatjs/ts-transformer@npm:3.14.0": - version: 3.14.0 - resolution: "@formatjs/ts-transformer@npm:3.14.0" - dependencies: - "@formatjs/icu-messageformat-parser": "npm:2.11.2" - "@types/json-stable-stringify": "npm:^1.1.0" - "@types/node": "npm:^22.0.0" - chalk: "npm:^4.1.2" - json-stable-stringify: "npm:^1.1.1" - tslib: "npm:^2.8.0" - typescript: "npm:^5.6.0" - peerDependencies: - ts-jest: ^29 - peerDependenciesMeta: - ts-jest: - optional: true - checksum: 10c0/80599a9e76685d710aeba88857fc3d682cc4f17996e870c582a40288e149d6dd496a3be0684682f7ed3892ca677c6b9cbd6b804dbf457da87b493a7a756a18a1 - languageName: node - linkType: hard - "@formatjs/ts-transformer@npm:3.14.2": version: 3.14.2 resolution: "@formatjs/ts-transformer@npm:3.14.2" @@ -2687,13 +2629,6 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a - languageName: node - linkType: hard - "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.6.1": version: 0.6.1 resolution: "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.6.1" @@ -2748,20 +2683,20 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": - version: 1.5.0 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" - checksum: 10c0/2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.29 - resolution: "@jridgewell/trace-mapping@npm:0.3.29" +"@jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.31": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/fb547ba31658c4d74eb17e7389f4908bf7c44cef47acb4c5baa57289daf68e6fe53c639f41f751b3923aca67010501264f70e7b49978ad1f040294b22c37b333 + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 languageName: node linkType: hard @@ -2795,13 +2730,13 @@ __metadata: "@gamestdio/websocket": "npm:^0.3.2" "@github/webauthn-json": "npm:^2.1.1" "@optimize-lodash/rollup-plugin": "npm:^5.0.2" - "@rails/ujs": "npm:7.1.502" + "@rails/ujs": "npm:7.1.600" "@react-spring/web": "npm:^9.7.5" "@reduxjs/toolkit": "npm:^2.0.1" - "@storybook/addon-a11y": "npm:^9.1.1" - "@storybook/addon-docs": "npm:^9.1.1" - "@storybook/addon-vitest": "npm:^9.1.1" - "@storybook/react-vite": "npm:^9.1.1" + "@storybook/addon-a11y": "npm:^10.0.2" + "@storybook/addon-docs": "npm:^10.0.2" + "@storybook/addon-vitest": "npm:^10.0.2" + "@storybook/react-vite": "npm:^10.0.2" "@testing-library/dom": "npm:^10.4.1" "@testing-library/react": "npm:^16.3.0" "@types/debug": "npm:^4" @@ -2823,7 +2758,6 @@ __metadata: "@types/react-router": "npm:^5.1.20" "@types/react-router-dom": "npm:^5.3.3" "@types/react-sparklines": "npm:^1.7.2" - "@types/react-swipeable-views": "npm:^0.13.1" "@types/react-test-renderer": "npm:^18.0.0" "@types/react-toggle": "npm:^4.0.3" "@types/redux-immutable": "npm:^4.0.3" @@ -2831,9 +2765,10 @@ __metadata: "@use-gesture/react": "npm:^10.3.1" "@vitejs/plugin-legacy": "npm:^7.2.1" "@vitejs/plugin-react": "npm:^5.0.0" - "@vitest/browser": "npm:^3.2.4" - "@vitest/coverage-v8": "npm:^3.2.4" - "@vitest/ui": "npm:^3.2.4" + "@vitest/browser": "npm:^4.0.5" + "@vitest/browser-playwright": "npm:^4.0.5" + "@vitest/coverage-v8": "npm:^4.0.5" + "@vitest/ui": "npm:^4.0.5" arrow-key-navigation: "npm:^1.2.0" async-mutex: "npm:^0.5.0" axios: "npm:^1.4.0" @@ -2857,12 +2792,12 @@ __metadata: eslint-import-resolver-typescript: "npm:^4.2.5" eslint-plugin-formatjs: "npm:^5.3.1" eslint-plugin-import: "npm:~2.32.0" - eslint-plugin-jsdoc: "npm:^54.0.0" + eslint-plugin-jsdoc: "npm:^61.1.11" eslint-plugin-jsx-a11y: "npm:~6.10.2" eslint-plugin-promise: "npm:~7.2.1" eslint-plugin-react: "npm:^7.37.4" - eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-storybook: "npm:^9.0.4" + eslint-plugin-react-hooks: "npm:^7.0.1" + eslint-plugin-storybook: "npm:^10.0.2" fake-indexeddb: "npm:^6.0.1" fast-glob: "npm:^3.3.3" fuzzysort: "npm:^3.0.0" @@ -2876,13 +2811,13 @@ __metadata: intl-messageformat: "npm:^10.7.16" js-yaml: "npm:^4.1.0" lande: "npm:^1.0.10" - lint-staged: "npm:^16.0.0" + lint-staged: "npm:^16.2.6" lodash: "npm:^4.17.21" marky: "npm:^1.2.5" msw: "npm:^2.10.2" msw-storybook-addon: "npm:^2.0.5" path-complete-extname: "npm:^1.0.0" - playwright: "npm:^1.54.1" + playwright: "npm:^1.56.1" postcss-preset-env: "npm:^10.1.5" prettier: "npm:^3.3.3" prop-types: "npm:^15.8.1" @@ -2900,7 +2835,6 @@ __metadata: react-router-dom: "npm:^5.3.4" react-select: "npm:^5.7.3" react-sparklines: "npm:^1.7.0" - react-swipeable-views: "npm:^0.14.0" react-test-renderer: "npm:^18.2.0" react-textarea-autosize: "npm:^8.4.1" react-toggle: "npm:^4.1.3" @@ -2912,7 +2846,7 @@ __metadata: sass: "npm:^1.62.1" scroll-behavior: "npm:^0.11.0" stacktrace-js: "npm:^2.0.2" - storybook: "npm:^9.1.1" + storybook: "npm:^10.0.2" stringz: "npm:^2.1.0" stylelint: "npm:^16.19.1" stylelint-config-prettier-scss: "npm:^1.0.0" @@ -2923,6 +2857,7 @@ __metadata: twitter-text: "npm:3.1.0" typescript: "npm:~5.9.0" typescript-eslint: "npm:^8.45.0" + typescript-plugin-css-modules: "npm:^5.2.0" use-debounce: "npm:^10.0.0" vite: "npm:^7.1.1" vite-plugin-manifest-sri: "npm:^0.2.0" @@ -2930,7 +2865,7 @@ __metadata: vite-plugin-static-copy: "npm:^3.1.1" vite-plugin-svgr: "npm:^4.3.0" vite-tsconfig-paths: "npm:^5.1.4" - vitest: "npm:^3.2.4" + vitest: "npm:^4.0.5" wicg-inert: "npm:^3.1.2" workbox-expiration: "npm:^7.3.0" workbox-routing: "npm:^7.3.0" @@ -2952,20 +2887,20 @@ __metadata: dependencies: "@eslint/js": "npm:^9.23.0" "@types/cors": "npm:^2.8.16" - "@types/express": "npm:^4.17.17" + "@types/express": "npm:^5.0.5" "@types/pg": "npm:^8.6.6" "@types/ws": "npm:^8.5.9" bufferutil: "npm:^4.0.7" cors: "npm:^2.8.5" dotenv: "npm:^16.0.3" - express: "npm:^4.18.2" + express: "npm:^5.1.0" globals: "npm:^16.0.0" ioredis: "npm:^5.3.2" jsdom: "npm:^27.0.0" pg: "npm:^8.5.0" pg-connection-string: "npm:^2.6.0" - pino: "npm:^9.0.0" - pino-http: "npm:^10.0.0" + pino: "npm:^10.0.0" + pino-http: "npm:^11.0.0" pino-pretty: "npm:^13.0.0" prom-client: "npm:^15.0.0" typescript: "npm:~5.9.0" @@ -3292,10 +3227,10 @@ __metadata: languageName: node linkType: hard -"@rails/ujs@npm:7.1.502": - version: 7.1.502 - resolution: "@rails/ujs@npm:7.1.502" - checksum: 10c0/79b46e8abd03e3fc633d93cc4e4c23838c628b775802fb38c2ce68b0e609ce287a67b81db112a93cc78c07ec82ca3b4cf87e74eb556d35148ce5f64c8be9201f +"@rails/ujs@npm:7.1.600": + version: 7.1.600 + resolution: "@rails/ujs@npm:7.1.600" + checksum: 10c0/0ccaa68a08fbc7b084ab89a1fe49520a5cba6d99f4b0feaf0cb3d00334c59d8d798932d7e49b84aa388875d039ea1e17eb115ed96a80ad157e408a13eceef53e languageName: node linkType: hard @@ -3398,10 +3333,10 @@ __metadata: languageName: node linkType: hard -"@rolldown/pluginutils@npm:1.0.0-beta.38": - version: 1.0.0-beta.38 - resolution: "@rolldown/pluginutils@npm:1.0.0-beta.38" - checksum: 10c0/8353ec2528349f79e27d1a3193806725b85830da334e935cbb606d88c1177c58ea6519c578e4e93e5f677f5b22aecb8738894dbed14603e14b6bffe3facf1002 +"@rolldown/pluginutils@npm:1.0.0-beta.43": + version: 1.0.0-beta.43 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.43" + checksum: 10c0/1c17a0b16c277a0fdbab080fd22ef91e37c1f0d710ecfdacb6a080068062eb14ff030d0e9d2ec2325a1d4246dba0c49625755c82c0090f6cbf98d16e80183e02 languageName: node linkType: hard @@ -3497,142 +3432,142 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.46.2" +"@rollup/rollup-android-arm-eabi@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.46.4" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-android-arm64@npm:4.46.2" +"@rollup/rollup-android-arm64@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-android-arm64@npm:4.46.4" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.46.2" +"@rollup/rollup-darwin-arm64@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-darwin-arm64@npm:4.46.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.46.2" +"@rollup/rollup-darwin-x64@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-darwin-x64@npm:4.46.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.46.2" +"@rollup/rollup-freebsd-arm64@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.46.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-freebsd-x64@npm:4.46.2" +"@rollup/rollup-freebsd-x64@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-freebsd-x64@npm:4.46.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.46.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.46.4" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.46.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.46.4" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.46.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.46.4" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.46.2" +"@rollup/rollup-linux-arm64-musl@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.46.4" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.46.2" +"@rollup/rollup-linux-loongarch64-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.46.4" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.46.2" +"@rollup/rollup-linux-ppc64-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.46.4" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.46.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.46.4" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.46.2" +"@rollup/rollup-linux-riscv64-musl@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.46.4" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.46.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.46.4" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.46.2" +"@rollup/rollup-linux-x64-gnu@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.46.4" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.46.2" +"@rollup/rollup-linux-x64-musl@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.46.4" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.46.2" +"@rollup/rollup-win32-arm64-msvc@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.46.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.46.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.46.4" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.46.2": - version: 4.46.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.46.2" +"@rollup/rollup-win32-x64-msvc@npm:4.46.4": + version: 4.46.4 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.46.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3644,6 +3579,13 @@ __metadata: languageName: node linkType: hard +"@sindresorhus/base62@npm:^1.0.0": + version: 1.0.0 + resolution: "@sindresorhus/base62@npm:1.0.0" + checksum: 10c0/9a14df0f058fdf4731c30f0f05728a4822144ee42236030039d7fa5a1a1072c2879feba8091fd4a17c8922d1056bc07bada77c31fddc3e15836fc05a266fd918 + languageName: node + linkType: hard + "@standard-schema/spec@npm:^1.0.0": version: 1.0.0 resolution: "@standard-schema/spec@npm:1.0.0" @@ -3658,80 +3600,96 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-a11y@npm:^9.1.1": - version: 9.1.7 - resolution: "@storybook/addon-a11y@npm:9.1.7" +"@storybook/addon-a11y@npm:^10.0.2": + version: 10.0.2 + resolution: "@storybook/addon-a11y@npm:10.0.2" dependencies: "@storybook/global": "npm:^5.0.0" axe-core: "npm:^4.2.0" peerDependencies: - storybook: ^9.1.7 - checksum: 10c0/c34f057acec41d6116669663e2a18b230c8905c409de6ef7fcff2cfe00741b8c435165c43301565e99ff275e541180de866c48c26d2676313334e2dd4696f5a3 + storybook: ^10.0.2 + checksum: 10c0/a47fed1aa098328bea173f257a0140dff4a5e2d2d6c90b0fa88a33a82583658afa09fa04d012930900fe87453a48d781847b7f5193da0f09b0b8598032596ca2 languageName: node linkType: hard -"@storybook/addon-docs@npm:^9.1.1": - version: 9.1.7 - resolution: "@storybook/addon-docs@npm:9.1.7" +"@storybook/addon-docs@npm:^10.0.2": + version: 10.0.2 + resolution: "@storybook/addon-docs@npm:10.0.2" dependencies: "@mdx-js/react": "npm:^3.0.0" - "@storybook/csf-plugin": "npm:9.1.7" - "@storybook/icons": "npm:^1.4.0" - "@storybook/react-dom-shim": "npm:9.1.7" + "@storybook/csf-plugin": "npm:10.0.2" + "@storybook/icons": "npm:^1.6.0" + "@storybook/react-dom-shim": "npm:10.0.2" react: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" react-dom: "npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^9.1.7 - checksum: 10c0/81f530b1230c60d344662aedb4839baa099da287c0188e8d5e10ab8cac0b02bb747e7d6475dbb1a85cba0cb5c475b8d48936355dd359020652ccbaba7d664aa0 + storybook: ^10.0.2 + checksum: 10c0/167e8b4b230431ac8afcb6dfceedc8450d8d2d5a84c61e7a5f8e28a1a47d1031194a780f16ed697bce03cce10c71a6aa9bb1f102bf68693c96cfc710f4b5dadb languageName: node linkType: hard -"@storybook/addon-vitest@npm:^9.1.1": - version: 9.1.7 - resolution: "@storybook/addon-vitest@npm:9.1.7" +"@storybook/addon-vitest@npm:^10.0.2": + version: 10.0.2 + resolution: "@storybook/addon-vitest@npm:10.0.2" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/icons": "npm:^1.4.0" + "@storybook/icons": "npm:^1.6.0" prompts: "npm:^2.4.0" ts-dedent: "npm:^2.2.0" peerDependencies: - "@vitest/browser": ^3.0.0 - "@vitest/runner": ^3.0.0 - storybook: ^9.1.7 - vitest: ^3.0.0 + "@vitest/browser": ^3.0.0 || ^4.0.0 + "@vitest/browser-playwright": ^4.0.0 + "@vitest/runner": ^3.0.0 || ^4.0.0 + storybook: ^10.0.2 + vitest: ^3.0.0 || ^4.0.0 peerDependenciesMeta: "@vitest/browser": optional: true + "@vitest/browser-playwright": + optional: true "@vitest/runner": optional: true vitest: optional: true - checksum: 10c0/744358491481d21e7728d07bd244038d378b5883257c3a2291b2fa5abef917493c1421921bc020fecfb15740a1b6331fdf598b15c91961ffc7ea924f8d945957 + checksum: 10c0/b97b6b01b242f1c71a44eadbe4d993a355954dab2515b6d21771bc1ff55636ffd32474ba4138d2f6d45a752c2b11cf6ac7aef68b9213f5188bc2ba90ee5d12c0 languageName: node linkType: hard -"@storybook/builder-vite@npm:9.1.7": - version: 9.1.7 - resolution: "@storybook/builder-vite@npm:9.1.7" +"@storybook/builder-vite@npm:10.0.2": + version: 10.0.2 + resolution: "@storybook/builder-vite@npm:10.0.2" dependencies: - "@storybook/csf-plugin": "npm:9.1.7" + "@storybook/csf-plugin": "npm:10.0.2" ts-dedent: "npm:^2.0.0" peerDependencies: - storybook: ^9.1.7 + storybook: ^10.0.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/39306d65373a934c4274196d5451467acb4128252c61b7abb801153fdf9b8278ca4ee8c9911def229f9c6045f24d39610fb5f0e553892478e9f541cdb9287859 + checksum: 10c0/a93bbb763c1f5d47b7b6c36f9225ca9a1f9f70c9f07c7b4ee61dd97f77a676b7d31c5c27b6ca48bb237fbaed626f592653380c2999bf9ae48be1071c0c007acf languageName: node linkType: hard -"@storybook/csf-plugin@npm:9.1.7": - version: 9.1.7 - resolution: "@storybook/csf-plugin@npm:9.1.7" +"@storybook/csf-plugin@npm:10.0.2": + version: 10.0.2 + resolution: "@storybook/csf-plugin@npm:10.0.2" dependencies: - unplugin: "npm:^1.3.1" + unplugin: "npm:^2.3.5" peerDependencies: - storybook: ^9.1.7 - checksum: 10c0/059fa960174a3f421eb09b41d0da43c43a46548a2535acc17a0e7989bb78f954180212a43b58392dfec6e92a3482621a13ec1b6ff00d1157a2355d369129842a + esbuild: "*" + rollup: "*" + storybook: ^10.0.2 + vite: "*" + webpack: "*" + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + checksum: 10c0/422823c3635c5bab48a258d8f6e7dadf02484afdfb48b08005be962d8bb5b4c8f507f3d68b79523ff11901178a7e913f98c047ec7aced5bcdf47a846c2bcd66f languageName: node linkType: hard @@ -3742,64 +3700,64 @@ __metadata: languageName: node linkType: hard -"@storybook/icons@npm:^1.4.0": - version: 1.4.0 - resolution: "@storybook/icons@npm:1.4.0" +"@storybook/icons@npm:^1.6.0": + version: 1.6.0 + resolution: "@storybook/icons@npm:1.6.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - checksum: 10c0/fd0514fb3fa431a8b5939fe1d9fc336b253ef2c25b34792d2d4ee59e13321108d34f8bf223a0981482f54f83c5ef47ffd1a98c376ca9071011c1b8afe2b01d43 + checksum: 10c0/bbec9201a78a730195f9cf377b15856dc414a54d04e30d16c379d062425cc617bfd0d6586ba1716012cfbdab461f0c9693a6a52920f9bd09c7b4291fb116f59c languageName: node linkType: hard -"@storybook/react-dom-shim@npm:9.1.7": - version: 9.1.7 - resolution: "@storybook/react-dom-shim@npm:9.1.7" +"@storybook/react-dom-shim@npm:10.0.2": + version: 10.0.2 + resolution: "@storybook/react-dom-shim@npm:10.0.2" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.7 - checksum: 10c0/bed0ebf47f2d2027a28d82be1af5c2413297bfae928b0c6d6a0752f3e30819821660c6abdcc75fa97e15593dc1c181dc36b36f488c8710db3adcabaf70695964 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.0.2 + checksum: 10c0/8d915c4c0f4e88cc582fe653aadc9b7797105081e84bb22d4911dbb72c6dd4df0054bb074ae92ad1634a92332f4331d250431ca654f621de9f7f0a53e0eefff6 languageName: node linkType: hard -"@storybook/react-vite@npm:^9.1.1": - version: 9.1.7 - resolution: "@storybook/react-vite@npm:9.1.7" +"@storybook/react-vite@npm:^10.0.2": + version: 10.0.2 + resolution: "@storybook/react-vite@npm:10.0.2" dependencies: "@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.6.1" "@rollup/pluginutils": "npm:^5.0.2" - "@storybook/builder-vite": "npm:9.1.7" - "@storybook/react": "npm:9.1.7" - find-up: "npm:^7.0.0" + "@storybook/builder-vite": "npm:10.0.2" + "@storybook/react": "npm:10.0.2" + empathic: "npm:^2.0.0" magic-string: "npm:^0.30.0" react-docgen: "npm:^8.0.0" resolve: "npm:^1.22.8" tsconfig-paths: "npm:^4.2.0" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.7 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.0.2 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/be74d1cacafc83f0c9dc22019aeb1e62a3c6faa2bcf98c1cd109ba3219fb61387d1be9875ffa5a59e824e7b7182c3491de47b2dcb4136368ee6c2189cff74e20 + checksum: 10c0/982e903ce89d5a87676bd345abee1cf26d4c78d477c5659b7c279ab5af80e3b1246610fd5f434e33895ca2dcd2efd06f7238c82b1b84f6fdec9e3ed0907f4cb3 languageName: node linkType: hard -"@storybook/react@npm:9.1.7": - version: 9.1.7 - resolution: "@storybook/react@npm:9.1.7" +"@storybook/react@npm:10.0.2": + version: 10.0.2 + resolution: "@storybook/react@npm:10.0.2" dependencies: "@storybook/global": "npm:^5.0.0" - "@storybook/react-dom-shim": "npm:9.1.7" + "@storybook/react-dom-shim": "npm:10.0.2" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^9.1.7 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^10.0.2 typescript: ">= 4.9.x" peerDependenciesMeta: typescript: optional: true - checksum: 10c0/6ba0d3877075c380d8ab47423cc8e93ff297018fadbbe2ecd224e3d60e6a0fdba561ea84c1ffb39228cb2efd1d8d432710c6ec0337b30f74a62dc2384df96c91 + checksum: 10c0/298054e8c5e61f6d7392154e704f5db26ce22c9cdc1cd178c020eb6abd30dc380e10be28269b8d9c7706b8edefaa737360af906d7e0d6ffc4cbac76f1d835805 languageName: node linkType: hard @@ -3942,7 +3900,7 @@ __metadata: languageName: node linkType: hard -"@testing-library/dom@npm:^10.4.0, @testing-library/dom@npm:^10.4.1": +"@testing-library/dom@npm:^10.4.1": version: 10.4.1 resolution: "@testing-library/dom@npm:10.4.1" dependencies: @@ -4175,27 +4133,26 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:^4.17.33": - version: 4.17.41 - resolution: "@types/express-serve-static-core@npm:4.17.41" +"@types/express-serve-static-core@npm:^5.0.0": + version: 5.1.0 + resolution: "@types/express-serve-static-core@npm:5.1.0" dependencies: "@types/node": "npm:*" "@types/qs": "npm:*" "@types/range-parser": "npm:*" "@types/send": "npm:*" - checksum: 10c0/dc166cbf4475c00a81fbcab120bf7477c527184be11ae149df7f26d9c1082114c68f8d387a2926fe80291b06477c8bbd9231ff4f5775de328e887695aefce269 + checksum: 10c0/1918233c68a0c69695f78331af1aed5fb5190f91da6309318f700adeb78573be840b5d206cb8eda804b65a9989fdeccdaaf84c1e95adc3615052749224b64519 languageName: node linkType: hard -"@types/express@npm:^4.17.17": - version: 4.17.23 - resolution: "@types/express@npm:4.17.23" +"@types/express@npm:^5.0.5": + version: 5.0.5 + resolution: "@types/express@npm:5.0.5" dependencies: "@types/body-parser": "npm:*" - "@types/express-serve-static-core": "npm:^4.17.33" - "@types/qs": "npm:*" - "@types/serve-static": "npm:*" - checksum: 10c0/60490cd4f73085007247e7d4fafad0a7abdafa34fa3caba2757512564ca5e094ece7459f0f324030a63d513f967bb86579a8682af76ae2fd718e889b0a2a4fe8 + "@types/express-serve-static-core": "npm:^5.0.0" + "@types/serve-static": "npm:^1" + checksum: 10c0/e96da91c121b43e0e84301a4cfe165908382d016234c11213aeb4f7401cf1a8694e16e3947d21b5c20b3389358d48d60a8c5c38657e041726ac9e8c884d2b8f0 languageName: node linkType: hard @@ -4254,13 +4211,6 @@ __metadata: languageName: node linkType: hard -"@types/json-stable-stringify@npm:^1.1.0": - version: 1.1.0 - resolution: "@types/json-stable-stringify@npm:1.1.0" - checksum: 10c0/8f69944701510243cd3a83aa44363a8a4d366f11a659b258f69fb3ad0f94ab1e2533206a2c929ac7fd18784d201b663b3f02a45934f545c926f051d8cb4df095 - languageName: node - linkType: hard - "@types/json5@npm:^0.0.29": version: 0.0.29 resolution: "@types/json5@npm:0.0.29" @@ -4282,13 +4232,6 @@ __metadata: languageName: node linkType: hard -"@types/mime@npm:*": - version: 3.0.4 - resolution: "@types/mime@npm:3.0.4" - checksum: 10c0/db478bc0f99e40f7b3e01d356a9bdf7817060808a294978111340317bcd80ca35382855578c5b60fbc84ae449674bd9bb38427b18417e1f8f19e4f72f8b242cd - languageName: node - linkType: hard - "@types/mime@npm:^1": version: 1.3.5 resolution: "@types/mime@npm:1.3.5" @@ -4327,13 +4270,13 @@ __metadata: linkType: hard "@types/pg@npm:^8.6.6": - version: 8.15.5 - resolution: "@types/pg@npm:8.15.5" + version: 8.15.6 + resolution: "@types/pg@npm:8.15.6" dependencies: "@types/node": "npm:*" pg-protocol: "npm:*" pg-types: "npm:^2.2.0" - checksum: 10c0/19a3cc1811918753f8c827733648c3a85c7b0355bf207c44eb1a3b79b2e6a0d85cb5457ec550d860fc9be7e88c7587a3600958ec8c61fa1ad573061c63af93f0 + checksum: 10c0/7f93f83a4da0dc6133918f824d826fa34e78fb8cf86392d28a0e095c836c6910c014ced5d4b364d83e8485a65ce369adeb9663b14ba301241d4c0f80073007f3 languageName: node linkType: hard @@ -4344,6 +4287,24 @@ __metadata: languageName: node linkType: hard +"@types/postcss-modules-local-by-default@npm:^4.0.2": + version: 4.0.2 + resolution: "@types/postcss-modules-local-by-default@npm:4.0.2" + dependencies: + postcss: "npm:^8.0.0" + checksum: 10c0/af13e40673abf96f1427c467bc9d96986fc0fb702f65ef702de05f70e51af2212bc0bdf177bfd817e418f2238bf210fdee3541dd2d939fde9a4df5f8972ad716 + languageName: node + linkType: hard + +"@types/postcss-modules-scope@npm:^3.0.4": + version: 3.0.4 + resolution: "@types/postcss-modules-scope@npm:3.0.4" + dependencies: + postcss: "npm:^8.0.0" + checksum: 10c0/6364674e429143fd686e0238d071377cf9ae1780a77f99e99292a06adc93057609146aaf55c09310ae99526c37e56be5a8a843086c0ff95513bd34c6bc4c7480 + languageName: node + linkType: hard + "@types/prop-types@npm:*, @types/prop-types@npm:^15.7.5": version: 15.7.15 resolution: "@types/prop-types@npm:15.7.15" @@ -4437,15 +4398,6 @@ __metadata: languageName: node linkType: hard -"@types/react-swipeable-views@npm:^0.13.1": - version: 0.13.6 - resolution: "@types/react-swipeable-views@npm:0.13.6" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/a26879146748417234bb7f44c5a71e6bab2b76c0b34c72f0493c18403487a5d77021510e8665bd8bd22786904fbbd90d6db55c8dd2bf983c32421139de851c94 - languageName: node - linkType: hard - "@types/react-test-renderer@npm:^18.0.0": version: 18.3.1 resolution: "@types/react-test-renderer@npm:18.3.1" @@ -4474,12 +4426,12 @@ __metadata: linkType: hard "@types/react@npm:^18.2.7": - version: 18.3.24 - resolution: "@types/react@npm:18.3.24" + version: 18.3.26 + resolution: "@types/react@npm:18.3.26" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10c0/9e188fa8e50f172cf647fc48fea2e04d88602afff47190b697de281a8ac88df9ee059864757a2a438ff599eaf9276d9a9e0e60585e88f7d57f01a2e4877d37ec + checksum: 10c0/7b62d91c33758f14637311921c92db6045b6328e2300666a35ef8130d06385e39acada005eaf317eee93228edc10ea5f0cd34a0385654d2014d24699a65bfeef languageName: node linkType: hard @@ -4514,24 +4466,24 @@ __metadata: languageName: node linkType: hard -"@types/send@npm:*": - version: 0.17.4 - resolution: "@types/send@npm:0.17.4" +"@types/send@npm:*, @types/send@npm:<1": + version: 0.17.6 + resolution: "@types/send@npm:0.17.6" dependencies: "@types/mime": "npm:^1" "@types/node": "npm:*" - checksum: 10c0/7f17fa696cb83be0a104b04b424fdedc7eaba1c9a34b06027239aba513b398a0e2b7279778af521f516a397ced417c96960e5f50fcfce40c4bc4509fb1a5883c + checksum: 10c0/a9d76797f0637738062f1b974e0fcf3d396a28c5dc18c3f95ecec5dabda82e223afbc2d56a0bca46b6326fd7bb229979916cea40de2270a98128fd94441b87c2 languageName: node linkType: hard -"@types/serve-static@npm:*": - version: 1.15.5 - resolution: "@types/serve-static@npm:1.15.5" +"@types/serve-static@npm:^1": + version: 1.15.10 + resolution: "@types/serve-static@npm:1.15.10" dependencies: "@types/http-errors": "npm:*" - "@types/mime": "npm:*" "@types/node": "npm:*" - checksum: 10c0/811d1a2f7e74a872195e7a013bcd87a2fb1edf07eaedcb9dcfd20c1eb4bc56ad4ea0d52141c13192c91ccda7c8aeb8a530d8a7e60b9c27f5990d7e62e0fecb03 + "@types/send": "npm:<1" + checksum: 10c0/842fca14c9e80468f89b6cea361773f2dcd685d4616a9f59013b55e1e83f536e4c93d6d8e3ba5072d40c4e7e64085210edd6646b15d538ded94512940a23021f languageName: node linkType: hard @@ -4572,106 +4524,106 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.45.0" +"@typescript-eslint/eslint-plugin@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/eslint-plugin@npm:8.46.3" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.45.0" - "@typescript-eslint/type-utils": "npm:8.45.0" - "@typescript-eslint/utils": "npm:8.45.0" - "@typescript-eslint/visitor-keys": "npm:8.45.0" + "@typescript-eslint/scope-manager": "npm:8.46.3" + "@typescript-eslint/type-utils": "npm:8.46.3" + "@typescript-eslint/utils": "npm:8.46.3" + "@typescript-eslint/visitor-keys": "npm:8.46.3" graphemer: "npm:^1.4.0" ignore: "npm:^7.0.0" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^2.1.0" peerDependencies: - "@typescript-eslint/parser": ^8.45.0 + "@typescript-eslint/parser": ^8.46.3 eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/0c60a0e5d07fa8618348db38b5a81e66143d528e1b3cdb5678bbc6c60590cd559b27c98c36f5663230fc4cf6920dff2cd604de30b58df26a37fcfcc5dc1dbd45 + checksum: 10c0/9c8a5efd9779418d2096634a072a9e2b108e146d0fc541572db56ff28ff37469f03dd404fdb3b0c3161be4cc4857ce14259f30eba1a93d4771de5d1562624e45 languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/parser@npm:8.45.0" +"@typescript-eslint/parser@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/parser@npm:8.46.3" dependencies: - "@typescript-eslint/scope-manager": "npm:8.45.0" - "@typescript-eslint/types": "npm:8.45.0" - "@typescript-eslint/typescript-estree": "npm:8.45.0" - "@typescript-eslint/visitor-keys": "npm:8.45.0" + "@typescript-eslint/scope-manager": "npm:8.46.3" + "@typescript-eslint/types": "npm:8.46.3" + "@typescript-eslint/typescript-estree": "npm:8.46.3" + "@typescript-eslint/visitor-keys": "npm:8.46.3" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/8b419bcf795b112a39fcac05dcf147835059345b6399035ffa3f76a9d8e320f3fac79cae2fe4320dcda83fa059b017ca7626a7b4e3da08a614415c8867d169b8 + checksum: 10c0/8a8b47abbbc8bbc68f423df23189afefd296305d50a31c6bec9bdde563adc9ddf99b89a6b8466965fda4aee9118263bae36422dd1c25d7595dd82f8897b5df61 languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/project-service@npm:8.45.0" +"@typescript-eslint/project-service@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/project-service@npm:8.46.3" dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.45.0" - "@typescript-eslint/types": "npm:^8.45.0" + "@typescript-eslint/tsconfig-utils": "npm:^8.46.3" + "@typescript-eslint/types": "npm:^8.46.3" debug: "npm:^4.3.4" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/98af065a1a3ed9d3d1eb265e09d3e9c2ae676d500a8c1d764f5609fe2c1b86749516b709804eb814fae688be7809d11748b9ae691d43c28da51dac390ca81fa9 + checksum: 10c0/24ef305bbb550a8e27a7d6377663c1f2773b39b7a9f12c8b95c66c0d15f8150787b036bbff9ae4c2a0a18ab68c62435b0e03889df294bef00b3ae8846cd20659 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/scope-manager@npm:8.45.0" +"@typescript-eslint/scope-manager@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/scope-manager@npm:8.46.3" dependencies: - "@typescript-eslint/types": "npm:8.45.0" - "@typescript-eslint/visitor-keys": "npm:8.45.0" - checksum: 10c0/54cd36206f6b4fc8e1e48576ed01e0d6ab20c2a9c4c7d90d5cc3a2d317dd8a13abe148ffecf471b16f1224aba5749e0905472745626bef9ae5bed771776f4abe + "@typescript-eslint/types": "npm:8.46.3" + "@typescript-eslint/visitor-keys": "npm:8.46.3" + checksum: 10c0/de8c116477e2a05a895ecd848a8289974a76cab884e07683c8085b3a2ce53895871d9bcd9de94723d6b2a437a6c526c77afcc75d6030cc4f1dccb9b47f4fc069 languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.45.0, @typescript-eslint/tsconfig-utils@npm:^8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.45.0" +"@typescript-eslint/tsconfig-utils@npm:8.46.3, @typescript-eslint/tsconfig-utils@npm:^8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.3" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/227a9b7a5baaf35466fd369992cb933192515df1156ddf22f438deb344c2523695208e1036f5590b20603f31724de75a47fe0ee84e2fd4c8e9f3606f23f68112 + checksum: 10c0/a9686141204a96591ee51814a79fa676a8da845638eabb2363f9d82902660fd48ea47f7ec15a618129e45021ad154e1d193127248915752546d60d475d6a566e languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/type-utils@npm:8.45.0" +"@typescript-eslint/type-utils@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/type-utils@npm:8.46.3" dependencies: - "@typescript-eslint/types": "npm:8.45.0" - "@typescript-eslint/typescript-estree": "npm:8.45.0" - "@typescript-eslint/utils": "npm:8.45.0" + "@typescript-eslint/types": "npm:8.46.3" + "@typescript-eslint/typescript-estree": "npm:8.46.3" + "@typescript-eslint/utils": "npm:8.46.3" debug: "npm:^4.3.4" ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/ce0f4c209c2418ebeb65e7de053499fb68bf6000bdd71068594fdb8c8ac3dbbd62935a3cea233989491f7da3ef5db87e7efd2910133c6abf6d0cbf57248f6442 + checksum: 10c0/06e20dff5a22feb6581703e8d35159ad6694d9e1df8fbb75869fcd89893826ca533b7b30b795a16d532e9d8ea6720462b1361d1e7a11d431a4cd11b3f47a22b5 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.45.0, @typescript-eslint/types@npm:^8.34.1, @typescript-eslint/types@npm:^8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/types@npm:8.45.0" - checksum: 10c0/0213a0573c671d13bc91961a2b2e814ec7f6381ff093bce6704017bd96b2fc7fee25906c815cedb32a0601cf5071ca6c7c5f940d087c3b0d3dd7d4bc03478278 +"@typescript-eslint/types@npm:8.46.3, @typescript-eslint/types@npm:^8.46.0, @typescript-eslint/types@npm:^8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/types@npm:8.46.3" + checksum: 10c0/6a6ccefbd086e6c38172fe14d04ba27c1c34755af7c25e752547c42d978b91bf6b97da56a5e63d098fbd679b4a5076c4dd4be6c947fd39b4c5feea5fed6deeb6 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.45.0" +"@typescript-eslint/typescript-estree@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/typescript-estree@npm:8.46.3" dependencies: - "@typescript-eslint/project-service": "npm:8.45.0" - "@typescript-eslint/tsconfig-utils": "npm:8.45.0" - "@typescript-eslint/types": "npm:8.45.0" - "@typescript-eslint/visitor-keys": "npm:8.45.0" + "@typescript-eslint/project-service": "npm:8.46.3" + "@typescript-eslint/tsconfig-utils": "npm:8.46.3" + "@typescript-eslint/types": "npm:8.46.3" + "@typescript-eslint/visitor-keys": "npm:8.46.3" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -4680,32 +4632,32 @@ __metadata: ts-api-utils: "npm:^2.1.0" peerDependencies: typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/8c2f44a00fe859a6cd4b50157c484c5b6a1c7af5d48e89ae79c5f4924947964962fc8f478ad4c2ade788907fceee9b72d4e376508ea79b51392f91082a37d239 + checksum: 10c0/3a2bb879a3b42eda478015beee42729efdc78c0cfc70fa009442706626813114f8f9a1e918638ab957df385681ab073cf2076c508973ff9a72e2425e4e521b4f languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.45.0, @typescript-eslint/utils@npm:^8.27.0, @typescript-eslint/utils@npm:^8.8.1": - version: 8.45.0 - resolution: "@typescript-eslint/utils@npm:8.45.0" +"@typescript-eslint/utils@npm:8.46.3, @typescript-eslint/utils@npm:^8.27.0, @typescript-eslint/utils@npm:^8.8.1": + version: 8.46.3 + resolution: "@typescript-eslint/utils@npm:8.46.3" dependencies: "@eslint-community/eslint-utils": "npm:^4.7.0" - "@typescript-eslint/scope-manager": "npm:8.45.0" - "@typescript-eslint/types": "npm:8.45.0" - "@typescript-eslint/typescript-estree": "npm:8.45.0" + "@typescript-eslint/scope-manager": "npm:8.46.3" + "@typescript-eslint/types": "npm:8.46.3" + "@typescript-eslint/typescript-estree": "npm:8.46.3" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/b3c83a23813b15e20e303d7153789508c01e06dec355b1a80547c59aa36998d498102f45fcd13f111031fac57270608abb04d20560248d4448fd00b1cf4dc4ab + checksum: 10c0/cf85b166f75c2fd248004fb59643315347489d9ab589738cda1b4c36c25e7947c197a1c21e46cb25959be7d0f310b352c4436f8d3e0a91d64e4fafb3ef4b4e3d languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.45.0": - version: 8.45.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.45.0" +"@typescript-eslint/visitor-keys@npm:8.46.3": + version: 8.46.3 + resolution: "@typescript-eslint/visitor-keys@npm:8.46.3" dependencies: - "@typescript-eslint/types": "npm:8.45.0" + "@typescript-eslint/types": "npm:8.46.3" eslint-visitor-keys: "npm:^4.2.1" - checksum: 10c0/119adcf50c902dad7f7757bcdd88fad0a23a171d309d9b7cefe78af12e451cf84c04ae611f4c31f7e23f16c2b47665ad92e6e5648fc77d542ef306f465bf1f29 + checksum: 10c0/c5f96840e0c31541e1a2390712a6cb290eff59fc97a3ffa7ecab353d3bb3cf0d8c6f62d68db271bf194aa8c4582be735b6121fcc5b30449e01799642be77de6e languageName: node linkType: hard @@ -4886,72 +4838,78 @@ __metadata: linkType: hard "@vitejs/plugin-react@npm:^5.0.0": - version: 5.0.4 - resolution: "@vitejs/plugin-react@npm:5.0.4" + version: 5.1.0 + resolution: "@vitejs/plugin-react@npm:5.1.0" dependencies: "@babel/core": "npm:^7.28.4" "@babel/plugin-transform-react-jsx-self": "npm:^7.27.1" "@babel/plugin-transform-react-jsx-source": "npm:^7.27.1" - "@rolldown/pluginutils": "npm:1.0.0-beta.38" + "@rolldown/pluginutils": "npm:1.0.0-beta.43" "@types/babel__core": "npm:^7.20.5" - react-refresh: "npm:^0.17.0" + react-refresh: "npm:^0.18.0" peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - checksum: 10c0/bb9360a4b4c0abf064d22211756b999faf23889ac150de490590ca7bd029b0ef7f4cd8ba3a32b86682a62d46fb7bebd75b3fa9835c57c78123f4a646de2e0136 + checksum: 10c0/e192a12e2b854df109eafb1d06c0bc848e8e2b162c686aa6b999b1048658983e72674b2068ccc37562fcce44d32ad92b65f3a4e1897a0cb7859c2ee69cc63eac languageName: node linkType: hard -"@vitest/browser@npm:^3.2.4": - version: 3.2.4 - resolution: "@vitest/browser@npm:3.2.4" +"@vitest/browser-playwright@npm:^4.0.5": + version: 4.0.7 + resolution: "@vitest/browser-playwright@npm:4.0.7" dependencies: - "@testing-library/dom": "npm:^10.4.0" - "@testing-library/user-event": "npm:^14.6.1" - "@vitest/mocker": "npm:3.2.4" - "@vitest/utils": "npm:3.2.4" - magic-string: "npm:^0.30.17" - sirv: "npm:^3.0.1" - tinyrainbow: "npm:^2.0.0" - ws: "npm:^8.18.2" + "@vitest/browser": "npm:4.0.7" + "@vitest/mocker": "npm:4.0.7" + tinyrainbow: "npm:^3.0.3" peerDependencies: playwright: "*" - vitest: 3.2.4 - webdriverio: ^7.0.0 || ^8.0.0 || ^9.0.0 + vitest: 4.0.7 peerDependenciesMeta: playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - checksum: 10c0/0db39daad675aad187eff27d5a7f17a9f533d7abc7476ee1a0b83a9c62a7227b24395f4814e034ecb2ebe39f1a2dec0a8c6a7f79b8d5680c3ac79e408727d742 + optional: false + checksum: 10c0/85969557a441c141b14bc13e3b2f1b70f7e7aa3eb8a63489b4b3af253b3fcd8019293cb56e1dea50f338eca9bc845e21ec85f1c88ab6bc3ee494fbdacac153a3 languageName: node linkType: hard -"@vitest/coverage-v8@npm:^3.2.4": - version: 3.2.4 - resolution: "@vitest/coverage-v8@npm:3.2.4" +"@vitest/browser@npm:4.0.7, @vitest/browser@npm:^4.0.5": + version: 4.0.7 + resolution: "@vitest/browser@npm:4.0.7" + dependencies: + "@vitest/mocker": "npm:4.0.7" + "@vitest/utils": "npm:4.0.7" + magic-string: "npm:^0.30.19" + pixelmatch: "npm:7.1.0" + pngjs: "npm:^7.0.0" + sirv: "npm:^3.0.2" + tinyrainbow: "npm:^3.0.3" + ws: "npm:^8.18.3" + peerDependencies: + vitest: 4.0.7 + checksum: 10c0/22b6d666f7ae6220dea8d55afd787b435f4dc19656d22c7892f7caafd3c26b62fc87a091384c6044aa49b84c187581f6cad44fd8a65f1583abef5197a162b5c6 + languageName: node + linkType: hard + +"@vitest/coverage-v8@npm:^4.0.5": + version: 4.0.7 + resolution: "@vitest/coverage-v8@npm:4.0.7" dependencies: - "@ampproject/remapping": "npm:^2.3.0" "@bcoe/v8-coverage": "npm:^1.0.2" - ast-v8-to-istanbul: "npm:^0.3.3" - debug: "npm:^4.4.1" + "@vitest/utils": "npm:4.0.7" + ast-v8-to-istanbul: "npm:^0.3.5" + debug: "npm:^4.4.3" istanbul-lib-coverage: "npm:^3.2.2" istanbul-lib-report: "npm:^3.0.1" istanbul-lib-source-maps: "npm:^5.0.6" - istanbul-reports: "npm:^3.1.7" - magic-string: "npm:^0.30.17" + istanbul-reports: "npm:^3.2.0" magicast: "npm:^0.3.5" std-env: "npm:^3.9.0" - test-exclude: "npm:^7.0.1" - tinyrainbow: "npm:^2.0.0" + tinyrainbow: "npm:^3.0.3" peerDependencies: - "@vitest/browser": 3.2.4 - vitest: 3.2.4 + "@vitest/browser": 4.0.7 + vitest: 4.0.7 peerDependenciesMeta: "@vitest/browser": optional: true - checksum: 10c0/cae3e58d81d56e7e1cdecd7b5baab7edd0ad9dee8dec9353c52796e390e452377d3f04174d40b6986b17c73241a5e773e422931eaa8102dcba0605ff24b25193 + checksum: 10c0/4a34c6de4d1e8173856af078c053e5a6d4a3ad0085fd613fddbe5067b7083d6d11858788a994a3bd427630ddd56cc5eb948b59b425b2c7ba7dd73094d2f1844f languageName: node linkType: hard @@ -4968,6 +4926,20 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/expect@npm:4.0.7" + dependencies: + "@standard-schema/spec": "npm:^1.0.0" + "@types/chai": "npm:^5.2.2" + "@vitest/spy": "npm:4.0.7" + "@vitest/utils": "npm:4.0.7" + chai: "npm:^6.0.1" + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/366d7be563149b6143a6f275ae37b77ac7b13d96cd5b0992bfece5c801c1ed1cb7f4a1a1921e9fa5c47f8ad4e73bdfb9f3f362acc42be34cedcb907020c313a2 + languageName: node + linkType: hard + "@vitest/mocker@npm:3.2.4": version: 3.2.4 resolution: "@vitest/mocker@npm:3.2.4" @@ -4987,7 +4959,26 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:3.2.4, @vitest/pretty-format@npm:^3.2.4": +"@vitest/mocker@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/mocker@npm:4.0.7" + dependencies: + "@vitest/spy": "npm:4.0.7" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.19" + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10c0/a500d2eca0e8b43f63358bd102e1203f3e478c0896ebe41dcdac0ab048e991736dc053bd4129dcf62ba94d4d3d2e43793175cd7deb6552cf54a2a9c8a5bab77b + languageName: node + linkType: hard + +"@vitest/pretty-format@npm:3.2.4": version: 3.2.4 resolution: "@vitest/pretty-format@npm:3.2.4" dependencies: @@ -4996,25 +4987,33 @@ __metadata: languageName: node linkType: hard -"@vitest/runner@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/runner@npm:3.2.4" +"@vitest/pretty-format@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/pretty-format@npm:4.0.7" dependencies: - "@vitest/utils": "npm:3.2.4" - pathe: "npm:^2.0.3" - strip-literal: "npm:^3.0.0" - checksum: 10c0/e8be51666c72b3668ae3ea348b0196656a4a5adb836cb5e270720885d9517421815b0d6c98bfdf1795ed02b994b7bfb2b21566ee356a40021f5bf4f6ed4e418a + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/4084355dbc7b1b9ee4b777adbbc44833dfd4c4a4bb2de8cb5ef28f490bf1c699eb31820157692dc87504b26e6b7bd931d0f316472895bfbc608327a671646032 languageName: node linkType: hard -"@vitest/snapshot@npm:3.2.4": - version: 3.2.4 - resolution: "@vitest/snapshot@npm:3.2.4" +"@vitest/runner@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/runner@npm:4.0.7" dependencies: - "@vitest/pretty-format": "npm:3.2.4" - magic-string: "npm:^0.30.17" + "@vitest/utils": "npm:4.0.7" pathe: "npm:^2.0.3" - checksum: 10c0/f8301a3d7d1559fd3d59ed51176dd52e1ed5c2d23aa6d8d6aa18787ef46e295056bc726a021698d8454c16ed825ecba163362f42fa90258bb4a98cfd2c9424fc + checksum: 10c0/717d7ce765eba1493051b309f82755a4b1d8594de6cd9d036864c9464dadc604c703388d96e070fe843b0216d2a7b66e59d18ad3db8055990114b3506bc172bf + languageName: node + linkType: hard + +"@vitest/snapshot@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/snapshot@npm:4.0.7" + dependencies: + "@vitest/pretty-format": "npm:4.0.7" + magic-string: "npm:^0.30.19" + pathe: "npm:^2.0.3" + checksum: 10c0/0382303038ebc58d419047fd329f848336e06b292839ea6ec05063092ce32464eb6a21c00e6487541e42b8155fa0c10b8cc2f6445ff85256b7d73feeb4a8afef languageName: node linkType: hard @@ -5027,20 +5026,27 @@ __metadata: languageName: node linkType: hard -"@vitest/ui@npm:^3.2.4": - version: 3.2.4 - resolution: "@vitest/ui@npm:3.2.4" +"@vitest/spy@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/spy@npm:4.0.7" + checksum: 10c0/88c8fdffa54cdfb9f4157316d1fb3308ad1630791881866878c7cbf837ad8e6e6aa79041c82635b2598ed551cf93409d34a434c87b779a30a66f55221de636fa + languageName: node + linkType: hard + +"@vitest/ui@npm:^4.0.5": + version: 4.0.7 + resolution: "@vitest/ui@npm:4.0.7" dependencies: - "@vitest/utils": "npm:3.2.4" + "@vitest/utils": "npm:4.0.7" fflate: "npm:^0.8.2" flatted: "npm:^3.3.3" pathe: "npm:^2.0.3" - sirv: "npm:^3.0.1" - tinyglobby: "npm:^0.2.14" - tinyrainbow: "npm:^2.0.0" + sirv: "npm:^3.0.2" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.0.3" peerDependencies: - vitest: 3.2.4 - checksum: 10c0/c3de1b757905d050706c7ab0199185dd8c7e115f2f348b8d5a7468528c6bf90c2c46096e8901602349ac04f5ba83ac23cd98c38827b104d5151cf8ba21739a0c + vitest: 4.0.7 + checksum: 10c0/e7173da36e9549a8b04ee4015a64882075aa9f49a59cb135616d22c6d881244c938cf41f6ef149d7e1f42ff414dc72f2bb23f5334b4285801adf83280b23a279 languageName: node linkType: hard @@ -5055,6 +5061,16 @@ __metadata: languageName: node linkType: hard +"@vitest/utils@npm:4.0.7": + version: 4.0.7 + resolution: "@vitest/utils@npm:4.0.7" + dependencies: + "@vitest/pretty-format": "npm:4.0.7" + tinyrainbow: "npm:^3.0.3" + checksum: 10c0/a2305c5117a30f1685f362767a0e0cc47265f3602469641f6eb01b4b708e2b1c35c33ccf480314348b21978d70a78311cce3f5bdd09de6456d528c5469093217 + languageName: node + linkType: hard + "abbrev@npm:^3.0.0": version: 3.0.1 resolution: "abbrev@npm:3.0.1" @@ -5062,13 +5078,13 @@ __metadata: languageName: node linkType: hard -"accepts@npm:~1.3.8": - version: 1.3.8 - resolution: "accepts@npm:1.3.8" +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" dependencies: - mime-types: "npm:~2.1.34" - negotiator: "npm:0.6.3" - checksum: 10c0/3a35c5f5586cfb9a21163ca47a5f77ac34fa8ceb5d17d2fa2c0d81f41cbd7f8c6fa52c77e2c039acc0f4d09e71abdc51144246900f6bef5e3c4b333f77d89362 + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef languageName: node linkType: hard @@ -5081,7 +5097,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.8.2": +"acorn@npm:^8.15.0, acorn@npm:^8.8.2": version: 8.15.0 resolution: "acorn@npm:8.15.0" bin: @@ -5226,13 +5242,6 @@ __metadata: languageName: node linkType: hard -"array-flatten@npm:1.1.1": - version: 1.1.1 - resolution: "array-flatten@npm:1.1.1" - checksum: 10c0/806966c8abb2f858b08f5324d9d18d7737480610f3bd5d3498aaae6eb5efdc501a884ba019c9b4a8f02ff67002058749d05548fd42fa8643f02c9c7f22198b91 - languageName: node - linkType: hard - "array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": version: 3.1.9 resolution: "array-includes@npm:3.1.9" @@ -5367,14 +5376,14 @@ __metadata: languageName: node linkType: hard -"ast-v8-to-istanbul@npm:^0.3.3": - version: 0.3.3 - resolution: "ast-v8-to-istanbul@npm:0.3.3" +"ast-v8-to-istanbul@npm:^0.3.5": + version: 0.3.8 + resolution: "ast-v8-to-istanbul@npm:0.3.8" dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.25" + "@jridgewell/trace-mapping": "npm:^0.3.31" estree-walker: "npm:^3.0.3" js-tokens: "npm:^9.0.1" - checksum: 10c0/ffc39bc3ab4b8c1f7aea945960ce6b1e518bab3da7c800277eab2da07d397eeae4a2cb8a5a5f817225646c8ea495c1e4434fbe082c84bae8042abddef53f50b2 + checksum: 10c0/6f7d74fc36011699af6d4ad88ecd8efc7d74bd90b8e8dbb1c69d43c8f4bec0ed361fb62a5b5bd98bbee02ee87c62cd8bcc25a39634964e45476bf5489dfa327f languageName: node linkType: hard @@ -5457,13 +5466,13 @@ __metadata: linkType: hard "axios@npm:^1.4.0": - version: 1.12.2 - resolution: "axios@npm:1.12.2" + version: 1.13.2 + resolution: "axios@npm:1.13.2" dependencies: follow-redirects: "npm:^1.15.6" form-data: "npm:^4.0.4" proxy-from-env: "npm:^1.1.0" - checksum: 10c0/80b063e318cf05cd33a4d991cea0162f3573481946f9129efb7766f38fde4c061c34f41a93a9f9521f02b7c9565ccbc197c099b0186543ac84a24580017adfed + checksum: 10c0/e8a42e37e5568ae9c7a28c348db0e8cf3e43d06fcbef73f0048669edfe4f71219664da7b6cc991b0c0f01c28a48f037c515263cb79be1f1ae8ff034cd813867b languageName: node linkType: hard @@ -5570,15 +5579,6 @@ __metadata: languageName: node linkType: hard -"better-opn@npm:^3.0.2": - version: 3.0.2 - resolution: "better-opn@npm:3.0.2" - dependencies: - open: "npm:^8.0.4" - checksum: 10c0/911ef25d44da75aabfd2444ce7a4294a8000ebcac73068c04a60298b0f7c7506b60421aa4cd02ac82502fb42baaff7e4892234b51e6923eded44c5a11185f2f5 - languageName: node - linkType: hard - "bidi-js@npm:^1.0.3": version: 1.0.3 resolution: "bidi-js@npm:1.0.3" @@ -5616,23 +5616,20 @@ __metadata: languageName: node linkType: hard -"body-parser@npm:1.20.3": - version: 1.20.3 - resolution: "body-parser@npm:1.20.3" +"body-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "body-parser@npm:2.2.0" dependencies: - bytes: "npm:3.1.2" - content-type: "npm:~1.0.5" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" - on-finished: "npm:2.4.1" - qs: "npm:6.13.0" - raw-body: "npm:2.5.2" - type-is: "npm:~1.6.18" - unpipe: "npm:1.0.0" - checksum: 10c0/0a9a93b7518f222885498dcecaad528cf010dd109b071bf471c93def4bfe30958b83e03496eb9c1ad4896db543d999bb62be1a3087294162a88cfa1b42c16310 + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.0" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.6.3" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.0" + raw-body: "npm:^3.0.0" + type-is: "npm:^2.0.0" + checksum: 10c0/a9ded39e71ac9668e2211afa72e82ff86cc5ef94de1250b7d1ba9cc299e4150408aaa5f1e8b03dd4578472a3ce6d1caa2a23b27a6c18e526e48b4595174c116c languageName: node linkType: hard @@ -5709,20 +5706,13 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2": +"bytes@npm:3.1.2, bytes@npm:^3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e languageName: node linkType: hard -"cac@npm:^6.7.14": - version: 6.7.14 - resolution: "cac@npm:6.7.14" - checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 - languageName: node - linkType: hard - "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -5822,6 +5812,13 @@ __metadata: languageName: node linkType: hard +"chai@npm:^6.0.1": + version: 6.2.0 + resolution: "chai@npm:6.2.0" + checksum: 10c0/a4b7d7f5907187e09f1847afa838d6d1608adc7d822031b7900813c4ed5d9702911ac2468bf290676f22fddb3d727b1be90b57c1d0a69b902534ee29cdc6ff8a + languageName: node + linkType: hard + "chalk@npm:^3.0.0": version: 3.0.0 resolution: "chalk@npm:3.0.0" @@ -6014,10 +6011,10 @@ __metadata: languageName: node linkType: hard -"commander@npm:14.0.1": - version: 14.0.1 - resolution: "commander@npm:14.0.1" - checksum: 10c0/64439c0651ddd01c1d0f48c8f08e97c18a0a1fa693879451f1203ad01132af2c2aa85da24cf0d8e098ab9e6dc385a756be670d2999a3c628ec745c3ec124587b +"commander@npm:^14.0.1": + version: 14.0.2 + resolution: "commander@npm:14.0.2" + checksum: 10c0/245abd1349dbad5414cb6517b7b5c584895c02c4f7836ff5395f301192b8566f9796c82d7bd6c92d07eba8775fe4df86602fca5d86d8d10bcc2aded1e21c2aeb languageName: node linkType: hard @@ -6049,16 +6046,16 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4": - version: 0.5.4 - resolution: "content-disposition@npm:0.5.4" +"content-disposition@npm:^1.0.0": + version: 1.0.0 + resolution: "content-disposition@npm:1.0.0" dependencies: safe-buffer: "npm:5.2.1" - checksum: 10c0/bac0316ebfeacb8f381b38285dc691c9939bf0a78b0b7c2d5758acadad242d04783cee5337ba7d12a565a19075af1b3c11c728e1e4946de73c6ff7ce45f3f1bb + checksum: 10c0/c7b1ba0cea2829da0352ebc1b7f14787c73884bc707c8bc2271d9e3bf447b372270d09f5d3980dc5037c749ceef56b9a13fccd0b0001c87c3f12579967e4dd27 languageName: node linkType: hard -"content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:^1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10c0/b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af @@ -6079,27 +6076,29 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:1.0.6": - version: 1.0.6 - resolution: "cookie-signature@npm:1.0.6" - checksum: 10c0/b36fd0d4e3fef8456915fcf7742e58fbfcc12a17a018e0eb9501c9d5ef6893b596466f03b0564b81af29ff2538fd0aa4b9d54fe5ccbfb4c90ea50ad29fe2d221 +"cookie-signature@npm:^1.2.1": + version: 1.2.2 + resolution: "cookie-signature@npm:1.2.2" + checksum: 10c0/54e05df1a293b3ce81589b27dddc445f462f6fa6812147c033350cd3561a42bc14481674e05ed14c7bd0ce1e8bb3dc0e40851bad75415733711294ddce0b7bc6 languageName: node linkType: hard -"cookie@npm:0.7.1": - version: 0.7.1 - resolution: "cookie@npm:0.7.1" - checksum: 10c0/5de60c67a410e7c8dc8a46a4b72eb0fe925871d057c9a5d2c0e8145c4270a4f81076de83410c4d397179744b478e33cd80ccbcc457abf40a9409ad27dcd21dde - languageName: node - linkType: hard - -"cookie@npm:^0.7.2": +"cookie@npm:^0.7.1, cookie@npm:^0.7.2": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10c0/9596e8ccdbf1a3a88ae02cf5ee80c1c50959423e1022e4e60b91dd87c622af1da309253d8abdb258fb5e3eacb4f08e579dc58b4897b8087574eee0fd35dfa5d2 languageName: node linkType: hard +"copy-anything@npm:^2.0.1": + version: 2.0.6 + resolution: "copy-anything@npm:2.0.6" + dependencies: + is-what: "npm:^3.14.1" + checksum: 10c0/2702998a8cc015f9917385b7f16b0d85f1f6e5e2fd34d99f14df584838f492f49aa0c390d973684c687e895c5c58d08b308a0400ac3e1e3d6fa1e5884a5402ad + languageName: node + linkType: hard + "core-js-compat@npm:^3.43.0": version: 3.44.0 resolution: "core-js-compat@npm:3.44.0" @@ -6284,14 +6283,14 @@ __metadata: languageName: node linkType: hard -"cssstyle@npm:^5.3.1": - version: 5.3.1 - resolution: "cssstyle@npm:5.3.1" +"cssstyle@npm:^5.3.2": + version: 5.3.2 + resolution: "cssstyle@npm:5.3.2" dependencies: "@asamuzakjp/css-color": "npm:^4.0.3" "@csstools/css-syntax-patches-for-csstree": "npm:^1.0.14" css-tree: "npm:^3.1.0" - checksum: 10c0/41c93a6816337403f6107adb76d06989155523842a6c1c070436af13e9ff2bc72031cf469cd1d86ca1b9e1edacbe07b1c2dea5aaf5b530b982878844ba7f2b25 + checksum: 10c0/513f0bd5d80fa91beadd24a9f4d4705f1f7e783acd90049ba6ceaf452101326208dd0d1d088d3565c4df94e4730582bf3857ea0fd3e733d10b6141be6eb68e40 languageName: node linkType: hard @@ -6359,16 +6358,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9": - version: 2.6.9 - resolution: "debug@npm:2.6.9" - dependencies: - ms: "npm:2.0.0" - checksum: 10c0/121908fb839f7801180b69a7e218a40b5a0b718813b886b7d6bdb82001b931c938e2941d1e4450f33a1b1df1da653f5f7a0440c197f29fbf8a6e9d45ff6ef589 - languageName: node - linkType: hard - -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.6, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.6, debug@npm:^4.4.0, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -6460,7 +6450,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: 10c0/58bd06ec20e19529b06f7ad07ddab60e504d9e0faca4bd23079fac2d279c3594334d736508dc350e06e510aba5e22e4594483b3a6562ce7c17dd797f4cc4ad2c @@ -6474,13 +6464,6 @@ __metadata: languageName: node linkType: hard -"destroy@npm:1.2.0": - version: 1.2.0 - resolution: "destroy@npm:1.2.0" - checksum: 10c0/bd7633942f57418f5a3b80d5cb53898127bcf53e24cdf5d5f4396be471417671f0fee48a4ebe9a1e9defbde2a31280011af58a57e090ff822f589b443ed4e643 - languageName: node - linkType: hard - "detect-it@npm:^4.0.1": version: 4.0.1 resolution: "detect-it@npm:4.0.1" @@ -6567,10 +6550,10 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.0.3": - version: 16.5.0 - resolution: "dotenv@npm:16.5.0" - checksum: 10c0/5bc94c919fbd955bf0ba44d33922a1e93d1078e64a1db5c30faeded1d996e7a83c55332cb8ea4fae5a9ca4d0be44cbceb95c5811e70f9f095298df09d1997dd9 +"dotenv@npm:^16.0.3, dotenv@npm:^16.4.2": + version: 16.6.1 + resolution: "dotenv@npm:16.6.1" + checksum: 10c0/15ce56608326ea0d1d9414a5c8ee6dcf0fffc79d2c16422b4ac2268e7e2d76ff5a572d37ffe747c377de12005f14b3cc22361e79fc7f1061cce81f77d2c973dc languageName: node linkType: hard @@ -6674,14 +6657,14 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~1.0.2": - version: 1.0.2 - resolution: "encodeurl@npm:1.0.2" - checksum: 10c0/f6c2387379a9e7c1156c1c3d4f9cb7bb11cf16dd4c1682e1f6746512564b053df5781029b6061296832b59fb22f459dbe250386d217c2f6e203601abb2ee0bec +"empathic@npm:^2.0.0": + version: 2.0.0 + resolution: "empathic@npm:2.0.0" + checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 languageName: node linkType: hard -"encodeurl@npm:~2.0.0": +"encodeurl@npm:^2.0.0": version: 2.0.0 resolution: "encodeurl@npm:2.0.0" checksum: 10c0/5d317306acb13e6590e28e27924c754163946a2480de11865c991a3a7eed4315cd3fba378b543ca145829569eefe9b899f3d84bb09870f675ae60bc924b01ceb @@ -6741,6 +6724,17 @@ __metadata: languageName: node linkType: hard +"errno@npm:^0.1.1": + version: 0.1.8 + resolution: "errno@npm:0.1.8" + dependencies: + prr: "npm:~1.0.1" + bin: + errno: cli.js + checksum: 10c0/83758951967ec57bf00b5f5b7dc797e6d65a6171e57ea57adcf1bd1a0b477fd9b5b35fae5be1ff18f4090ed156bce1db749fe7e317aac19d485a5d150f6a4936 + languageName: node + linkType: hard + "error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" @@ -6907,17 +6901,6 @@ __metadata: languageName: node linkType: hard -"esbuild-register@npm:^3.5.0": - version: 3.6.0 - resolution: "esbuild-register@npm:3.6.0" - dependencies: - debug: "npm:^4.3.4" - peerDependencies: - esbuild: ">=0.12 <1" - checksum: 10c0/77193b7ca32ba9f81b35ddf3d3d0138efb0b1429d71b39480cfee932e1189dd2e492bd32bf04a4d0bc3adfbc7ec7381ceb5ffd06efe35f3e70904f1f686566d5 - languageName: node - linkType: hard - "esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0, esbuild@npm:^0.25.0": version: 0.25.5 resolution: "esbuild@npm:0.25.5" @@ -7011,7 +6994,7 @@ __metadata: languageName: node linkType: hard -"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3": +"escape-html@npm:^1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" checksum: 10c0/524c739d776b36c3d29fa08a22e03e8824e3b2fd57500e5e44ecf3cc4707c34c60f9ca0781c0e33d191f2991161504c295e98f68c78fe7baa6e57081ec6ac0a3 @@ -7088,11 +7071,11 @@ __metadata: linkType: hard "eslint-plugin-formatjs@npm:^5.3.1": - version: 5.4.0 - resolution: "eslint-plugin-formatjs@npm:5.4.0" + version: 5.4.2 + resolution: "eslint-plugin-formatjs@npm:5.4.2" dependencies: - "@formatjs/icu-messageformat-parser": "npm:2.11.2" - "@formatjs/ts-transformer": "npm:3.14.0" + "@formatjs/icu-messageformat-parser": "npm:2.11.4" + "@formatjs/ts-transformer": "npm:3.14.2" "@types/eslint": "npm:^9.6.1" "@types/picomatch": "npm:^3" "@typescript-eslint/utils": "npm:^8.27.0" @@ -7102,7 +7085,7 @@ __metadata: unicode-emoji-utils: "npm:^1.2.0" peerDependencies: eslint: ^9.23.0 - checksum: 10c0/5c74a53988df68ffed4e68bb58a4ee75cdcd92b7d94f699e2edbcdd8c2c45930f500c7211da0a4616714d7d83bbbdc105328e5aacf0c9c7582a78fdfc9fa2b55 + checksum: 10c0/46bee038c54a7da58647eaccee6c956857ad81499b60f814914921b26852e6bf9b0efabb9556d7aab0e151ba349dcf949dc5f14a356b80bc5e63f338e7f7cc7f languageName: node linkType: hard @@ -7135,23 +7118,27 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsdoc@npm:^54.0.0": - version: 54.0.0 - resolution: "eslint-plugin-jsdoc@npm:54.0.0" +"eslint-plugin-jsdoc@npm:^61.1.11": + version: 61.1.12 + resolution: "eslint-plugin-jsdoc@npm:61.1.12" dependencies: - "@es-joy/jsdoccomment": "npm:~0.52.0" + "@es-joy/jsdoccomment": "npm:~0.76.0" + "@es-joy/resolve.exports": "npm:1.2.0" are-docs-informative: "npm:^0.0.2" comment-parser: "npm:1.4.1" - debug: "npm:^4.4.1" + debug: "npm:^4.4.3" escape-string-regexp: "npm:^4.0.0" espree: "npm:^10.4.0" esquery: "npm:^1.6.0" + html-entities: "npm:^2.6.0" + object-deep-merge: "npm:^2.0.0" parse-imports-exports: "npm:^0.2.4" - semver: "npm:^7.7.2" + semver: "npm:^7.7.3" spdx-expression-parse: "npm:^4.0.0" + to-valid-identifier: "npm:^1.0.0" peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - checksum: 10c0/cf0a388fc670ababe26f9584c467bc8c1592aa83affcf16118d8181c186a6d8f02a8ea65250766b45168fca5cb879a6af66e8457cdb98f0f923bd927572e2de5 + checksum: 10c0/a0d291796029f8c3711ece955afde3cbac2b366735ad99f22723e4d53e54b9dcb6224a7a23369d9bf95a25c01e64b7cf6e7807218b73a18fd33bfe6eabf0bbdd languageName: node linkType: hard @@ -7191,12 +7178,18 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^5.2.0": - version: 5.2.0 - resolution: "eslint-plugin-react-hooks@npm:5.2.0" +"eslint-plugin-react-hooks@npm:^7.0.1": + version: 7.0.1 + resolution: "eslint-plugin-react-hooks@npm:7.0.1" + dependencies: + "@babel/core": "npm:^7.24.4" + "@babel/parser": "npm:^7.24.4" + hermes-parser: "npm:^0.25.1" + zod: "npm:^3.25.0 || ^4.0.0" + zod-validation-error: "npm:^3.5.0 || ^4.0.0" peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 - checksum: 10c0/1c8d50fa5984c6dea32470651807d2922cc3934cf3425e78f84a24c2dfd972e7f019bee84aefb27e0cf2c13fea0ac1d4473267727408feeb1c56333ca1489385 + checksum: 10c0/1e711d1a9d1fa9cfc51fa1572500656577201199c70c795c6a27adfc1df39e5c598f69aab6aa91117753d23cc1f11388579a2bed14921cf9a4efe60ae8618496 languageName: node linkType: hard @@ -7228,15 +7221,15 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-storybook@npm:^9.0.4": - version: 9.1.1 - resolution: "eslint-plugin-storybook@npm:9.1.1" +"eslint-plugin-storybook@npm:^10.0.2": + version: 10.0.4 + resolution: "eslint-plugin-storybook@npm:10.0.4" dependencies: "@typescript-eslint/utils": "npm:^8.8.1" peerDependencies: eslint: ">=8" - storybook: ^9.1.1 - checksum: 10c0/4cf80aa078633021b153a3a5b790a39c9919b5fa7203727c15d8ae066e75d6e134d7d718e66a6a5db9815275f32942a2deae1979aeb36be2543572507faced2c + storybook: ^10.0.4 + checksum: 10c0/a2d486a6e45d1ce731333c439b51fc44b4a9292e8c0bca914534dab11cd37a3c25c62e8cbb1bb3b35e5e8b87d6ff2c7d8256c4f89a34c444138c4c738c52e1fc languageName: node linkType: hard @@ -7265,22 +7258,21 @@ __metadata: linkType: hard "eslint@npm:^9.23.0": - version: 9.32.0 - resolution: "eslint@npm:9.32.0" + version: 9.39.1 + resolution: "eslint@npm:9.39.1" dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/eslint-utils": "npm:^4.8.0" "@eslint-community/regexpp": "npm:^4.12.1" - "@eslint/config-array": "npm:^0.21.0" - "@eslint/config-helpers": "npm:^0.3.0" - "@eslint/core": "npm:^0.15.0" + "@eslint/config-array": "npm:^0.21.1" + "@eslint/config-helpers": "npm:^0.4.2" + "@eslint/core": "npm:^0.17.0" "@eslint/eslintrc": "npm:^3.3.1" - "@eslint/js": "npm:9.32.0" - "@eslint/plugin-kit": "npm:^0.3.4" + "@eslint/js": "npm:9.39.1" + "@eslint/plugin-kit": "npm:^0.4.1" "@humanfs/node": "npm:^0.16.6" "@humanwhocodes/module-importer": "npm:^1.0.1" "@humanwhocodes/retry": "npm:^0.4.2" "@types/estree": "npm:^1.0.6" - "@types/json-schema": "npm:^7.0.15" ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.6" @@ -7310,7 +7302,7 @@ __metadata: optional: true bin: eslint: bin/eslint.js - checksum: 10c0/e8a23924ec5f8b62e95483002ca25db74e25c23bd9c6d98a9f656ee32f820169bee3bfdf548ec728b16694f198b3db857d85a49210ee4a035242711d08fdc602 + checksum: 10c0/59b2480639404ba24578ca480f973683b87b7aac8aa7e349240474a39067804fd13cd8b9cb22fee074170b8c7c563b57bab703ec0f0d3f81ea017e5d2cad299d languageName: node linkType: hard @@ -7390,7 +7382,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10c0/12be11ef62fb9817314d790089a0a49fae4e1b50594135dcb8076312b7d7e470884b5100d249b28c18581b7fd52f8b485689ffae22a11ed9ec17377a33a08f84 @@ -7404,10 +7396,10 @@ __metadata: languageName: node linkType: hard -"expect-type@npm:^1.2.1": - version: 1.2.1 - resolution: "expect-type@npm:1.2.1" - checksum: 10c0/b775c9adab3c190dd0d398c722531726cdd6022849b4adba19dceab58dda7e000a7c6c872408cd73d665baa20d381eca36af4f7b393a4ba60dd10232d1fb8898 +"expect-type@npm:^1.2.2": + version: 1.2.2 + resolution: "expect-type@npm:1.2.2" + checksum: 10c0/6019019566063bbc7a690d9281d920b1a91284a4a093c2d55d71ffade5ac890cf37a51e1da4602546c4b56569d2ad2fc175a2ccee77d1ae06cb3af91ef84f44b languageName: node linkType: hard @@ -7418,49 +7410,45 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.18.2": - version: 4.21.2 - resolution: "express@npm:4.21.2" +"express@npm:^5.1.0": + version: 5.1.0 + resolution: "express@npm:5.1.0" dependencies: - accepts: "npm:~1.3.8" - array-flatten: "npm:1.1.1" - body-parser: "npm:1.20.3" - content-disposition: "npm:0.5.4" - content-type: "npm:~1.0.4" - cookie: "npm:0.7.1" - cookie-signature: "npm:1.0.6" - debug: "npm:2.6.9" - depd: "npm:2.0.0" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - finalhandler: "npm:1.3.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - merge-descriptors: "npm:1.0.3" - methods: "npm:~1.1.2" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - path-to-regexp: "npm:0.1.12" - proxy-addr: "npm:~2.0.7" - qs: "npm:6.13.0" - range-parser: "npm:~1.2.1" - safe-buffer: "npm:5.2.1" - send: "npm:0.19.0" - serve-static: "npm:1.16.2" - setprototypeof: "npm:1.2.0" - statuses: "npm:2.0.1" - type-is: "npm:~1.6.18" - utils-merge: "npm:1.0.1" - vary: "npm:~1.1.2" - checksum: 10c0/38168fd0a32756600b56e6214afecf4fc79ec28eca7f7a91c2ab8d50df4f47562ca3f9dee412da7f5cea6b1a1544b33b40f9f8586dbacfbdada0fe90dbb10a1f + accepts: "npm:^2.0.0" + body-parser: "npm:^2.2.0" + content-disposition: "npm:^1.0.0" + content-type: "npm:^1.0.5" + cookie: "npm:^0.7.1" + cookie-signature: "npm:^1.2.1" + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + finalhandler: "npm:^2.1.0" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + merge-descriptors: "npm:^2.0.0" + mime-types: "npm:^3.0.0" + on-finished: "npm:^2.4.1" + once: "npm:^1.4.0" + parseurl: "npm:^1.3.3" + proxy-addr: "npm:^2.0.7" + qs: "npm:^6.14.0" + range-parser: "npm:^1.2.1" + router: "npm:^2.2.0" + send: "npm:^1.1.0" + serve-static: "npm:^2.2.0" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10c0/80ce7c53c5f56887d759b94c3f2283e2e51066c98d4b72a4cc1338e832b77f1e54f30d0239cc10815a0f849bdb753e6a284d2fa48d4ab56faf9c501f55d751d6 languageName: node linkType: hard "fake-indexeddb@npm:^6.0.1": - version: 6.2.2 - resolution: "fake-indexeddb@npm:6.2.2" - checksum: 10c0/5ad98f05beb22d8591af1bcf8500d1a92d9a17b3e2c380dfa669770b4fecdbadc1ccd9c8ba5429a92a30fd2562f6ab24238992522a8574ffd365d7b809677f0a + version: 6.2.4 + resolution: "fake-indexeddb@npm:6.2.4" + checksum: 10c0/53b7e9e8f7e413c1a45a4f80f6deda00ef02676cc3a4457e73abff06720ec6b4f4f63fd65c1ef6b03298a1e7e4684d4bf65137a8b9ac166dcfade4b2acf229b4 languageName: node linkType: hard @@ -7590,18 +7578,17 @@ __metadata: languageName: node linkType: hard -"finalhandler@npm:1.3.1": - version: 1.3.1 - resolution: "finalhandler@npm:1.3.1" +"finalhandler@npm:^2.1.0": + version: 2.1.0 + resolution: "finalhandler@npm:2.1.0" dependencies: - debug: "npm:2.6.9" - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - on-finished: "npm:2.4.1" - parseurl: "npm:~1.3.3" - statuses: "npm:2.0.1" - unpipe: "npm:~1.0.0" - checksum: 10c0/d38035831865a49b5610206a3a9a9aae4e8523cbbcd01175d0480ffbf1278c47f11d89be3ca7f617ae6d94f29cf797546a4619cd84dd109009ef33f12f69019f + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + on-finished: "npm:^2.4.1" + parseurl: "npm:^1.3.3" + statuses: "npm:^2.0.1" + checksum: 10c0/da0bbca6d03873472ee890564eb2183f4ed377f25f3628a0fc9d16dac40bed7b150a0d82ebb77356e4c6d97d2796ad2dba22948b951dddee2c8768b0d1b9fb1f languageName: node linkType: hard @@ -7622,17 +7609,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^7.0.0": - version: 7.0.0 - resolution: "find-up@npm:7.0.0" - dependencies: - locate-path: "npm:^7.2.0" - path-exists: "npm:^5.0.0" - unicorn-magic: "npm:^0.1.0" - checksum: 10c0/e6ee3e6154560bc0ab3bc3b7d1348b31513f9bdf49a5dd2e952495427d559fa48cdf33953e85a309a323898b43fa1bfbc8b80c880dfc16068384783034030008 - languageName: node - linkType: hard - "flat-cache@npm:^4.0.0": version: 4.0.1 resolution: "flat-cache@npm:4.0.1" @@ -7717,10 +7693,10 @@ __metadata: languageName: node linkType: hard -"fresh@npm:0.5.2": - version: 0.5.2 - resolution: "fresh@npm:0.5.2" - checksum: 10c0/c6d27f3ed86cc5b601404822f31c900dd165ba63fff8152a3ef714e2012e7535027063bc67ded4cb5b3a49fa596495d46cacd9f47d6328459cf570f08b7d9e5a +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 10c0/0557548194cb9a809a435bf92bcfbc20c89e8b5eb38861b73ced36750437251e39a111fc3a18b98531be9dd91fe1411e4969f229dc579ec0251ce6c5d4900bbc languageName: node linkType: hard @@ -7919,7 +7895,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.4.1": +"glob@npm:^10.0.0, glob@npm:^10.2.2": version: 10.4.5 resolution: "glob@npm:10.4.5" dependencies: @@ -7977,9 +7953,9 @@ __metadata: linkType: hard "globals@npm:^16.0.0": - version: 16.3.0 - resolution: "globals@npm:16.3.0" - checksum: 10c0/c62dc20357d1c0bf2be4545d6c4141265d1a229bf1c3294955efb5b5ef611145391895e3f2729f8603809e81b30b516c33e6c2597573844449978606aad6eb38 + version: 16.5.0 + resolution: "globals@npm:16.5.0" + checksum: 10c0/615241dae7851c8012f5aa0223005b1ed6607713d6813de0741768bd4ddc39353117648f1a7086b4b0fa45eae733f1c0a0fe369aa4e543bb63f8de8990178ea9 languageName: node linkType: hard @@ -8028,7 +8004,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -8120,6 +8096,22 @@ __metadata: languageName: node linkType: hard +"hermes-estree@npm:0.25.1": + version: 0.25.1 + resolution: "hermes-estree@npm:0.25.1" + checksum: 10c0/48be3b2fa37a0cbc77a112a89096fa212f25d06de92781b163d67853d210a8a5c3784fac23d7d48335058f7ed283115c87b4332c2a2abaaccc76d0ead1a282ac + languageName: node + linkType: hard + +"hermes-parser@npm:^0.25.1": + version: 0.25.1 + resolution: "hermes-parser@npm:0.25.1" + dependencies: + hermes-estree: "npm:0.25.1" + checksum: 10c0/3abaa4c6f1bcc25273f267297a89a4904963ea29af19b8e4f6eabe04f1c2c7e9abd7bfc4730ddb1d58f2ea04b6fee74053d8bddb5656ec6ebf6c79cc8d14202c + languageName: node + linkType: hard + "history@npm:^4.10.1, history@npm:^4.9.0": version: 4.10.1 resolution: "history@npm:4.10.1" @@ -8159,6 +8151,13 @@ __metadata: languageName: node linkType: hard +"html-entities@npm:^2.6.0": + version: 2.6.0 + resolution: "html-entities@npm:2.6.0" + checksum: 10c0/7c8b15d9ea0cd00dc9279f61bab002ba6ca8a7a0f3c36ed2db3530a67a9621c017830d1d2c1c65beb9b8e3436ea663e9cf8b230472e0e413359399413b27c8b7 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -8180,7 +8179,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:2.0.0": +"http-errors@npm:2.0.0, http-errors@npm:^2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" dependencies: @@ -8229,16 +8228,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.4.24": - version: 0.4.24 - resolution: "iconv-lite@npm:0.4.24" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3" - checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 - languageName: node - linkType: hard - -"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -8247,6 +8237,24 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:0.7.0": + version: 0.7.0 + resolution: "iconv-lite@npm:0.7.0" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/2382400469071c55b6746c531eed5fa4d033e5db6690b7331fb2a5f59a30d7a9782932e92253db26df33c1cf46fa200a3fbe524a2a7c62037c762283f188ec2f + languageName: node + linkType: hard + +"icss-utils@npm:^5.0.0, icss-utils@npm:^5.1.0": + version: 5.1.0 + resolution: "icss-utils@npm:5.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/39c92936fabd23169c8611d2b5cc39e39d10b19b0d223352f20a7579f75b39d5f786114a6b8fc62bee8c5fed59ba9e0d38f7219a4db383e324fb3061664b043d + languageName: node + linkType: hard + "idb-keyval@npm:^6.2.0": version: 6.2.1 resolution: "idb-keyval@npm:6.2.1" @@ -8282,6 +8290,15 @@ __metadata: languageName: node linkType: hard +"image-size@npm:~0.5.0": + version: 0.5.5 + resolution: "image-size@npm:0.5.5" + bin: + image-size: bin/image-size.js + checksum: 10c0/655204163af06732f483a9fe7cce9dff4a29b7b2e88f5c957a5852e8143fa750f5e54b1955a2ca83de99c5220dbd680002d0d4e09140b01433520f4d5a0b1f4c + languageName: node + linkType: hard + "immer@npm:^10.0.3": version: 10.0.3 resolution: "immer@npm:10.0.3" @@ -8654,6 +8671,13 @@ __metadata: languageName: node linkType: hard +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 10c0/ebd5c672d73db781ab33ccb155fb9969d6028e37414d609b115cc534654c91ccd061821d5b987eefaa97cf4c62f0b909bb2f04db88306de26e91bfe8ddc01503 + languageName: node + linkType: hard + "is-regex@npm:^1.2.1": version: 1.2.1 resolution: "is-regex@npm:1.2.1" @@ -8759,6 +8783,13 @@ __metadata: languageName: node linkType: hard +"is-what@npm:^3.14.1": + version: 3.14.1 + resolution: "is-what@npm:3.14.1" + checksum: 10c0/4b770b85454c877b6929a84fd47c318e1f8c2ff70fd72fd625bc3fde8e0c18a6e57345b6e7aa1ee9fbd1c608d27cfe885df473036c5c2e40cd2187250804a2c7 + languageName: node + linkType: hard + "is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" @@ -8825,13 +8856,13 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.1.7": - version: 3.1.7 - resolution: "istanbul-reports@npm:3.1.7" +"istanbul-reports@npm:^3.2.0": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" dependencies: html-escaper: "npm:^2.0.0" istanbul-lib-report: "npm:^3.0.0" - checksum: 10c0/a379fadf9cf8dc5dfe25568115721d4a7eb82fbd50b005a6672aff9c6989b20cc9312d7865814e0859cd8df58cbf664482e1d3604be0afde1f7fc3ccc1394a51 + checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc languageName: node linkType: hard @@ -8908,19 +8939,20 @@ __metadata: languageName: node linkType: hard -"jsdoc-type-pratt-parser@npm:~4.1.0": - version: 4.1.0 - resolution: "jsdoc-type-pratt-parser@npm:4.1.0" - checksum: 10c0/7700372d2e733a32f7ea0a1df9cec6752321a5345c11a91b2ab478a031a426e934f16d5c1f15c8566c7b2c10af9f27892a29c2c789039f595470e929a4aa60ea +"jsdoc-type-pratt-parser@npm:~6.10.0": + version: 6.10.0 + resolution: "jsdoc-type-pratt-parser@npm:6.10.0" + checksum: 10c0/8ea395df0cae0e41d4bdba5f8d81b8d3e467fe53d1e4182a5d4e653235a5f17d60ed137343d68dbc74fa10e767f1c58fb85b1f6d5489c2cf16fc7216cc6d3e1a languageName: node linkType: hard "jsdom@npm:^27.0.0": - version: 27.0.1 - resolution: "jsdom@npm:27.0.1" + version: 27.1.0 + resolution: "jsdom@npm:27.1.0" dependencies: - "@asamuzakjp/dom-selector": "npm:^6.7.2" - cssstyle: "npm:^5.3.1" + "@acemir/cssom": "npm:^0.9.19" + "@asamuzakjp/dom-selector": "npm:^6.7.3" + cssstyle: "npm:^5.3.2" data-urls: "npm:^6.0.0" decimal.js: "npm:^10.6.0" html-encoding-sniffer: "npm:^4.0.0" @@ -8928,7 +8960,6 @@ __metadata: https-proxy-agent: "npm:^7.0.6" is-potential-custom-element-name: "npm:^1.0.1" parse5: "npm:^8.0.0" - rrweb-cssom: "npm:^0.8.0" saxes: "npm:^6.0.0" symbol-tree: "npm:^3.2.4" tough-cookie: "npm:^6.0.0" @@ -8944,7 +8975,7 @@ __metadata: peerDependenciesMeta: canvas: optional: true - checksum: 10c0/563ff3ebfd9a3dc66082cdf2427198b647993753b4c37b2d0064b5b47cf7be5154c62df10eb8122254f7b89c73ecb6fc870fa038e22ab9975b23079ee62e050e + checksum: 10c0/b3da39ab7c858df28a2300362924925327f5bff5727371523b99cac7f51bc2891c4b8516205c9acbd34430819f7e69f7790a2092a965359ed65d8111b3a79507 languageName: node linkType: hard @@ -8999,7 +9030,7 @@ __metadata: languageName: node linkType: hard -"json-stable-stringify@npm:^1.1.1, json-stable-stringify@npm:^1.3.0": +"json-stable-stringify@npm:^1.3.0": version: 1.3.0 resolution: "json-stable-stringify@npm:1.3.0" dependencies: @@ -9071,13 +9102,6 @@ __metadata: languageName: node linkType: hard -"keycode@npm:^2.1.7": - version: 2.2.1 - resolution: "keycode@npm:2.2.1" - checksum: 10c0/e38ecbdc62f57e18ef9f7ad88aefded84e05b89115a40eea3081a7002d7c055765ddb5f5c3e2dd36ac2b2ab3901053c8286c9db082fd807b3abeb7e44034d96a - languageName: node - linkType: hard - "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -9149,6 +9173,41 @@ __metadata: languageName: node linkType: hard +"less@npm:^4.2.0": + version: 4.4.2 + resolution: "less@npm:4.4.2" + dependencies: + copy-anything: "npm:^2.0.1" + errno: "npm:^0.1.1" + graceful-fs: "npm:^4.1.2" + image-size: "npm:~0.5.0" + make-dir: "npm:^2.1.0" + mime: "npm:^1.4.1" + needle: "npm:^3.1.0" + parse-node-version: "npm:^1.0.1" + source-map: "npm:~0.6.0" + tslib: "npm:^2.3.0" + dependenciesMeta: + errno: + optional: true + graceful-fs: + optional: true + image-size: + optional: true + make-dir: + optional: true + mime: + optional: true + needle: + optional: true + source-map: + optional: true + bin: + lessc: bin/lessc + checksum: 10c0/f8b796e45ef171adc390b5250f3018922cd046c256181dd9d4cbcbbdc5d6de7cb88c8327741c10eff7ff76421cd826fd95a664ea1b88fbf6f31742428d4a2dab + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -9166,6 +9225,13 @@ __metadata: languageName: node linkType: hard +"lilconfig@npm:^2.0.5": + version: 2.1.0 + resolution: "lilconfig@npm:2.1.0" + checksum: 10c0/64645641aa8d274c99338e130554abd6a0190533c0d9eb2ce7ebfaf2e05c7d9961f3ffe2bfa39efd3b60c521ba3dd24fa236fe2775fc38501bf82bf49d4678b8 + languageName: node + linkType: hard + "lines-and-columns@npm:^1.1.6": version: 1.2.4 resolution: "lines-and-columns@npm:1.2.4" @@ -9173,26 +9239,26 @@ __metadata: languageName: node linkType: hard -"lint-staged@npm:^16.0.0": - version: 16.2.0 - resolution: "lint-staged@npm:16.2.0" +"lint-staged@npm:^16.2.6": + version: 16.2.6 + resolution: "lint-staged@npm:16.2.6" dependencies: - commander: "npm:14.0.1" - listr2: "npm:9.0.4" - micromatch: "npm:4.0.8" - nano-spawn: "npm:1.0.3" - pidtree: "npm:0.6.0" - string-argv: "npm:0.3.2" - yaml: "npm:2.8.1" + commander: "npm:^14.0.1" + listr2: "npm:^9.0.5" + micromatch: "npm:^4.0.8" + nano-spawn: "npm:^2.0.0" + pidtree: "npm:^0.6.0" + string-argv: "npm:^0.3.2" + yaml: "npm:^2.8.1" bin: lint-staged: bin/lint-staged.js - checksum: 10c0/0903eea526d390fd04ec10c2b6c3c3accdff53647d1918d3c30236d46fa7714a4a109d1aeda7364ecc689728c7b188bc430911b170834228fe0010d938c9a631 + checksum: 10c0/6bae38082a0fcb3f699b144d1a4b85394f259f17a1f8a58b22122b9f1c6bb5e8340d6ee4bff12e52dbc4267377d6dde9e5c206157f381f1924a2640717f769c1 languageName: node linkType: hard -"listr2@npm:9.0.4": - version: 9.0.4 - resolution: "listr2@npm:9.0.4" +"listr2@npm:^9.0.5": + version: 9.0.5 + resolution: "listr2@npm:9.0.5" dependencies: cli-truncate: "npm:^5.0.0" colorette: "npm:^2.0.20" @@ -9200,7 +9266,7 @@ __metadata: log-update: "npm:^6.1.0" rfdc: "npm:^1.4.1" wrap-ansi: "npm:^9.0.0" - checksum: 10c0/69feca532f5b3317112a74bc7589ad29f98ccfbe1a582bdab556d536978b094e5841b94069e01cf59ea919684dfb68218754526ddd317b1dc829ab57f7450e45 + checksum: 10c0/46448d1ba0addc9d71aeafd05bb8e86ded9641ccad930ac302c2bd2ad71580375604743e18586fcb8f11906edf98e8e17fca75ba0759947bf275d381f68e311d languageName: node linkType: hard @@ -9213,12 +9279,10 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^7.2.0": - version: 7.2.0 - resolution: "locate-path@npm:7.2.0" - dependencies: - p-locate: "npm:^6.0.0" - checksum: 10c0/139e8a7fe11cfbd7f20db03923cacfa5db9e14fa14887ea121345597472b4a63c1a42a8a5187defeeff6acf98fd568da7382aa39682d38f0af27433953a97751 +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: 10c0/fcba15d21a458076dd309fce6b1b4bf611d84a0ec252cb92447c948c533ac250b95d2e00955801ebc367e5af5ed288b996d75d37d2035260a937008e14eaf432 languageName: node linkType: hard @@ -9352,12 +9416,12 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:~0.30.11": - version: 0.30.17 - resolution: "magic-string@npm:0.30.17" +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:^0.30.19, magic-string@npm:~0.30.11": + version: 0.30.21 + resolution: "magic-string@npm:0.30.21" dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.5.0" - checksum: 10c0/16826e415d04b88378f200fe022b53e638e3838b9e496edda6c0e086d7753a44a6ed187adc72d19f3623810589bf139af1a315541cd6a26ae0771a0193eaf7b8 + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10c0/299378e38f9a270069fc62358522ddfb44e94244baa0d6a8980ab2a9b2490a1d03b236b447eee309e17eb3bddfa482c61259d47960eb018a904f0ded52780c4a languageName: node linkType: hard @@ -9372,6 +9436,16 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^2.1.0": + version: 2.1.0 + resolution: "make-dir@npm:2.1.0" + dependencies: + pify: "npm:^4.0.1" + semver: "npm:^5.6.0" + checksum: 10c0/ada869944d866229819735bee5548944caef560d7a8536ecbc6536edca28c72add47cc4f6fc39c54fb25d06b58da1f8994cf7d9df7dadea047064749efc085d8 + languageName: node + linkType: hard + "make-dir@npm:^4.0.0": version: 4.0.0 resolution: "make-dir@npm:4.0.0" @@ -9435,10 +9509,10 @@ __metadata: languageName: node linkType: hard -"media-typer@npm:0.3.0": - version: 0.3.0 - resolution: "media-typer@npm:0.3.0" - checksum: 10c0/d160f31246907e79fed398470285f21bafb45a62869dc469b1c8877f3f064f5eabc4bcc122f9479b8b605bc5c76187d7871cf84c4ee3ecd3e487da1993279928 +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: 10c0/7b4baa40b25964bb90e2121ee489ec38642127e48d0cc2b6baa442688d3fde6262bfdca86d6bbf6ba708784afcac168c06840c71facac70e390f5f759ac121b9 languageName: node linkType: hard @@ -9456,10 +9530,10 @@ __metadata: languageName: node linkType: hard -"merge-descriptors@npm:1.0.3": - version: 1.0.3 - resolution: "merge-descriptors@npm:1.0.3" - checksum: 10c0/866b7094afd9293b5ea5dcd82d71f80e51514bed33b4c4e9f516795dc366612a4cbb4dc94356e943a8a6914889a914530badff27f397191b9b75cda20b6bae93 +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: 10c0/95389b7ced3f9b36fbdcf32eb946dc3dd1774c2fdf164609e55b18d03aa499b12bd3aae3a76c1c7185b96279e9803525550d3eb292b5224866060a288f335cb3 languageName: node linkType: hard @@ -9470,14 +9544,7 @@ __metadata: languageName: node linkType: hard -"methods@npm:~1.1.2": - version: 1.1.2 - resolution: "methods@npm:1.1.2" - checksum: 10c0/bdf7cc72ff0a33e3eede03708c08983c4d7a173f91348b4b1e4f47d4cdbf734433ad971e7d1e8c77247d9e5cd8adb81ea4c67b0a2db526b758b2233d7814b8b2 - languageName: node - linkType: hard - -"micromatch@npm:4.0.8, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": +"micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -9494,7 +9561,14 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10c0/8d907917bc2a90fa2df842cdf5dfeaf509adc15fe0531e07bb2f6ab15992416479015828d6a74200041c492e42cce3ebf78e5ce714388a0a538ea9c53eece284 + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -9503,7 +9577,16 @@ __metadata: languageName: node linkType: hard -"mime@npm:1.6.0": +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": + version: 3.0.1 + resolution: "mime-types@npm:3.0.1" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10c0/bd8c20d3694548089cf229016124f8f40e6a60bbb600161ae13e45f793a2d5bb40f96bbc61f275836696179c77c1d6bf4967b2a75e0a8ad40fe31f4ed5be4da5 + languageName: node + linkType: hard + +"mime@npm:^1.4.1": version: 1.6.0 resolution: "mime@npm:1.6.0" bin: @@ -9652,14 +9735,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.0.0": - version: 2.0.0 - resolution: "ms@npm:2.0.0" - checksum: 10c0/f8fda810b39fd7255bbdc451c46286e549794fcc700dc9cd1d25658bbc4dc2563a5de6fe7c60f798a16a60c6ceb53f033cb353f493f0cf63e5199b702943159d - languageName: node - linkType: hard - -"ms@npm:2.1.3, ms@npm:^2.1.1, ms@npm:^2.1.3": +"ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 @@ -9718,10 +9794,10 @@ __metadata: languageName: node linkType: hard -"nano-spawn@npm:1.0.3": - version: 1.0.3 - resolution: "nano-spawn@npm:1.0.3" - checksum: 10c0/ea18857e493710a50ded333dd71677953bd9bd9e6a17ade74af957763c50a9a02205ef31bc0d6784f5b3ad82db3d9f47531e9baac2acf01118f9b7c35bd9d5de +"nano-spawn@npm:^2.0.0": + version: 2.0.0 + resolution: "nano-spawn@npm:2.0.0" + checksum: 10c0/d00f9b5739f86e28cb732ffd774793e110810cded246b8393c75c4f22674af47f98ee37b19f022ada2d8c9425f800e841caa0662fbff4c0930a10e39339fb366 languageName: node linkType: hard @@ -9750,10 +9826,15 @@ __metadata: languageName: node linkType: hard -"negotiator@npm:0.6.3": - version: 0.6.3 - resolution: "negotiator@npm:0.6.3" - checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 +"needle@npm:^3.1.0": + version: 3.3.1 + resolution: "needle@npm:3.3.1" + dependencies: + iconv-lite: "npm:^0.6.3" + sax: "npm:^1.2.4" + bin: + needle: bin/needle + checksum: 10c0/233b9315d47b735867d03e7a018fb665ee6cacf3a83b991b19538019cf42b538a3e85ca745c840b4c5e9a0ffdca76472f941363bf7c166214ae8cbc650fd4d39 languageName: node linkType: hard @@ -9867,6 +9948,13 @@ __metadata: languageName: node linkType: hard +"object-deep-merge@npm:^2.0.0": + version: 2.0.0 + resolution: "object-deep-merge@npm:2.0.0" + checksum: 10c0/69e8741131ad49fa8720fb96007a3c82dca1119b5d874151d2ecbcc3b44ccd46e8553c7a30b0abcba752c099ba361bbba97f33a68c9ae54c57eed7be116ffc97 + languageName: node + linkType: hard + "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -9949,7 +10037,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:2.4.1": +"on-finished@npm:^2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -9976,7 +10064,7 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.0.0, open@npm:^8.0.4": +"open@npm:^8.0.0": version: 8.4.2 resolution: "open@npm:8.4.2" dependencies: @@ -10037,15 +10125,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^4.0.0": - version: 4.0.0 - resolution: "p-limit@npm:4.0.0" - dependencies: - yocto-queue: "npm:^1.0.0" - checksum: 10c0/a56af34a77f8df2ff61ddfb29431044557fcbcb7642d5a3233143ebba805fc7306ac1d448de724352861cb99de934bc9ab74f0d16fe6a5460bdbdf938de875ad - languageName: node - linkType: hard - "p-locate@npm:^5.0.0": version: 5.0.0 resolution: "p-locate@npm:5.0.0" @@ -10055,15 +10134,6 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^6.0.0": - version: 6.0.0 - resolution: "p-locate@npm:6.0.0" - dependencies: - p-limit: "npm:^4.0.0" - checksum: 10c0/d72fa2f41adce59c198270aa4d3c832536c87a1806e0f69dffb7c1a7ca998fb053915ca833d90f166a8c082d3859eabfed95f01698a3214c20df6bb8de046312 - languageName: node - linkType: hard - "p-map@npm:^7.0.2, p-map@npm:^7.0.3": version: 7.0.3 resolution: "p-map@npm:7.0.3" @@ -10115,6 +10185,13 @@ __metadata: languageName: node linkType: hard +"parse-node-version@npm:^1.0.1": + version: 1.0.1 + resolution: "parse-node-version@npm:1.0.1" + checksum: 10c0/999cd3d7da1425c2e182dce82b226c6dc842562d3ed79ec47f5c719c32a7f6c1a5352495b894fc25df164be7f2ede4224758255da9902ddef81f2b77ba46bb2c + languageName: node + linkType: hard + "parse-statements@npm:1.0.11": version: 1.0.11 resolution: "parse-statements@npm:1.0.11" @@ -10131,7 +10208,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 @@ -10152,13 +10229,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^5.0.0": - version: 5.0.0 - resolution: "path-exists@npm:5.0.0" - checksum: 10c0/b170f3060b31604cde93eefdb7392b89d832dfbc1bed717c9718cbe0f230c1669b7e75f87e19901da2250b84d092989a0f9e44d2ef41deb09aa3ad28e691a40a - languageName: node - linkType: hard - "path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" @@ -10190,13 +10260,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:0.1.12": - version: 0.1.12 - resolution: "path-to-regexp@npm:0.1.12" - checksum: 10c0/1c6ff10ca169b773f3bba943bbc6a07182e332464704572962d277b900aeee81ac6aa5d060ff9e01149636c30b1f63af6e69dd7786ba6e0ddb39d4dee1f0645b - languageName: node - linkType: hard - "path-to-regexp@npm:^1.7.0": version: 1.9.0 resolution: "path-to-regexp@npm:1.9.0" @@ -10213,6 +10276,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^8.0.0": + version: 8.3.0 + resolution: "path-to-regexp@npm:8.3.0" + checksum: 10c0/ee1544a73a3f294a97a4c663b0ce71bbf1621d732d80c9c9ed201b3e911a86cb628ebad691b9d40f40a3742fe22011e5a059d8eed2cf63ec2cb94f6fb4efe67c + languageName: node + linkType: hard + "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -10336,7 +10406,7 @@ __metadata: languageName: node linkType: hard -"pidtree@npm:0.6.0": +"pidtree@npm:^0.6.0": version: 0.6.0 resolution: "pidtree@npm:0.6.0" bin: @@ -10345,6 +10415,13 @@ __metadata: languageName: node linkType: hard +"pify@npm:^4.0.1": + version: 4.0.1 + resolution: "pify@npm:4.0.1" + checksum: 10c0/6f9d404b0d47a965437403c9b90eca8bb2536407f03de165940e62e72c8c8b75adda5516c6b9b23675a5877cc0bcac6bdfb0ef0e39414cd2476d5495da40e7cf + languageName: node + linkType: hard + "pino-abstract-transport@npm:^2.0.0": version: 2.0.0 resolution: "pino-abstract-transport@npm:2.0.0" @@ -10354,21 +10431,21 @@ __metadata: languageName: node linkType: hard -"pino-http@npm:^10.0.0": - version: 10.5.0 - resolution: "pino-http@npm:10.5.0" +"pino-http@npm:^11.0.0": + version: 11.0.0 + resolution: "pino-http@npm:11.0.0" dependencies: get-caller-file: "npm:^2.0.5" - pino: "npm:^9.0.0" + pino: "npm:^10.0.0" pino-std-serializers: "npm:^7.0.0" process-warning: "npm:^5.0.0" - checksum: 10c0/17597d653a4088f7faed4d58500a5ef51d4d05247307696760006313c33c1d23177af98fb902e15b8e2cd92d81306c884673f841ba5b9bf0c064802f3c0bd775 + checksum: 10c0/75110c7a7f1b1c4eadfbff3b87599ef9d100c20c3ffd19541f0cb37cd11285a3f221bb90d33df0772ed94a3f7d5b2007bd7365c5f5525cff2178d4deef140ee5 languageName: node linkType: hard "pino-pretty@npm:^13.0.0": - version: 13.1.1 - resolution: "pino-pretty@npm:13.1.1" + version: 13.1.2 + resolution: "pino-pretty@npm:13.1.2" dependencies: colorette: "npm:^2.0.7" dateformat: "npm:^4.6.3" @@ -10385,7 +10462,7 @@ __metadata: strip-json-comments: "npm:^5.0.2" bin: pino-pretty: bin.js - checksum: 10c0/845c07afd3d73cb96ad2049cfa7fca12b8280a51e30d6db8b490857690637556bb8e7f05b2fa640b3e4a7edd9b1369110042d670fda743ef98fe3be29876c8c7 + checksum: 10c0/4d8e7472e37bdb6e0d6d7d34f25f65ced46c0f64a9579bb805602321caf1c0b10359f89a1ee9742bea875f411a02ce7c19730f7a1e5387dfcfd10ff5c9804709 languageName: node linkType: hard @@ -10396,9 +10473,9 @@ __metadata: languageName: node linkType: hard -"pino@npm:^9.0.0": - version: 9.14.0 - resolution: "pino@npm:9.14.0" +"pino@npm:^10.0.0": + version: 10.1.0 + resolution: "pino@npm:10.1.0" dependencies: "@pinojs/redact": "npm:^0.4.0" atomic-sleep: "npm:^1.0.0" @@ -10413,7 +10490,18 @@ __metadata: thread-stream: "npm:^3.0.0" bin: pino: bin.js - checksum: 10c0/9a10d9bf820a585eae9bc270fb4e55c895e48280d54adbbb4063ec061694b22d8809c80203cf5fe9f920a54c832b0b8dfb67cb28a04baa13abebaf261a9c9f3e + checksum: 10c0/49c1dd80d5f99f02bde1acf2f60cef7686948a937f751f6cb368c2868c7e82e54aeabac63a34587e16019965cbf0eb6e609edf92c439a98a0a4fcb0add277eaf + languageName: node + linkType: hard + +"pixelmatch@npm:7.1.0": + version: 7.1.0 + resolution: "pixelmatch@npm:7.1.0" + dependencies: + pngjs: "npm:^7.0.0" + bin: + pixelmatch: bin/pixelmatch + checksum: 10c0/ff069f92edaa841ac9b58b0ab74e1afa1f3b5e770eea0218c96bac1da4e752f5f6b79a0f9c4ba6b02afb955d39b8c78bcc3cc884f8122b67a1f2efbbccbe1a73 languageName: node linkType: hard @@ -10426,7 +10514,7 @@ __metadata: languageName: node linkType: hard -"playwright@npm:^1.54.1": +"playwright@npm:^1.56.1": version: 1.56.1 resolution: "playwright@npm:1.56.1" dependencies: @@ -10441,6 +10529,13 @@ __metadata: languageName: node linkType: hard +"pngjs@npm:^7.0.0": + version: 7.0.0 + resolution: "pngjs@npm:7.0.0" + checksum: 10c0/0d4c7a0fd476a9c33df7d0a2a73e1d56537628a668841f6995c2bca070cf30819f9254a64363266bc14ef2fee47659dd3b4f2b18eec7ab65143015139f497b38 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": version: 1.0.0 resolution: "possible-typed-array-names@npm:1.0.0" @@ -10643,6 +10738,24 @@ __metadata: languageName: node linkType: hard +"postcss-load-config@npm:^3.1.4": + version: 3.1.4 + resolution: "postcss-load-config@npm:3.1.4" + dependencies: + lilconfig: "npm:^2.0.5" + yaml: "npm:^1.10.2" + peerDependencies: + postcss: ">=8.0.9" + ts-node: ">=9.0.0" + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + checksum: 10c0/7d2cc6695c2fc063e4538316d651a687fdb55e48db453ff699de916a6ee55ab68eac2b120c28a6b8ca7aa746a588888351b810a215b5cd090eabea62c5762ede + languageName: node + linkType: hard + "postcss-logical@npm:^8.1.0": version: 8.1.0 resolution: "postcss-logical@npm:8.1.0" @@ -10661,6 +10774,39 @@ __metadata: languageName: node linkType: hard +"postcss-modules-extract-imports@npm:^3.0.0": + version: 3.1.0 + resolution: "postcss-modules-extract-imports@npm:3.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/402084bcab376083c4b1b5111b48ec92974ef86066f366f0b2d5b2ac2b647d561066705ade4db89875a13cb175b33dd6af40d16d32b2ea5eaf8bac63bd2bf219 + languageName: node + linkType: hard + +"postcss-modules-local-by-default@npm:^4.0.4": + version: 4.2.0 + resolution: "postcss-modules-local-by-default@npm:4.2.0" + dependencies: + icss-utils: "npm:^5.0.0" + postcss-selector-parser: "npm:^7.0.0" + postcss-value-parser: "npm:^4.1.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/b0b83feb2a4b61f5383979d37f23116c99bc146eba1741ca3cf1acca0e4d0dbf293ac1810a6ab4eccbe1ee76440dd0a9eb2db5b3bba4f99fc1b3ded16baa6358 + languageName: node + linkType: hard + +"postcss-modules-scope@npm:^3.1.1": + version: 3.2.1 + resolution: "postcss-modules-scope@npm:3.2.1" + dependencies: + postcss-selector-parser: "npm:^7.0.0" + peerDependencies: + postcss: ^8.1.0 + checksum: 10c0/bd2d81f79e3da0ef6365b8e2c78cc91469d05b58046b4601592cdeef6c4050ed8fe1478ae000a1608042fc7e692cb51fecbd2d9bce3f4eace4d32e883ffca10b + languageName: node + linkType: hard + "postcss-nesting@npm:^13.0.2": version: 13.0.2 resolution: "postcss-nesting@npm:13.0.2" @@ -10857,14 +11003,14 @@ __metadata: languageName: node linkType: hard -"postcss-value-parser@npm:^4.2.0": +"postcss-value-parser@npm:^4.1.0, postcss-value-parser@npm:^4.2.0": version: 4.2.0 resolution: "postcss-value-parser@npm:4.2.0" checksum: 10c0/f4142a4f56565f77c1831168e04e3effd9ffcc5aebaf0f538eee4b2d465adfd4b85a44257bb48418202a63806a7da7fe9f56c330aebb3cac898e46b4cbf49161 languageName: node linkType: hard -"postcss@npm:^8.5.6": +"postcss@npm:^8.0.0, postcss@npm:^8.4.35, postcss@npm:^8.5.6": version: 8.5.6 resolution: "postcss@npm:8.5.6" dependencies: @@ -10990,7 +11136,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.5.10, prop-types@npm:^15.5.4, prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": +"prop-types@npm:^15.5.10, prop-types@npm:^15.6.0, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -11001,7 +11147,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -11018,6 +11164,13 @@ __metadata: languageName: node linkType: hard +"prr@npm:~1.0.1": + version: 1.0.1 + resolution: "prr@npm:1.0.1" + checksum: 10c0/5b9272c602e4f4472a215e58daff88f802923b84bc39c8860376bb1c0e42aaf18c25d69ad974bd06ec6db6f544b783edecd5502cd3d184748d99080d68e4be5f + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.0 resolution: "pump@npm:3.0.0" @@ -11042,12 +11195,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:6.13.0": - version: 6.13.0 - resolution: "qs@npm:6.13.0" +"qs@npm:^6.14.0": + version: 6.14.0 + resolution: "qs@npm:6.14.0" dependencies: - side-channel: "npm:^1.0.6" - checksum: 10c0/62372cdeec24dc83a9fb240b7533c0fdcf0c5f7e0b83343edd7310f0ab4c8205a5e7c56406531f2e47e1b4878a3821d652be4192c841de5b032ca83619d8f860 + side-channel: "npm:^1.1.0" + checksum: 10c0/8ea5d91bf34f440598ee389d4a7d95820e3b837d3fd9f433871f7924801becaa0cd3b3b4628d49a7784d06a8aea9bc4554d2b6d8d584e2d221dc06238a42909c languageName: node linkType: hard @@ -11074,22 +11227,22 @@ __metadata: languageName: node linkType: hard -"range-parser@npm:~1.2.1": +"range-parser@npm:^1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" checksum: 10c0/96c032ac2475c8027b7a4e9fe22dc0dfe0f6d90b85e496e0f016fbdb99d6d066de0112e680805075bd989905e2123b3b3d002765149294dce0c1f7f01fcc2ea0 languageName: node linkType: hard -"raw-body@npm:2.5.2": - version: 2.5.2 - resolution: "raw-body@npm:2.5.2" +"raw-body@npm:^3.0.0": + version: 3.0.1 + resolution: "raw-body@npm:3.0.1" dependencies: bytes: "npm:3.1.2" http-errors: "npm:2.0.0" - iconv-lite: "npm:0.4.24" + iconv-lite: "npm:0.7.0" unpipe: "npm:1.0.0" - checksum: 10c0/b201c4b66049369a60e766318caff5cb3cc5a900efd89bdac431463822d976ad0670912c931fdbdcf5543207daf6f6833bca57aa116e1661d2ea91e12ca692c4 + checksum: 10c0/892f4fbd21ecab7e2fed0f045f7af9e16df7e8050879639d4e482784a2f4640aaaa33d916a0e98013f23acb82e09c2e3c57f84ab97104449f728d22f65a7d79a languageName: node linkType: hard @@ -11143,19 +11296,6 @@ __metadata: languageName: node linkType: hard -"react-event-listener@npm:^0.6.0": - version: 0.6.6 - resolution: "react-event-listener@npm:0.6.6" - dependencies: - "@babel/runtime": "npm:^7.2.0" - prop-types: "npm:^15.6.0" - warning: "npm:^4.0.1" - peerDependencies: - react: ^16.3.0 - checksum: 10c0/07ca093d74b7963cb6048953517f881a0fdee9b485d31dabd49814cda51543eee20e714dd423e25946984b0ac26dbcb80aaf1211b0170e9b0cfa92fa85b0984e - languageName: node - linkType: hard - "react-fast-compare@npm:^3.1.1": version: 3.2.2 resolution: "react-fast-compare@npm:3.2.2" @@ -11302,10 +11442,10 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.17.0": - version: 0.17.0 - resolution: "react-refresh@npm:0.17.0" - checksum: 10c0/002cba940384c9930008c0bce26cac97a9d5682bc623112c2268ba0c155127d9c178a9a5cc2212d560088d60dfd503edd808669a25f9b377f316a32361d0b23c +"react-refresh@npm:^0.18.0": + version: 0.18.0 + resolution: "react-refresh@npm:0.18.0" + checksum: 10c0/34a262f7fd803433a534f50deb27a148112a81adcae440c7d1cbae7ef14d21ea8f2b3d783e858cb7698968183b77755a38b4d4b5b1d79b4f4689c2f6d358fff2 languageName: node linkType: hard @@ -11398,49 +11538,6 @@ __metadata: languageName: node linkType: hard -"react-swipeable-views-core@npm:^0.14.1": - version: 0.14.1 - resolution: "react-swipeable-views-core@npm:0.14.1" - dependencies: - "@babel/runtime": "npm:7.0.0" - warning: "npm:^4.0.1" - peerDependencies: - react: ^15.3.0 || ^16.0.0 || ^17.0.0 - checksum: 10c0/4da08493dad34f8498b66c596c1f40cd9a62e4968e71d00c79a26bf45e25ba3a3323e690641121cc8e7fd9c695e7da37fe781fa3f69e7d2b60fff3bfe4621426 - languageName: node - linkType: hard - -"react-swipeable-views-utils@npm:^0.14.1": - version: 0.14.1 - resolution: "react-swipeable-views-utils@npm:0.14.1" - dependencies: - "@babel/runtime": "npm:7.0.0" - keycode: "npm:^2.1.7" - prop-types: "npm:^15.6.0" - react-event-listener: "npm:^0.6.0" - react-swipeable-views-core: "npm:^0.14.1" - shallow-equal: "npm:^1.2.1" - peerDependencies: - react: ^15.3.0 || ^16.0.0 || ^17.0.0 - checksum: 10c0/f9a9930e7df9dab9cd0f5344c7cf0423cc8aff4728436eb7dc13588186fbd1a557c8250b6329ec09242f3f6d2700d33e1155ab191ce8de48aa860fad6fb1814b - languageName: node - linkType: hard - -"react-swipeable-views@npm:^0.14.0": - version: 0.14.1 - resolution: "react-swipeable-views@npm:0.14.1" - dependencies: - "@babel/runtime": "npm:7.0.0" - prop-types: "npm:^15.5.4" - react-swipeable-views-core: "npm:^0.14.1" - react-swipeable-views-utils: "npm:^0.14.1" - warning: "npm:^4.0.1" - peerDependencies: - react: ^15.3.0 || ^16.0.0 || ^17.0.0 - checksum: 10c0/7ee6d19cc33172e0846835eafd4b24ece0f26aed5cc9bbe80d3ec7c8d22f327443df8b2d50ddb4b837e1d6fbb40744abc41f62cdcab8e941e0663a952d627a15 - languageName: node - linkType: hard - "react-test-renderer@npm:^18.2.0": version: 18.3.1 resolution: "react-test-renderer@npm:18.3.1" @@ -11639,13 +11736,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.12.0": - version: 0.12.1 - resolution: "regenerator-runtime@npm:0.12.1" - checksum: 10c0/dbefbb38f5d6d55261aec1182d7c97ac93f2eec6ef9c756d9656eb5152f5cb3f8d873df020ddb4a3a8126c2ac1a3c2e534413cffe18d8f89b1c2a480a0a38601 - languageName: node - linkType: hard - "regenerator-runtime@npm:^0.13.3": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" @@ -11734,6 +11824,20 @@ __metadata: languageName: node linkType: hard +"reserved-identifiers@npm:^1.0.0": + version: 1.2.0 + resolution: "reserved-identifiers@npm:1.2.0" + checksum: 10c0/b82651b12e6c608e80463c3753d275bc20fd89294d0415f04e670aeec3611ae3582ddc19e8fedd497e7d0bcbfaddab6a12823ec86e855b1e6a245e0a734eb43d + languageName: node + linkType: hard + +"reserved-words@npm:^0.1.2": + version: 0.1.2 + resolution: "reserved-words@npm:0.1.2" + checksum: 10c0/88360388d88f4b36c1f5d47f8d596936dbf950bddd642c04ce940f1dab1fa58ef6fec23f5fab81a1bfe5cd0f223b2b635311496fcf0ef3db93ad4dfb6d7be186 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -11898,29 +12002,29 @@ __metadata: linkType: hard "rollup@npm:^4.43.0": - version: 4.46.2 - resolution: "rollup@npm:4.46.2" + version: 4.46.4 + resolution: "rollup@npm:4.46.4" dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.46.2" - "@rollup/rollup-android-arm64": "npm:4.46.2" - "@rollup/rollup-darwin-arm64": "npm:4.46.2" - "@rollup/rollup-darwin-x64": "npm:4.46.2" - "@rollup/rollup-freebsd-arm64": "npm:4.46.2" - "@rollup/rollup-freebsd-x64": "npm:4.46.2" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.46.2" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.46.2" - "@rollup/rollup-linux-arm64-gnu": "npm:4.46.2" - "@rollup/rollup-linux-arm64-musl": "npm:4.46.2" - "@rollup/rollup-linux-loongarch64-gnu": "npm:4.46.2" - "@rollup/rollup-linux-ppc64-gnu": "npm:4.46.2" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.46.2" - "@rollup/rollup-linux-riscv64-musl": "npm:4.46.2" - "@rollup/rollup-linux-s390x-gnu": "npm:4.46.2" - "@rollup/rollup-linux-x64-gnu": "npm:4.46.2" - "@rollup/rollup-linux-x64-musl": "npm:4.46.2" - "@rollup/rollup-win32-arm64-msvc": "npm:4.46.2" - "@rollup/rollup-win32-ia32-msvc": "npm:4.46.2" - "@rollup/rollup-win32-x64-msvc": "npm:4.46.2" + "@rollup/rollup-android-arm-eabi": "npm:4.46.4" + "@rollup/rollup-android-arm64": "npm:4.46.4" + "@rollup/rollup-darwin-arm64": "npm:4.46.4" + "@rollup/rollup-darwin-x64": "npm:4.46.4" + "@rollup/rollup-freebsd-arm64": "npm:4.46.4" + "@rollup/rollup-freebsd-x64": "npm:4.46.4" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.46.4" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.46.4" + "@rollup/rollup-linux-arm64-gnu": "npm:4.46.4" + "@rollup/rollup-linux-arm64-musl": "npm:4.46.4" + "@rollup/rollup-linux-loongarch64-gnu": "npm:4.46.4" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.46.4" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.46.4" + "@rollup/rollup-linux-riscv64-musl": "npm:4.46.4" + "@rollup/rollup-linux-s390x-gnu": "npm:4.46.4" + "@rollup/rollup-linux-x64-gnu": "npm:4.46.4" + "@rollup/rollup-linux-x64-musl": "npm:4.46.4" + "@rollup/rollup-win32-arm64-msvc": "npm:4.46.4" + "@rollup/rollup-win32-ia32-msvc": "npm:4.46.4" + "@rollup/rollup-win32-x64-msvc": "npm:4.46.4" "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -11968,14 +12072,20 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/f428497fe119fe7c4e34f1020d45ba13e99b94c9aa36958d88823d932b155c9df3d84f53166f3ee913ff68ea6c7599a9ab34861d88562ad9d8420f64ca5dad4c + checksum: 10c0/17871534544bd19ec9b5bc1d82a8509addbdb7ee0dd865f20352a8b5695e7b9288af842cd50187bed9fece61b0f1d7b7ff43cf070265d3a2e7d8348497e3ba1e languageName: node linkType: hard -"rrweb-cssom@npm:^0.8.0": - version: 0.8.0 - resolution: "rrweb-cssom@npm:0.8.0" - checksum: 10c0/56f2bfd56733adb92c0b56e274c43f864b8dd48784d6fe946ef5ff8d438234015e59ad837fc2ad54714b6421384141c1add4eb569e72054e350d1f8a50b8ac7b +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + is-promise: "npm:^4.0.0" + parseurl: "npm:^1.3.3" + path-to-regexp: "npm:^8.0.0" + checksum: 10c0/3279de7450c8eae2f6e095e9edacbdeec0abb5cb7249c6e719faa0db2dba43574b4fff5892d9220631c9abaff52dd3cad648cfea2aaace845e1a071915ac8867 languageName: node linkType: hard @@ -12036,16 +12146,16 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 languageName: node linkType: hard -"sass@npm:^1.62.1": - version: 1.93.2 - resolution: "sass@npm:1.93.2" +"sass@npm:^1.62.1, sass@npm:^1.70.0": + version: 1.93.3 + resolution: "sass@npm:1.93.3" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -12056,7 +12166,21 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/5a19f12dbe8c142e40c1e0473d1e624898242b1c21010301e169b528be8c580df6356329c798522b525eb11eda4b04b9b77422badc55c47889600f8477201d2b + checksum: 10c0/b9facc64de10c9d1514272c1dcbb48ca99d5f591a1cd43fd27d641275d9d95948f1299107ab5b309e2abb552667cca84a38a1a3df5116eb72eba4144bf850b6a + languageName: node + linkType: hard + +"sax@npm:^1.2.4": + version: 1.4.1 + resolution: "sax@npm:1.4.1" + checksum: 10c0/6bf86318a254c5d898ede6bd3ded15daf68ae08a5495a2739564eb265cd13bcc64a07ab466fb204f67ce472bb534eb8612dac587435515169593f4fffa11de7c + languageName: node + linkType: hard + +"sax@npm:~1.3.0": + version: 1.3.0 + resolution: "sax@npm:1.3.0" + checksum: 10c0/599dbe0ba9d8bd55e92d920239b21d101823a6cedff71e542589303fa0fa8f3ece6cf608baca0c51be846a2e88365fac94a9101a9c341d94b98e30c4deea5bea languageName: node linkType: hard @@ -12103,6 +12227,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.6.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: 10c0/e4cf10f86f168db772ae95d86ba65b3fd6c5967c94d97c708ccb463b778c2ee53b914cd7167620950fc07faf5a564e6efe903836639e512a1aa15fbc9667fa25 + languageName: node + linkType: hard + "semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -12112,33 +12245,31 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1, semver@npm:^7.7.2": - version: 7.7.2 - resolution: "semver@npm:7.7.2" +"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1, semver@npm:^7.7.3": + version: 7.7.3 + resolution: "semver@npm:7.7.3" bin: semver: bin/semver.js - checksum: 10c0/aca305edfbf2383c22571cb7714f48cadc7ac95371b4b52362fb8eeffdfbc0de0669368b82b2b15978f8848f01d7114da65697e56cd8c37b0dab8c58e543f9ea + checksum: 10c0/4afe5c986567db82f44c8c6faef8fe9df2a9b1d98098fc1721f57c696c4c21cebd572f297fc21002f81889492345b8470473bc6f4aff5fb032a6ea59ea2bc45e languageName: node linkType: hard -"send@npm:0.19.0": - version: 0.19.0 - resolution: "send@npm:0.19.0" +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.0 + resolution: "send@npm:1.2.0" dependencies: - debug: "npm:2.6.9" - depd: "npm:2.0.0" - destroy: "npm:1.2.0" - encodeurl: "npm:~1.0.2" - escape-html: "npm:~1.0.3" - etag: "npm:~1.8.1" - fresh: "npm:0.5.2" - http-errors: "npm:2.0.0" - mime: "npm:1.6.0" - ms: "npm:2.1.3" - on-finished: "npm:2.4.1" - range-parser: "npm:~1.2.1" - statuses: "npm:2.0.1" - checksum: 10c0/ea3f8a67a8f0be3d6bf9080f0baed6d2c51d11d4f7b4470de96a5029c598a7011c497511ccc28968b70ef05508675cebff27da9151dd2ceadd60be4e6cf845e3 + debug: "npm:^4.3.5" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + mime-types: "npm:^3.0.1" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.1" + checksum: 10c0/531bcfb5616948d3468d95a1fd0adaeb0c20818ba4a500f439b800ca2117971489e02074ce32796fd64a6772ea3e7235fe0583d8241dbd37a053dc3378eff9a5 languageName: node linkType: hard @@ -12151,15 +12282,15 @@ __metadata: languageName: node linkType: hard -"serve-static@npm:1.16.2": - version: 1.16.2 - resolution: "serve-static@npm:1.16.2" +"serve-static@npm:^2.2.0": + version: 2.2.0 + resolution: "serve-static@npm:2.2.0" dependencies: - encodeurl: "npm:~2.0.0" - escape-html: "npm:~1.0.3" - parseurl: "npm:~1.3.3" - send: "npm:0.19.0" - checksum: 10c0/528fff6f5e12d0c5a391229ad893910709bc51b5705962b09404a1d813857578149b8815f35d3ee5752f44cd378d0f31669d4b1d7e2d11f41e08283d5134bd1f + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + parseurl: "npm:^1.3.3" + send: "npm:^1.2.0" + checksum: 10c0/30e2ed1dbff1984836cfd0c65abf5d3f3f83bcd696c99d2d3c97edbd4e2a3ff4d3f87108a7d713640d290a7b6fe6c15ddcbc61165ab2eaad48ea8d3b52c7f913 languageName: node linkType: hard @@ -12207,13 +12338,6 @@ __metadata: languageName: node linkType: hard -"shallow-equal@npm:^1.2.1": - version: 1.2.1 - resolution: "shallow-equal@npm:1.2.1" - checksum: 10c0/51e03abadd97c9ebe590547d92db9148446962a3f23a3a0fb1ba2fccab80af881eef0ff1f8ccefd3f066c0bc5a4c8ca53706194813b95c8835fa66448a843a26 - languageName: node - linkType: hard - "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -12265,7 +12389,7 @@ __metadata: languageName: node linkType: hard -"side-channel@npm:^1.0.6, side-channel@npm:^1.1.0": +"side-channel@npm:^1.1.0": version: 1.1.0 resolution: "side-channel@npm:1.1.0" dependencies: @@ -12292,14 +12416,14 @@ __metadata: languageName: node linkType: hard -"sirv@npm:^3.0.1": - version: 3.0.1 - resolution: "sirv@npm:3.0.1" +"sirv@npm:^3.0.2": + version: 3.0.2 + resolution: "sirv@npm:3.0.2" dependencies: "@polka/url": "npm:^1.0.0-next.24" mrmime: "npm:^2.0.0" totalist: "npm:^3.0.0" - checksum: 10c0/7cf64b28daa69b15f77b38b0efdd02c007b72bb3ec5f107b208ebf59f01b174ef63a1db3aca16d2df925501831f4c209be6ece3302b98765919ef5088b45bf80 + checksum: 10c0/5930e4397afdb14fbae13751c3be983af4bda5c9aadec832607dc2af15a7162f7d518c71b30e83ae3644b9a24cea041543cc969e5fe2b80af6ce8ea3174b2d04 languageName: node linkType: hard @@ -12392,7 +12516,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.0, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf @@ -12423,17 +12547,17 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:~0.6.1": +"source-map@npm:^0.6.0, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 languageName: node linkType: hard -"source-map@npm:^0.7.4": - version: 0.7.4 - resolution: "source-map@npm:0.7.4" - checksum: 10c0/dc0cf3768fe23c345ea8760487f8c97ef6fca8a73c83cd7c9bf2fde8bc2c34adb9c0824d6feb14bc4f9e37fb522e18af621543f1289038a66ac7586da29aa7dc +"source-map@npm:^0.7.3, source-map@npm:^0.7.4": + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10c0/59f6f05538539b274ba771d2e9e32f6c65451982510564438e048bc1352f019c6efcdc6dd07909b1968144941c14015c2c7d4369fb7c4d7d53ae769716dcc16c languageName: node linkType: hard @@ -12582,19 +12706,18 @@ __metadata: languageName: node linkType: hard -"storybook@npm:^9.1.1": - version: 9.1.7 - resolution: "storybook@npm:9.1.7" +"storybook@npm:^10.0.2": + version: 10.0.2 + resolution: "storybook@npm:10.0.2" dependencies: "@storybook/global": "npm:^5.0.0" + "@storybook/icons": "npm:^1.6.0" "@testing-library/jest-dom": "npm:^6.6.3" "@testing-library/user-event": "npm:^14.6.1" "@vitest/expect": "npm:3.2.4" "@vitest/mocker": "npm:3.2.4" "@vitest/spy": "npm:3.2.4" - better-opn: "npm:^3.0.2" esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" - esbuild-register: "npm:^3.5.0" recast: "npm:^0.23.5" semver: "npm:^7.6.2" ws: "npm:^8.18.0" @@ -12604,8 +12727,8 @@ __metadata: prettier: optional: true bin: - storybook: ./bin/index.cjs - checksum: 10c0/daf3fb47ada1368604db7a1bc53775a5ceb485cd103351670e74d3378cb7bc1e396f72530a4821f3919207fb55ce7904ce894f55566844f9a14279553a8bd534 + storybook: ./dist/bin/dispatcher.js + checksum: 10c0/abf796718bff0a848959f9dcfdb2699ce8aa824c3d190c401fcff325db0a0fcd5d0436be5628a93284e03a6f8bc5d2be3147eeef352cf9b879e3b7644875dcf5 languageName: node linkType: hard @@ -12616,7 +12739,7 @@ __metadata: languageName: node linkType: hard -"string-argv@npm:0.3.2": +"string-argv@npm:^0.3.2": version: 0.3.2 resolution: "string-argv@npm:0.3.2" checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82 @@ -12830,15 +12953,6 @@ __metadata: languageName: node linkType: hard -"strip-literal@npm:^3.0.0": - version: 3.0.0 - resolution: "strip-literal@npm:3.0.0" - dependencies: - js-tokens: "npm:^9.0.1" - checksum: 10c0/d81657f84aba42d4bbaf2a677f7e7f34c1f3de5a6726db8bc1797f9c0b303ba54d4660383a74bde43df401cf37cce1dff2c842c55b077a4ceee11f9e31fba828 - languageName: node - linkType: hard - "stylelint-config-prettier-scss@npm:^1.0.0": version: 1.0.0 resolution: "stylelint-config-prettier-scss@npm:1.0.0" @@ -12923,20 +13037,20 @@ __metadata: linkType: hard "stylelint@npm:^16.19.1": - version: 16.24.0 - resolution: "stylelint@npm:16.24.0" + version: 16.25.0 + resolution: "stylelint@npm:16.25.0" dependencies: "@csstools/css-parser-algorithms": "npm:^3.0.5" "@csstools/css-tokenizer": "npm:^3.0.4" "@csstools/media-query-list-parser": "npm:^4.0.3" "@csstools/selector-specificity": "npm:^5.0.0" - "@dual-bundle/import-meta-resolve": "npm:^4.1.0" + "@dual-bundle/import-meta-resolve": "npm:^4.2.1" balanced-match: "npm:^2.0.0" colord: "npm:^2.9.3" cosmiconfig: "npm:^9.0.0" css-functions-list: "npm:^3.2.3" css-tree: "npm:^3.1.0" - debug: "npm:^4.4.1" + debug: "npm:^4.4.3" fast-glob: "npm:^3.3.3" fastest-levenshtein: "npm:^1.0.16" file-entry-cache: "npm:^10.1.4" @@ -12966,7 +13080,7 @@ __metadata: write-file-atomic: "npm:^5.0.1" bin: stylelint: bin/stylelint.mjs - checksum: 10c0/f694bfa86b8030d71e0ebd7eb815e927869481325af9a096d574d60d459944d3f11c295a5ed8885ae3d090aa1ab9431698fba1b7b99cea9884f7c762433a2891 + checksum: 10c0/80fa44ff5197419647306d9b2cf3804c10255ac30a96bb3390f2a3f1debee80e2e1cde81bb4e87d9179ababc9cc0ad6c362661835ee1d32a509b7fe44a8d3dd6 languageName: node linkType: hard @@ -12977,6 +13091,21 @@ __metadata: languageName: node linkType: hard +"stylus@npm:^0.62.0": + version: 0.62.0 + resolution: "stylus@npm:0.62.0" + dependencies: + "@adobe/css-tools": "npm:~4.3.1" + debug: "npm:^4.3.2" + glob: "npm:^7.1.6" + sax: "npm:~1.3.0" + source-map: "npm:^0.7.3" + bin: + stylus: bin/stylus + checksum: 10c0/62afe3a6d781f66d7d283e8218dc1a15530d7d89fc2f09457a723975b2073e96e0d32c61d7f0dd1bd2686aae4ab6cc6933dc85e1b72eebab8aa30167bd16962b + languageName: node + linkType: hard + "substring-trie@npm:^1.0.2": version: 1.0.2 resolution: "substring-trie@npm:1.0.2" @@ -13131,17 +13260,6 @@ __metadata: languageName: node linkType: hard -"test-exclude@npm:^7.0.1": - version: 7.0.1 - resolution: "test-exclude@npm:7.0.1" - dependencies: - "@istanbuljs/schema": "npm:^0.1.2" - glob: "npm:^10.4.1" - minimatch: "npm:^9.0.4" - checksum: 10c0/6d67b9af4336a2e12b26a68c83308c7863534c65f27ed4ff7068a56f5a58f7ac703e8fc80f698a19bb154fd8f705cdf7ec347d9512b2c522c737269507e7b263 - languageName: node - linkType: hard - "thread-stream@npm:^3.0.0": version: 3.0.0 resolution: "thread-stream@npm:3.0.0" @@ -13196,13 +13314,6 @@ __metadata: languageName: node linkType: hard -"tinypool@npm:^1.1.1": - version: 1.1.1 - resolution: "tinypool@npm:1.1.1" - checksum: 10c0/bf26727d01443061b04fa863f571016950888ea994ba0cd8cba3a1c51e2458d84574341ab8dbc3664f1c3ab20885c8cf9ff1cc4b18201f04c2cde7d317fff69b - languageName: node - linkType: hard - "tinyrainbow@npm:^2.0.0": version: 2.0.0 resolution: "tinyrainbow@npm:2.0.0" @@ -13210,6 +13321,13 @@ __metadata: languageName: node linkType: hard +"tinyrainbow@npm:^3.0.3": + version: 3.0.3 + resolution: "tinyrainbow@npm:3.0.3" + checksum: 10c0/1e799d35cd23cabe02e22550985a3051dc88814a979be02dc632a159c393a998628eacfc558e4c746b3006606d54b00bcdea0c39301133956d10a27aa27e988c + languageName: node + linkType: hard + "tinyspy@npm:^4.0.3": version: 4.0.3 resolution: "tinyspy@npm:4.0.3" @@ -13244,6 +13362,16 @@ __metadata: languageName: node linkType: hard +"to-valid-identifier@npm:^1.0.0": + version: 1.0.0 + resolution: "to-valid-identifier@npm:1.0.0" + dependencies: + "@sindresorhus/base62": "npm:^1.0.0" + reserved-identifiers: "npm:^1.0.0" + checksum: 10c0/569b49f43b5aaaa20677e67f0f1cdcff344855149934cfb80c793c7ac7c30e191b224bc81cab40fb57641af9ca73795c78053c164a2addc617671e2d22c13a4a + languageName: node + linkType: hard + "toidentifier@npm:1.0.1": version: 1.0.1 resolution: "toidentifier@npm:1.0.1" @@ -13352,7 +13480,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.8.0": +"tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 @@ -13408,13 +13536,14 @@ __metadata: languageName: node linkType: hard -"type-is@npm:~1.6.18": - version: 1.6.18 - resolution: "type-is@npm:1.6.18" +"type-is@npm:^2.0.0, type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" dependencies: - media-typer: "npm:0.3.0" - mime-types: "npm:~2.1.24" - checksum: 10c0/a23daeb538591b7efbd61ecf06b6feb2501b683ffdc9a19c74ef5baba362b4347e42f1b4ed81f5882a8c96a3bfff7f93ce3ffaf0cbbc879b532b04c97a55db9d + content-type: "npm:^1.0.5" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10c0/7f7ec0a060b16880bdad36824ab37c26019454b67d73e8a465ed5a3587440fbe158bc765f0da68344498235c877e7dbbb1600beccc94628ed05599d667951b99 languageName: node linkType: hard @@ -13472,37 +13601,66 @@ __metadata: linkType: hard "typescript-eslint@npm:^8.28.0, typescript-eslint@npm:^8.45.0": - version: 8.45.0 - resolution: "typescript-eslint@npm:8.45.0" + version: 8.46.3 + resolution: "typescript-eslint@npm:8.46.3" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.45.0" - "@typescript-eslint/parser": "npm:8.45.0" - "@typescript-eslint/typescript-estree": "npm:8.45.0" - "@typescript-eslint/utils": "npm:8.45.0" + "@typescript-eslint/eslint-plugin": "npm:8.46.3" + "@typescript-eslint/parser": "npm:8.46.3" + "@typescript-eslint/typescript-estree": "npm:8.46.3" + "@typescript-eslint/utils": "npm:8.46.3" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <6.0.0" - checksum: 10c0/2342b0bffe6f719711adbb42116f90cb1fe1670e2e74dde2739482c9d61c2a975ee16e2d560684613050544b543342ec1b11b46e158a48ecc605f5882d2d5da7 + checksum: 10c0/c6d9398b16429b614c96405caae018b7ea74df55abf5ba9248ca9d02327704d6e1c3bdd2e2f52cfb25c9e5465ad93d73e19ee7fc3afbb837a6aeeecdf02c979b + languageName: node + linkType: hard + +"typescript-plugin-css-modules@npm:^5.2.0": + version: 5.2.0 + resolution: "typescript-plugin-css-modules@npm:5.2.0" + dependencies: + "@types/postcss-modules-local-by-default": "npm:^4.0.2" + "@types/postcss-modules-scope": "npm:^3.0.4" + dotenv: "npm:^16.4.2" + icss-utils: "npm:^5.1.0" + less: "npm:^4.2.0" + lodash.camelcase: "npm:^4.3.0" + postcss: "npm:^8.4.35" + postcss-load-config: "npm:^3.1.4" + postcss-modules-extract-imports: "npm:^3.0.0" + postcss-modules-local-by-default: "npm:^4.0.4" + postcss-modules-scope: "npm:^3.1.1" + reserved-words: "npm:^0.1.2" + sass: "npm:^1.70.0" + source-map-js: "npm:^1.0.2" + stylus: "npm:^0.62.0" + tsconfig-paths: "npm:^4.2.0" + peerDependencies: + typescript: ">=4.0.0" + dependenciesMeta: + stylus: + optional: true + checksum: 10c0/7cd024f7145c0a29d9b78f2fb49c42cdf1747b50a43391f9993132ba42a727266f9b544fd868d905d5352e0a8676a19ae7a9aa56d516cc819c3ab39d66aa25e4 languageName: node linkType: hard "typescript@npm:^5.6.0, typescript@npm:~5.9.0": - version: 5.9.2 - resolution: "typescript@npm:5.9.2" + version: 5.9.3 + resolution: "typescript@npm:5.9.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/cd635d50f02d6cf98ed42de2f76289701c1ec587a363369255f01ed15aaf22be0813226bff3c53e99d971f9b540e0b3cc7583dbe05faded49b1b0bed2f638a18 + checksum: 10c0/6bd7552ce39f97e711db5aa048f6f9995b53f1c52f7d8667c1abdc1700c68a76a308f579cd309ce6b53646deb4e9a1be7c813a93baaf0a28ccd536a30270e1c5 languageName: node linkType: hard "typescript@patch:typescript@npm%3A^5.6.0#optional!builtin, typescript@patch:typescript@npm%3A~5.9.0#optional!builtin": - version: 5.9.2 - resolution: "typescript@patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5" + version: 5.9.3 + resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/34d2a8e23eb8e0d1875072064d5e1d9c102e0bdce56a10a25c0b917b8aa9001a9cf5c225df12497e99da107dc379360bc138163c66b55b95f5b105b50578067e + checksum: 10c0/ad09fdf7a756814dce65bc60c1657b40d44451346858eea230e10f2e95a289d9183b6e32e5c11e95acc0ccc214b4f36289dcad4bf1886b0adb84d711d336a430 languageName: node linkType: hard @@ -13579,13 +13737,6 @@ __metadata: languageName: node linkType: hard -"unicorn-magic@npm:^0.1.0": - version: 0.1.0 - resolution: "unicorn-magic@npm:0.1.0" - checksum: 10c0/e4ed0de05b0a05e735c7d8a2930881e5efcfc3ec897204d5d33e7e6247f4c31eac92e383a15d9a6bccb7319b4271ee4bea946e211bf14951fec6ff2cbbb66a92 - languageName: node - linkType: hard - "unique-filename@npm:^4.0.0": version: 4.0.0 resolution: "unique-filename@npm:4.0.0" @@ -13620,20 +13771,22 @@ __metadata: languageName: node linkType: hard -"unpipe@npm:1.0.0, unpipe@npm:~1.0.0": +"unpipe@npm:1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" checksum: 10c0/193400255bd48968e5c5383730344fbb4fa114cdedfab26e329e50dd2d81b134244bb8a72c6ac1b10ab0281a58b363d06405632c9d49ca9dfd5e90cbd7d0f32c languageName: node linkType: hard -"unplugin@npm:^1.3.1": - version: 1.16.1 - resolution: "unplugin@npm:1.16.1" +"unplugin@npm:^2.3.5": + version: 2.3.10 + resolution: "unplugin@npm:2.3.10" dependencies: - acorn: "npm:^8.14.0" + "@jridgewell/remapping": "npm:^2.3.5" + acorn: "npm:^8.15.0" + picomatch: "npm:^4.0.3" webpack-virtual-modules: "npm:^0.6.2" - checksum: 10c0/dd5f8c5727d0135847da73cf03fb199107f1acf458167034886fda3405737dab871ad3926431b4f70e1e82cdac482ac1383cea4019d782a68515c8e3e611b6cc + checksum: 10c0/29dcd738772aeff91c6f0154f156c95c58a37a4674fcb7cc34d6868af763834f0f447a1c3af074818c0c5602baead49bd3b9399a13f0425d69a00a527e58ddda languageName: node linkType: hard @@ -13811,13 +13964,6 @@ __metadata: languageName: node linkType: hard -"utils-merge@npm:1.0.1": - version: 1.0.1 - resolution: "utils-merge@npm:1.0.1" - checksum: 10c0/02ba649de1b7ca8854bfe20a82f1dfbdda3fb57a22ab4a8972a63a34553cf7aa51bc9081cf7e001b035b88186d23689d69e71b510e610a09a4c66f68aa95b672 - languageName: node - linkType: hard - "uuid@npm:^13.0.0": version: 13.0.0 resolution: "uuid@npm:13.0.0" @@ -13834,28 +13980,13 @@ __metadata: languageName: node linkType: hard -"vary@npm:^1, vary@npm:~1.1.2": +"vary@npm:^1, vary@npm:^1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" checksum: 10c0/f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f languageName: node linkType: hard -"vite-node@npm:3.2.4": - version: 3.2.4 - resolution: "vite-node@npm:3.2.4" - dependencies: - cac: "npm:^6.7.14" - debug: "npm:^4.4.1" - es-module-lexer: "npm:^1.7.0" - pathe: "npm:^2.0.3" - vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" - bin: - vite-node: vite-node.mjs - checksum: 10c0/6ceca67c002f8ef6397d58b9539f80f2b5d79e103a18367288b3f00a8ab55affa3d711d86d9112fce5a7fa658a212a087a005a045eb8f4758947dd99af2a6c6b - languageName: node - linkType: hard - "vite-plugin-manifest-sri@npm:^0.2.0": version: 0.2.0 resolution: "vite-plugin-manifest-sri@npm:0.2.0" @@ -13927,9 +14058,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0, vite@npm:^7.1.1": - version: 7.1.12 - resolution: "vite@npm:7.1.12" +"vite@npm:^6.0.0 || ^7.0.0, vite@npm:^7.1.1": + version: 7.2.2 + resolution: "vite@npm:7.2.2" dependencies: esbuild: "npm:^0.25.0" fdir: "npm:^6.5.0" @@ -13978,43 +14109,42 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/cef4d4b4a84e663e09b858964af36e916892ac8540068df42a05ced637ceeae5e9ef71c72d54f3cfc1f3c254af16634230e221b6e2327c2a66d794bb49203262 + checksum: 10c0/9c76ee441f8dbec645ddaecc28d1f9cf35670ffa91cff69af7b1d5081545331603f0b1289d437b2fa8dc43cdc77b4d96b5bd9c9aed66310f490cb1a06f9c814c languageName: node linkType: hard -"vitest@npm:^3.2.4": - version: 3.2.4 - resolution: "vitest@npm:3.2.4" +"vitest@npm:^4.0.5": + version: 4.0.7 + resolution: "vitest@npm:4.0.7" dependencies: - "@types/chai": "npm:^5.2.2" - "@vitest/expect": "npm:3.2.4" - "@vitest/mocker": "npm:3.2.4" - "@vitest/pretty-format": "npm:^3.2.4" - "@vitest/runner": "npm:3.2.4" - "@vitest/snapshot": "npm:3.2.4" - "@vitest/spy": "npm:3.2.4" - "@vitest/utils": "npm:3.2.4" - chai: "npm:^5.2.0" - debug: "npm:^4.4.1" - expect-type: "npm:^1.2.1" - magic-string: "npm:^0.30.17" + "@vitest/expect": "npm:4.0.7" + "@vitest/mocker": "npm:4.0.7" + "@vitest/pretty-format": "npm:4.0.7" + "@vitest/runner": "npm:4.0.7" + "@vitest/snapshot": "npm:4.0.7" + "@vitest/spy": "npm:4.0.7" + "@vitest/utils": "npm:4.0.7" + debug: "npm:^4.4.3" + es-module-lexer: "npm:^1.7.0" + expect-type: "npm:^1.2.2" + magic-string: "npm:^0.30.19" pathe: "npm:^2.0.3" - picomatch: "npm:^4.0.2" + picomatch: "npm:^4.0.3" std-env: "npm:^3.9.0" tinybench: "npm:^2.9.0" tinyexec: "npm:^0.3.2" - tinyglobby: "npm:^0.2.14" - tinypool: "npm:^1.1.1" - tinyrainbow: "npm:^2.0.0" - vite: "npm:^5.0.0 || ^6.0.0 || ^7.0.0-0" - vite-node: "npm:3.2.4" + tinyglobby: "npm:^0.2.15" + tinyrainbow: "npm:^3.0.3" + vite: "npm:^6.0.0 || ^7.0.0" why-is-node-running: "npm:^2.3.0" peerDependencies: "@edge-runtime/vm": "*" "@types/debug": ^4.1.12 - "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0 - "@vitest/browser": 3.2.4 - "@vitest/ui": 3.2.4 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.0.7 + "@vitest/browser-preview": 4.0.7 + "@vitest/browser-webdriverio": 4.0.7 + "@vitest/ui": 4.0.7 happy-dom: "*" jsdom: "*" peerDependenciesMeta: @@ -14024,7 +14154,11 @@ __metadata: optional: true "@types/node": optional: true - "@vitest/browser": + "@vitest/browser-playwright": + optional: true + "@vitest/browser-preview": + optional: true + "@vitest/browser-webdriverio": optional: true "@vitest/ui": optional: true @@ -14034,7 +14168,7 @@ __metadata: optional: true bin: vitest: vitest.mjs - checksum: 10c0/5bf53ede3ae6a0e08956d72dab279ae90503f6b5a05298a6a5e6ef47d2fd1ab386aaf48fafa61ed07a0ebfe9e371772f1ccbe5c258dd765206a8218bf2eb79eb + checksum: 10c0/d5312e11e9ffbaf239fa5cb5d43e81a43adbdb085bf113c237eff3531805a347e6587ad1dd368a5e9639ff23f8f48650e689fb49c3cf9375d922ef2767a6416a languageName: node linkType: hard @@ -14047,7 +14181,7 @@ __metadata: languageName: node linkType: hard -"warning@npm:^4.0.1, warning@npm:^4.0.3": +"warning@npm:^4.0.3": version: 4.0.3 resolution: "warning@npm:4.0.3" dependencies: @@ -14502,7 +14636,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.12.1, ws@npm:^8.18.0, ws@npm:^8.18.2, ws@npm:^8.18.3": +"ws@npm:^8.12.1, ws@npm:^8.18.0, ws@npm:^8.18.3": version: 8.18.3 resolution: "ws@npm:8.18.3" peerDependencies: @@ -14566,7 +14700,14 @@ __metadata: languageName: node linkType: hard -"yaml@npm:2.8.1": +"yaml@npm:^1.10.0, yaml@npm:^1.10.2": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f + languageName: node + linkType: hard + +"yaml@npm:^2.8.1": version: 2.8.1 resolution: "yaml@npm:2.8.1" bin: @@ -14575,13 +14716,6 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.10.0": - version: 1.10.2 - resolution: "yaml@npm:1.10.2" - checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f - languageName: node - linkType: hard - "yargs-parser@npm:^21.1.1": version: 21.1.1 resolution: "yargs-parser@npm:21.1.1" @@ -14611,13 +14745,6 @@ __metadata: languageName: node linkType: hard -"yocto-queue@npm:^1.0.0": - version: 1.2.1 - resolution: "yocto-queue@npm:1.2.1" - checksum: 10c0/5762caa3d0b421f4bdb7a1926b2ae2189fc6e4a14469258f183600028eb16db3e9e0306f46e8ebf5a52ff4b81a881f22637afefbef5399d6ad440824e9b27f9f - languageName: node - linkType: hard - "yoctocolors-cjs@npm:^2.1.2": version: 2.1.2 resolution: "yoctocolors-cjs@npm:2.1.2" @@ -14631,3 +14758,19 @@ __metadata: checksum: 10c0/2d110bfcb0f8b8dbf225423f6556da9c5bca95c8b849c1218983676158a24b5cd0350357e0c4d504e27f8c7e18d471d9712576f35114a81a51bcf83453f02beb languageName: node linkType: hard + +"zod-validation-error@npm:^3.5.0 || ^4.0.0": + version: 4.0.2 + resolution: "zod-validation-error@npm:4.0.2" + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + checksum: 10c0/0ccfec48c46de1be440b719cd02044d4abb89ed0e14c13e637cd55bf29102f67ccdba373f25def0fc7130e5f15025be4d557a7edcc95d5a3811599aade689e1b + languageName: node + linkType: hard + +"zod@npm:^3.25.0 || ^4.0.0": + version: 4.1.12 + resolution: "zod@npm:4.1.12" + checksum: 10c0/b64c1feb19e99d77075261eaf613e0b2be4dfcd3551eff65ad8b4f2a079b61e379854d066f7d447491fcf193f45babd8095551a9d47973d30b46b6d8e2c46774 + languageName: node + linkType: hard